aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Pop <sebastian.pop@amd.com>2009-07-31 02:33:46 +0000
committerSebastian Pop <sebastian.pop@amd.com>2009-07-31 02:33:46 +0000
commitfd908faaa0dd0b72499d21262daa14ba58210ec5 (patch)
tree85edd3d66198b38bc8add2a6dbdcd982a8bf9208
parentfc5e9d93cf8a078e67e66640b20218b4ea99834b (diff)
Leave the loop_latch basic block empty.
2009-07-30 Sebastian Pop <sebastian.pop@amd.com> * cfgloop.h (create_empty_loop_on_edge): Pass an extra argument. * cfgloopmanip.c (create_empty_loop_on_edge): Leave the loop_latch basic block empty. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@150293 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/cfgloop.h2
-rw-r--r--gcc/cfgloopmanip.c84
3 files changed, 52 insertions, 40 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cbf948d0251..448a47177a1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2009-07-30 Sebastian Pop <sebastian.pop@amd.com>
+ * cfgloop.h (create_empty_loop_on_edge): Pass an extra argument.
+ * cfgloopmanip.c (create_empty_loop_on_edge): Leave the loop_latch
+ basic block empty.
+
+2009-07-30 Sebastian Pop <sebastian.pop@amd.com>
+
* doc/invoke.texi (-fgraphite-force-parallel): Documented.
2009-07-30 Sebastian Pop <sebastian.pop@amd.com>
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 2bc965b577b..93fa12e5e3e 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -283,7 +283,7 @@ extern bool can_duplicate_loop_p (const struct loop *loop);
extern edge create_empty_if_region_on_edge (edge, tree);
extern struct loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree,
- tree *, struct loop *);
+ tree *, tree *, struct loop *);
extern struct loop * duplicate_loop (struct loop *, struct loop *);
extern bool duplicate_loop_to_header_edge (struct loop *, edge,
unsigned, sbitmap, edge,
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 28cfa3cfc9a..40e3f8e9a59 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -588,31 +588,35 @@ create_empty_if_region_on_edge (edge entry_edge, tree condition)
/* create_empty_loop_on_edge
|
- | ------------- ------------------------
- | | pred_bb | | pred_bb |
- | ------------- | IV_0 = INITIAL_VALUE |
- | | ------------------------
- | | ______ | ENTRY_EDGE
- | | ENTRY_EDGE / V V
- | | ====> | -----------------------------
- | | | | IV_BEFORE = phi (IV_0, IV) |
- | | | | loop_header |
- | V | | IV_BEFORE <= UPPER_BOUND |
- | ------------- | -----------------------\-----
- | | succ_bb | | | \
- | ------------- | | \ exit_e
- | | V V---------
- | | -------------- | succ_bb |
- | | | loop_latch | ----------
- | | |IV = IV_BEFORE + STRIDE
- | | --------------
- | \ /
- | \ ___ /
+ | - pred_bb - ------ pred_bb ------
+ | | | | iv0 = initial_value |
+ | -----|----- ---------|-----------
+ | | ______ | entry_edge
+ | | entry_edge / | |
+ | | ====> | -V---V- loop_header -------------
+ | V | | iv_before = phi (iv0, iv_after) |
+ | - succ_bb - | ---|-----------------------------
+ | | | | |
+ | ----------- | ---V--- loop_body ---------------
+ | | | iv_after = iv_before + stride |
+ | | | if (iv_after <= upper_bound) |
+ | | ---|--------------\--------------
+ | | | \ exit_e
+ | | V \
+ | | - loop_latch - V- succ_bb -
+ | | | | | |
+ | | /------------- -----------
+ | \ ___ /
Creates an empty loop as shown above, the IV_BEFORE is the SSA_NAME
that is used before the increment of IV. IV_BEFORE should be used for
adding code to the body that uses the IV. OUTER is the outer loop in
- which the new loop should be inserted. */
+ which the new loop should be inserted.
+
+ Both INITIAL_VALUE and UPPER_BOUND expressions are gimplified and
+ inserted on the loop entry edge. This implies that this function
+ should be used only when the UPPER_BOUND expression is a loop
+ invariant. */
struct loop *
create_empty_loop_on_edge (edge entry_edge,
@@ -620,6 +624,7 @@ create_empty_loop_on_edge (edge entry_edge,
tree stride, tree upper_bound,
tree iv,
tree *iv_before,
+ tree *iv_after,
struct loop *outer)
{
basic_block loop_header, loop_latch, succ_bb, pred_bb;
@@ -627,13 +632,11 @@ create_empty_loop_on_edge (edge entry_edge,
int freq;
gcov_type cnt;
gimple_stmt_iterator gsi;
- bool insert_after;
gimple_seq stmts;
gimple cond_expr;
tree exit_test;
edge exit_e;
int prob;
- tree upper_bound_gimplified;
gcc_assert (entry_edge && initial_value && stride && upper_bound && iv);
@@ -667,6 +670,11 @@ create_empty_loop_on_edge (edge entry_edge,
/* Update dominators. */
update_dominators_in_loop (loop);
+ /* Modify edge flags. */
+ exit_e = single_exit (loop);
+ exit_e->flags = EDGE_LOOP_EXIT | EDGE_FALSE_VALUE;
+ single_pred_edge (loop_latch)->flags = EDGE_TRUE_VALUE;
+
/* Construct IV code in loop. */
initial_value = force_gimple_operand (initial_value, &stmts, true, iv);
if (stmts)
@@ -675,24 +683,20 @@ create_empty_loop_on_edge (edge entry_edge,
gsi_commit_edge_inserts ();
}
- standard_iv_increment_position (loop, &gsi, &insert_after);
- create_iv (initial_value, stride, iv, loop, &gsi, insert_after,
- iv_before, NULL);
-
- /* Modify edge flags. */
- exit_e = single_exit (loop);
- exit_e->flags = EDGE_LOOP_EXIT | EDGE_FALSE_VALUE;
- single_pred_edge (loop_latch)->flags = EDGE_TRUE_VALUE;
+ upper_bound = force_gimple_operand (upper_bound, &stmts, true, NULL);
+ if (stmts)
+ {
+ gsi_insert_seq_on_edge (loop_preheader_edge (loop), stmts);
+ gsi_commit_edge_inserts ();
+ }
- gsi = gsi_last_bb (exit_e->src);
+ gsi = gsi_last_bb (loop_header);
+ create_iv (initial_value, stride, iv, loop, &gsi, false,
+ iv_before, iv_after);
- upper_bound_gimplified =
- force_gimple_operand_gsi (&gsi, upper_bound, true, NULL,
- false, GSI_NEW_STMT);
- gsi = gsi_last_bb (exit_e->src);
-
- cond_expr = gimple_build_cond
- (LE_EXPR, *iv_before, upper_bound_gimplified, NULL_TREE, NULL_TREE);
+ /* Insert loop exit condition. */
+ cond_expr = gimple_build_cond
+ (LE_EXPR, *iv_after, upper_bound, NULL_TREE, NULL_TREE);
exit_test = gimple_cond_lhs (cond_expr);
exit_test = force_gimple_operand_gsi (&gsi, exit_test, true, NULL,
@@ -701,6 +705,8 @@ create_empty_loop_on_edge (edge entry_edge,
gsi = gsi_last_bb (exit_e->src);
gsi_insert_after (&gsi, cond_expr, GSI_NEW_STMT);
+ split_block_after_labels (loop_header);
+
return loop;
}