aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog36
-rw-r--r--gcc/cfgloop.c45
-rw-r--r--gcc/cfgloop.h7
-rw-r--r--gcc/cfgloopmanip.c14
-rw-r--r--gcc/doc/loop.texi10
-rw-r--r--gcc/lambda-code.c14
-rw-r--r--gcc/modulo-sched.c20
-rw-r--r--gcc/tree-if-conv.c2
-rw-r--r--gcc/tree-loop-linear.c4
-rw-r--r--gcc/tree-scalar-evolution.c11
-rw-r--r--gcc/tree-ssa-loop-ivcanon.c4
-rw-r--r--gcc/tree-ssa-loop-ivopts.c2
-rw-r--r--gcc/tree-ssa-loop-niter.c2
-rw-r--r--gcc/tree-vect-analyze.c12
-rw-r--r--gcc/tree-vect-transform.c16
-rw-r--r--gcc/tree-vectorizer.c37
16 files changed, 147 insertions, 89 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fb72e0a..1ed3890 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,41 @@
2006-11-22 Zdenek Dvorak <dvorakz@suse.cz>
+ * tree-loop-linear.c (linear_transform_loops): Use single_exit accessor
+ functions.
+ * tree-ssa-loop-niter.c (loop_only_exit_p): Ditto.
+ * cfgloopmanip.c (update_single_exits_after_duplication,
+ update_single_exit_for_duplicated_loop, loop_version): Ditto.
+ * tree-scalar-evolution.c (get_loop_exit_condition,
+ get_exit_conditions_rec, loop_closed_phi_def,
+ number_of_iterations_in_loop, scev_const_prop): Ditto.
+ * tree-ssa-loop-ivopts.c (single_dom_exit): Ditto.
+ * modulo-sched.c (generate_prolog_epilog, loop_canon_p, sms_schedule):
+ Ditto.
+ * tree-ssa-loop-ivcanon.c (canonicalize_loop_induction_variables):
+ Ditto.
+ * tree-vectorizer.c (slpeel_update_phis_for_duplicate_loop,
+ slpeel_update_phi_nodes_for_guard1, slpeel_update_phi_nodes_for_guard2,
+ slpeel_make_loop_iterate_ntimes,
+ slpeel_tree_duplicate_loop_to_edge_cfg, slpeel_can_duplicate_loop_p,
+ slpeel_verify_cfg_after_peeling, slpeel_tree_peel_loop_to_edge):
+ Ditto.
+ * tree-if-conv.c (if_convertible_loop_p): Ditto.
+ * tree-vect-analyze.c (vect_analyze_operations, vect_stmt_relevant_p,
+ vect_analyze_loop_form): Ditto.
+ * lambda-code.c (lambda_loopnest_to_gcc_loopnest, exit_phi_for_loop_p,
+ can_convert_to_perfect_nest, perfect_nestify): Ditto.
+ * tree-vect-transform.c (vect_create_epilog_for_reduction,
+ vect_update_ivs_after_vectorizer, vect_do_peeling_for_loop_bound,
+ vect_transform_loop): Ditto.
+ * cfgloop.c (mark_single_exit_loops, verify_loop_structure): Ditto.
+ (single_exit, set_single_exit): New functions.
+ * cfgloop.h (struct loop): Rename single_exit field to single_exit_.
+ (single_exit, set_single_exit): Declare.
+ * doc/loop.texi: Undocument single_exit field. Document single_exit
+ accessor function.
+
+2006-11-22 Zdenek Dvorak <dvorakz@suse.cz>
+
PR tree-optimization/29902
* tree-ssa-loop-manip.c (can_unroll_loop_p): Return false if
any involved ssa name appears in abnormal phi node.
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index e00e6a6..b168b97 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -251,7 +251,7 @@ mark_single_exit_loops (struct loops *loops)
{
loop = loops->parray[i];
if (loop)
- loop->single_exit = NULL;
+ set_single_exit (loop, NULL);
}
FOR_EACH_BB (bb)
@@ -273,10 +273,10 @@ mark_single_exit_loops (struct loops *loops)
{
/* If we have already seen an exit, mark this by the edge that
surely does not occur as any exit. */
- if (loop->single_exit)
- loop->single_exit = single_succ_edge (ENTRY_BLOCK_PTR);
+ if (single_exit (loop))
+ set_single_exit (loop, single_succ_edge (ENTRY_BLOCK_PTR));
else
- loop->single_exit = e;
+ set_single_exit (loop, e);
}
}
}
@@ -287,8 +287,8 @@ mark_single_exit_loops (struct loops *loops)
if (!loop)
continue;
- if (loop->single_exit == single_succ_edge (ENTRY_BLOCK_PTR))
- loop->single_exit = NULL;
+ if (single_exit (loop) == single_succ_edge (ENTRY_BLOCK_PTR))
+ set_single_exit (loop, NULL);
}
loops->state |= LOOPS_HAVE_MARKED_SINGLE_EXITS;
@@ -1142,12 +1142,12 @@ verify_loop_structure (struct loops *loops)
loop = loop->outer)
{
sizes[loop->num]++;
- if (loop->single_exit
- && loop->single_exit != e)
+ if (single_exit (loop)
+ && single_exit (loop) != e)
{
error ("wrong single exit %d->%d recorded for loop %d",
- loop->single_exit->src->index,
- loop->single_exit->dest->index,
+ single_exit (loop)->src->index,
+ single_exit (loop)->dest->index,
loop->num);
error ("right exit is %d->%d",
e->src->index, e->dest->index);
@@ -1164,19 +1164,19 @@ verify_loop_structure (struct loops *loops)
continue;
if (sizes[i] == 1
- && !loop->single_exit)
+ && !single_exit (loop))
{
error ("single exit not recorded for loop %d", loop->num);
err = 1;
}
if (sizes[i] != 1
- && loop->single_exit)
+ && single_exit (loop))
{
error ("loop %d should not have single exit (%d -> %d)",
loop->num,
- loop->single_exit->src->index,
- loop->single_exit->dest->index);
+ single_exit (loop)->src->index,
+ single_exit (loop)->dest->index);
err = 1;
}
}
@@ -1216,3 +1216,20 @@ loop_exit_edge_p (const struct loop *loop, edge e)
return (flow_bb_inside_loop_p (loop, e->src)
&& !flow_bb_inside_loop_p (loop, e->dest));
}
+
+/* Returns the single exit edge of LOOP, or NULL if LOOP has either no exit
+ or more than one exit. */
+
+edge
+single_exit (const struct loop *loop)
+{
+ return loop->single_exit_;
+}
+
+/* Records E as a single exit edge of LOOP. */
+
+void
+set_single_exit (struct loop *loop, edge e)
+{
+ loop->single_exit_ = e;
+}
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 0874f54..aa648c2 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -143,8 +143,9 @@ struct loop
struct nb_iter_bound *bounds;
/* If not NULL, loop has just single exit edge stored here (edges to the
- EXIT_BLOCK_PTR do not count. */
- edge single_exit;
+ EXIT_BLOCK_PTR do not count. Do not use direcly, this field should
+ only be accessed via single_exit/set_single_exit functions. */
+ edge single_exit_;
/* True when the loop does not carry data dependences, and
consequently the iterations can be executed in any order. False
@@ -219,6 +220,8 @@ extern basic_block *get_loop_body (const struct loop *);
extern basic_block *get_loop_body_in_dom_order (const struct loop *);
extern basic_block *get_loop_body_in_bfs_order (const struct loop *);
extern VEC (edge, heap) *get_loop_exit_edges (const struct loop *);
+edge single_exit (const struct loop *);
+void set_single_exit (struct loop *, edge);
extern unsigned num_loop_branches (const struct loop *);
extern edge loop_preheader_edge (const struct loop *);
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 028db02..63cab60 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -766,11 +766,11 @@ update_single_exits_after_duplication (basic_block *bbs, unsigned nbbs,
for (; loop->outer; loop = loop->outer)
{
- if (!loop->single_exit)
+ if (!single_exit (loop))
continue;
- if (loop->single_exit->src->flags & BB_DUPLICATED)
- loop->single_exit = NULL;
+ if (single_exit (loop)->src->flags & BB_DUPLICATED)
+ set_single_exit (loop, NULL);
}
for (i = 0; i < nbbs; i++)
@@ -784,7 +784,7 @@ update_single_exit_for_duplicated_loop (struct loop *loop)
{
struct loop *copy = loop->copy;
basic_block src, dest;
- edge exit = loop->single_exit;
+ edge exit = single_exit (loop);
if (!exit)
return;
@@ -796,7 +796,7 @@ update_single_exit_for_duplicated_loop (struct loop *loop)
exit = find_edge (src, dest);
gcc_assert (exit != NULL);
- copy->single_exit = exit;
+ set_single_exit (copy, exit);
}
/* Updates single exit information for copies of ORIG_LOOPS and their subloops.
@@ -1336,9 +1336,9 @@ loop_version (struct loops *loops, struct loop * loop,
cond_bb, true_edge, false_edge,
false /* Do not redirect all edges. */);
- exit = loop->single_exit;
+ exit = single_exit (loop);
if (exit)
- nloop->single_exit = find_edge (get_bb_copy (exit->src), exit->dest);
+ set_single_exit (nloop, find_edge (get_bb_copy (exit->src), exit->dest));
/* loopify redirected latch_edge. Update its PENDING_STMTS. */
lv_flush_pending_stmts (latch_edge);
diff --git a/gcc/doc/loop.texi b/gcc/doc/loop.texi
index 8c6f52c..642a523 100644
--- a/gcc/doc/loop.texi
+++ b/gcc/doc/loop.texi
@@ -104,8 +104,8 @@ flag is not set for blocks and edges that belong to natural loops that
are in such an irreducible region (but it is set for the entry and exit
edges of such a loop, if they lead to/from this region).
@item @code{LOOPS_HAVE_MARKED_SINGLE_EXITS}: If a loop has exactly one
-exit edge, this edge is stored in @code{single_exit} field of the loop
-structure. @code{NULL} is stored there otherwise.
+exit edge, this edge is recorded in the loop structure. @code{single_exit}
+function can be used to retrieve this edge.
@end itemize
These properties may also be computed/enforced later, using functions
@@ -140,9 +140,6 @@ the basic blocks of the sub-loops).
number of super-loops of the loop.
@item @code{outer}, @code{inner}, @code{next}: The super-loop, the first
sub-loop, and the sibling of the loop in the loops tree.
-@item @code{single_exit}: The exit edge of the loop, if the loop has
-exactly one exit and the loops were analyzed with
-LOOPS_HAVE_MARKED_SINGLE_EXITS.
@end itemize
There are other fields in the loop structures, many of them used only by
@@ -176,6 +173,9 @@ with @code{EDGE_LOOP_EXIT} flag.
@code{get_loop_body_in_bfs_order}: Enumerates the basic blocks in the
loop in depth-first search order in reversed CFG, ordered by dominance
relation, and breath-first search order, respectively.
+@item @code{single_exit}: Returns the single exit edge of the loop, or
+@code{NULL} if the loop has more than one exit. You can only use this
+function if LOOPS_HAVE_MARKED_SINGLE_EXITS property is used.
@item @code{get_loop_exit_edges}: Enumerates the exit edges of a loop.
@item @code{just_once_each_iteration_p}: Returns true if the basic block
is executed exactly once during each iteration of a loop (that is, it
diff --git a/gcc/lambda-code.c b/gcc/lambda-code.c
index d2876a7..f4fce42 100644
--- a/gcc/lambda-code.c
+++ b/gcc/lambda-code.c
@@ -1875,7 +1875,7 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
type,
new_ivs,
invariants, MIN_EXPR, &stmts);
- exit = temp->single_exit;
+ exit = single_exit (temp);
exitcond = get_loop_exit_condition (temp);
bb = bb_for_stmt (exitcond);
bsi = bsi_start (bb);
@@ -2211,7 +2211,7 @@ exit_phi_for_loop_p (struct loop *loop, tree stmt)
if (TREE_CODE (stmt) != PHI_NODE
|| PHI_NUM_ARGS (stmt) != 1
- || bb_for_stmt (stmt) != loop->single_exit->dest)
+ || bb_for_stmt (stmt) != single_exit (loop)->dest)
return false;
return true;
@@ -2387,7 +2387,7 @@ can_convert_to_perfect_nest (struct loop *loop)
/* We also need to make sure the loop exit only has simple copy phis in it,
otherwise we don't know how to transform it into a perfect nest right
now. */
- exitdest = loop->single_exit->dest;
+ exitdest = single_exit (loop)->dest;
for (phi = phi_nodes (exitdest); phi; phi = PHI_CHAIN (phi))
if (PHI_NUM_ARGS (phi) != 1)
@@ -2463,8 +2463,8 @@ perfect_nestify (struct loops *loops,
htab_t replacements = NULL;
/* Create the new loop. */
- olddest = loop->single_exit->dest;
- preheaderbb = split_edge (loop->single_exit);
+ olddest = single_exit (loop)->dest;
+ preheaderbb = split_edge (single_exit (loop));
headerbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
/* Push the exit phi nodes that we are moving. */
@@ -2517,14 +2517,14 @@ perfect_nestify (struct loops *loops,
newloop = duplicate_loop (loops, loop, olddest->loop_father);
newloop->header = headerbb;
newloop->latch = latchbb;
- newloop->single_exit = e;
+ set_single_exit (newloop, e);
add_bb_to_loop (latchbb, newloop);
add_bb_to_loop (bodybb, newloop);
add_bb_to_loop (headerbb, newloop);
set_immediate_dominator (CDI_DOMINATORS, bodybb, headerbb);
set_immediate_dominator (CDI_DOMINATORS, headerbb, preheaderbb);
set_immediate_dominator (CDI_DOMINATORS, preheaderbb,
- loop->single_exit->src);
+ single_exit (loop)->src);
set_immediate_dominator (CDI_DOMINATORS, latchbb, bodybb);
set_immediate_dominator (CDI_DOMINATORS, olddest, bodybb);
/* Create the new iv. */
diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
index 62918a0..a7dae15 100644
--- a/gcc/modulo-sched.c
+++ b/gcc/modulo-sched.c
@@ -755,8 +755,8 @@ generate_prolog_epilog (partial_schedule_ptr ps, struct loop * loop, rtx count_r
duplicate_insns_of_cycles (ps, i + 1, last_stage, 0);
/* Put the epilogue on the exit edge. */
- gcc_assert (loop->single_exit);
- e = loop->single_exit;
+ gcc_assert (single_exit (loop));
+ e = single_exit (loop);
split_edge_and_insert (e, get_insns());
end_sequence ();
}
@@ -814,7 +814,7 @@ loop_canon_p (struct loop *loop)
if (loop->inner || ! loop->outer)
return false;
- if (!loop->single_exit)
+ if (!single_exit (loop))
{
if (dump_file)
{
@@ -943,14 +943,14 @@ sms_schedule (void)
get_ebb_head_tail (bb, bb, &head, &tail);
latch_edge = loop_latch_edge (loop);
- gcc_assert (loop->single_exit);
- if (loop->single_exit->count)
- trip_count = latch_edge->count / loop->single_exit->count;
+ gcc_assert (single_exit (loop));
+ if (single_exit (loop)->count)
+ trip_count = latch_edge->count / single_exit (loop)->count;
/* Perfrom SMS only on loops that their average count is above threshold. */
if ( latch_edge->count
- && (latch_edge->count < loop->single_exit->count * SMS_LOOP_AVERAGE_COUNT_THRESHOLD))
+ && (latch_edge->count < single_exit (loop)->count * SMS_LOOP_AVERAGE_COUNT_THRESHOLD))
{
if (dump_file)
{
@@ -1037,9 +1037,9 @@ sms_schedule (void)
get_ebb_head_tail (loop->header, loop->header, &head, &tail);
latch_edge = loop_latch_edge (loop);
- gcc_assert (loop->single_exit);
- if (loop->single_exit->count)
- trip_count = latch_edge->count / loop->single_exit->count;
+ gcc_assert (single_exit (loop));
+ if (single_exit (loop)->count)
+ trip_count = latch_edge->count / single_exit (loop)->count;
if (dump_file)
{
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index a4daaa2..7ccb48c 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -521,7 +521,7 @@ if_convertible_loop_p (struct loop *loop, bool for_vectorizer ATTRIBUTE_UNUSED)
}
/* More than one loop exit is too much to handle. */
- if (!loop->single_exit)
+ if (!single_exit (loop))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "multiple exits\n");
diff --git a/gcc/tree-loop-linear.c b/gcc/tree-loop-linear.c
index 2840e9b..89bd1e8 100644
--- a/gcc/tree-loop-linear.c
+++ b/gcc/tree-loop-linear.c
@@ -270,7 +270,7 @@ linear_transform_loops (struct loops *loops)
...
}
} */
- if (!loop_nest || !loop_nest->inner || !loop_nest->single_exit)
+ if (!loop_nest || !loop_nest->inner || !single_exit (loop_nest))
continue;
VEC_truncate (tree, oldivs, 0);
VEC_truncate (tree, invariants, 0);
@@ -278,7 +278,7 @@ linear_transform_loops (struct loops *loops)
for (temp = loop_nest->inner; temp; temp = temp->inner)
{
/* If we have a sibling loop or multiple exit edges, jump ship. */
- if (temp->next || !temp->single_exit)
+ if (temp->next || !single_exit (temp))
{
problem = true;
break;
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 9bd122a..d4570a5 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -966,8 +966,7 @@ tree
get_loop_exit_condition (struct loop *loop)
{
tree res = NULL_TREE;
- edge exit_edge = loop->single_exit;
-
+ edge exit_edge = single_exit (loop);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "(get_loop_exit_condition \n ");
@@ -1003,7 +1002,7 @@ get_exit_conditions_rec (struct loop *loop,
get_exit_conditions_rec (loop->inner, exit_conditions);
get_exit_conditions_rec (loop->next, exit_conditions);
- if (loop->single_exit)
+ if (single_exit (loop))
{
tree loop_condition = get_loop_exit_condition (loop);
@@ -2107,7 +2106,7 @@ loop_closed_phi_def (tree var)
return NULL_TREE;
loop = loop_containing_stmt (SSA_NAME_DEF_STMT (var));
- exit = loop->single_exit;
+ exit = single_exit (loop);
if (!exit)
return NULL_TREE;
@@ -2485,7 +2484,7 @@ number_of_iterations_in_loop (struct loop *loop)
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "(number_of_iterations_in_loop\n");
- exit = loop->single_exit;
+ exit = single_exit (loop);
if (!exit)
goto end;
@@ -2961,7 +2960,7 @@ scev_const_prop (void)
/* If we do not know exact number of iterations of the loop, we cannot
replace the final value. */
- exit = loop->single_exit;
+ exit = single_exit (loop);
if (!exit)
continue;
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index a56679d..46e1531 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -283,7 +283,7 @@ canonicalize_loop_induction_variables (struct loops *loops, struct loop *loop,
niter = number_of_iterations_in_loop (loop);
if (TREE_CODE (niter) == INTEGER_CST)
{
- exit = loop->single_exit;
+ exit = single_exit (loop);
if (!just_once_each_iteration_p (loop, exit->src))
return false;
@@ -297,7 +297,7 @@ canonicalize_loop_induction_variables (struct loops *loops, struct loop *loop,
{
/* If the loop has more than one exit, try checking all of them
for # of iterations determinable through scev. */
- if (!loop->single_exit)
+ if (!single_exit (loop))
niter = find_loop_niter (loop, &exit);
/* Finally if everything else fails, try brute force evaluation. */
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 6642b5d..0842fd0 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -349,7 +349,7 @@ iv_cand (struct ivopts_data *data, unsigned i)
edge
single_dom_exit (struct loop *loop)
{
- edge exit = loop->single_exit;
+ edge exit = single_exit (loop);
if (!exit)
return NULL;
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index f410d8c..6fad5c3 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -1006,7 +1006,7 @@ loop_only_exit_p (struct loop *loop, edge exit)
unsigned i;
tree call;
- if (exit != loop->single_exit)
+ if (exit != single_exit (loop))
return false;
body = get_loop_body (loop);
diff --git a/gcc/tree-vect-analyze.c b/gcc/tree-vect-analyze.c
index 8151c74..190e7dc 100644
--- a/gcc/tree-vect-analyze.c
+++ b/gcc/tree-vect-analyze.c
@@ -384,7 +384,7 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
"not vectorized: can't create epilog loop 1.");
return false;
}
- if (!slpeel_can_duplicate_loop_p (loop, loop->single_exit))
+ if (!slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
fprintf (vect_dump,
@@ -1522,7 +1522,7 @@ vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo,
/* We expect all such uses to be in the loop exit phis
(because of loop closed form) */
gcc_assert (TREE_CODE (USE_STMT (use_p)) == PHI_NODE);
- gcc_assert (bb == loop->single_exit->dest);
+ gcc_assert (bb == single_exit (loop)->dest);
*live_p = true;
}
@@ -1873,13 +1873,13 @@ vect_analyze_loop_form (struct loop *loop)
return NULL;
}
- if (!loop->single_exit
+ if (!single_exit (loop)
|| loop->num_nodes != 2
|| EDGE_COUNT (loop->header->preds) != 2)
{
if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
{
- if (!loop->single_exit)
+ if (!single_exit (loop))
fprintf (vect_dump, "not vectorized: multiple exits.");
else if (loop->num_nodes != 2)
fprintf (vect_dump, "not vectorized: too many BBs in loop.");
@@ -1903,9 +1903,9 @@ vect_analyze_loop_form (struct loop *loop)
}
/* Make sure there exists a single-predecessor exit bb: */
- if (!single_pred_p (loop->single_exit->dest))
+ if (!single_pred_p (single_exit (loop)->dest))
{
- edge e = loop->single_exit;
+ edge e = single_exit (loop);
if (!(e->flags & EDGE_ABNORMAL))
{
split_loop_exit_edge (e);
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c
index 6091575..b57208e 100644
--- a/gcc/tree-vect-transform.c
+++ b/gcc/tree-vect-transform.c
@@ -995,9 +995,9 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
/* 2.1 Create new loop-exit-phi to preserve loop-closed form:
v_out1 = phi <v_loop> */
- exit_bb = loop->single_exit->dest;
+ exit_bb = single_exit (loop)->dest;
new_phi = create_phi_node (SSA_NAME_VAR (vect_def), exit_bb);
- SET_PHI_ARG_DEF (new_phi, loop->single_exit->dest_idx, vect_def);
+ SET_PHI_ARG_DEF (new_phi, single_exit (loop)->dest_idx, vect_def);
exit_bsi = bsi_start (exit_bb);
/* 2.2 Get the relevant tree-code to use in the epilog for schemes 2,3
@@ -3325,7 +3325,7 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters,
edge update_e)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- basic_block exit_bb = loop->single_exit->dest;
+ basic_block exit_bb = single_exit (loop)->dest;
tree phi, phi1;
basic_block update_bb = update_e->dest;
@@ -3436,7 +3436,7 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio,
&ratio_mult_vf_name, ratio);
loop_num = loop->num;
- new_loop = slpeel_tree_peel_loop_to_edge (loop, loops, loop->single_exit,
+ new_loop = slpeel_tree_peel_loop_to_edge (loop, loops, single_exit (loop),
ratio_mult_vf_name, ni_name, false);
gcc_assert (new_loop);
gcc_assert (loop_num == loop->num);
@@ -3451,7 +3451,7 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio,
is on the path where the LOOP IVs are used and need to be updated. */
preheader = loop_preheader_edge (new_loop)->src;
- if (EDGE_PRED (preheader, 0)->src == loop->single_exit->dest)
+ if (EDGE_PRED (preheader, 0)->src == single_exit (loop)->dest)
update_e = EDGE_PRED (preheader, 0);
else
update_e = EDGE_PRED (preheader, 1);
@@ -3842,10 +3842,10 @@ vect_transform_loop (loop_vec_info loop_vinfo,
here by adding a new (empty) block on the exit-edge of the loop,
with the proper loop-exit phis to maintain loop-closed-form. **/
- merge_bb = loop->single_exit->dest;
+ merge_bb = single_exit (loop)->dest;
gcc_assert (EDGE_COUNT (merge_bb->preds) == 2);
- new_exit_bb = split_edge (loop->single_exit);
- new_exit_e = loop->single_exit;
+ new_exit_bb = split_edge (single_exit (loop));
+ new_exit_e = single_exit (loop);
e = EDGE_SUCC (new_exit_bb, 0);
for (orig_phi = phi_nodes (merge_bb); orig_phi;
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 8bc6885..7fa5d66 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -279,7 +279,7 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
tree def;
edge orig_loop_latch = loop_latch_edge (orig_loop);
edge orig_entry_e = loop_preheader_edge (orig_loop);
- edge new_loop_exit_e = new_loop->single_exit;
+ edge new_loop_exit_e = single_exit (new_loop);
edge new_loop_entry_e = loop_preheader_edge (new_loop);
edge entry_arg_e = (after ? orig_loop_latch : orig_entry_e);
@@ -519,7 +519,7 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
tree name;
/* Create new bb between loop and new_merge_bb. */
- *new_exit_bb = split_edge (loop->single_exit);
+ *new_exit_bb = split_edge (single_exit (loop));
new_exit_e = EDGE_SUCC (*new_exit_bb, 0);
@@ -564,7 +564,7 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
*new_exit_bb);
/* 2.2. NEW_EXIT_BB has one incoming edge: the exit-edge of the loop. */
- add_phi_arg (new_phi, loop_arg, loop->single_exit);
+ add_phi_arg (new_phi, loop_arg, single_exit (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);
@@ -644,7 +644,7 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
tree arg;
/* Create new bb between loop and new_merge_bb. */
- *new_exit_bb = split_edge (loop->single_exit);
+ *new_exit_bb = split_edge (single_exit (loop));
new_exit_e = EDGE_SUCC (*new_exit_bb, 0);
@@ -709,7 +709,7 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
*new_exit_bb);
/* 2.2. NEW_EXIT_BB has one incoming edge: the exit-edge of the loop. */
- add_phi_arg (new_phi, loop_arg, loop->single_exit);
+ add_phi_arg (new_phi, loop_arg, single_exit (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);
@@ -766,12 +766,12 @@ slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
{
tree indx_before_incr, indx_after_incr, cond_stmt, cond;
tree orig_cond;
- edge exit_edge = loop->single_exit;
+ edge exit_edge = single_exit (loop);
block_stmt_iterator loop_cond_bsi;
block_stmt_iterator incr_bsi;
bool insert_after;
tree begin_label = tree_block_label (loop->latch);
- tree exit_label = tree_block_label (loop->single_exit->dest);
+ tree exit_label = tree_block_label (single_exit (loop)->dest);
tree init = build_int_cst (TREE_TYPE (niters), 0);
tree step = build_int_cst (TREE_TYPE (niters), 1);
tree then_label;
@@ -832,8 +832,9 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, struct loops *loops,
bool was_imm_dom;
basic_block exit_dest;
tree phi, phi_arg;
+ edge exit, new_exit;
- at_exit = (e == loop->single_exit);
+ at_exit = (e == single_exit (loop));
if (!at_exit && e != loop_preheader_edge (loop))
return NULL;
@@ -854,22 +855,24 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, struct loops *loops,
return NULL;
}
- exit_dest = loop->single_exit->dest;
+ exit_dest = single_exit (loop)->dest;
was_imm_dom = (get_immediate_dominator (CDI_DOMINATORS,
exit_dest) == loop->header ?
true : false);
new_bbs = XNEWVEC (basic_block, loop->num_nodes);
+ exit = single_exit (loop);
copy_bbs (bbs, loop->num_nodes, new_bbs,
- &loop->single_exit, 1, &new_loop->single_exit, NULL,
+ &exit, 1, &new_exit, NULL,
e->src);
+ set_single_exit (new_loop, new_exit);
/* Duplicating phi args at exit bbs as coming
also from exit of duplicated loop. */
for (phi = phi_nodes (exit_dest); phi; phi = PHI_CHAIN (phi))
{
- phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, loop->single_exit);
+ phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, single_exit (loop));
if (phi_arg)
{
edge new_loop_exit_edge;
@@ -969,7 +972,7 @@ slpeel_add_loop_guard (basic_block guard_bb, tree cond, basic_block exit_bb,
bool
slpeel_can_duplicate_loop_p (struct loop *loop, edge e)
{
- edge exit_e = loop->single_exit;
+ edge exit_e = single_exit (loop);
edge entry_e = loop_preheader_edge (loop);
tree orig_cond = get_loop_exit_condition (loop);
block_stmt_iterator loop_exit_bsi = bsi_last (exit_e->src);
@@ -983,7 +986,7 @@ slpeel_can_duplicate_loop_p (struct loop *loop, edge e)
|| !loop->outer
|| loop->num_nodes != 2
|| !empty_block_p (loop->latch)
- || !loop->single_exit
+ || !single_exit (loop)
/* Verify that new loop exit condition can be trivially modified. */
|| (!orig_cond || orig_cond != bsi_stmt (loop_exit_bsi))
|| (e != exit_e && e != entry_e))
@@ -997,7 +1000,7 @@ void
slpeel_verify_cfg_after_peeling (struct loop *first_loop,
struct loop *second_loop)
{
- basic_block loop1_exit_bb = first_loop->single_exit->dest;
+ basic_block loop1_exit_bb = single_exit (first_loop)->dest;
basic_block loop2_entry_bb = loop_preheader_edge (second_loop)->src;
basic_block loop1_entry_bb = loop_preheader_edge (first_loop)->src;
@@ -1076,7 +1079,7 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops,
basic_block bb_before_first_loop;
basic_block bb_between_loops;
basic_block new_exit_bb;
- edge exit_e = loop->single_exit;
+ edge exit_e = single_exit (loop);
LOC loop_loc;
if (!slpeel_can_duplicate_loop_p (loop, e))
@@ -1155,7 +1158,7 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops,
*/
bb_before_first_loop = split_edge (loop_preheader_edge (first_loop));
- bb_before_second_loop = split_edge (first_loop->single_exit);
+ bb_before_second_loop = split_edge (single_exit (first_loop));
pre_condition =
fold_build2 (LE_EXPR, boolean_type_node, first_niters,
@@ -1194,7 +1197,7 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops,
*/
bb_between_loops = new_exit_bb;
- bb_after_second_loop = split_edge (second_loop->single_exit);
+ bb_after_second_loop = split_edge (single_exit (second_loop));
pre_condition =
fold_build2 (EQ_EXPR, boolean_type_node, first_niters, niters);