Commit 8e74b397 by Sebastian Pop Committed by Sebastian Pop

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.

From-SVN: r150293
parent 109e0d57
2009-07-30 Sebastian Pop <sebastian.pop@amd.com> 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. * doc/invoke.texi (-fgraphite-force-parallel): Documented.
2009-07-30 Sebastian Pop <sebastian.pop@amd.com> 2009-07-30 Sebastian Pop <sebastian.pop@amd.com>
......
...@@ -283,7 +283,7 @@ extern bool can_duplicate_loop_p (const struct loop *loop); ...@@ -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 edge create_empty_if_region_on_edge (edge, tree);
extern struct loop *create_empty_loop_on_edge (edge, tree, tree, tree, 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 struct loop * duplicate_loop (struct loop *, struct loop *);
extern bool duplicate_loop_to_header_edge (struct loop *, edge, extern bool duplicate_loop_to_header_edge (struct loop *, edge,
unsigned, sbitmap, edge, unsigned, sbitmap, edge,
......
...@@ -588,31 +588,35 @@ create_empty_if_region_on_edge (edge entry_edge, tree condition) ...@@ -588,31 +588,35 @@ create_empty_if_region_on_edge (edge entry_edge, tree condition)
/* create_empty_loop_on_edge /* create_empty_loop_on_edge
| |
| ------------- ------------------------ | - pred_bb - ------ pred_bb ------
| | pred_bb | | pred_bb | | | | | iv0 = initial_value |
| ------------- | IV_0 = INITIAL_VALUE | | -----|----- ---------|-----------
| | ------------------------ | | ______ | entry_edge
| | ______ | ENTRY_EDGE | | entry_edge / | |
| | ENTRY_EDGE / V V | | ====> | -V---V- loop_header -------------
| | ====> | ----------------------------- | V | | iv_before = phi (iv0, iv_after) |
| | | | IV_BEFORE = phi (IV_0, IV) | | - succ_bb - | ---|-----------------------------
| | | | loop_header | | | | | |
| V | | IV_BEFORE <= UPPER_BOUND | | ----------- | ---V--- loop_body ---------------
| ------------- | -----------------------\----- | | | iv_after = iv_before + stride |
| | succ_bb | | | \ | | | if (iv_after <= upper_bound) |
| ------------- | | \ exit_e | | ---|--------------\--------------
| | V V--------- | | | \ exit_e
| | -------------- | succ_bb | | | V \
| | | loop_latch | ---------- | | - loop_latch - V- succ_bb -
| | |IV = IV_BEFORE + STRIDE | | | | | |
| | -------------- | | /------------- -----------
| \ / | \ ___ /
| \ ___ /
Creates an empty loop as shown above, the IV_BEFORE is the SSA_NAME 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 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 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 * struct loop *
create_empty_loop_on_edge (edge entry_edge, create_empty_loop_on_edge (edge entry_edge,
...@@ -620,6 +624,7 @@ 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 stride, tree upper_bound,
tree iv, tree iv,
tree *iv_before, tree *iv_before,
tree *iv_after,
struct loop *outer) struct loop *outer)
{ {
basic_block loop_header, loop_latch, succ_bb, pred_bb; basic_block loop_header, loop_latch, succ_bb, pred_bb;
...@@ -627,13 +632,11 @@ create_empty_loop_on_edge (edge entry_edge, ...@@ -627,13 +632,11 @@ create_empty_loop_on_edge (edge entry_edge,
int freq; int freq;
gcov_type cnt; gcov_type cnt;
gimple_stmt_iterator gsi; gimple_stmt_iterator gsi;
bool insert_after;
gimple_seq stmts; gimple_seq stmts;
gimple cond_expr; gimple cond_expr;
tree exit_test; tree exit_test;
edge exit_e; edge exit_e;
int prob; int prob;
tree upper_bound_gimplified;
gcc_assert (entry_edge && initial_value && stride && upper_bound && iv); gcc_assert (entry_edge && initial_value && stride && upper_bound && iv);
...@@ -667,6 +670,11 @@ create_empty_loop_on_edge (edge entry_edge, ...@@ -667,6 +670,11 @@ create_empty_loop_on_edge (edge entry_edge,
/* Update dominators. */ /* Update dominators. */
update_dominators_in_loop (loop); 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. */ /* Construct IV code in loop. */
initial_value = force_gimple_operand (initial_value, &stmts, true, iv); initial_value = force_gimple_operand (initial_value, &stmts, true, iv);
if (stmts) if (stmts)
...@@ -675,24 +683,20 @@ create_empty_loop_on_edge (edge entry_edge, ...@@ -675,24 +683,20 @@ create_empty_loop_on_edge (edge entry_edge,
gsi_commit_edge_inserts (); gsi_commit_edge_inserts ();
} }
standard_iv_increment_position (loop, &gsi, &insert_after); upper_bound = force_gimple_operand (upper_bound, &stmts, true, NULL);
create_iv (initial_value, stride, iv, loop, &gsi, insert_after, if (stmts)
iv_before, NULL); {
gsi_insert_seq_on_edge (loop_preheader_edge (loop), stmts);
/* Modify edge flags. */ gsi_commit_edge_inserts ();
exit_e = single_exit (loop); }
exit_e->flags = EDGE_LOOP_EXIT | EDGE_FALSE_VALUE;
single_pred_edge (loop_latch)->flags = EDGE_TRUE_VALUE;
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 = /* Insert loop exit condition. */
force_gimple_operand_gsi (&gsi, upper_bound, true, NULL, cond_expr = gimple_build_cond
false, GSI_NEW_STMT); (LE_EXPR, *iv_after, upper_bound, NULL_TREE, NULL_TREE);
gsi = gsi_last_bb (exit_e->src);
cond_expr = gimple_build_cond
(LE_EXPR, *iv_before, upper_bound_gimplified, NULL_TREE, NULL_TREE);
exit_test = gimple_cond_lhs (cond_expr); exit_test = gimple_cond_lhs (cond_expr);
exit_test = force_gimple_operand_gsi (&gsi, exit_test, true, NULL, exit_test = force_gimple_operand_gsi (&gsi, exit_test, true, NULL,
...@@ -701,6 +705,8 @@ create_empty_loop_on_edge (edge entry_edge, ...@@ -701,6 +705,8 @@ create_empty_loop_on_edge (edge entry_edge,
gsi = gsi_last_bb (exit_e->src); gsi = gsi_last_bb (exit_e->src);
gsi_insert_after (&gsi, cond_expr, GSI_NEW_STMT); gsi_insert_after (&gsi, cond_expr, GSI_NEW_STMT);
split_block_after_labels (loop_header);
return loop; return loop;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment