On Mon, Oct 22, 2012 at 4:12 PM, Michael Matz <m...@suse.de> wrote: > Hi, > > On Tue, 11 Sep 2012, Michael Matz wrote: > >> the operands cache is ugly. This patch removes it at least for the def >> operands, saving three pointers for roughly each normal statement (the >> pointer in gsbase, and two pointers from def_optype_d). This is >> relatively easy to do, because all statements except ASMs have at most one >> def (and one vdef), which themself aren't pointed to by something else, >> unlike the use operands which have more structure for the SSA web. >> >> Performance wise the patch is a slight improvement (1% for some C++ >> testcases, but relatively noisy, but at least not slower), bootstrap time >> is unaffected. As the iterator is a bit larger code size increases by 1 >> promille. >> >> The patch is regstrapped on x86_64-linux. If it's approved I'll adjust >> the WORD count markers in gimple.h, I left it out in this submission as >> it's just verbose noise in comments. > > So, 2nd try after some internal feedback. This version changes the > operand order of asms to also have the defs at the beginning, which makes > the iterators slightly nicer, and joins some more fields of the iterator, > though not all that we could merge. > > Again, if approved I'll adjust the word count markers. Regstrapping on > x86_64-linux in progress, speed similar as before. Okay for trunk?
Ok. Thanks, Richard. > > Ciao, > Michael. > -- > * tree-ssa-operands.h (struct def_optype_d, def_optype_p): Remove. > (ssa_operands.free_defs): Remove. > (DEF_OP_PTR, DEF_OP): Remove. > (struct ssa_operand_iterator_d): Remove 'defs', add 'flags' > members, rename 'phi_stmt' to 'stmt', 'phi_i' to 'i' and 'num_phi' > to 'numops'. > * gimple.h (gimple_statement_with_ops.def_ops): Remove. > (gimple_def_ops, gimple_set_def_ops): Remove. > (gimple_vdef_op): Don't take const gimple, adjust. > (gimple_asm_input_op, gimple_asm_input_op_ptr, > gimple_asm_set_input_op, gimple_asm_output_op, > gimple_asm_output_op_ptr, gimple_asm_set_output_op): Adjust asserts, > and rewrite to move def operands to front. > (gimple_asm_clobber_op, gimple_asm_set_clobber_op, > gimple_asm_label_op, gimple_asm_set_label_op): Correct asserts. > * tree-ssa-operands.c (build_defs): Remove. > (init_ssa_operands): Don't initialize it. > (fini_ssa_operands): Don't free it. > (cleanup_build_arrays): Don't truncate it. > (finalize_ssa_stmt_operands): Don't assert on it. > (alloc_def, add_def_op, append_def): Remove. > (finalize_ssa_defs): Remove building of def_ops list. > (finalize_ssa_uses): Don't mark for SSA renaming here, ... > (add_stmt_operand): ... but here, don't call append_def. > (get_indirect_ref_operands): Remove recurse_on_base argument. > (get_expr_operands): Adjust call to get_indirect_ref_operands. > (verify_ssa_operands): Don't check def operands. > (free_stmt_operands): Don't free def operands. > * gimple.c (gimple_copy): Don't clear def operands. > * tree-flow-inline.h (op_iter_next_use): Adjust to explicitely > handle def operand. > (op_iter_next_tree, op_iter_next_def): Ditto. > (clear_and_done_ssa_iter): Clear new fields. > (op_iter_init): Adjust to setup new iterator structure. > (op_iter_init_phiuse): Adjust. > > Index: tree-ssa-operands.h > =================================================================== > --- tree-ssa-operands.h.orig 2012-09-24 15:24:52.000000000 +0200 > +++ tree-ssa-operands.h 2012-10-22 15:12:30.000000000 +0200 > @@ -34,14 +34,6 @@ typedef ssa_use_operand_t *use_operand_p > #define NULL_USE_OPERAND_P ((use_operand_p)NULL) > #define NULL_DEF_OPERAND_P ((def_operand_p)NULL) > > -/* This represents the DEF operands of a stmt. */ > -struct def_optype_d > -{ > - struct def_optype_d *next; > - tree *def_ptr; > -}; > -typedef struct def_optype_d *def_optype_p; > - > /* This represents the USE operands of a stmt. */ > struct use_optype_d > { > @@ -68,7 +60,6 @@ struct GTY(()) ssa_operands { > > bool ops_active; > > - struct def_optype_d * GTY ((skip (""))) free_defs; > struct use_optype_d * GTY ((skip (""))) free_uses; > }; > > @@ -82,9 +73,6 @@ struct GTY(()) ssa_operands { > #define USE_OP_PTR(OP) (&((OP)->use_ptr)) > #define USE_OP(OP) (USE_FROM_PTR (USE_OP_PTR (OP))) > > -#define DEF_OP_PTR(OP) ((OP)->def_ptr) > -#define DEF_OP(OP) (DEF_FROM_PTR (DEF_OP_PTR (OP))) > - > #define PHI_RESULT_PTR(PHI) gimple_phi_result_ptr (PHI) > #define PHI_RESULT(PHI) DEF_FROM_PTR (PHI_RESULT_PTR (PHI)) > #define SET_PHI_RESULT(PHI, V) SET_DEF (PHI_RESULT_PTR (PHI), (V)) > @@ -133,13 +121,13 @@ enum ssa_op_iter_type { > > typedef struct ssa_operand_iterator_d > { > - bool done; > enum ssa_op_iter_type iter_type; > - def_optype_p defs; > + bool done; > + int flags; > + unsigned i; > + unsigned numops; > use_optype_p uses; > - int phi_i; > - int num_phi; > - gimple phi_stmt; > + gimple stmt; > } ssa_op_iter; > > /* These flags are used to determine which operands are returned during > Index: gimple.h > =================================================================== > --- gimple.h.orig 2012-10-19 15:03:43.000000000 +0200 > +++ gimple.h 2012-10-22 15:12:30.000000000 +0200 > @@ -220,12 +222,12 @@ struct GTY(()) gimple_statement_with_ops > /* [ WORD 1-6 ] */ > struct gimple_statement_base gsbase; > > + /* XXX adjust word count */ > /* [ 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 > more information (like immediate use chaining). */ > - struct def_optype_d GTY((skip (""))) *def_ops; > struct use_optype_d GTY((skip (""))) *use_ops; > }; > > @@ -1372,27 +1374,6 @@ gimple_has_mem_ops (const_gimple g) > } > > > -/* Return the set of DEF operands for statement G. */ > - > -static inline struct def_optype_d * > -gimple_def_ops (const_gimple g) > -{ > - if (!gimple_has_ops (g)) > - return NULL; > - return g->gsops.opbase.def_ops; > -} > - > - > -/* Set DEF to be the set of DEF operands for statement G. */ > - > -static inline void > -gimple_set_def_ops (gimple g, struct def_optype_d *def) > -{ > - gcc_gimple_checking_assert (gimple_has_ops (g)); > - g->gsops.opbase.def_ops = def; > -} > - > - > /* Return the set of USE operands for statement G. */ > > static inline struct use_optype_d * > @@ -1432,15 +1413,12 @@ gimple_vuse_op (const_gimple g) > /* Return the set of VDEF operand for statement G. */ > > static inline def_operand_p > -gimple_vdef_op (const_gimple g) > +gimple_vdef_op (gimple g) > { > - struct def_optype_d *ops; > if (!gimple_has_mem_ops (g)) > return NULL_DEF_OPERAND_P; > - ops = g->gsops.opbase.def_ops; > - if (ops > - && DEF_OP_PTR (ops) == &g->gsmembase.vdef) > - return DEF_OP_PTR (ops); > + if (g->gsmembase.vdef) > + return &g->gsmembase.vdef; > return NULL_DEF_OPERAND_P; > } > > @@ -2941,8 +2919,8 @@ static inline tree > gimple_asm_input_op (const_gimple gs, unsigned index) > { > GIMPLE_CHECK (gs, GIMPLE_ASM); > - gcc_gimple_checking_assert (index <= gs->gimple_asm.ni); > - return gimple_op (gs, index); > + gcc_gimple_checking_assert (index < gs->gimple_asm.ni); > + return gimple_op (gs, index + gs->gimple_asm.no); > } > > /* Return a pointer to input operand INDEX of GIMPLE_ASM GS. */ > @@ -2951,8 +2929,8 @@ static inline tree * > gimple_asm_input_op_ptr (const_gimple gs, unsigned index) > { > GIMPLE_CHECK (gs, GIMPLE_ASM); > - gcc_gimple_checking_assert (index <= gs->gimple_asm.ni); > - return gimple_op_ptr (gs, index); > + gcc_gimple_checking_assert (index < gs->gimple_asm.ni); > + return gimple_op_ptr (gs, index + gs->gimple_asm.no); > } > > > @@ -2962,9 +2940,9 @@ static inline void > gimple_asm_set_input_op (gimple gs, unsigned index, tree in_op) > { > GIMPLE_CHECK (gs, GIMPLE_ASM); > - gcc_gimple_checking_assert (index <= gs->gimple_asm.ni > + gcc_gimple_checking_assert (index < gs->gimple_asm.ni > && TREE_CODE (in_op) == TREE_LIST); > - gimple_set_op (gs, index, in_op); > + gimple_set_op (gs, index + gs->gimple_asm.no, in_op); > } > > > @@ -2974,8 +2952,8 @@ static inline tree > gimple_asm_output_op (const_gimple gs, unsigned index) > { > GIMPLE_CHECK (gs, GIMPLE_ASM); > - gcc_gimple_checking_assert (index <= gs->gimple_asm.no); > - return gimple_op (gs, index + gs->gimple_asm.ni); > + gcc_gimple_checking_assert (index < gs->gimple_asm.no); > + return gimple_op (gs, index); > } > > /* Return a pointer to output operand INDEX of GIMPLE_ASM GS. */ > @@ -2984,8 +2962,8 @@ static inline tree * > gimple_asm_output_op_ptr (const_gimple gs, unsigned index) > { > GIMPLE_CHECK (gs, GIMPLE_ASM); > - gcc_gimple_checking_assert (index <= gs->gimple_asm.no); > - return gimple_op_ptr (gs, index + gs->gimple_asm.ni); > + gcc_gimple_checking_assert (index < gs->gimple_asm.no); > + return gimple_op_ptr (gs, index); > } > > > @@ -2995,9 +2973,9 @@ static inline void > gimple_asm_set_output_op (gimple gs, unsigned index, tree out_op) > { > GIMPLE_CHECK (gs, GIMPLE_ASM); > - gcc_gimple_checking_assert (index <= gs->gimple_asm.no > + gcc_gimple_checking_assert (index < gs->gimple_asm.no > && TREE_CODE (out_op) == TREE_LIST); > - gimple_set_op (gs, index + gs->gimple_asm.ni, out_op); > + gimple_set_op (gs, index, out_op); > } > > > @@ -3007,7 +2985,7 @@ static inline tree > gimple_asm_clobber_op (const_gimple gs, unsigned index) > { > GIMPLE_CHECK (gs, GIMPLE_ASM); > - gcc_gimple_checking_assert (index <= gs->gimple_asm.nc); > + gcc_gimple_checking_assert (index < gs->gimple_asm.nc); > return gimple_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.no); > } > > @@ -3018,7 +2996,7 @@ static inline void > gimple_asm_set_clobber_op (gimple gs, unsigned index, tree clobber_op) > { > GIMPLE_CHECK (gs, GIMPLE_ASM); > - gcc_gimple_checking_assert (index <= gs->gimple_asm.nc > + gcc_gimple_checking_assert (index < gs->gimple_asm.nc > && TREE_CODE (clobber_op) == TREE_LIST); > gimple_set_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.no, > clobber_op); > } > @@ -3029,7 +3007,7 @@ static inline tree > gimple_asm_label_op (const_gimple gs, unsigned index) > { > GIMPLE_CHECK (gs, GIMPLE_ASM); > - gcc_gimple_checking_assert (index <= gs->gimple_asm.nl); > + gcc_gimple_checking_assert (index < gs->gimple_asm.nl); > return gimple_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.nc); > } > > @@ -3039,7 +3017,7 @@ static inline void > gimple_asm_set_label_op (gimple gs, unsigned index, tree label_op) > { > GIMPLE_CHECK (gs, GIMPLE_ASM); > - gcc_gimple_checking_assert (index <= gs->gimple_asm.nl > + gcc_gimple_checking_assert (index < gs->gimple_asm.nl > && TREE_CODE (label_op) == TREE_LIST); > gimple_set_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.nc, > label_op); > } > Index: tree-flow-inline.h > =================================================================== > --- tree-flow-inline.h.orig 2012-09-24 15:26:16.000000000 +0200 > +++ tree-flow-inline.h 2012-10-22 15:27:36.000000000 +0200 > @@ -580,9 +580,9 @@ op_iter_next_use (ssa_op_iter *ptr) > ptr->uses = ptr->uses->next; > return use_p; > } > - if (ptr->phi_i < ptr->num_phi) > + if (ptr->i < ptr->numops) > { > - return PHI_ARG_DEF_PTR (ptr->phi_stmt, (ptr->phi_i)++); > + return PHI_ARG_DEF_PTR (ptr->stmt, (ptr->i)++); > } > ptr->done = true; > return NULL_USE_OPERAND_P; > @@ -592,14 +592,33 @@ op_iter_next_use (ssa_op_iter *ptr) > static inline def_operand_p > op_iter_next_def (ssa_op_iter *ptr) > { > - def_operand_p def_p; > gcc_checking_assert (ptr->iter_type == ssa_op_iter_def); > - if (ptr->defs) > + if (ptr->flags & SSA_OP_VDEF) > { > - def_p = DEF_OP_PTR (ptr->defs); > - ptr->defs = ptr->defs->next; > - return def_p; > + tree *p; > + ptr->flags &= ~SSA_OP_VDEF; > + p = gimple_vdef_ptr (ptr->stmt); > + if (p && *p) > + return p; > } > + if (ptr->flags & SSA_OP_DEF) > + { > + while (ptr->i < ptr->numops) > + { > + tree *val = gimple_op_ptr (ptr->stmt, ptr->i); > + ptr->i++; > + if (*val) > + { > + if (TREE_CODE (*val) == TREE_LIST) > + val = &TREE_VALUE (*val); > + if (TREE_CODE (*val) == SSA_NAME > + || is_gimple_reg (*val)) > + return val; > + } > + } > + ptr->flags &= ~SSA_OP_DEF; > + } > + > ptr->done = true; > return NULL_DEF_OPERAND_P; > } > @@ -616,16 +635,32 @@ op_iter_next_tree (ssa_op_iter *ptr) > ptr->uses = ptr->uses->next; > return val; > } > - if (ptr->defs) > + if (ptr->flags & SSA_OP_VDEF) > { > - val = DEF_OP (ptr->defs); > - ptr->defs = ptr->defs->next; > - return val; > + ptr->flags &= ~SSA_OP_VDEF; > + if ((val = gimple_vdef (ptr->stmt))) > + return val; > + } > + if (ptr->flags & SSA_OP_DEF) > + { > + while (ptr->i < ptr->numops) > + { > + val = gimple_op (ptr->stmt, ptr->i); > + ptr->i++; > + if (val) > + { > + if (TREE_CODE (val) == TREE_LIST) > + val = TREE_VALUE (val); > + if (TREE_CODE (val) == SSA_NAME > + || is_gimple_reg (val)) > + return val; > + } > + } > + ptr->flags &= ~SSA_OP_DEF; > } > > ptr->done = true; > return NULL_TREE; > - > } > > > @@ -636,13 +671,13 @@ op_iter_next_tree (ssa_op_iter *ptr) > static inline void > clear_and_done_ssa_iter (ssa_op_iter *ptr) > { > - ptr->defs = NULL; > + ptr->i = 0; > + ptr->numops = 0; > ptr->uses = NULL; > ptr->iter_type = ssa_op_iter_none; > - ptr->phi_i = 0; > - ptr->num_phi = 0; > - ptr->phi_stmt = NULL; > + ptr->stmt = NULL; > ptr->done = true; > + ptr->flags = 0; > } > > /* Initialize the iterator PTR to the virtual defs in STMT. */ > @@ -655,21 +690,34 @@ op_iter_init (ssa_op_iter *ptr, gimple s > gcc_checking_assert (gimple_code (stmt) != GIMPLE_PHI > && (!(flags & SSA_OP_VDEF) || (flags & SSA_OP_DEF)) > && (!(flags & SSA_OP_VUSE) || (flags & SSA_OP_USE))); > - ptr->defs = (flags & (SSA_OP_DEF|SSA_OP_VDEF)) ? gimple_def_ops (stmt) : > NULL; > - if (!(flags & SSA_OP_VDEF) > - && ptr->defs > - && gimple_vdef (stmt) != NULL_TREE) > - ptr->defs = ptr->defs->next; > + ptr->numops = 0; > + if (flags & (SSA_OP_DEF | SSA_OP_VDEF)) > + { > + switch (gimple_code (stmt)) > + { > + case GIMPLE_ASSIGN: > + case GIMPLE_CALL: > + ptr->numops = 1; > + break; > + case GIMPLE_ASM: > + ptr->numops = gimple_asm_noutputs (stmt); > + break; > + default: > + ptr->numops = 0; > + flags &= ~(SSA_OP_DEF | SSA_OP_VDEF); > + break; > + } > + } > ptr->uses = (flags & (SSA_OP_USE|SSA_OP_VUSE)) ? gimple_use_ops (stmt) : > NULL; > if (!(flags & SSA_OP_VUSE) > && ptr->uses > && gimple_vuse (stmt) != NULL_TREE) > ptr->uses = ptr->uses->next; > ptr->done = false; > + ptr->i = 0; > > - ptr->phi_i = 0; > - ptr->num_phi = 0; > - ptr->phi_stmt = NULL; > + ptr->stmt = stmt; > + ptr->flags = flags; > } > > /* Initialize iterator PTR to the use operands in STMT based on FLAGS. Return > @@ -839,9 +887,10 @@ op_iter_init_phiuse (ssa_op_iter *ptr, g > return NULL_USE_OPERAND_P; > } > > - ptr->phi_stmt = phi; > - ptr->num_phi = gimple_phi_num_args (phi); > + ptr->stmt = phi; > + ptr->numops = gimple_phi_num_args (phi); > ptr->iter_type = ssa_op_iter_use; > + ptr->flags = flags; > return op_iter_next_use (ptr); > } > > Index: tree-ssa-operands.c > =================================================================== > --- tree-ssa-operands.c.orig 2012-09-24 15:26:38.000000000 +0200 > +++ tree-ssa-operands.c 2012-10-22 15:12:30.000000000 +0200 > @@ -106,9 +106,6 @@ along with GCC; see the file COPYING3. > /* Operand is in a place where opf_non_addressable does not apply. */ > #define opf_not_non_addressable (1 << 4) > > -/* Array for building all the def operands. */ > -static VEC(tree,heap) *build_defs; > - > /* Array for building all the use operands. */ > static VEC(tree,heap) *build_uses; > > @@ -185,7 +182,6 @@ init_ssa_operands (struct function *fn) > { > if (!n_initialized++) > { > - build_defs = VEC_alloc (tree, heap, 5); > build_uses = VEC_alloc (tree, heap, 10); > build_vuse = NULL_TREE; > build_vdef = NULL_TREE; > @@ -210,13 +206,11 @@ fini_ssa_operands (void) > > if (!--n_initialized) > { > - VEC_free (tree, heap, build_defs); > VEC_free (tree, heap, build_uses); > build_vdef = NULL_TREE; > build_vuse = NULL_TREE; > } > > - gimple_ssa_operands (cfun)->free_defs = NULL; > gimple_ssa_operands (cfun)->free_uses = NULL; > > while ((ptr = gimple_ssa_operands (cfun)->operand_memory) != NULL) > @@ -242,8 +236,7 @@ ssa_operand_alloc (unsigned size) > { > char *ptr; > > - gcc_assert (size == sizeof (struct use_optype_d) > - || size == sizeof (struct def_optype_d)); > + gcc_assert (size == sizeof (struct use_optype_d)); > > if (gimple_ssa_operands (cfun)->operand_memory_index + size > >= gimple_ssa_operands (cfun)->ssa_operand_mem_size) > @@ -282,25 +275,6 @@ ssa_operand_alloc (unsigned size) > } > > > -/* Allocate a DEF operand. */ > - > -static inline struct def_optype_d * > -alloc_def (void) > -{ > - struct def_optype_d *ret; > - if (gimple_ssa_operands (cfun)->free_defs) > - { > - ret = gimple_ssa_operands (cfun)->free_defs; > - gimple_ssa_operands (cfun)->free_defs > - = gimple_ssa_operands (cfun)->free_defs->next; > - } > - else > - ret = (struct def_optype_d *) > - ssa_operand_alloc (sizeof (struct def_optype_d)); > - return ret; > -} > - > - > /* Allocate a USE operand. */ > > static inline struct use_optype_d * > @@ -320,21 +294,6 @@ alloc_use (void) > } > > > -/* Adds OP to the list of defs after LAST. */ > - > -static inline def_optype_p > -add_def_op (tree *op, def_optype_p last) > -{ > - def_optype_p new_def; > - > - new_def = alloc_def (); > - DEF_OP_PTR (new_def) = op; > - last->next = new_def; > - new_def->next = NULL; > - return new_def; > -} > - > - > /* Adds OP to the list of uses of statement STMT after LAST. */ > > static inline use_optype_p > @@ -358,14 +317,6 @@ add_use_op (gimple stmt, tree *op, use_o > static inline void > finalize_ssa_defs (gimple stmt) > { > - unsigned new_i; > - struct def_optype_d new_list; > - def_optype_p old_ops, last; > - unsigned int num = VEC_length (tree, build_defs); > - > - /* There should only be a single real definition per assignment. */ > - gcc_assert ((stmt && gimple_code (stmt) != GIMPLE_ASSIGN) || num <= 1); > - > /* Pre-pend the vdef we may have built. */ > if (build_vdef != NULL_TREE) > { > @@ -375,17 +326,8 @@ finalize_ssa_defs (gimple stmt) > oldvdef = SSA_NAME_VAR (oldvdef); > if (oldvdef != build_vdef) > gimple_set_vdef (stmt, build_vdef); > - VEC_safe_insert (tree, heap, build_defs, 0, (tree)gimple_vdef_ptr > (stmt)); > - ++num; > } > > - new_list.next = NULL; > - last = &new_list; > - > - old_ops = gimple_def_ops (stmt); > - > - new_i = 0; > - > /* Clear and unlink a no longer necessary VDEF. */ > if (build_vdef == NULL_TREE > && gimple_vdef (stmt) != NULL_TREE) > @@ -405,30 +347,6 @@ finalize_ssa_defs (gimple stmt) > cfun->gimple_df->rename_vops = 1; > cfun->gimple_df->ssa_renaming_needed = 1; > } > - > - /* Check for the common case of 1 def that hasn't changed. */ > - if (old_ops && old_ops->next == NULL && num == 1 > - && (tree *) VEC_index (tree, build_defs, 0) == DEF_OP_PTR (old_ops)) > - return; > - > - /* If there is anything in the old list, free it. */ > - if (old_ops) > - { > - old_ops->next = gimple_ssa_operands (cfun)->free_defs; > - gimple_ssa_operands (cfun)->free_defs = old_ops; > - } > - > - /* If there is anything remaining in the build_defs list, simply emit it. > */ > - for ( ; new_i < num; new_i++) > - { > - tree *op = (tree *) VEC_index (tree, build_defs, new_i); > - if (DECL_P (*op)) > - cfun->gimple_df->ssa_renaming_needed = 1; > - last = add_def_op (op, last); > - } > - > - /* Now set the stmt's operands. */ > - gimple_set_def_ops (stmt, new_list.next); > } > > > @@ -488,8 +406,6 @@ finalize_ssa_uses (gimple stmt) > for (new_i = 0; new_i < VEC_length (tree, build_uses); new_i++) > { > tree *op = (tree *) VEC_index (tree, build_uses, new_i); > - if (DECL_P (*op)) > - cfun->gimple_df->ssa_renaming_needed = 1; > last = add_use_op (stmt, op, last); > } > > @@ -506,7 +422,6 @@ cleanup_build_arrays (void) > { > build_vdef = NULL_TREE; > build_vuse = NULL_TREE; > - VEC_truncate (tree, build_defs, 0); > VEC_truncate (tree, build_uses, 0); > } > > @@ -527,22 +442,12 @@ finalize_ssa_stmt_operands (gimple stmt) > static inline void > start_ssa_stmt_operands (void) > { > - gcc_assert (VEC_length (tree, build_defs) == 0); > gcc_assert (VEC_length (tree, build_uses) == 0); > gcc_assert (build_vuse == NULL_TREE); > gcc_assert (build_vdef == NULL_TREE); > } > > > -/* Add DEF_P to the list of pointers to operands. */ > - > -static inline void > -append_def (tree *def_p) > -{ > - VEC_safe_push (tree, heap, build_defs, (tree) def_p); > -} > - > - > /* Add USE_P to the list of pointers to operands. */ > > static inline void > @@ -620,9 +525,11 @@ add_stmt_operand (tree *var_p, gimple st > { > /* The variable is a GIMPLE register. Add it to real operands. */ > if (flags & opf_def) > - append_def (var_p); > + ; > else > append_use (var_p); > + if (DECL_P (*var_p)) > + cfun->gimple_df->ssa_renaming_needed = 1; > } > else > { > @@ -669,15 +576,10 @@ mark_address_taken (tree ref) > STMT is the statement being processed, EXPR is the MEM_REF > that got us here. > > - FLAGS is as in get_expr_operands. > - > - RECURSE_ON_BASE should be set to true if we want to continue > - calling get_expr_operands on the base pointer, and false if > - something else will do it for us. */ > + FLAGS is as in get_expr_operands. */ > > static void > -get_indirect_ref_operands (gimple stmt, tree expr, int flags, > - bool recurse_on_base) > +get_indirect_ref_operands (gimple stmt, tree expr, int flags) > { > tree *pptr = &TREE_OPERAND (expr, 0); > > @@ -689,10 +591,9 @@ get_indirect_ref_operands (gimple stmt, > add_virtual_operand (stmt, flags); > > /* If requested, add a USE operand for the base pointer. */ > - if (recurse_on_base) > - get_expr_operands (stmt, pptr, > - opf_non_addressable | opf_use > - | (flags & (opf_no_vops|opf_not_non_addressable))); > + get_expr_operands (stmt, pptr, > + opf_non_addressable | opf_use > + | (flags & (opf_no_vops|opf_not_non_addressable))); > } > > > @@ -853,7 +754,7 @@ get_expr_operands (gimple stmt, tree *ex > return; > > case MEM_REF: > - get_indirect_ref_operands (stmt, expr, flags, true); > + get_indirect_ref_operands (stmt, expr, flags); > return; > > case TARGET_MEM_REF: > @@ -1126,31 +1027,6 @@ verify_ssa_operands (gimple stmt) > return true; > } > > - FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF) > - { > - FOR_EACH_VEC_ELT (tree, build_defs, i, def) > - { > - if (def_p == (tree *)def) > - { > - VEC_replace (tree, build_defs, i, NULL_TREE); > - break; > - } > - } > - if (i == VEC_length (tree, build_defs)) > - { > - error ("excess def operand for stmt"); > - debug_generic_expr (DEF_FROM_PTR (def_p)); > - return true; > - } > - } > - FOR_EACH_VEC_ELT (tree, build_defs, i, def) > - if (def != NULL_TREE) > - { > - error ("def operand missing for stmt"); > - debug_generic_expr (*(tree *)def); > - return true; > - } > - > if (gimple_has_volatile_ops (stmt) != volatile_p) > { > error ("stmt volatile flag not up-to-date"); > @@ -1168,18 +1044,8 @@ verify_ssa_operands (gimple stmt) > void > free_stmt_operands (gimple stmt) > { > - def_optype_p defs = gimple_def_ops (stmt), last_def; > use_optype_p uses = gimple_use_ops (stmt), last_use; > > - if (defs) > - { > - for (last_def = defs; last_def->next; last_def = last_def->next) > - continue; > - last_def->next = gimple_ssa_operands (cfun)->free_defs; > - gimple_ssa_operands (cfun)->free_defs = defs; > - gimple_set_def_ops (stmt, NULL); > - } > - > if (uses) > { > for (last_use = uses; last_use->next; last_use = last_use->next) > Index: gimple.c > =================================================================== > --- gimple.c.orig 2012-09-24 15:26:19.000000000 +0200 > +++ gimple.c 2012-10-22 15:13:10.000000000 +0200 > @@ -2345,7 +2345,6 @@ gimple_copy (gimple stmt) > /* Clear out SSA operand vectors on COPY. */ > if (gimple_has_ops (stmt)) > { > - gimple_set_def_ops (copy, NULL); > gimple_set_use_ops (copy, NULL); > > /* SSA operands need to be updated. */