From 8e74b39765b22212a3b4ec138b2cc3b938ccc9d8 Mon Sep 17 00:00:00 2001 From: Sebastian Pop Date: Fri, 31 Jul 2009 02:33:46 +0000 Subject: [PATCH] Leave the loop_latch basic block empty. 2009-07-30 Sebastian Pop * 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 --- gcc/ChangeLog | 6 ++++ gcc/cfgloop.h | 2 +- gcc/cfgloopmanip.c | 84 +++++++++++++++++++++++++++++------------------------- 3 files changed, 52 insertions(+), 40 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cbf948d..448a471 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2009-07-30 Sebastian Pop + * 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 + * doc/invoke.texi (-fgraphite-force-parallel): Documented. 2009-07-30 Sebastian Pop diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 2bc965b..93fa12e5 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 28cfa3c..40e3f8e 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; } -- 2.7.4