This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[6/6] Fold prev/next into gimple: do it


Hi,

and this patch flips the switch.  It removes the old seq_node and seq 
structures, adds the prev/next to gimple_statement_base, merges gimple, 
gimple_seq and gimple_seq_node and rewrites the helpers dealing with 
sequences or iterators to deal with the data structure of a cyclic list in 
the prev links and a NULL-ended list in the next links.

Note how a const_gimple_seq doesn't make sense anymore (I've typedefed it 
simply to gimple) as I'd have to add const casts for the (few) accessors.

Due to the adjustment of the WORD markers in gimple.h this patch is a bit 
longer than the functional changes imply.

There's one thing I'd like an opinion about: I've added two new flags to 
gimple_statement_base: start_of_seq and end_of_seq, and I had to 
shorten the uid member by two bits for that.  The two flags are used only 
for asserts (though they are updated always, they just aren't read except 
in asserts).  As I'm now finished developing this thing I'm not super sure 
about the usefullness of the asserts anymore, IIRC they didn't hit very 
often while developing; rather bugs usually turned into endless loops in 
sequence walkers.  So, I'd be happy to take them out again, straighten the 
asserts and leave uid be a normal 32bit integer.  Just tell me.

As per [0/6] regstrapped with the other five patches on x86_64-linux.  
Okay for trunk (with or without the start/end_of_seq flags)?


Ciao,
Michael.
----------------------
2012-05-02  Michael Matz  <matz@suse.de>

	* coretypes.h (gimple_seq, const_gimple_seq): Typedef as gimple.
	* gimple.h (struct gimple_seq_node_d, struct gimple_seq_d): Remove.
	(const_gimple_seq_node): Remove.
	(gimple_seq_node): Typedef as gimple.
	(struct gimple_statement_base): Add start_of_seq and end_of_seq
	members, make uid a 30 bit bitfield, add next and prev members.
	Adjust all WORD markers in using structs.
	(union gimple_statement_d): Link via gsbase.next field for GC and PCH.
	(gimple_seq_first, gimple_seq_first_stmt, gimple_seq_last,
	gimple_seq_last_stmt): Adjust as gimple_seq, gimple_seq_node and
	gimple are the same.
	(gimple_seq_set_last, gimple_seq_set_first): Don't allocate
	gimple_seq, adjust.
	(gsi_start_1, gsi_last_1, gsi_end_p, gsi_one_before_end_p): Adjust.
	(gsi_next, gsi_prev): Adjust, handle prev cyclic list correctly.
	(gsi_stmt): Adjust.
	(gsi_stmt_ptr): Remove.
	(enum gimple_alloc_kind): Remove gimple_alloc_kind_seq member.

	* gimple-iterator.c (update_bb_for_stmts): Take last parameter
	again, adjust for above changes.
	(update_call_edge_frequencies): Adjust for above changes.
	(gsi_insert_seq_nodes_before): Rewrite for new data structure.
	(gsi_insert_seq_nodes_after): Ditto.
	(gsi_split_seq_after): Ditto.
	(gsi_set_stmt): Ditto.
	(gsi_split_seq_before): Ditto.
	(gsi_remove): Ditto.
	(gsi_insert_seq_before_without_update): Don't free sequence.
	(gsi_insert_seq_after_without_update): Ditto.
	(gsi_replace): Assert some more invariants.
	(gsi_insert_before_without_update, gsi_insert_after_without_update):
	Tidy.
	(gsi_for_stmt): Don't search for stmt.
	(gsi_insert_on_edge_immediate): Tidy.

	* gimple.c (gimple_alloc_k): Remove "sequences".
	(gimple_seq_cache): Remove.
	(gimple_alloc_stat): Make stmt a singleton sequence.
	(gimple_seq_alloc, gimple_seq_free): Remove.
	(gimple_assign_set_rhs_with_ops_1): Ensure new stmt is a singleton.
	(gimple_copy): Ditto.
	* gimplify.c (gimplify_cleanup_point_expr): Use gsi_set_stmt,
	create iterator from correct sequence.
	* tree-phinodes.c (make_phi_node): Make stmt a singleton.

Index: gimple.h
===================================================================
*** gimple.h.orig	2012-05-01 22:44:17.000000000 +0200
--- gimple.h	2012-05-01 22:44:18.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 32,40 ****
  #include "tree-ssa-alias.h"
  #include "internal-fn.h"
  
! struct gimple_seq_node_d;
! typedef struct gimple_seq_node_d *gimple_seq_node;
! typedef const struct gimple_seq_node_d *const_gimple_seq_node;
  
  /* For each block, the PHI nodes that need to be rewritten are stored into
     these vectors.  */
--- 32,38 ----
  #include "tree-ssa-alias.h"
  #include "internal-fn.h"
  
! typedef gimple gimple_seq_node;
  
  /* For each block, the PHI nodes that need to be rewritten are stored into
     these vectors.  */
*************** enum plf_mask {
*** 133,159 ****
      GF_PLF_2	= 1 << 1
  };
  
- /* A node in a gimple_seq_d.  */
- struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) gimple_seq_node_d {
-   gimple stmt;
-   struct gimple_seq_node_d *prev;
-   struct gimple_seq_node_d *next;
- };
- 
- /* A double-linked sequence of gimple statements.  */
- struct GTY ((chain_next ("%h.next_free"))) gimple_seq_d {
-   /* First and last statements in the sequence.  */
-   gimple_seq_node first;
-   gimple_seq_node last;
- 
-   /* Sequences are created/destroyed frequently.  To minimize
-      allocation activity, deallocated sequences are kept in a pool of
-      available sequences.  This is the pointer to the next free
-      sequence in the pool.  */
-   gimple_seq next_free;
- };
- 
- 
  /* Iterator object for GIMPLE statement sequences.  */
  
  typedef struct
--- 131,136 ----
*************** struct GTY(()) gimple_statement_base {
*** 216,222 ****
    /* UID of this statement.  This is used by passes that want to
       assign IDs to statements.  It must be assigned and used by each
       pass.  By default it should be assumed to contain garbage.  */
!   unsigned uid;
  
    /* [ WORD 2 ]
       Locus information for debug info.  */
--- 193,201 ----
    /* UID of this statement.  This is used by passes that want to
       assign IDs to statements.  It must be assigned and used by each
       pass.  By default it should be assumed to contain garbage.  */
!   unsigned uid			: 30;
!   unsigned start_of_seq		: 1;
!   unsigned end_of_seq		: 1;
  
    /* [ WORD 2 ]
       Locus information for debug info.  */
*************** struct GTY(()) gimple_statement_base {
*** 229,235 ****
       Basic block holding this statement.  */
    struct basic_block_def *bb;
  
!   /* [ WORD 4 ]
       Lexical block holding this statement.  */
    tree block;
  };
--- 208,223 ----
       Basic block holding this statement.  */
    struct basic_block_def *bb;
  
!   /* [ WORD 4-5 ]
!      Linked lists of gimple statements.  The next pointers form
!      a NULL terminated list, the prev pointers are a cyclic list.
!      A gimple statement is hence also a double-ended list of
!      statements, with the pointer itself being the first element,
!      and the prev pointer being the last.  */
!   gimple next;
!   gimple GTY((skip)) prev;
! 
!   /* [ WORD 6 ]
       Lexical block holding this statement.  */
    tree block;
  };
