diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 86 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 8 | ||||
-rw-r--r-- | gcc/tree-dfa.c | 9 | ||||
-rw-r--r-- | gcc/tree-flow-inline.h | 76 | ||||
-rw-r--r-- | gcc/tree-flow.h | 1 | ||||
-rw-r--r-- | gcc/tree-into-ssa.c | 204 | ||||
-rw-r--r-- | gcc/tree-optimize.c | 5 | ||||
-rw-r--r-- | gcc/tree-pass.h | 1 | ||||
-rw-r--r-- | gcc/tree-pretty-print.c | 13 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-dce.c | 135 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-im.c | 5 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-manip.c | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-operands.c | 25 | ||||
-rw-r--r-- | gcc/tree-ssa-operands.h | 42 | ||||
-rw-r--r-- | gcc/tree-ssa.c | 6 | ||||
-rw-r--r-- | gcc/tree-vectorizer.c | 7 |
17 files changed, 465 insertions, 162 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 767af3e..75423d8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,89 @@ +2004-10-27 Daniel Berlin <dberlin@dberlin.org> + + Fix PR tree-optimization/17133 + + * tree-cfg.c (rewrite_to_new_ssa_names_bb): Also rewrite must + def kill operand. + + * tree-flow-inline.h: V_MUST_DEF_OP became V_MUST_DEF_RESULT. + (get_v_must_def_result_ptr): Modify for new structure of + v_must_defs array. + (get_v_must_def_kill_ptr): New. + (op_iter_next_use): Add support for the kill that occurs in V_MUST_DEFs. + (op_iter_next_tree): Ditto. Also V_MAY_DEF_OP became V_MAY_DEF_RESULT. + (op_iter_next_def): V_MAY_DEF_OP became V_MAY_DEF_RESULT. + (op_iter_init): Initialize new mustu members. + (op_iter_next_mustdef): New function. + (op_iter_init_mustdef): Ditto. + + * tree-flow.h (rewrite_def_def_chains): New function. + + * tree-into-ssa.c (mark_def_sites): Handle mustdefkill operands. + (ssa_mark_def_sites): Ditto. + (rewrite_stmt): Ditto. + (ssa_rewrite_stmt): Ditto. + (rewrite_blocks): Factor out from rewrite_into_ssa. + (mark_def_block_sites): Ditto. + (rewrite_def_def_chains): New function, just rewrites def-def + chains without phi node insertion. + + * tree-pass.h (TODO_fix_def_def_chains): New todo flag. + + * tree-optimize.c (execute_todo): Handle TODO_fix_def_def_chains. + + * tree-pretty-print.c (dump_vops): Print out MUST_DEF's so that + they include the rhs now. + + * tree-ssa-ccp.c (visit_assignment): V_MUST_DEF_OP became + V_MUST_DEF_RESULT. + + * tree-ssa-dce.c (mark_operand_necessary): Add phionly argument. + Update callers. + (mark_really_necessary_kill_operand_phis): New function. + (perform_tree_ssa_dce): Call it. + (pass_dce): Add TODO_fix_def_def_chains. + (pass_cd_dce): Ditto. + + * tree-ssa-loop-im.c (determine_max_movement): Look at kills as + well. + (rewrite_mem_refs): Ditto. + + * tree-ssa-loop-manip.c (find_uses_to_rename_stmt): Look at kills + as well. + + * tree-ssa-operands.c (allocate_v_may_def_optype): + v_may_def_operand_type_t became v_def_use_operand_type_t. + (allocate_v_must_def_optype) Ditto. + (finalize_ssa_v_must_defs): Update for new operand type, as well + as setting the use portion as well. + (copy_virtual_operands): Copy the kill operand as well. + (create_ssa_artficial_load_stmt): V_MUST_DEF_OP became + V_MUST_DEF_RESULT. + + * tree-ssa-operands.h (v_may_def_operand_type): Renamed to + v_def_use_operand_type. + (v_must_def_optype_d): Use v_def_use_operand_type. + (V_MUST_DEF_OP_*): Renamed to V_MUST_DEF_RESULT_* + (V_MUST_DEF_KILL_*): New macros. + (struct ssa_operand_iterator_d): Add num_v_mustu and v_mustu_i + members. + Rename existing must_i and num_v_must members to mustd_i and + num_v_mustd. + (SSA_OP_VMUSTDEFKILL): New flag. + (SSA_OP_VIRTUAL_KILLS): New flag. + (SSA_OP_ALL_OPERANDS): Add in SSA_OP_ALL_KILLS. + (SSA_OP_ALL_KILLS): New flag. + (FOR_EACH_SSA_MUSTDEF_OPERAND): New macro. + + * tree-ssa.c (verify_ssa): Verify virtual kills as well. + + * tree-vectorizer.c (vect_create_data_ref_ptr): V_MUST_DEF_OP + became V_MUST_DEF_RESULT. + (rename_variables_in_bb): Rename kill pointer as well. + + * tree-dfa.c (compute_immediate_uses_for_stmt): Add kills into the + immediate uses. + 2004-10-27 Richard Sandiford <rsandifo@redhat.com> * dbxout.c (dbxout_source_line): Move declaration of begin_label to diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index af78901..a963124 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -4542,8 +4542,12 @@ rewrite_to_new_ssa_names_bb (basic_block bb, htab_t map) v_must_defs = V_MUST_DEF_OPS (ann); for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) - rewrite_to_new_ssa_names_def - (V_MUST_DEF_OP_PTR (v_must_defs, i), stmt, map); + { + rewrite_to_new_ssa_names_def + (V_MUST_DEF_RESULT_PTR (v_must_defs, i), stmt, map); + rewrite_to_new_ssa_names_use + (V_MUST_DEF_KILL_PTR (v_must_defs, i), map); + } } FOR_EACH_EDGE (e, ei, bb->succs) diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index cce0ff6..de4e225 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -312,7 +312,14 @@ compute_immediate_uses_for_stmt (tree stmt, int flags, bool (*calc_for)(tree)) if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (use))) add_immediate_use (imm_rdef_stmt, stmt); } - } + + FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_KILLS) + { + tree imm_rdef_stmt = SSA_NAME_DEF_STMT (use); + if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (use))) + add_immediate_use (imm_rdef_stmt, stmt); + } + } } diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index 0507921..e3c955e 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -267,14 +267,25 @@ get_vuse_op_ptr(vuse_optype vuses, unsigned int index) return op; } -/* Return a def_operand_p that is the V_MUST_DEF_OP for the +/* Return a def_operand_p that is the V_MUST_DEF_RESULT for the V_MUST_DEF at INDEX in the V_MUST_DEFS array. */ static inline def_operand_p -get_v_must_def_op_ptr (v_must_def_optype v_must_defs, unsigned int index) +get_v_must_def_result_ptr (v_must_def_optype v_must_defs, unsigned int index) { def_operand_p op; gcc_assert (index < v_must_defs->num_v_must_defs); - op.def = &(v_must_defs->v_must_defs[index]); + op.def = &(v_must_defs->v_must_defs[index].def); + return op; +} + +/* Return a use_operand_p that is the V_MUST_DEF_KILL for the + V_MUST_DEF at INDEX in the V_MUST_DEFS array. */ +static inline use_operand_p +get_v_must_def_kill_ptr (v_must_def_optype v_must_defs, unsigned int index) +{ + use_operand_p op; + gcc_assert (index < v_must_defs->num_v_must_defs); + op.use = &(v_must_defs->v_must_defs[index].use); return op; } @@ -670,7 +681,12 @@ op_iter_next_use (ssa_op_iter *ptr) if (ptr->v_mayu_i < ptr->num_v_mayu) { return V_MAY_DEF_OP_PTR (ptr->ops->v_may_def_ops, - (ptr->v_mayu_i)++); + (ptr->v_mayu_i)++); + } + if (ptr->v_mustu_i < ptr->num_v_mustu) + { + return V_MUST_DEF_KILL_PTR (ptr->ops->v_must_def_ops, + (ptr->v_mustu_i)++); } ptr->done = true; return NULL_USE_OPERAND_P; @@ -684,10 +700,10 @@ op_iter_next_def (ssa_op_iter *ptr) { return DEF_OP_PTR (ptr->ops->def_ops, (ptr->def_i)++); } - if (ptr->v_must_i < ptr->num_v_must) + if (ptr->v_mustd_i < ptr->num_v_mustd) { - return V_MUST_DEF_OP_PTR (ptr->ops->v_must_def_ops, - (ptr->v_must_i)++); + return V_MUST_DEF_RESULT_PTR (ptr->ops->v_must_def_ops, + (ptr->v_mustd_i)++); } if (ptr->v_mayd_i < ptr->num_v_mayd) { @@ -714,14 +730,18 @@ op_iter_next_tree (ssa_op_iter *ptr) { return V_MAY_DEF_OP (ptr->ops->v_may_def_ops, (ptr->v_mayu_i)++); } + if (ptr->v_mustu_i < ptr->num_v_mustu) + { + return V_MUST_DEF_KILL (ptr->ops->v_must_def_ops, (ptr->v_mustu_i)++); + } if (ptr->def_i < ptr->num_def) { return DEF_OP (ptr->ops->def_ops, (ptr->def_i)++); } - if (ptr->v_must_i < ptr->num_v_must) + if (ptr->v_mustd_i < ptr->num_v_mustd) { - return V_MUST_DEF_OP (ptr->ops->v_must_def_ops, - (ptr->v_must_i)++); + return V_MUST_DEF_RESULT (ptr->ops->v_must_def_ops, + (ptr->v_mustd_i)++); } if (ptr->v_mayd_i < ptr->num_v_mayd) { @@ -749,14 +769,17 @@ op_iter_init (ssa_op_iter *ptr, tree stmt, int flags) ? NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0; ptr->num_v_mayd = (flags & SSA_OP_VMAYDEF) ? NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0; - ptr->num_v_must = (flags & SSA_OP_VMUSTDEF) + ptr->num_v_mustu = (flags & SSA_OP_VMUSTDEFKILL) + ? NUM_V_MUST_DEFS (ops->v_must_def_ops) : 0; + ptr->num_v_mustd = (flags & SSA_OP_VMUSTDEF) ? NUM_V_MUST_DEFS (ops->v_must_def_ops) : 0; ptr->def_i = 0; ptr->use_i = 0; ptr->vuse_i = 0; ptr->v_mayu_i = 0; ptr->v_mayd_i = 0; - ptr->v_must_i = 0; + ptr->v_mustu_i = 0; + ptr->v_mustd_i = 0; } /* Initialize iterator PTR to the use operands in STMT based on FLAGS. Return @@ -786,6 +809,25 @@ op_iter_init_tree (ssa_op_iter *ptr, tree stmt, int flags) return op_iter_next_tree (ptr); } +/* Get the next iterator mustdef value for PTR, returning the mustdef values in + KILL and DEF. */ +static inline void +op_iter_next_mustdef (use_operand_p *kill, def_operand_p *def, ssa_op_iter *ptr) +{ + if (ptr->v_mustu_i < ptr->num_v_mustu) + { + *def = V_MUST_DEF_RESULT_PTR (ptr->ops->v_must_def_ops, ptr->v_mustu_i); + *kill = V_MUST_DEF_KILL_PTR (ptr->ops->v_must_def_ops, (ptr->v_mustu_i)++); + return; + } + else + { + *def = NULL_DEF_OPERAND_P; + *kill = NULL_USE_OPERAND_P; + } + ptr->done = true; + return; +} /* Get the next iterator maydef value for PTR, returning the maydef values in USE and DEF. */ static inline void @@ -815,4 +857,14 @@ op_iter_init_maydef (ssa_op_iter *ptr, tree stmt, use_operand_p *use, op_iter_init (ptr, stmt, SSA_OP_VMAYUSE); op_iter_next_maydef (use, def, ptr); } + +/* Initialize iterator PTR to the operands in STMT. Return the first operands + in KILL and DEF. */ +static inline void +op_iter_init_mustdef (ssa_op_iter *ptr, tree stmt, use_operand_p *kill, + def_operand_p *def) +{ + op_iter_init (ptr, stmt, SSA_OP_VMUSTDEFKILL); + op_iter_next_mustdef (kill, def, ptr); +} #endif /* _TREE_FLOW_INLINE_H */ diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 14b5972..37cf556 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -583,6 +583,7 @@ extern void kill_redundant_phi_nodes (void); /* In tree-into-ssa.c */ extern void rewrite_into_ssa (bool); extern void rewrite_ssa_into_ssa (void); +extern void rewrite_def_def_chains (void); void compute_global_livein (bitmap, bitmap); tree duplicate_ssa_name (tree, tree); diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 972bec9..079065e 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -379,13 +379,13 @@ mark_def_sites (struct dom_walk_data *walk_data, /* If a variable is used before being set, then the variable is live across a block boundary, so mark it live-on-entry to BB. */ - FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE | SSA_OP_VUSE) + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE | SSA_OP_VUSE | SSA_OP_VMUSTDEFKILL) { if (prepare_use_operand_for_rename (use_p, &uid) && !TEST_BIT (kills, uid)) set_livein_block (USE_FROM_PTR (use_p), bb); } - + /* Note that virtual definitions are irrelevant for computing KILLS because a V_MAY_DEF does not constitute a killing definition of the variable. However, the operand of a virtual definitions is a use @@ -438,7 +438,7 @@ ssa_mark_def_sites (struct dom_walk_data *walk_data, /* If a variable is used before being set, then the variable is live across a block boundary, so mark it live-on-entry to BB. */ - FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_USES) + FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS) { uid = SSA_NAME_VERSION (use); @@ -1077,7 +1077,7 @@ rewrite_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, gcc_assert (!ann->modified); /* Step 1. Rewrite USES and VUSES in the statement. */ - FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES) + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS) rewrite_operand (use_p); /* Step 2. Register the statement's DEF and VDEF operands. */ @@ -1121,7 +1121,7 @@ ssa_rewrite_stmt (struct dom_walk_data *walk_data, gcc_assert (!ann->modified); /* Step 1. Rewrite USES and VUSES in the statement. */ - FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES) + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS) { if (TEST_BIT (names_to_rename, SSA_NAME_VERSION (USE_FROM_PTR (use_p)))) SET_USE (use_p, get_reaching_def (USE_FROM_PTR (use_p))); @@ -1382,7 +1382,105 @@ invalidate_name_tags (bitmap vars_to_rename) } } +/* Rewrite the actual blocks, statements, and phi arguments, to be in SSA + form. ADD_PHI_ARGS is true if we should be adding arguments to phi nodes, + because they may have been just inserted. */ + +static void +rewrite_blocks (bool add_phi_args) +{ + struct dom_walk_data walk_data; + + /* Rewrite all the basic blocks in the program. */ + timevar_push (TV_TREE_SSA_REWRITE_BLOCKS); + + /* Setup callbacks for the generic dominator tree walker. */ + walk_data.walk_stmts_backward = false; + walk_data.dom_direction = CDI_DOMINATORS; + walk_data.initialize_block_local_data = NULL; + walk_data.before_dom_children_before_stmts = rewrite_initialize_block; + walk_data.before_dom_children_walk_stmts = rewrite_stmt; + walk_data.before_dom_children_after_stmts = NULL; + if (add_phi_args) + walk_data.before_dom_children_after_stmts = rewrite_add_phi_arguments; + walk_data.after_dom_children_before_stmts = NULL; + walk_data.after_dom_children_walk_stmts = NULL; + walk_data.after_dom_children_after_stmts = rewrite_finalize_block; + walk_data.global_data = NULL; + walk_data.block_local_data_size = 0; + + VARRAY_TREE_INIT (block_defs_stack, 10, "Block DEFS Stack"); + + /* Initialize the dominator walker. */ + init_walk_dominator_tree (&walk_data); + + /* Recursively walk the dominator tree rewriting each statement in + each basic block. */ + walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); + + /* Finalize the dominator walker. */ + fini_walk_dominator_tree (&walk_data); + + htab_delete (def_blocks); + + timevar_pop (TV_TREE_SSA_REWRITE_BLOCKS); +} + +/* Mark the definition site blocks for each variable, so that we know where + the variable is actually live. */ + +static void +mark_def_site_blocks (void) +{ + size_t i; + struct dom_walk_data walk_data; + struct mark_def_sites_global_data mark_def_sites_global_data; + + /* Allocate memory for the DEF_BLOCKS hash table. */ + def_blocks = htab_create (VARRAY_ACTIVE_SIZE (referenced_vars), + def_blocks_hash, def_blocks_eq, def_blocks_free); + + for (i = 0; i < num_referenced_vars; i++) + set_current_def (referenced_var (i), NULL_TREE); + + /* Ensure that the dominance information is OK. */ + calculate_dominance_info (CDI_DOMINATORS); + + /* Setup callbacks for the generic dominator tree walker to find and + mark definition sites. */ + walk_data.walk_stmts_backward = false; + walk_data.dom_direction = CDI_DOMINATORS; + walk_data.initialize_block_local_data = NULL; + walk_data.before_dom_children_before_stmts = mark_def_sites_initialize_block; + walk_data.before_dom_children_walk_stmts = mark_def_sites; + walk_data.before_dom_children_after_stmts = NULL; + walk_data.after_dom_children_before_stmts = NULL; + walk_data.after_dom_children_walk_stmts = NULL; + walk_data.after_dom_children_after_stmts = NULL; + + /* Notice that this bitmap is indexed using variable UIDs, so it must be + large enough to accommodate all the variables referenced in the + function, not just the ones we are renaming. */ + mark_def_sites_global_data.kills = sbitmap_alloc (num_referenced_vars); + walk_data.global_data = &mark_def_sites_global_data; + + /* We do not have any local data. */ + walk_data.block_local_data_size = 0; + + /* Initialize the dominator walker. */ + init_walk_dominator_tree (&walk_data); + + /* Recursively walk the dominator tree. */ + walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); + + /* Finalize the dominator walker. */ + fini_walk_dominator_tree (&walk_data); + + /* We no longer need this bitmap, clear and free it. */ + sbitmap_free (mark_def_sites_global_data.kills); + +} /* Main entry point into the SSA builder. The renaming process proceeds in five main phases: @@ -1395,13 +1493,11 @@ invalidate_name_tags (bitmap vars_to_rename) order. 3- Find and mark all the blocks that define variables - (mark_def_sites). + (mark_def_site_blocks). 4- Insert PHI nodes at dominance frontiers (insert_phi_nodes). - 5- Rename all the blocks (rewrite_initialize_block, - rewrite_add_phi_arguments) and statements in the program - (rewrite_stmt). + 5- Rename all the blocks (rewrite_blocks) and statements in the program. Steps 3 and 5 are done using the dominator tree walker (walk_dominator_tree). @@ -1414,10 +1510,7 @@ rewrite_into_ssa (bool all) { bitmap *dfs; basic_block bb; - struct dom_walk_data walk_data; - struct mark_def_sites_global_data mark_def_sites_global_data; bitmap old_vars_to_rename = vars_to_rename; - unsigned i; timevar_push (TV_TREE_SSA_OTHER); @@ -1441,9 +1534,7 @@ rewrite_into_ssa (bool all) remove_all_phi_nodes_for (vars_to_rename); } - /* Allocate memory for the DEF_BLOCKS hash table. */ - def_blocks = htab_create (VARRAY_ACTIVE_SIZE (referenced_vars), - def_blocks_hash, def_blocks_eq, def_blocks_free); + mark_def_site_blocks (); /* Initialize dominance frontier and immediate dominator bitmaps. Also count the number of predecessors for each block. Doing so @@ -1452,80 +1543,13 @@ rewrite_into_ssa (bool all) FOR_EACH_BB (bb) dfs[bb->index] = BITMAP_XMALLOC (); - for (i = 0; i < num_referenced_vars; i++) - set_current_def (referenced_var (i), NULL_TREE); - - /* Ensure that the dominance information is OK. */ - calculate_dominance_info (CDI_DOMINATORS); - /* Compute dominance frontiers. */ compute_dominance_frontiers (dfs); - /* Setup callbacks for the generic dominator tree walker to find and - mark definition sites. */ - walk_data.walk_stmts_backward = false; - walk_data.dom_direction = CDI_DOMINATORS; - walk_data.initialize_block_local_data = NULL; - walk_data.before_dom_children_before_stmts = mark_def_sites_initialize_block; - walk_data.before_dom_children_walk_stmts = mark_def_sites; - walk_data.before_dom_children_after_stmts = NULL; - walk_data.after_dom_children_before_stmts = NULL; - walk_data.after_dom_children_walk_stmts = NULL; - walk_data.after_dom_children_after_stmts = NULL; - - /* Notice that this bitmap is indexed using variable UIDs, so it must be - large enough to accommodate all the variables referenced in the - function, not just the ones we are renaming. */ - mark_def_sites_global_data.kills = sbitmap_alloc (num_referenced_vars); - walk_data.global_data = &mark_def_sites_global_data; - - /* We do not have any local data. */ - walk_data.block_local_data_size = 0; - - /* Initialize the dominator walker. */ - init_walk_dominator_tree (&walk_data); - - /* Recursively walk the dominator tree. */ - walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); - - /* Finalize the dominator walker. */ - fini_walk_dominator_tree (&walk_data); - - /* We no longer need this bitmap, clear and free it. */ - sbitmap_free (mark_def_sites_global_data.kills); - /* Insert PHI nodes at dominance frontiers of definition blocks. */ insert_phi_nodes (dfs, NULL); - /* Rewrite all the basic blocks in the program. */ - timevar_push (TV_TREE_SSA_REWRITE_BLOCKS); - - /* Setup callbacks for the generic dominator tree walker. */ - walk_data.walk_stmts_backward = false; - walk_data.dom_direction = CDI_DOMINATORS; - walk_data.initialize_block_local_data = NULL; - walk_data.before_dom_children_before_stmts = rewrite_initialize_block; - walk_data.before_dom_children_walk_stmts = rewrite_stmt; - walk_data.before_dom_children_after_stmts = rewrite_add_phi_arguments; - walk_data.after_dom_children_before_stmts = NULL; - walk_data.after_dom_children_walk_stmts = NULL; - walk_data.after_dom_children_after_stmts = rewrite_finalize_block; - walk_data.global_data = NULL; - walk_data.block_local_data_size = 0; - - VARRAY_TREE_INIT (block_defs_stack, 10, "Block DEFS Stack"); - - /* Initialize the dominator walker. */ - init_walk_dominator_tree (&walk_data); - - /* Recursively walk the dominator tree rewriting each statement in - each basic block. */ - walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); - - /* Finalize the dominator walker. */ - fini_walk_dominator_tree (&walk_data); - - timevar_pop (TV_TREE_SSA_REWRITE_BLOCKS); + rewrite_blocks (true); /* Debugging dumps. */ if (dump_file && (dump_flags & TDF_STATS)) @@ -1539,12 +1563,22 @@ rewrite_into_ssa (bool all) BITMAP_XFREE (dfs[bb->index]); free (dfs); - htab_delete (def_blocks); - vars_to_rename = old_vars_to_rename; timevar_pop (TV_TREE_SSA_OTHER); } +/* Rewrite the def-def chains so that they have the correct reaching + definitions. */ + +void +rewrite_def_def_chains (void) +{ + /* Ensure that the dominance information is OK. */ + calculate_dominance_info (CDI_DOMINATORS); + mark_def_site_blocks (); + rewrite_blocks (false); + +} /* The marked ssa names may have more than one definition; add phi nodes and rewrite them to fix this. */ diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index fed16c3..88d18a7 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -420,6 +420,11 @@ execute_todo (int properties, unsigned int flags) rewrite_into_ssa (false); bitmap_clear (vars_to_rename); } + if (flags & TODO_fix_def_def_chains) + { + rewrite_def_def_chains (); + bitmap_clear (vars_to_rename); + } if ((flags & TODO_dump_func) && dump_file) { diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 6250ae6..7140766 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -106,6 +106,7 @@ struct dump_file_info #define TODO_verify_ssa (1 << 3) #define TODO_verify_flow (1 << 4) #define TODO_verify_stmts (1 << 5) +#define TODO_fix_def_def_chains (1 << 6) /* rewrite def-def chains */ #define TODO_verify_all \ (TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts) diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index a473139..3f2d4b6 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -2131,9 +2131,10 @@ newline_and_indent (pretty_printer *buffer, int spc) static void dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags) { - tree use, def; + tree use; use_operand_p use_p; def_operand_p def_p; + use_operand_p kill_p; ssa_op_iter iter; FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter) @@ -2148,10 +2149,14 @@ dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags) newline_and_indent (buffer, spc); } - FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_VMUSTDEF) + FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter) { - pp_string (buffer, "# V_MUST_DEF <"); - dump_generic_node (buffer, def, spc + 2, flags, false); + pp_string (buffer, "# "); + dump_generic_node (buffer, DEF_FROM_PTR (def_p), + spc + 2, flags, false); + pp_string (buffer, " = V_MUST_DEF <"); + dump_generic_node (buffer, USE_FROM_PTR (kill_p), + spc + 2, flags, false); pp_string (buffer, ">;"); newline_and_indent (buffer, spc); } diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 3e8fa7b..b97424f 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1041,7 +1041,7 @@ visit_assignment (tree stmt, tree *output_p) { /* If we make it here, then stmt only has one definition: a V_MUST_DEF. */ - lhs = V_MUST_DEF_OP (v_must_defs, 0); + lhs = V_MUST_DEF_RESULT (v_must_defs, 0); } if (TREE_CODE (rhs) == SSA_NAME) diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index 341b768..2c68861 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -112,7 +112,7 @@ static void find_control_dependence (struct edge_list *, int); static inline basic_block find_pdom (basic_block); static inline void mark_stmt_necessary (tree, bool); -static inline void mark_operand_necessary (tree); +static inline void mark_operand_necessary (tree, bool); static void mark_stmt_if_obviously_necessary (tree, bool); static void find_obviously_necessary_stmts (struct edge_list *); @@ -234,10 +234,11 @@ mark_stmt_necessary (tree stmt, bool add_to_worklist) VARRAY_PUSH_TREE (worklist, stmt); } -/* Mark the statement defining operand OP as necessary. */ +/* Mark the statement defining operand OP as necessary. PHIONLY is true + if we should only mark it necessary if it is a phi node. */ static inline void -mark_operand_necessary (tree op) +mark_operand_necessary (tree op, bool phionly) { tree stmt; int ver; @@ -253,7 +254,8 @@ mark_operand_necessary (tree op) gcc_assert (stmt); if (NECESSARY (stmt) - || IS_EMPTY_STMT (stmt)) + || IS_EMPTY_STMT (stmt) + || (phionly && TREE_CODE (stmt) != PHI_NODE)) return; NECESSARY (stmt) = 1; @@ -592,7 +594,7 @@ propagate_necessity (struct edge_list *el) { tree arg = PHI_ARG_DEF (i, k); if (TREE_CODE (arg) == SSA_NAME) - mark_operand_necessary (arg); + mark_operand_necessary (arg, false); } if (aggressive) @@ -624,11 +626,79 @@ propagate_necessity (struct edge_list *el) links). */ FOR_EACH_SSA_TREE_OPERAND (use, i, iter, SSA_OP_ALL_USES) - mark_operand_necessary (use); + mark_operand_necessary (use, false); } } } + + +/* Propagate necessity around virtual phi nodes used in kill operands. + The reason this isn't done during propagate_necessity is because we don't + want to keep phis around that are just there for must-defs, unless we + absolutely have to. After we've rewritten the reaching definitions to be + correct in the previous part of the fixup routine, we can simply propagate + around the information about which of these virtual phi nodes are really + used, and set the NECESSARY flag accordingly. + Note that we do the minimum here to ensure that we keep alive the phis that + are actually used in the corrected SSA form. In particular, some of these + phis may now have all of the same operand, and will be deleted by some + other pass. */ + +static void +mark_really_necessary_kill_operand_phis (void) +{ + basic_block bb; + int i; + + /* Seed the worklist with the new virtual phi arguments and virtual + uses */ + FOR_EACH_BB (bb) + { + block_stmt_iterator bsi; + tree phi; + + for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) + { + if (!is_gimple_reg (PHI_RESULT (phi)) && NECESSARY (phi)) + { + for (i = 0; i < PHI_NUM_ARGS (phi); i++) + mark_operand_necessary (PHI_ARG_DEF (phi, i), true); + } + } + + for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi)) + { + tree stmt = bsi_stmt (bsi); + + if (NECESSARY (stmt)) + { + use_operand_p use_p; + ssa_op_iter iter; + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, + SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS) + { + tree use = USE_FROM_PTR (use_p); + mark_operand_necessary (use, true); + } + } + } + } + + /* Mark all virtual phis still in use as necessary, and all of their + arguments that are phis as necessary. */ + while (VARRAY_ACTIVE_SIZE (worklist) > 0) + { + tree use = VARRAY_TOP_TREE (worklist); + VARRAY_POP (worklist); + + for (i = 0; i < PHI_NUM_ARGS (use); i++) + mark_operand_necessary (PHI_ARG_DEF (use, i), true); + } +} + + + /* Eliminate unnecessary statements. Any instruction not marked as necessary contributes nothing to the program, and can be deleted. */ @@ -640,7 +710,7 @@ eliminate_unnecessary_stmts (void) if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "\nEliminating unnecessary statements:\n"); - + clear_special_calls (); FOR_EACH_BB (bb) { @@ -650,23 +720,23 @@ eliminate_unnecessary_stmts (void) /* Remove dead statements. */ for (i = bsi_start (bb); ! bsi_end_p (i) ; ) { - tree t = bsi_stmt (i); - - stats.total++; - - /* If `i' is not necessary then remove it. */ - if (! NECESSARY (t)) - remove_dead_stmt (&i, bb); - else - { - tree call = get_call_expr_in (t); - if (call) - notice_special_calls (call); - bsi_next (&i); - } + tree t = bsi_stmt (i); + + stats.total++; + + /* If `i' is not necessary then remove it. */ + if (! NECESSARY (t)) + remove_dead_stmt (&i, bb); + else + { + tree call = get_call_expr_in (t); + if (call) + notice_special_calls (call); + bsi_next (&i); + } } } -} + } /* Remove dead PHI nodes from block BB. */ @@ -711,6 +781,9 @@ static void remove_dead_stmt (block_stmt_iterator *i, basic_block bb) { tree t = bsi_stmt (*i); + def_operand_p def_p; + + ssa_op_iter iter; if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -765,9 +838,16 @@ remove_dead_stmt (block_stmt_iterator *i, basic_block bb) while (EDGE_COUNT (bb->succs) != 1) remove_edge (EDGE_SUCC (bb, 1)); } - - bsi_remove (i); - release_defs (t); + + FOR_EACH_SSA_DEF_OPERAND (def_p, t, iter, + SSA_OP_VIRTUAL_DEFS | SSA_OP_VIRTUAL_KILLS) + { + tree def = DEF_FROM_PTR (def_p); + bitmap_set_bit (vars_to_rename, + var_ann (SSA_NAME_VAR (def))->uid); + } + bsi_remove (i); + release_defs (t); } /* Print out removed statement statistics. */ @@ -875,6 +955,7 @@ perform_tree_ssa_dce (bool aggressive) propagate_necessity (el); + mark_really_necessary_kill_operand_phis (); eliminate_unnecessary_stmts (); if (aggressive) @@ -926,7 +1007,7 @@ struct tree_opt_pass pass_dce = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */ + TODO_fix_def_def_chains |TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */ 0 /* letter */ }; @@ -943,7 +1024,7 @@ struct tree_opt_pass pass_cd_dce = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_ggc_collect | TODO_verify_ssa | TODO_verify_flow, + TODO_fix_def_def_chains | TODO_ggc_collect | TODO_verify_ssa | TODO_verify_flow, /* todo_flags_finish */ 0 /* letter */ }; diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index 27bc1c0..bcdd9d7 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -436,7 +436,7 @@ determine_max_movement (tree stmt, bool must_preserve_exec) if (!add_dependency (val, lim_data, loop, true)) return false; - FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_VIRTUAL_USES) + FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS) if (!add_dependency (val, lim_data, loop, false)) return false; @@ -1034,8 +1034,7 @@ rewrite_mem_refs (tree tmp_var, struct mem_ref *mem_refs) for (; mem_refs; mem_refs = mem_refs->next) { - FOR_EACH_SSA_TREE_OPERAND (var, mem_refs->stmt, iter, - (SSA_OP_VIRTUAL_DEFS | SSA_OP_VUSE)) + FOR_EACH_SSA_TREE_OPERAND (var, mem_refs->stmt, iter, SSA_OP_ALL_VIRTUALS) { var = SSA_NAME_VAR (var); bitmap_set_bit (vars_to_rename, var_ann (var)->uid); diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c index dc4b174..1f949a4 100644 --- a/gcc/tree-ssa-loop-manip.c +++ b/gcc/tree-ssa-loop-manip.c @@ -254,7 +254,7 @@ find_uses_to_rename_stmt (tree stmt, bitmap *use_blocks) get_stmt_operands (stmt); - FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES) + FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS) find_uses_to_rename_use (bb, var, use_blocks); } diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index 953ef8d..55cebf2 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -174,7 +174,7 @@ allocate_v_may_def_optype (unsigned num) v_may_def_optype v_may_def_ops; unsigned size; size = sizeof (struct v_may_def_optype_d) - + sizeof (v_may_def_operand_type_t) * (num - 1); + + sizeof (v_def_use_operand_type_t) * (num - 1); v_may_def_ops = ggc_alloc (size); v_may_def_ops->num_v_may_defs = num; return v_may_def_ops; @@ -202,7 +202,7 @@ allocate_v_must_def_optype (unsigned num) { v_must_def_optype v_must_def_ops; unsigned size; - size = sizeof (struct v_must_def_optype_d) + sizeof (tree) * (num - 1); + size = sizeof (struct v_must_def_optype_d) + sizeof (v_def_use_operand_type_t) * (num - 1); v_must_def_ops = ggc_alloc (size); v_must_def_ops->num_v_must_defs = num; return v_must_def_ops; @@ -650,7 +650,7 @@ finalize_ssa_v_must_defs (v_must_def_optype *old_ops_p, build_diff = false; for (x = 0; x < num; x++) { - tree var = old_ops->v_must_defs[x]; + tree var = old_ops->v_must_defs[x].def; if (TREE_CODE (var) == SSA_NAME) var = SSA_NAME_VAR (var); if (var != VARRAY_TREE (build_v_must_defs, x)) @@ -677,17 +677,21 @@ finalize_ssa_v_must_defs (v_must_def_optype *old_ops_p, /* Look for VAR in the original vector. */ for (i = 0; i < old_num; i++) { - result = old_ops->v_must_defs[i]; + result = old_ops->v_must_defs[i].def; if (TREE_CODE (result) == SSA_NAME) result = SSA_NAME_VAR (result); if (result == var) { - v_must_def_ops->v_must_defs[x] = old_ops->v_must_defs[i]; + v_must_def_ops->v_must_defs[x].def = old_ops->v_must_defs[i].def; + v_must_def_ops->v_must_defs[x].use = old_ops->v_must_defs[i].use; break; } } if (i == old_num) - v_must_def_ops->v_must_defs[x] = var; + { + v_must_def_ops->v_must_defs[x].def = var; + v_must_def_ops->v_must_defs[x].use = var; + } } } VARRAY_POP_ALL (build_v_must_defs); @@ -1672,7 +1676,10 @@ copy_virtual_operands (tree dst, tree src) { *v_must_defs_new = allocate_v_must_def_optype (NUM_V_MUST_DEFS (v_must_defs)); for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) - SET_V_MUST_DEF_OP (*v_must_defs_new, i, V_MUST_DEF_OP (v_must_defs, i)); + { + SET_V_MUST_DEF_RESULT (*v_must_defs_new, i, V_MUST_DEF_RESULT (v_must_defs, i)); + SET_V_MUST_DEF_KILL (*v_must_defs_new, i, V_MUST_DEF_KILL (v_must_defs, i)); + } } } @@ -1701,7 +1708,7 @@ create_ssa_artficial_load_stmt (stmt_operands_p old_ops, tree new_stmt) free_vuses (&(ann->operands.vuse_ops)); free_v_may_defs (&(ann->operands.v_may_def_ops)); free_v_must_defs (&(ann->operands.v_must_def_ops)); - + /* For each VDEF on the original statement, we want to create a VUSE of the V_MAY_DEF result or V_MUST_DEF op on the new statement. */ @@ -1713,7 +1720,7 @@ create_ssa_artficial_load_stmt (stmt_operands_p old_ops, tree new_stmt) for (j = 0; j < NUM_V_MUST_DEFS (old_ops->v_must_def_ops); j++) { - op = V_MUST_DEF_OP (old_ops->v_must_def_ops, j); + op = V_MUST_DEF_RESULT (old_ops->v_must_def_ops, j); append_vuse (op); } diff --git a/gcc/tree-ssa-operands.h b/gcc/tree-ssa-operands.h index ad0a916..521845f 100644 --- a/gcc/tree-ssa-operands.h +++ b/gcc/tree-ssa-operands.h @@ -58,17 +58,17 @@ typedef struct use_optype_d GTY(()) typedef use_optype_t *use_optype; /* Operand type which stores a def and a use tree. */ -typedef struct v_may_def_operand_type GTY(()) +typedef struct v_def_use_operand_type GTY(()) { tree def; tree use; -} v_may_def_operand_type_t; +} v_def_use_operand_type_t; /* This represents the MAY_DEFS for a stmt. */ typedef struct v_may_def_optype_d GTY(()) { unsigned num_v_may_defs; - struct v_may_def_operand_type GTY((length ("%h.num_v_may_defs"))) + struct v_def_use_operand_type GTY((length ("%h.num_v_may_defs"))) v_may_defs[1]; } v_may_def_optype_t; @@ -87,7 +87,7 @@ typedef vuse_optype_t *vuse_optype; typedef struct v_must_def_optype_d GTY(()) { unsigned num_v_must_defs; - tree GTY((length("%h.num_v_must_defs"))) v_must_defs[1]; + v_def_use_operand_type_t GTY((length("%h.num_v_must_defs"))) v_must_defs[1]; } v_must_def_optype_t; typedef v_must_def_optype_t *v_must_def_optype; @@ -157,12 +157,14 @@ typedef stmt_operands_t *stmt_operands_p; #define V_MUST_DEF_OPS(ANN) get_v_must_def_ops (ANN) #define STMT_V_MUST_DEF_OPS(STMT) get_v_must_def_ops (stmt_ann (STMT)) #define NUM_V_MUST_DEFS(OPS) ((OPS) ? (OPS)->num_v_must_defs : 0) -#define V_MUST_DEF_OP_PTR(OPS, I) get_v_must_def_op_ptr ((OPS), (I)) -#define V_MUST_DEF_OP(OPS, I) \ - (DEF_FROM_PTR (V_MUST_DEF_OP_PTR ((OPS), (I)))) -#define SET_V_MUST_DEF_OP(OPS, I, V) \ - (SET_DEF (V_MUST_DEF_OP_PTR ((OPS), (I)), (V))) - +#define V_MUST_DEF_RESULT_PTR(OPS, I) get_v_must_def_result_ptr ((OPS), (I)) +#define V_MUST_DEF_RESULT(OPS, I) \ + (DEF_FROM_PTR (V_MUST_DEF_RESULT_PTR ((OPS), (I)))) +#define SET_V_MUST_DEF_RESULT(OPS, I, V) \ + (SET_DEF (V_MUST_DEF_RESULT_PTR ((OPS), (I)), (V))) +#define V_MUST_DEF_KILL_PTR(OPS, I) get_v_must_def_kill_ptr ((OPS), (I)) +#define V_MUST_DEF_KILL(OPS, I) (USE_FROM_PTR (V_MUST_DEF_KILL_PTR ((OPS), (I)))) +#define SET_V_MUST_DEF_KILL(OPS, I, V) (SET_USE (V_MUST_DEF_KILL_PTR ((OPS), (I)), (V))) #define PHI_RESULT_PTR(PHI) get_phi_result_ptr (PHI) #define PHI_RESULT(PHI) DEF_FROM_PTR (PHI_RESULT_PTR (PHI)) @@ -199,13 +201,15 @@ typedef struct ssa_operand_iterator_d int num_vuse; int num_v_mayu; int num_v_mayd; - int num_v_must; + int num_v_mustu; + int num_v_mustd; int use_i; int def_i; int vuse_i; int v_mayu_i; int v_mayd_i; - int v_must_i; + int v_mustu_i; + int v_mustd_i; stmt_operands_p ops; bool done; } ssa_op_iter; @@ -218,13 +222,17 @@ typedef struct ssa_operand_iterator_d #define SSA_OP_VMAYUSE 0x08 /* USE portion of V_MAY_DEFS. */ #define SSA_OP_VMAYDEF 0x10 /* DEF portion of V_MAY_DEFS. */ #define SSA_OP_VMUSTDEF 0x20 /* V_MUST_DEF definitions. */ +#define SSA_OP_VMUSTDEFKILL 0x40 /* V_MUST_DEF kills. */ /* These are commonly grouped operand flags. */ #define SSA_OP_VIRTUAL_USES (SSA_OP_VUSE | SSA_OP_VMAYUSE) #define SSA_OP_VIRTUAL_DEFS (SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF) +#define SSA_OP_VIRTUAL_KILLS (SSA_OP_VMUSTDEFKILL) +#define SSA_OP_ALL_VIRTUALS (SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS | SSA_OP_VIRTUAL_DEFS) #define SSA_OP_ALL_USES (SSA_OP_VIRTUAL_USES | SSA_OP_USE) #define SSA_OP_ALL_DEFS (SSA_OP_VIRTUAL_DEFS | SSA_OP_DEF) -#define SSA_OP_ALL_OPERANDS (SSA_OP_ALL_USES | SSA_OP_ALL_DEFS) +#define SSA_OP_ALL_KILLS (SSA_OP_VIRTUAL_KILLS) +#define SSA_OP_ALL_OPERANDS (SSA_OP_ALL_USES | SSA_OP_ALL_DEFS | SSA_OP_ALL_KILLS) /* This macro executes a loop over the operands of STMT specified in FLAG, returning each operand as a 'tree' in the variable TREEVAR. ITER is an @@ -258,4 +266,12 @@ typedef struct ssa_operand_iterator_d !op_iter_done (&(ITER)); \ op_iter_next_maydef (&(USEVAR), &(DEFVAR), &(ITER))) +/* This macro executes a loop over the V_MUST_DEF operands of STMT. The def + and kill for each V_MUST_DEF is returned in DEFVAR and KILLVAR. + ITER is an ssa_op_iter structure used to control the loop. */ +#define FOR_EACH_SSA_MUSTDEF_OPERAND(DEFVAR, KILLVAR, STMT, ITER) \ + for (op_iter_init_mustdef (&(ITER), STMT, &(KILLVAR), &(DEFVAR)); \ + !op_iter_done (&(ITER)); \ + op_iter_next_mustdef (&(KILLVAR), &(DEFVAR), &(ITER))) + #endif /* GCC_TREE_SSA_OPERANDS_H */ diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 7f73bcf..d9379ba 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -672,7 +672,7 @@ verify_ssa (void) { tree stmt = bsi_stmt (bsi); - FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_VIRTUAL_USES) + FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS) { if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)], op, stmt, false, true, @@ -1082,7 +1082,8 @@ replace_immediate_uses (tree var, tree repl) } else { - FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_VIRTUAL_USES) + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, + SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS) if (USE_FROM_PTR (use_p) == var) propagate_value (use_p, repl); } @@ -1464,3 +1465,4 @@ struct tree_opt_pass pass_late_warn_uninitialized = 0, /* todo_flags_finish */ 0 /* letter */ }; + diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index 656c612..df16c2c 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -381,7 +381,10 @@ rename_variables_in_bb (basic_block bb) v_must_defs = V_MUST_DEF_OPS (ann); for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) - rename_def_op (V_MUST_DEF_OP_PTR (v_must_defs, i), stmt); + { + rename_use_op (V_MUST_DEF_KILL_PTR (v_must_defs, i)); + rename_def_op (V_MUST_DEF_RESULT_PTR (v_must_defs, i), stmt); + } } FOR_EACH_EDGE (e, ei, bb->succs) @@ -1853,7 +1856,7 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset, } for (i = 0; i < nv_must_defs; i++) { - tree def = V_MUST_DEF_OP (v_must_defs, i); + tree def = V_MUST_DEF_RESULT (v_must_defs, i); if (TREE_CODE (def) == SSA_NAME) bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid); } |