diff options
author | razya <razya@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-07-05 13:08:01 +0000 |
---|---|---|
committer | razya <razya@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-07-05 13:08:01 +0000 |
commit | 2a556654cacdccf03b05488f557f3619951c82d2 (patch) | |
tree | 67135b0c880f731ab81c64aa984089f4ac3e36f2 /gcc/tree-parloops.c | |
parent | 3014ed2c7915cdc95fff08916a1a05dc03b16f04 (diff) | |
download | gcc-2a556654cacdccf03b05488f557f3619951c82d2.tar.gz |
07-05-2011 Razya Ladelsky <razya@il.ibm.com>
* tree-cfg.c (gimple_duplicate_sese_tail): Remove handling of
the loop's number of iterations.
* tree-parloops.c (transform_to_exit_first_loop): Add the
handling of the loop's number of iterations before the call
to gimple_duplicate_sese_tail.
Insert the stmt caclculating the new rhs of the loop's
condition stmt to the preheader instead of iters_bb.
* testsuite/gcc.dg/autopar/pr49580.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@175851 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-parloops.c')
-rw-r--r-- | gcc/tree-parloops.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index 921821d5fbd..339ddcc18a5 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -1474,6 +1474,8 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit gimple phi, nphi, cond_stmt, stmt, cond_nit; gimple_stmt_iterator gsi; tree nit_1; + edge exit_1; + tree new_rhs; split_block_after_labels (loop->header); orig_header = single_succ (loop->header); @@ -1502,6 +1504,38 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit control = t; } } + + /* Setting the condition towards peeling the last iteration: + If the block consisting of the exit condition has the latch as + successor, then the body of the loop is executed before + the exit condition is tested. In such case, moving the + condition to the entry, causes that the loop will iterate + one less iteration (which is the wanted outcome, since we + peel out the last iteration). If the body is executed after + the condition, moving the condition to the entry requires + decrementing one iteration. */ + exit_1 = EDGE_SUCC (exit->src, EDGE_SUCC (exit->src, 0) == exit); + if (exit_1->dest == loop->latch) + new_rhs = gimple_cond_rhs (cond_stmt); + else + { + new_rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (gimple_cond_rhs (cond_stmt)), + gimple_cond_rhs (cond_stmt), + build_int_cst (TREE_TYPE (gimple_cond_rhs (cond_stmt)), 1)); + if (TREE_CODE (gimple_cond_rhs (cond_stmt)) == SSA_NAME) + { + basic_block preheader; + gimple_stmt_iterator gsi1; + + preheader = loop_preheader_edge(loop)->src; + gsi1 = gsi_after_labels (preheader); + new_rhs = force_gimple_operand_gsi (&gsi1, new_rhs, true, + NULL_TREE,false,GSI_CONTINUE_LINKING); + } + } + gimple_cond_set_rhs (cond_stmt, unshare_expr (new_rhs)); + gimple_cond_set_lhs (cond_stmt, unshare_expr (gimple_cond_lhs (cond_stmt))); + bbs = get_loop_body_in_dom_order (loop); for (n = 0; bbs[n] != loop->latch; n++) |