diff options
author | spop <spop@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-07-31 02:33:46 +0000 |
---|---|---|
committer | spop <spop@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-07-31 02:33:46 +0000 |
commit | b65ec27fff70d4767110ff0ffa7c7b27396ddc10 (patch) | |
tree | 85edd3d66198b38bc8add2a6dbdcd982a8bf9208 /gcc/cfgloopmanip.c | |
parent | 56c337f991314454c71d0b6738c88eeb80d3aad1 (diff) | |
download | gcc-b65ec27fff70d4767110ff0ffa7c7b27396ddc10.tar.gz |
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: svn+ssh://gcc.gnu.org/svn/gcc/trunk@150293 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgloopmanip.c')
-rw-r--r-- | gcc/cfgloopmanip.c | 84 |
1 files changed, 45 insertions, 39 deletions
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; } |