diff options
author | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-01-09 14:40:40 +0000 |
---|---|---|
committer | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-01-09 14:40:40 +0000 |
commit | b123eaab661e58a140bfc33dde9c12e2ab91f82b (patch) | |
tree | 595e1768bdc44cb318f183c1b788f77697ae0164 /gcc/tree-vect-loop-manip.c | |
parent | d3ab9b67ea650c4b3711fb8e6c2ebe16c8d12ebf (diff) | |
download | gcc-b123eaab661e58a140bfc33dde9c12e2ab91f82b.tar.gz |
gcc/ChangeLog:
PR debug/42604
PR debug/42395
* tree-vect-loop-manip.c (adjust_info): New type.
(adjust_vec): New pointer to vector.
(adjust_debug_stmts_now, adjust_vec_debug_stmts): New.
(adjust_debug_stmts, adjust_phi_and_debug_stmts): New.
(slpeel_update_phis_for_duplicate_loop): Use them.
(slpeel_update_phi_nodes_for_guard1): Likewise.
(slpeel_update_phi_nodes_for_guard2): Likewise.
(slpeel_tree_peel_loop_to_edge): Likewise.
(vect_update_ivs_after_vectorizer): Likewise.
gcc/testsuite/ChangeLog:
PR debug/42604
PR debug/42395
* gcc.dg/vect/pr42604.c: New.
* gcc.dg/vect/pr42395.c: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@155761 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vect-loop-manip.c')
-rw-r--r-- | gcc/tree-vect-loop-manip.c | 158 |
1 files changed, 148 insertions, 10 deletions
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index d3068b30852..72b905660be 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -113,6 +113,131 @@ rename_variables_in_loop (struct loop *loop) free (bbs); } +typedef struct +{ + tree from, to; + basic_block bb; +} adjust_info; + +DEF_VEC_O(adjust_info); +DEF_VEC_ALLOC_O_STACK(adjust_info); +#define VEC_adjust_info_stack_alloc(alloc) VEC_stack_alloc (adjust_info, alloc) + +/* A stack of values to be adjusted in debug stmts. We have to + process them LIFO, so that the closest substitution applies. If we + processed them FIFO, without the stack, we might substitute uses + with a PHI DEF that would soon become non-dominant, and when we got + to the suitable one, it wouldn't have anything to substitute any + more. */ +static VEC(adjust_info, stack) *adjust_vec; + +/* Adjust any debug stmts that referenced AI->from values to use the + loop-closed AI->to, if the references are dominated by AI->bb and + not by the definition of AI->from. */ + +static void +adjust_debug_stmts_now (adjust_info *ai) +{ + basic_block bbphi = ai->bb; + tree orig_def = ai->from; + tree new_def = ai->to; + imm_use_iterator imm_iter; + gimple stmt; + basic_block bbdef = gimple_bb (SSA_NAME_DEF_STMT (orig_def)); + + gcc_assert (dom_info_available_p (CDI_DOMINATORS)); + + /* Adjust any debug stmts that held onto non-loop-closed + references. */ + FOR_EACH_IMM_USE_STMT (stmt, imm_iter, orig_def) + { + use_operand_p use_p; + basic_block bbuse; + + if (!is_gimple_debug (stmt)) + continue; + + gcc_assert (gimple_debug_bind_p (stmt)); + + bbuse = gimple_bb (stmt); + + if ((bbuse == bbphi + || dominated_by_p (CDI_DOMINATORS, bbuse, bbphi)) + && !(bbuse == bbdef + || dominated_by_p (CDI_DOMINATORS, bbuse, bbdef))) + { + if (new_def) + FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter) + SET_USE (use_p, new_def); + else + { + gimple_debug_bind_reset_value (stmt); + update_stmt (stmt); + } + } + } +} + +/* Adjust debug stmts as scheduled before. */ + +static void +adjust_vec_debug_stmts (void) +{ + if (!MAY_HAVE_DEBUG_STMTS) + return; + + gcc_assert (adjust_vec); + + while (!VEC_empty (adjust_info, adjust_vec)) + { + adjust_debug_stmts_now (VEC_last (adjust_info, adjust_vec)); + VEC_pop (adjust_info, adjust_vec); + } + + VEC_free (adjust_info, stack, adjust_vec); +} + +/* Adjust any debug stmts that referenced FROM values to use the + loop-closed TO, if the references are dominated by BB and not by + the definition of FROM. If adjust_vec is non-NULL, adjustments + will be postponed until adjust_vec_debug_stmts is called. */ + +static void +adjust_debug_stmts (tree from, tree to, basic_block bb) +{ + adjust_info ai; + + if (MAY_HAVE_DEBUG_STMTS && TREE_CODE (from) == SSA_NAME + && SSA_NAME_VAR (from) != gimple_vop (cfun)) + { + ai.from = from; + ai.to = to; + ai.bb = bb; + + if (adjust_vec) + VEC_safe_push (adjust_info, stack, adjust_vec, &ai); + else + adjust_debug_stmts_now (&ai); + } +} + +/* Change E's phi arg in UPDATE_PHI to NEW_DEF, and record information + to adjust any debug stmts that referenced the old phi arg, + presumably non-loop-closed references left over from other + transformations. */ + +static void +adjust_phi_and_debug_stmts (gimple update_phi, edge e, tree new_def) +{ + tree orig_def = PHI_ARG_DEF_FROM_EDGE (update_phi, e); + + SET_PHI_ARG_DEF (update_phi, e->dest_idx, new_def); + + if (MAY_HAVE_DEBUG_STMTS) + adjust_debug_stmts (orig_def, PHI_RESULT (update_phi), + gimple_bb (update_phi)); +} + /* Update the PHI nodes of NEW_LOOP. @@ -195,13 +320,15 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop, /* An ordinary ssa name defined in the loop. */ add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus); + /* Drop any debug references outside the loop, if they would + become ill-formed SSA. */ + adjust_debug_stmts (def, NULL, single_exit (orig_loop)->dest); + /* step 3 (case 1). */ if (!after) { gcc_assert (new_loop_exit_e == orig_entry_e); - SET_PHI_ARG_DEF (phi_orig, - new_loop_exit_e->dest_idx, - new_ssa_name); + adjust_phi_and_debug_stmts (phi_orig, new_loop_exit_e, new_ssa_name); } } } @@ -413,7 +540,7 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop, /* 1.3. Update phi in successor block. */ gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == loop_arg || PHI_ARG_DEF_FROM_EDGE (update_phi, e) == guard_arg); - SET_PHI_ARG_DEF (update_phi, e->dest_idx, PHI_RESULT (new_phi)); + adjust_phi_and_debug_stmts (update_phi, e, PHI_RESULT (new_phi)); update_phi2 = new_phi; @@ -431,7 +558,8 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop, /* 2.3. Update phi in successor of NEW_EXIT_BB: */ gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg); - SET_PHI_ARG_DEF (update_phi2, new_exit_e->dest_idx, PHI_RESULT (new_phi)); + adjust_phi_and_debug_stmts (update_phi2, new_exit_e, + PHI_RESULT (new_phi)); /* 2.4. Record the newly created name with set_current_def. We want to find a name such that @@ -560,7 +688,7 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop, /* 1.3. Update phi in successor block. */ gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == orig_def); - SET_PHI_ARG_DEF (update_phi, e->dest_idx, PHI_RESULT (new_phi)); + adjust_phi_and_debug_stmts (update_phi, e, PHI_RESULT (new_phi)); update_phi2 = new_phi; @@ -575,7 +703,8 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop, /* 2.3. Update phi in successor of NEW_EXIT_BB: */ gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg); - SET_PHI_ARG_DEF (update_phi2, new_exit_e->dest_idx, PHI_RESULT (new_phi)); + adjust_phi_and_debug_stmts (update_phi2, new_exit_e, + PHI_RESULT (new_phi)); /** 3. Handle loop-closed-ssa-form phis for first loop **/ @@ -612,7 +741,8 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop, /* 3.4. Update phi in successor of GUARD_BB: */ gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, guard_edge) == guard_arg); - SET_PHI_ARG_DEF (update_phi2, guard_edge->dest_idx, PHI_RESULT (new_phi)); + adjust_phi_and_debug_stmts (update_phi2, guard_edge, + PHI_RESULT (new_phi)); } } @@ -1083,6 +1213,12 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, return NULL; } + if (MAY_HAVE_DEBUG_STMTS) + { + gcc_assert (!adjust_vec); + adjust_vec = VEC_alloc (adjust_info, stack, 32); + } + if (e == exit_e) { /* NEW_LOOP was placed after LOOP. */ @@ -1278,6 +1414,8 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, if (update_first_loop_count) slpeel_make_loop_iterate_ntimes (first_loop, first_niters); + adjust_vec_debug_stmts (); + BITMAP_FREE (definitions); delete_update_ssa (); @@ -1668,7 +1806,7 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters, true, GSI_SAME_STMT); /* Fix phi expressions in the successor bb. */ - SET_PHI_ARG_DEF (phi1, update_e->dest_idx, ni_name); + adjust_phi_and_debug_stmts (phi1, update_e, ni_name); } } @@ -2399,7 +2537,7 @@ vect_loop_versioning (loop_vec_info loop_vinfo, bool do_versioning, arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, e); add_phi_arg (new_phi, arg, new_exit_e, gimple_phi_arg_location_from_edge (orig_phi, e)); - SET_PHI_ARG_DEF (orig_phi, e->dest_idx, PHI_RESULT (new_phi)); + adjust_phi_and_debug_stmts (orig_phi, e, PHI_RESULT (new_phi)); } /* End loop-exit-fixes after versioning. */ |