*************** struct GTY(()) gimple_statement_base {
*** 239,248 ****
  
  struct GTY(()) gimple_statement_with_ops_base
  {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5-6 ]
       SSA operand vectors.  NOTE: It should be possible to
       amalgamate these vectors with the operand vector OP.  However,
       the SSA operand vectors are organized differently and contain
--- 227,236 ----
  
  struct GTY(()) gimple_statement_with_ops_base
  {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 7-8 ]
       SSA operand vectors.  NOTE: It should be possible to
       amalgamate these vectors with the operand vector OP.  However,
       the SSA operand vectors are organized differently and contain
*************** struct GTY(()) gimple_statement_with_ops
*** 256,265 ****
  
  struct GTY(()) gimple_statement_with_ops
  {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_with_ops_base opbase;
  
!   /* [ WORD 7 ]
       Operand vector.  NOTE!  This must always be the last field
       of this structure.  In particular, this means that this
       structure cannot be embedded inside another one.  */
--- 244,253 ----
  
  struct GTY(()) gimple_statement_with_ops
  {
!   /* [ WORD 1-8 ]  */
    struct gimple_statement_with_ops_base opbase;
  
!   /* [ WORD 9 ]
       Operand vector.  NOTE!  This must always be the last field
       of this structure.  In particular, this means that this
       structure cannot be embedded inside another one.  */
*************** struct GTY(()) gimple_statement_with_ops
*** 271,280 ****
  
  struct GTY(()) gimple_statement_with_memory_ops_base
  {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_with_ops_base opbase;
  
!   /* [ WORD 7-8 ]
       Virtual operands for this statement.  The GC will pick them
       up via the ssa_names array.  */
    tree GTY((skip (""))) vdef;
--- 259,268 ----
  
  struct GTY(()) gimple_statement_with_memory_ops_base
  {
!   /* [ WORD 1-8 ]  */
    struct gimple_statement_with_ops_base opbase;
  
!   /* [ WORD 9-10 ]
       Virtual operands for this statement.  The GC will pick them
       up via the ssa_names array.  */
    tree GTY((skip (""))) vdef;
*************** struct GTY(()) gimple_statement_with_mem
*** 286,295 ****
  
  struct GTY(()) gimple_statement_with_memory_ops
  {
!   /* [ WORD 1-8 ]  */
    struct gimple_statement_with_memory_ops_base membase;
  
!   /* [ WORD 9 ]
       Operand vector.  NOTE!  This must always be the last field
       of this structure.  In particular, this means that this
       structure cannot be embedded inside another one.  */
--- 274,283 ----
  
  struct GTY(()) gimple_statement_with_memory_ops
  {
!   /* [ WORD 1-10 ]  */
    struct gimple_statement_with_memory_ops_base membase;
  
!   /* [ WORD 11 ]
       Operand vector.  NOTE!  This must always be the last field
       of this structure.  In particular, this means that this
       structure cannot be embedded inside another one.  */
*************** struct GTY(()) gimple_statement_with_mem
*** 301,320 ****
  
  struct GTY(()) gimple_statement_call
  {
!   /* [ WORD 1-8 ]  */
    struct gimple_statement_with_memory_ops_base membase;
  
!   /* [ WORD 9-12 ]  */
    struct pt_solution call_used;
    struct pt_solution call_clobbered;
  
!   /* [ WORD 13 ]  */
    union GTY ((desc ("%1.membase.opbase.gsbase.subcode & GF_CALL_INTERNAL"))) {
      tree GTY ((tag ("0"))) fntype;
      enum internal_fn GTY ((tag ("GF_CALL_INTERNAL"))) internal_fn;
    } u;
  
!   /* [ WORD 14 ]
       Operand vector.  NOTE!  This must always be the last field
       of this structure.  In particular, this means that this
       structure cannot be embedded inside another one.  */
--- 289,308 ----
  
  struct GTY(()) gimple_statement_call
  {
!   /* [ WORD 1-10 ]  */
    struct gimple_statement_with_memory_ops_base membase;
  
!   /* [ WORD 11-14 ]  */
    struct pt_solution call_used;
    struct pt_solution call_clobbered;
  
!   /* [ WORD 15 ]  */
    union GTY ((desc ("%1.membase.opbase.gsbase.subcode & GF_CALL_INTERNAL"))) {
      tree GTY ((tag ("0"))) fntype;
      enum internal_fn GTY ((tag ("GF_CALL_INTERNAL"))) internal_fn;
    } u;
  
!   /* [ WORD 16 ]
       Operand vector.  NOTE!  This must always be the last field
       of this structure.  In particular, this means that this
       structure cannot be embedded inside another one.  */
*************** struct GTY(()) gimple_statement_call
*** 325,334 ****
  /* OpenMP statements (#pragma omp).  */
  
  struct GTY(()) gimple_statement_omp {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5 ]  */
    gimple_seq body;
  };
  
--- 313,322 ----
  /* OpenMP statements (#pragma omp).  */
  
  struct GTY(()) gimple_statement_omp {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 7 ]  */
    gimple_seq body;
  };
  
*************** struct GTY(()) gimple_statement_omp {
*** 336,349 ****
  /* GIMPLE_BIND */
  
  struct GTY(()) gimple_statement_bind {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5 ]
       Variables declared in this scope.  */
    tree vars;
  
!   /* [ WORD 6 ]
       This is different than the BLOCK field in gimple_statement_base,
       which is analogous to TREE_BLOCK (i.e., the lexical block holding
       this statement).  This field is the equivalent of BIND_EXPR_BLOCK
--- 324,337 ----
  /* GIMPLE_BIND */
  
  struct GTY(()) gimple_statement_bind {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 7 ]
       Variables declared in this scope.  */
    tree vars;
  
!   /* [ WORD 8 ]
       This is different than the BLOCK field in gimple_statement_base,
       which is analogous to TREE_BLOCK (i.e., the lexical block holding
       this statement).  This field is the equivalent of BIND_EXPR_BLOCK
*************** struct GTY(()) gimple_statement_bind {
*** 351,357 ****
       gimple-low.c.  */
    tree block;
  
!   /* [ WORD 7 ]  */
    gimple_seq body;
  };
  
--- 339,345 ----
       gimple-low.c.  */
    tree block;
  
!   /* [ WORD 9 ]  */
    gimple_seq body;
  };
  
*************** struct GTY(()) gimple_statement_bind {
*** 359,371 ****
  /* GIMPLE_CATCH */
  
  struct GTY(()) gimple_statement_catch {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5 ]  */
    tree types;
  
!   /* [ WORD 6 ]  */
    gimple_seq handler;
  };
  
--- 347,359 ----
  /* GIMPLE_CATCH */
  
  struct GTY(()) gimple_statement_catch {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 7 ]  */
    tree types;
  
!   /* [ WORD 8 ]  */
    gimple_seq handler;
  };
  
*************** struct GTY(()) gimple_statement_catch {
*** 373,386 ****
  /* GIMPLE_EH_FILTER */
  
  struct GTY(()) gimple_statement_eh_filter {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5 ]
       Filter types.  */
    tree types;
  
!   /* [ WORD 6 ]
       Failure actions.  */
    gimple_seq failure;
  };
--- 361,374 ----
  /* GIMPLE_EH_FILTER */
  
  struct GTY(()) gimple_statement_eh_filter {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 7 ]
       Filter types.  */
    tree types;
  
!   /* [ WORD 8 ]
       Failure actions.  */
    gimple_seq failure;
  };
*************** struct GTY(()) gimple_statement_eh_filte
*** 388,424 ****
  /* GIMPLE_EH_ELSE */
  
  struct GTY(()) gimple_statement_eh_else {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5,6 ] */
    gimple_seq n_body, e_body;
  };
  
  /* GIMPLE_EH_MUST_NOT_THROW */
  
  struct GTY(()) gimple_statement_eh_mnt {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5 ] Abort function decl.  */
    tree fndecl;
  };
  
  /* GIMPLE_PHI */
  
  struct GTY(()) gimple_statement_phi {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5 ]  */
    unsigned capacity;
    unsigned nargs;
  
!   /* [ WORD 6 ]  */
    tree result;
  
!   /* [ WORD 7 ]  */
    struct phi_arg_d GTY ((length ("%h.nargs"))) args[1];
  };
  
--- 376,412 ----
  /* GIMPLE_EH_ELSE */
  
  struct GTY(()) gimple_statement_eh_else {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 7,8 ] */
    gimple_seq n_body, e_body;
  };
  
  /* GIMPLE_EH_MUST_NOT_THROW */
  
  struct GTY(()) gimple_statement_eh_mnt {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 7 ] Abort function decl.  */
    tree fndecl;
  };
  
  /* GIMPLE_PHI */
  
  struct GTY(()) gimple_statement_phi {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 7 ]  */
    unsigned capacity;
    unsigned nargs;
  
!   /* [ WORD 8 ]  */
    tree result;
  
!   /* [ WORD 9 ]  */
    struct phi_arg_d GTY ((length ("%h.nargs"))) args[1];
  };
  
*************** struct GTY(()) gimple_statement_phi {
*** 427,436 ****
  
  struct GTY(()) gimple_statement_eh_ctrl
  {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5 ]
       Exception region number.  */
    int region;
  };
--- 415,424 ----
  
  struct GTY(()) gimple_statement_eh_ctrl
  {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 7 ]
       Exception region number.  */
    int region;
  };
*************** struct GTY(()) gimple_statement_eh_ctrl
*** 439,452 ****
  /* GIMPLE_TRY */
  
  struct GTY(()) gimple_statement_try {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5 ]
       Expression to evaluate.  */
    gimple_seq eval;
  
!   /* [ WORD 6 ]
       Cleanup expression.  */
    gimple_seq cleanup;
  };
--- 427,440 ----
  /* GIMPLE_TRY */
  
  struct GTY(()) gimple_statement_try {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 7 ]
       Expression to evaluate.  */
    gimple_seq eval;
  
!   /* [ WORD 8 ]
       Cleanup expression.  */
    gimple_seq cleanup;
  };
*************** enum gimple_try_flags
*** 468,474 ****
  /* GIMPLE_WITH_CLEANUP_EXPR */
  
  struct GTY(()) gimple_statement_wce {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
    /* Subcode: CLEANUP_EH_ONLY.  True if the cleanup should only be
--- 456,462 ----
  /* GIMPLE_WITH_CLEANUP_EXPR */
  
  struct GTY(()) gimple_statement_wce {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_base gsbase;
  
    /* Subcode: CLEANUP_EH_ONLY.  True if the cleanup should only be
*************** struct GTY(()) gimple_statement_wce {
*** 476,482 ****
  	      scope.  This flag is analogous to the CLEANUP_EH_ONLY flag
  	      in TARGET_EXPRs.  */
  
!   /* [ WORD 5 ]
       Cleanup expression.  */
    gimple_seq cleanup;
  };
--- 464,470 ----
  	      scope.  This flag is analogous to the CLEANUP_EH_ONLY flag
  	      in TARGET_EXPRs.  */
  
!   /* [ WORD 7 ]
       Cleanup expression.  */
    gimple_seq cleanup;
  };
