summaryrefslogtreecommitdiff
path: root/gcc/tree-vect-loop-manip.c
diff options
context:
space:
mode:
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2010-01-09 14:40:40 +0000
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2010-01-09 14:40:40 +0000
commitb123eaab661e58a140bfc33dde9c12e2ab91f82b (patch)
tree595e1768bdc44cb318f183c1b788f77697ae0164 /gcc/tree-vect-loop-manip.c
parentd3ab9b67ea650c4b3711fb8e6c2ebe16c8d12ebf (diff)
downloadgcc-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.c158
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. */