*************** struct GTY(()) gimple_statement_wce {
*** 486,506 ****
  
  struct GTY(()) gimple_statement_asm
  {
!   /* [ WORD 1-8 ]  */
    struct gimple_statement_with_memory_ops_base membase;
  
!   /* [ WORD 9 ]
       __asm__ statement.  */
    const char *string;
  
!   /* [ WORD 10 ]
         Number of inputs, outputs, clobbers, labels.  */
    unsigned char ni;
    unsigned char no;
    unsigned char nc;
    unsigned char nl;
  
!   /* [ WORD 11 ]
       Operand vector.  NOTE!  This must always be the last field
       of this structure.  In particular, this means that this
       structure cannot be embedded inside another one.  */
--- 474,494 ----
  
  struct GTY(()) gimple_statement_asm
  {
!   /* [ WORD 1-10 ]  */
    struct gimple_statement_with_memory_ops_base membase;
  
!   /* [ WORD 11 ]
       __asm__ statement.  */
    const char *string;
  
!   /* [ WORD 12 ]
         Number of inputs, outputs, clobbers, labels.  */
    unsigned char ni;
    unsigned char no;
    unsigned char nc;
    unsigned char nl;
  
!   /* [ WORD 13 ]
       Operand vector.  NOTE!  This must always be the last field
       of this structure.  In particular, this means that this
       structure cannot be embedded inside another one.  */
*************** struct GTY(()) gimple_statement_asm
*** 510,519 ****
  /* GIMPLE_OMP_CRITICAL */
  
  struct GTY(()) gimple_statement_omp_critical {
!   /* [ WORD 1-5 ]  */
    struct gimple_statement_omp omp;
  
!   /* [ WORD 6 ]
       Critical section name.  */
    tree name;
  };
--- 498,507 ----
  /* GIMPLE_OMP_CRITICAL */
  
  struct GTY(()) gimple_statement_omp_critical {
!   /* [ WORD 1-7 ]  */
    struct gimple_statement_omp omp;
  
!   /* [ WORD 8 ]
       Critical section name.  */
    tree name;
  };
*************** struct GTY(()) gimple_omp_for_iter {
*** 539,558 ****
  /* GIMPLE_OMP_FOR */
  
  struct GTY(()) gimple_statement_omp_for {
!   /* [ WORD 1-5 ]  */
    struct gimple_statement_omp omp;
  
!   /* [ WORD 6 ]  */
    tree clauses;
  
!   /* [ WORD 7 ]
       Number of elements in iter array.  */
    size_t collapse;
  
!   /* [ WORD 8 ]  */
    struct gimple_omp_for_iter * GTY((length ("%h.collapse"))) iter;
  
!   /* [ WORD 9 ]
       Pre-body evaluated before the loop body begins.  */
    gimple_seq pre_body;
  };
--- 527,546 ----
  /* GIMPLE_OMP_FOR */
  
  struct GTY(()) gimple_statement_omp_for {
!   /* [ WORD 1-7 ]  */
    struct gimple_statement_omp omp;
  
!   /* [ WORD 8 ]  */
    tree clauses;
  
!   /* [ WORD 9 ]
       Number of elements in iter array.  */
    size_t collapse;
  
!   /* [ WORD 10 ]  */
    struct gimple_omp_for_iter * GTY((length ("%h.collapse"))) iter;
  
!   /* [ WORD 11 ]
       Pre-body evaluated before the loop body begins.  */
    gimple_seq pre_body;
  };
*************** struct GTY(()) gimple_statement_omp_for
*** 561,578 ****
  /* GIMPLE_OMP_PARALLEL */
  
  struct GTY(()) gimple_statement_omp_parallel {
!   /* [ WORD 1-5 ]  */
    struct gimple_statement_omp omp;
  
!   /* [ WORD 6 ]
       Clauses.  */
    tree clauses;
  
!   /* [ WORD 7 ]
       Child function holding the body of the parallel region.  */
    tree child_fn;
  
!   /* [ WORD 8 ]
       Shared data argument.  */
    tree data_arg;
  };
--- 549,566 ----
  /* GIMPLE_OMP_PARALLEL */
  
  struct GTY(()) gimple_statement_omp_parallel {
!   /* [ WORD 1-7 ]  */
    struct gimple_statement_omp omp;
  
!   /* [ WORD 8 ]
       Clauses.  */
    tree clauses;
  
!   /* [ WORD 9 ]
       Child function holding the body of the parallel region.  */
    tree child_fn;
  
!   /* [ WORD 10 ]
       Shared data argument.  */
    tree data_arg;
  };
*************** struct GTY(()) gimple_statement_omp_para
*** 581,594 ****
  /* GIMPLE_OMP_TASK */
  
  struct GTY(()) gimple_statement_omp_task {
!   /* [ WORD 1-8 ]  */
    struct gimple_statement_omp_parallel par;
  
!   /* [ WORD 9 ]
       Child function holding firstprivate initialization if needed.  */
    tree copy_fn;
  
!   /* [ WORD 10-11 ]
       Size and alignment in bytes of the argument data block.  */
    tree arg_size;
    tree arg_align;
--- 569,582 ----
  /* GIMPLE_OMP_TASK */
  
  struct GTY(()) gimple_statement_omp_task {
!   /* [ WORD 1-10 ]  */
    struct gimple_statement_omp_parallel par;
  
!   /* [ WORD 11 ]
       Child function holding firstprivate initialization if needed.  */
    tree copy_fn;
  
!   /* [ WORD 12-13 ]
       Size and alignment in bytes of the argument data block.  */
    tree arg_size;
    tree arg_align;
*************** struct GTY(()) gimple_statement_omp_task
*** 602,614 ****
  /* GIMPLE_OMP_SECTIONS */
  
  struct GTY(()) gimple_statement_omp_sections {
!   /* [ WORD 1-5 ]  */
    struct gimple_statement_omp omp;
  
!   /* [ WORD 6 ]  */
    tree clauses;
  
!   /* [ WORD 7 ]
       The control variable used for deciding which of the sections to
       execute.  */
    tree control;
--- 590,602 ----
  /* GIMPLE_OMP_SECTIONS */
  
  struct GTY(()) gimple_statement_omp_sections {
!   /* [ WORD 1-7 ]  */
    struct gimple_statement_omp omp;
  
!   /* [ WORD 8 ]  */
    tree clauses;
  
!   /* [ WORD 9 ]
       The control variable used for deciding which of the sections to
       execute.  */
    tree control;
*************** struct GTY(()) gimple_statement_omp_sect
*** 620,642 ****
           do not need the body field.  */
  
  struct GTY(()) gimple_statement_omp_continue {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5 ]  */
    tree control_def;
  
!   /* [ WORD 6 ]  */
    tree control_use;
  };
  
  /* GIMPLE_OMP_SINGLE */
  
  struct GTY(()) gimple_statement_omp_single {
!   /* [ WORD 1-5 ]  */
    struct gimple_statement_omp omp;
  
!   /* [ WORD 6 ]  */
    tree clauses;
  };
  
--- 608,630 ----
           do not need the body field.  */
  
  struct GTY(()) gimple_statement_omp_continue {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 7 ]  */
    tree control_def;
  
!   /* [ WORD 8 ]  */
    tree control_use;
  };
  
  /* GIMPLE_OMP_SINGLE */
  
  struct GTY(()) gimple_statement_omp_single {
!   /* [ WORD 1-7 ]  */
    struct gimple_statement_omp omp;
  
!   /* [ WORD 7 ]  */
    tree clauses;
  };
  
*************** struct GTY(()) gimple_statement_omp_sing
*** 646,655 ****
     contains a sequence, which we don't need here.  */
  
  struct GTY(()) gimple_statement_omp_atomic_load {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5-6 ]  */
    tree rhs, lhs;
  };
  
--- 634,643 ----
     contains a sequence, which we don't need here.  */
  
  struct GTY(()) gimple_statement_omp_atomic_load {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 7-8 ]  */
    tree rhs, lhs;
  };
  
*************** struct GTY(()) gimple_statement_omp_atom
*** 657,666 ****
     See note on GIMPLE_OMP_ATOMIC_LOAD.  */
  
  struct GTY(()) gimple_statement_omp_atomic_store {
!   /* [ WORD 1-4 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 5 ]  */
    tree val;
  };
  
--- 645,654 ----
     See note on GIMPLE_OMP_ATOMIC_LOAD.  */
  
  struct GTY(()) gimple_statement_omp_atomic_store {
!   /* [ WORD 1-6 ]  */
    struct gimple_statement_base gsbase;
  
!   /* [ WORD 7 ]  */
    tree val;
  };
  
*************** enum gimple_statement_structure_enum {
*** 712,718 ****
  /* Define the overall contents of a gimple tuple.  It may be any of the
     structures declared above for various types of tuples.  */
  
! union GTY ((desc ("gimple_statement_structure (&%h)"), variable_size)) gimple_statement_d {
    struct gimple_statement_base GTY ((tag ("GSS_BASE"))) gsbase;
    struct gimple_statement_with_ops GTY ((tag ("GSS_WITH_OPS"))) gsops;
    struct gimple_statement_with_memory_ops_base GTY ((tag ("GSS_WITH_MEM_OPS_BASE"))) gsmembase;
--- 700,707 ----
  /* Define the overall contents of a gimple tuple.  It may be any of the
     structures declared above for various types of tuples.  */
  
! union GTY ((desc ("gimple_statement_structure (&%h)"),
! 	    chain_next ("%h.gsbase.next"), variable_size)) gimple_statement_d {
    struct gimple_statement_base GTY ((tag ("GSS_BASE"))) gsbase;
    struct gimple_statement_with_ops GTY ((tag ("GSS_WITH_OPS"))) gsops;
    struct gimple_statement_with_memory_ops_base GTY ((tag ("GSS_WITH_MEM_OPS_BASE"))) gsmembase;
*************** extern bool types_compatible_p (tree, tr
*** 1037,1043 ****
  static inline gimple_seq_node
  gimple_seq_first (const_gimple_seq s)
  {
!   return s ? s->first : NULL;
  }
  
  
--- 1026,1032 ----
  static inline gimple_seq_node
  gimple_seq_first (const_gimple_seq s)
  {
!   return s;
  }
  
  
*************** static inline gimple
*** 1047,1053 ****
  gimple_seq_first_stmt (const_gimple_seq s)
  {
    gimple_seq_node n = gimple_seq_first (s);
!   return (n) ? n->stmt : NULL;
  }
  
  
--- 1036,1042 ----
  gimple_seq_first_stmt (const_gimple_seq s)
  {
    gimple_seq_node n = gimple_seq_first (s);
!   return n;
  }
  
  
*************** gimple_seq_first_stmt (const_gimple_seq
*** 1056,1062 ****
  static inline gimple_seq_node
  gimple_seq_last (const_gimple_seq s)
  {
!   return s ? s->last : NULL;
  }
  
  
--- 1045,1051 ----
  static inline gimple_seq_node
  gimple_seq_last (const_gimple_seq s)
  {
!   return s ? s->gsbase.prev : NULL;
  }
  
  
*************** static inline gimple
*** 1066,1072 ****
  gimple_seq_last_stmt (const_gimple_seq s)
  {
    gimple_seq_node n = gimple_seq_last (s);
!   return (n) ? n->stmt : NULL;
  }
  
  
--- 1055,1061 ----
  gimple_seq_last_stmt (const_gimple_seq s)
  {
    gimple_seq_node n = gimple_seq_last (s);
!   return n;
  }
  
  
*************** gimple_seq_last_stmt (const_gimple_seq s
*** 1075,1083 ****
  static inline void
  gimple_seq_set_last (gimple_seq *ps, gimple_seq_node last)
  {
!   if (!*ps)
!     *ps = gimple_seq_alloc ();
!   (*ps)->last = last;
  }
  
  
--- 1064,1071 ----
  static inline void
  gimple_seq_set_last (gimple_seq *ps, gimple_seq_node last)
  {
!   (*ps)->gsbase.prev = last;
!   last->gsbase.end_of_seq = 1;
  }
  
  
*************** gimple_seq_set_last (gimple_seq *ps, gim
*** 1086,1094 ****
  static inline void
  gimple_seq_set_first (gimple_seq *ps, gimple_seq_node first)
  {
!   if (!*ps)
!     *ps = gimple_seq_alloc ();
!   (*ps)->first = first;
  }
  
  
--- 1074,1081 ----
  static inline void
  gimple_seq_set_first (gimple_seq *ps, gimple_seq_node first)
  {
!   *ps = first;
!   first->gsbase.start_of_seq = 1;
  }
  
  
*************** gimple_seq_set_first (gimple_seq *ps, gi
*** 1097,1103 ****
  static inline bool
  gimple_seq_empty_p (const_gimple_seq s)
  {
!   return s == NULL || s->first == NULL;
  }
  
  
--- 1084,1090 ----
  static inline bool
  gimple_seq_empty_p (const_gimple_seq s)
  {
!   return s == NULL;
  }
  
  
*************** gsi_start_1 (gimple_seq *seq)
*** 4955,4961 ****
  
    i.ptr = gimple_seq_first (*seq);
    i.seq = seq;
!   i.bb = (i.ptr && i.ptr->stmt) ? gimple_bb (i.ptr->stmt) : NULL;
  
    return i;
  }
--- 4942,4948 ----
  
    i.ptr = gimple_seq_first (*seq);
    i.seq = seq;
!   i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
  
    return i;
  }
*************** gsi_last_1 (gimple_seq *seq)
*** 5009,5015 ****
  
    i.ptr = gimple_seq_last (*seq);
    i.seq = seq;
!   i.bb = (i.ptr && i.ptr->stmt) ? gimple_bb (i.ptr->stmt) : NULL;
  
    return i;
  }
--- 4996,5002 ----
  
    i.ptr = gimple_seq_last (*seq);
    i.seq = seq;
!   i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
  
    return i;
  }
*************** gsi_end_p (gimple_stmt_iterator i)
*** 5058,5064 ****
  static inline bool
  gsi_one_before_end_p (gimple_stmt_iterator i)
  {
!   return i.ptr != NULL && i.ptr->next == NULL;
  }
  
  
--- 5045,5051 ----
  static inline bool
  gsi_one_before_end_p (gimple_stmt_iterator i)
  {
!   return i.ptr != NULL && i.ptr->gsbase.next == NULL;
  }
  
  
*************** gsi_one_before_end_p (gimple_stmt_iterat
*** 5067,5073 ****
  static inline void
  gsi_next (gimple_stmt_iterator *i)
  {
!   i->ptr = i->ptr->next;
  }
  
  /* Advance the iterator to the previous gimple statement.  */
--- 5054,5060 ----
  static inline void
  gsi_next (gimple_stmt_iterator *i)
  {
!   i->ptr = i->ptr->gsbase.next;
  }
  
  /* Advance the iterator to the previous gimple statement.  */
*************** gsi_next (gimple_stmt_iterator *i)
*** 5075,5081 ****
  static inline void
  gsi_prev (gimple_stmt_iterator *i)
  {
!   i->ptr = i->ptr->prev;
  }
  
  /* Return the current stmt.  */
--- 5062,5072 ----
  static inline void
  gsi_prev (gimple_stmt_iterator *i)
  {
!   gimple prev = i->ptr->gsbase.prev;
!   if (prev->gsbase.next)
!     i->ptr = prev;
!   else
!     i->ptr = NULL;
  }
  
  /* Return the current stmt.  */
*************** gsi_prev (gimple_stmt_iterator *i)
*** 5083,5089 ****
  static inline gimple
  gsi_stmt (gimple_stmt_iterator i)
  {
!   return i.ptr->stmt;
  }
  
  /* Return a block statement iterator that points to the first non-label
--- 5074,5080 ----
  static inline gimple
  gsi_stmt (gimple_stmt_iterator i)
  {
!   return i.ptr;
  }
  
  /* Return a block statement iterator that points to the first non-label
*************** gsi_last_nondebug_bb (basic_block bb)
*** 5152,5169 ****
    return i;
  }
  
- /* Return a pointer to the current stmt.
- 
-   NOTE: You may want to use gsi_replace on the iterator itself,
-   as this performs additional bookkeeping that will not be done
-   if you simply assign through a pointer returned by gsi_stmt_ptr.  */
- 
- static inline gimple *
- gsi_stmt_ptr (gimple_stmt_iterator *i)
- {
-   return &i->ptr->stmt;
- }
- 
  
  /* Return the basic block associated with this iterator.  */
  
--- 5143,5148 ----
*************** enum gimple_alloc_kind
*** 5308,5314 ****
    gimple_alloc_kind_assign,	/* Assignments.  */
    gimple_alloc_kind_phi,	/* PHI nodes.  */
    gimple_alloc_kind_cond,	/* Conditionals.  */
-   gimple_alloc_kind_seq,	/* Sequences.  */
    gimple_alloc_kind_rest,	/* Everything else.  */
    gimple_alloc_kind_all
  };
--- 5287,5292 ----
Index: gimple-iterator.c
===================================================================
*** gimple-iterator.c.orig	2012-05-01 22:44:17.000000000 +0200
--- gimple-iterator.c	2012-05-01 22:44:18.000000000 +0200
*************** update_modified_stmts (gimple_seq seq)
*** 57,68 ****
     starting at FIRST and LAST.  */
  
  static void
! update_bb_for_stmts (gimple_seq_node first, basic_block bb)
  {
    gimple_seq_node n;
  
!   for (n = first; n; n = n->next)
!     gimple_set_bb (n->stmt, bb);
  }
  
  /* Set the frequencies for the cgraph_edges for each of the calls
--- 57,73 ----
     starting at FIRST and LAST.  */
  
  static void
! update_bb_for_stmts (gimple_seq_node first, gimple_seq_node last,
! 		     basic_block bb)
  {
    gimple_seq_node n;
  
!   for (n = first; n; n = n->gsbase.next)
!     {
!       gimple_set_bb (n, bb);
!       if (n == last)
! 	break;
!     }
  }
  
  /* Set the frequencies for the cgraph_edges for each of the calls
*************** update_call_edge_frequencies (gimple_seq
*** 75,82 ****
    int bb_freq = 0;
    gimple_seq_node n;
  
!   for (n = first; n ; n = n->next)
!     if (is_gimple_call (n->stmt))
        {
  	struct cgraph_edge *e;
  
--- 80,87 ----
    int bb_freq = 0;
    gimple_seq_node n;
  
!   for (n = first; n ; n = n->gsbase.next)
!     if (is_gimple_call (n))
        {
  	struct cgraph_edge *e;
  
*************** update_call_edge_frequencies (gimple_seq
*** 89,95 ****
  		       (current_function_decl, bb));
  	  }
  
! 	e = cgraph_edge (cfun_node, n->stmt);
  	if (e != NULL)
  	  e->frequency = bb_freq;
        }
--- 94,100 ----
  		       (current_function_decl, bb));
  	  }
  
! 	e = cgraph_edge (cfun_node, n);
  	if (e != NULL)
  	  e->frequency = bb_freq;
        }
*************** gsi_insert_seq_nodes_before (gimple_stmt
*** 113,131 ****
    basic_block bb;
    gimple_seq_node cur = i->ptr;
  
    if ((bb = gsi_bb (*i)) != NULL)
!     update_bb_for_stmts (first, bb);
  
    /* Link SEQ before CUR in the sequence.  */
    if (cur)
      {
!       first->prev = cur->prev;
!       if (first->prev)
! 	first->prev->next = first;
        else
  	gimple_seq_set_first (i->seq, first);
!       last->next = cur;
!       cur->prev = last;
      }
    else
      {
--- 118,143 ----
    basic_block bb;
    gimple_seq_node cur = i->ptr;
  
+   gcc_assert ((!first->gsbase.prev->gsbase.next || first->gsbase.start_of_seq)
+ 	      && (!last->gsbase.next || last->gsbase.end_of_seq)
+ 	      && (!cur || cur->gsbase.prev));
+ 
    if ((bb = gsi_bb (*i)) != NULL)
!     update_bb_for_stmts (first, last, bb);
  
    /* Link SEQ before CUR in the sequence.  */
    if (cur)
      {
!       first->gsbase.prev = cur->gsbase.prev;
!       if (first->gsbase.prev->gsbase.next)
! 	first->gsbase.prev->gsbase.next = first;
        else
  	gimple_seq_set_first (i->seq, first);
!       first->gsbase.start_of_seq = cur->gsbase.start_of_seq;
!       last->gsbase.next = cur;
!       last->gsbase.end_of_seq = 0;
!       cur->gsbase.prev = last;
!       cur->gsbase.start_of_seq = 0;
      }
    else
      {
*************** gsi_insert_seq_nodes_before (gimple_stmt
*** 136,144 ****
  	 labels, so it returns an iterator after the end of the block, and
  	 we need to insert before it; it might be cleaner to add a flag to the
  	 iterator saying whether we are at the start or end of the list).  */
!       first->prev = itlast;
        if (itlast)
! 	itlast->next = first;
        else
  	gimple_seq_set_first (i->seq, first);
        gimple_seq_set_last (i->seq, last);
--- 148,161 ----
  	 labels, so it returns an iterator after the end of the block, and
  	 we need to insert before it; it might be cleaner to add a flag to the
  	 iterator saying whether we are at the start or end of the list).  */
!       last->gsbase.next = NULL;
        if (itlast)
! 	{
! 	  first->gsbase.prev = itlast;
! 	  itlast->gsbase.next = first;
! 	  itlast->gsbase.end_of_seq = 0;
! 	  first->gsbase.start_of_seq = 0;
! 	}
        else
  	gimple_seq_set_first (i->seq, first);
        gimple_seq_set_last (i->seq, last);
*************** gsi_insert_seq_before_without_update (gi
*** 183,192 ****
    first = gimple_seq_first (seq);
    last = gimple_seq_last (seq);
  
-   gimple_seq_set_first (&seq, NULL);
-   gimple_seq_set_last (&seq, NULL);
-   gimple_seq_free (seq);
- 
    /* Empty sequences need no work.  */
    if (!first || !last)
      {
--- 200,205 ----
*************** gsi_insert_seq_nodes_after (gimple_stmt_
*** 230,254 ****
    basic_block bb;
    gimple_seq_node cur = i->ptr;
  
    /* If the iterator is inside a basic block, we need to update the
       basic block information for all the nodes between FIRST and LAST.  */
    if ((bb = gsi_bb (*i)) != NULL)
!     update_bb_for_stmts (first, bb);
  
    /* Link SEQ after CUR.  */
    if (cur)
      {
!       last->next = cur->next;
!       if (last->next)
! 	last->next->prev = last;
        else
  	gimple_seq_set_last (i->seq, last);
!       first->prev = cur;
!       cur->next = first;
      }
    else
      {
        gcc_assert (!gimple_seq_last (*i->seq));
        gimple_seq_set_first (i->seq, first);
        gimple_seq_set_last (i->seq, last);
      }
--- 243,277 ----
    basic_block bb;
    gimple_seq_node cur = i->ptr;
  
+   gcc_assert ((!first->gsbase.prev->gsbase.next || first->gsbase.start_of_seq)
+ 	      && (!last->gsbase.next || last->gsbase.end_of_seq)
+ 	      && (!cur || cur->gsbase.prev));
+ 
    /* If the iterator is inside a basic block, we need to update the
       basic block information for all the nodes between FIRST and LAST.  */
    if ((bb = gsi_bb (*i)) != NULL)
!     update_bb_for_stmts (first, last, bb);
  
    /* Link SEQ after CUR.  */
    if (cur)
      {
!       last->gsbase.next = cur->gsbase.next;
!       if (last->gsbase.next)
! 	{
! 	  last->gsbase.next->gsbase.prev = last;
! 	  last->gsbase.end_of_seq = 0;
! 	}
        else
  	gimple_seq_set_last (i->seq, last);
!       first->gsbase.prev = cur;
!       cur->gsbase.next = first;
!       cur->gsbase.end_of_seq = 0;
!       first->gsbase.start_of_seq = 0;
      }
    else
      {
        gcc_assert (!gimple_seq_last (*i->seq));
+       last->gsbase.next = NULL;
        gimple_seq_set_first (i->seq, first);
        gimple_seq_set_last (i->seq, last);
      }
*************** gsi_insert_seq_after_without_update (gim
*** 294,303 ****
    first = gimple_seq_first (seq);
    last = gimple_seq_last (seq);
  
-   gimple_seq_set_first (&seq, NULL);
-   gimple_seq_set_last (&seq, NULL);
-   gimple_seq_free (seq);
- 
    /* Empty sequences need no work.  */
    if (!first || !last)
      {
--- 317,322 ----
*************** gsi_split_seq_after (gimple_stmt_iterato
*** 334,350 ****
    cur = i.ptr;
  
    /* How can we possibly split after the end, or before the beginning?  */
!   gcc_assert (cur && cur->next);
!   next = cur->next;
  
    pold_seq = i.seq;
-   new_seq = NULL;
  
    gimple_seq_set_first (&new_seq, next);
    gimple_seq_set_last (&new_seq, gimple_seq_last (*pold_seq));
    gimple_seq_set_last (pold_seq, cur);
!   cur->next = NULL;
!   next->prev = NULL;
  
    return new_seq;
  }
--- 353,367 ----
    cur = i.ptr;
  
    /* How can we possibly split after the end, or before the beginning?  */
!   gcc_assert (cur && cur->gsbase.next);
!   next = cur->gsbase.next;
  
    pold_seq = i.seq;
  
    gimple_seq_set_first (&new_seq, next);
    gimple_seq_set_last (&new_seq, gimple_seq_last (*pold_seq));
    gimple_seq_set_last (pold_seq, cur);
!   cur->gsbase.next = NULL;
  
    return new_seq;
  }
*************** gsi_split_seq_after (gimple_stmt_iterato
*** 357,369 ****
  void
  gsi_set_stmt (gimple_stmt_iterator *gsi, gimple stmt)
  {
!   *gsi_stmt_ptr (gsi) = stmt;
  }
  
  
  /* Move all statements in the sequence before I to a new sequence.
!    Return this new sequence at *PNEW_SEQ.
!    I is set to the head of the new list.  */
  
  void
  gsi_split_seq_before (gimple_stmt_iterator *i, gimple_seq *pnew_seq)
--- 374,404 ----
  void
  gsi_set_stmt (gimple_stmt_iterator *gsi, gimple stmt)
  {
!   gimple orig_stmt = gsi_stmt (*gsi);
!   gimple prev, next;
! 
!   stmt->gsbase.next = next = orig_stmt->gsbase.next;
!   stmt->gsbase.prev = prev = orig_stmt->gsbase.prev;
!   /* Note how we don't clear next/prev of orig_stmt.  This is so that
!      copies of *GSI our callers might still hold (to orig_stmt)
!      can be advanced as if they too were replaced.  */
!   orig_stmt->gsbase.start_of_seq = 1;
!   orig_stmt->gsbase.end_of_seq = 1;
!   if (prev->gsbase.next)
!     prev->gsbase.next = stmt;
!   else
!     gimple_seq_set_first (gsi->seq, stmt);
!   if (next)
!     next->gsbase.prev = stmt;
!   else
!     gimple_seq_set_last (gsi->seq, stmt);
! 
!   gsi->ptr = stmt;
  }
  
  
  /* Move all statements in the sequence before I to a new sequence.
!    Return this new sequence.  I is set to the head of the new list.  */
  
  void
  gsi_split_seq_before (gimple_stmt_iterator *i, gimple_seq *pnew_seq)
*************** gsi_split_seq_before (gimple_stmt_iterat
*** 375,385 ****
  
    /* How can we possibly split after the end?  */
    gcc_assert (cur);
!   prev = cur->prev;
  
    old_seq = *i->seq;
    i->seq = pnew_seq;
-   *pnew_seq = NULL;
  
    /* Set the limits on NEW_SEQ.  */
    gimple_seq_set_first (pnew_seq, cur);
--- 410,421 ----
  
    /* How can we possibly split after the end?  */
    gcc_assert (cur);
!   prev = cur->gsbase.prev;
  
    old_seq = *i->seq;
+   if (!prev->gsbase.next)
+     *i->seq = NULL;
    i->seq = pnew_seq;
  
    /* Set the limits on NEW_SEQ.  */
    gimple_seq_set_first (pnew_seq, cur);
*************** gsi_split_seq_before (gimple_stmt_iterat
*** 387,397 ****
  
    /* Cut OLD_SEQ before I.  */
    gimple_seq_set_last (&old_seq, prev);
!   cur->prev = NULL;
!   if (prev)
!     prev->next = NULL;
!   else
!     gimple_seq_set_first (&old_seq, NULL);
  }
  
  
--- 423,430 ----
  
    /* Cut OLD_SEQ before I.  */
    gimple_seq_set_last (&old_seq, prev);
!   if (prev->gsbase.next)
!     prev->gsbase.next = NULL;
  }
  
  
*************** gsi_replace (gimple_stmt_iterator *gsi,
*** 408,415 ****
    if (stmt == orig_stmt)
      return;
  
!   gcc_assert (!gimple_has_lhs (orig_stmt)
! 	      || gimple_get_lhs (orig_stmt) == gimple_get_lhs (stmt));
  
    gimple_set_location (stmt, gimple_location (orig_stmt));
    gimple_set_bb (stmt, gsi_bb (*gsi));
--- 441,450 ----
    if (stmt == orig_stmt)
      return;
  
!   gcc_assert ((!gimple_has_lhs (orig_stmt)
! 	       || gimple_get_lhs (orig_stmt) == gimple_get_lhs (stmt))
! 	      && (!stmt->gsbase.prev->gsbase.next || stmt->gsbase.start_of_seq)
! 	      && (!stmt->gsbase.next || stmt->gsbase.end_of_seq));
  
    gimple_set_location (stmt, gimple_location (orig_stmt));
    gimple_set_bb (stmt, gsi_bb (*gsi));
*************** void
*** 463,474 ****
  gsi_insert_before_without_update (gimple_stmt_iterator *i, gimple stmt,
                                    enum gsi_iterator_update m)
  {
!   gimple_seq_node n;
! 
!   n = ggc_alloc_gimple_seq_node_d ();
!   n->prev = n->next = NULL;
!   n->stmt = stmt;
!   gsi_insert_seq_nodes_before (i, n, n, m);
  }
  
  /* Insert statement STMT before the statement pointed-to by iterator I.
--- 498,504 ----
  gsi_insert_before_without_update (gimple_stmt_iterator *i, gimple stmt,
                                    enum gsi_iterator_update m)
  {
!   gsi_insert_seq_nodes_before (i, stmt, stmt, m);
  }
  
  /* Insert statement STMT before the statement pointed-to by iterator I.
*************** void
*** 498,509 ****
  gsi_insert_after_without_update (gimple_stmt_iterator *i, gimple stmt,
                                   enum gsi_iterator_update m)
  {
!   gimple_seq_node n;
! 
!   n = ggc_alloc_gimple_seq_node_d ();
!   n->prev = n->next = NULL;
!   n->stmt = stmt;
!   gsi_insert_seq_nodes_after (i, n, n, m);
  }
  
  
--- 528,534 ----
  gsi_insert_after_without_update (gimple_stmt_iterator *i, gimple stmt,
                                   enum gsi_iterator_update m)
  {
!   gsi_insert_seq_nodes_after (i, stmt, stmt, m);
  }
  
  
*************** gsi_remove (gimple_stmt_iterator *i, boo
*** 553,571 ****
  
    /* Update the iterator and re-wire the links in I->SEQ.  */
    cur = i->ptr;
!   next = cur->next;
!   prev = cur->prev;
! 
!   if (prev)
!     prev->next = next;
!   else
!     gimple_seq_set_first (i->seq, next);
  
    if (next)
!     next->prev = prev;
!   else
      gimple_seq_set_last (i->seq, prev);
  
    i->ptr = next;
  
    return require_eh_edge_purge;
--- 578,603 ----
  
    /* Update the iterator and re-wire the links in I->SEQ.  */
    cur = i->ptr;
!   next = cur->gsbase.next;
!   prev = cur->gsbase.prev;
!   /* See gsi_set_stmt for why we don't reset prev/next of STMT.  */
!   stmt->gsbase.start_of_seq = 1;
!   stmt->gsbase.end_of_seq = 1;
  
    if (next)
!     /* Cur is not last.  */
!     next->gsbase.prev = prev;
!   else if (prev->gsbase.next)
!     /* Cur is last but not first.  */
      gimple_seq_set_last (i->seq, prev);
  
+   if (prev->gsbase.next)
+     /* Cur is not first.  */
+     prev->gsbase.next = next;
+   else
+     /* Cur is first.  */
+     *i->seq = next;
+ 
    i->ptr = next;
  
    return require_eh_edge_purge;
*************** gsi_for_stmt (gimple stmt)
*** 585,595 ****
    else
      i = gsi_start_bb (bb);
  
!   for (; !gsi_end_p (i); gsi_next (&i))
!     if (gsi_stmt (i) == stmt)
!       return i;
! 
!   gcc_unreachable ();
  }
  
  
--- 617,624 ----
    else
      i = gsi_start_bb (bb);
  
!   i.ptr = stmt;
!   return i;
  }
  
  
*************** basic_block
*** 755,761 ****
  gsi_insert_on_edge_immediate (edge e, gimple stmt)
  {
    gimple_stmt_iterator gsi;
-   struct gimple_seq_node_d node;
    basic_block new_bb = NULL;
    bool ins_after;
  
--- 784,789 ----
*************** gsi_insert_on_edge_immediate (edge e, gi
*** 763,771 ****
  
    ins_after = gimple_find_edge_insert_loc (e, &gsi, &new_bb);
  
!   node.stmt = stmt;
!   node.prev = node.next = NULL;
!   update_call_edge_frequencies (&node, gsi.bb);
  
    if (ins_after)
      gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
--- 791,797 ----
  
    ins_after = gimple_find_edge_insert_loc (e, &gsi, &new_bb);
  
!   update_call_edge_frequencies (stmt, gsi.bb);
  
    if (ins_after)
      gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
Index: gimple.c
===================================================================
*** gimple.c.orig	2012-05-01 22:44:17.000000000 +0200
--- gimple.c	2012-05-01 22:44:18.000000000 +0200
*************** static const char * const gimple_alloc_k
*** 90,105 ****
      "assignments",
      "phi nodes",
      "conditionals",
-     "sequences",
      "everything else"
  };
  
  #endif /* GATHER_STATISTICS */
  
- /* A cache of gimple_seq objects.  Sequences are created and destroyed
-    fairly often during gimplification.  */
- static GTY ((deletable)) struct gimple_seq_d *gimple_seq_cache;
- 
  /* Private API manipulation functions shared only with some
     other files.  */
  extern void gimple_set_stored_syms (gimple, bitmap, bitmap_obstack *);
--- 90,100 ----
*************** gimple_alloc_stat (enum gimple_code code
*** 154,159 ****
--- 149,157 ----
    /* Do not call gimple_set_modified here as it has other side
       effects and this tuple is still not completely built.  */
    stmt->gsbase.modified = 1;
+   stmt->gsbase.start_of_seq = 1;
+   stmt->gsbase.end_of_seq = 1;
+   stmt->gsbase.prev = stmt;
  
    return stmt;
  }
*************** gimple_check_failed (const_gimple gs, co
*** 1201,1253 ****
  #endif /* ENABLE_GIMPLE_CHECKING */
  
  
- /* Allocate a new GIMPLE sequence in GC memory and return it.  If
-    there are free sequences in GIMPLE_SEQ_CACHE return one of those
-    instead.  */
- 
- gimple_seq
- gimple_seq_alloc (void)
- {
-   gimple_seq seq = gimple_seq_cache;
-   if (seq)
-     {
-       gimple_seq_cache = gimple_seq_cache->next_free;
-       gcc_assert (gimple_seq_cache != seq);
-       memset (seq, 0, sizeof (*seq));
-     }
-   else
-     {
-       seq = ggc_alloc_cleared_gimple_seq_d ();
- #ifdef GATHER_STATISTICS
-       gimple_alloc_counts[(int) gimple_alloc_kind_seq]++;
-       gimple_alloc_sizes[(int) gimple_alloc_kind_seq] += sizeof (*seq);
- #endif
-     }
- 
-   return seq;
- }
- 
- /* Return SEQ to the free pool of GIMPLE sequences.  */
- 
- void
- gimple_seq_free (gimple_seq seq)
- {
-   if (seq == NULL)
-     return;
- 
-   gcc_assert (gimple_seq_first (seq) == NULL);
-   gcc_assert (gimple_seq_last (seq) == NULL);
- 
-   /* If this triggers, it's a sign that the same list is being freed
-      twice.  */
-   gcc_assert (seq != gimple_seq_cache || gimple_seq_cache == NULL);
- 
-   /* Add SEQ to the pool of free sequences.  */
-   seq->next_free = gimple_seq_cache;
-   gimple_seq_cache = seq;
- }
- 
- 
  /* Link gimple statement GS to the end of the sequence *SEQ_P.  If
     *SEQ_P is NULL, a new sequence is allocated.  */
  
--- 1199,1204 ----
*************** gimple_assign_set_rhs_with_ops_1 (gimple
*** 2183,2188 ****
--- 2134,2143 ----
        tree lhs = gimple_assign_lhs (stmt);
        gimple new_stmt = gimple_alloc (gimple_code (stmt), new_rhs_ops + 1);
        memcpy (new_stmt, stmt, gimple_size (gimple_code (stmt)));
+       new_stmt->gsbase.next = NULL;
+       new_stmt->gsbase.prev = new_stmt;
+       new_stmt->gsbase.start_of_seq = 1;
+       new_stmt->gsbase.end_of_seq = 1;
        gsi_replace (gsi, new_stmt, true);
        stmt = new_stmt;
  
*************** gimple_replace_lhs (gimple stmt, tree nl
*** 2272,2278 ****
  
  /* Return a deep copy of statement STMT.  All the operands from STMT
     are reallocated and copied using unshare_expr.  The DEF, USE, VDEF
!    and VUSE operand arrays are set to empty in the new copy.  */
  
  gimple
  gimple_copy (gimple stmt)
--- 2227,2234 ----
  
  /* Return a deep copy of statement STMT.  All the operands from STMT
     are reallocated and copied using unshare_expr.  The DEF, USE, VDEF
!    and VUSE operand arrays are set to empty in the new copy.  The new
!    copy isn't part of any sequence.  */
  
  gimple
  gimple_copy (gimple stmt)
*************** gimple_copy (gimple stmt)
*** 2284,2289 ****
--- 2240,2249 ----
  
    /* Shallow copy all the fields from STMT.  */
    memcpy (copy, stmt, gimple_size (code));
+   copy->gsbase.next = NULL;
+   copy->gsbase.prev = copy;
+   copy->gsbase.start_of_seq = 1;
+   copy->gsbase.end_of_seq = 1;
  
    /* If STMT has sub-statements, deep-copy them as well.  */
    if (gimple_has_substatements (stmt))
Index: gimplify.c
===================================================================
*** gimplify.c.orig	2012-05-01 22:44:17.000000000 +0200
--- gimplify.c	2012-05-01 22:44:18.000000000 +0200
*************** gimplify_cleanup_point_expr (tree *expr_
*** 5417,5424 ****
  	      gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
                /* Do not use gsi_replace here, as it may scan operands.
                   We want to do a simple structural modification only.  */
!               *gsi_stmt_ptr (&iter) = gtry;
! 	      iter = gsi_start (seq);
  	    }
  	}
        else
--- 5417,5424 ----
  	      gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
                /* Do not use gsi_replace here, as it may scan operands.
                   We want to do a simple structural modification only.  */
! 	      gsi_set_stmt (&iter, gtry);
! 	      iter = gsi_start (gtry->gimple_try.eval);
  	    }
  	}
        else
Index: tree-phinodes.c
===================================================================
*** tree-phinodes.c.orig	2012-05-01 22:44:02.000000000 +0200
--- tree-phinodes.c	2012-05-01 22:44:18.000000000 +0200
*************** make_phi_node (tree var, int len)
*** 221,226 ****
--- 221,229 ----
  		   - sizeof (struct phi_arg_d)
  		   + sizeof (struct phi_arg_d) * len));
    phi->gsbase.code = GIMPLE_PHI;
+   phi->gsbase.prev = phi;
+   phi->gsbase.start_of_seq = 1;
+   phi->gsbase.end_of_seq = 1;
    phi->gimple_phi.nargs = len;
    phi->gimple_phi.capacity = capacity;
    if (TREE_CODE (var) == SSA_NAME)
Index: coretypes.h
===================================================================
*** coretypes.h.orig	2012-05-01 22:39:06.000000000 +0200
--- coretypes.h	2012-05-01 22:44:18.000000000 +0200
*************** struct cl_decoded_option;
*** 72,80 ****
  struct cl_option_handlers;
  struct diagnostic_context;
  typedef struct diagnostic_context diagnostic_context;
! struct gimple_seq_d;
! typedef struct gimple_seq_d *gimple_seq;
! typedef const struct gimple_seq_d *const_gimple_seq;
  
  /* Address space number for named address space support.  */
  typedef unsigned char addr_space_t;
--- 72,79 ----
  struct cl_option_handlers;
  struct diagnostic_context;
  typedef struct diagnostic_context diagnostic_context;
! typedef gimple gimple_seq;
! typedef gimple const_gimple_seq;
  
  /* Address space number for named address space support.  */
  typedef unsigned char addr_space_t;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]