diff options
author | Daniel Berlin <dberlin@dberlin.org> | 2006-01-04 16:34:52 +0000 |
---|---|---|
committer | Daniel Berlin <dberlin@gcc.gnu.org> | 2006-01-04 16:34:52 +0000 |
commit | dc006c709db51286a35c58da49542e5c493c038d (patch) | |
tree | ebc033b9b67710f150a7a565c73db6c4da44a365 | |
parent | bc4071dd66fd4d093dc3fe3592ea879c2996868b (diff) | |
download | gcc-dc006c709db51286a35c58da49542e5c493c038d.zip gcc-dc006c709db51286a35c58da49542e5c493c038d.tar.gz gcc-dc006c709db51286a35c58da49542e5c493c038d.tar.bz2 |
lambda-code.c (can_put_in_inner_loop): Relax restrictions.
2006-01-04 Daniel Berlin <dberlin@dberlin.org>
* lambda-code.c (can_put_in_inner_loop): Relax
restrictions.
(can_put_after_inner_loop): New function.
(can_convert_to_perfect_nest): Use can_put_after_inner_loop as well.
(perfect_nestify): Change to make copies and modify uses.
From-SVN: r109337
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/lambda-code.c | 87 |
2 files changed, 67 insertions, 28 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a9a6e92..18e6151 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2006-01-04 Daniel Berlin <dberlin@dberlin.org> + + * lambda-code.c (can_put_in_inner_loop): Relax + restrictions. + (can_put_after_inner_loop): New function. + (can_convert_to_perfect_nest): Use can_put_after_inner_loop as well. + (perfect_nestify): Change to make copies and modify uses. + 2006-01-04 Richard Henderson <rth@redhat.com> Merge from gomp branch: diff --git a/gcc/lambda-code.c b/gcc/lambda-code.c index 43889f7..c19ea6c 100644 --- a/gcc/lambda-code.c +++ b/gcc/lambda-code.c @@ -2201,23 +2201,20 @@ exit_phi_for_loop_p (struct loop *loop, tree stmt) return true; } -/* Return true if STMT can be put back into INNER, a loop by moving it to the - beginning of that loop. */ +/* Return true if STMT can be put back into the loop INNER, by + copying it to the beginning of that loop and changing the uses. */ static bool can_put_in_inner_loop (struct loop *inner, tree stmt) { imm_use_iterator imm_iter; use_operand_p use_p; - basic_block use_bb = NULL; gcc_assert (TREE_CODE (stmt) == MODIFY_EXPR); if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS) || !expr_invariant_in_loop_p (inner, TREE_OPERAND (stmt, 1))) return false; - /* We require that the basic block of all uses be the same, or the use be an - exit phi. */ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, TREE_OPERAND (stmt, 0)) { if (!exit_phi_for_loop_p (inner, USE_STMT (use_p))) @@ -2226,17 +2223,39 @@ can_put_in_inner_loop (struct loop *inner, tree stmt) if (!flow_bb_inside_loop_p (inner, immbb)) return false; - if (use_bb == NULL) - use_bb = immbb; - else if (immbb != use_bb) + } + } + return true; +} + +/* Return true if STMT can be put *after* the inner loop of LOOP. */ +static bool +can_put_after_inner_loop (struct loop *loop, tree stmt) +{ + imm_use_iterator imm_iter; + use_operand_p use_p; + + if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS)) + return false; + + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, TREE_OPERAND (stmt, 0)) + { + if (!exit_phi_for_loop_p (loop, USE_STMT (use_p))) + { + basic_block immbb = bb_for_stmt (USE_STMT (use_p)); + + if (!dominated_by_p (CDI_DOMINATORS, + immbb, + loop->inner->header) + && !can_put_in_inner_loop (loop->inner, stmt)) return false; } } return true; - } + /* Return TRUE if LOOP is an imperfect nest that we can convert to a perfect one. LOOPIVS is a vector of induction variables, one per loop. ATM, we only handle imperfect nests of depth 2, where all of the statements @@ -2277,18 +2296,20 @@ can_convert_to_perfect_nest (struct loop *loop, if (stmt_uses_op (stmt, iv)) goto fail; - /* If this is a simple operation like a cast that is invariant - in the inner loop, only used there, and we can place it - there, then it's not going to hurt us. - This means that we will propagate casts and other cheap - invariant operations *back* - into the inner loop if we can interchange the loop, on the - theory that we are going to gain a lot more by interchanging - the loop than we are by leaving some invariant code there for - some other pass to clean up. */ + /* If this is a simple operation like a cast that is + invariant in the inner loop, or after the inner loop, + then see if we can place it back where it came from. + This means that we will propagate casts and other + cheap invariant operations *back* into or after + the inner loop if we can interchange the loop, on the + theory that we are going to gain a lot more by + interchanging the loop than we are by leaving some + invariant code there for some other pass to clean + up. */ if (TREE_CODE (stmt) == MODIFY_EXPR && is_gimple_cast (TREE_OPERAND (stmt, 1)) - && can_put_in_inner_loop (loop->inner, stmt)) + && (can_put_in_inner_loop (loop->inner, stmt) + || can_put_after_inner_loop (loop, stmt))) continue; /* Otherwise, if the bb of a statement we care about isn't @@ -2515,23 +2536,33 @@ perfect_nestify (struct loops *loops, bsi_prev (&bsi); continue; } - /* Move this statement back into the inner loop. - This looks a bit confusing, but we are really just - finding the first non-exit phi use and moving the - statement to the beginning of that use's basic - block. */ + + /* Make copies of this statement to put it back next + to its uses. */ FOR_EACH_IMM_USE_SAFE (use_p, imm_iter, TREE_OPERAND (stmt, 0)) { tree imm_stmt = USE_STMT (use_p); if (!exit_phi_for_loop_p (loop->inner, imm_stmt)) { - block_stmt_iterator tobsi = bsi_after_labels (bb_for_stmt (imm_stmt)); - bsi_move_after (&bsi, &tobsi); - update_stmt (stmt); - BREAK_FROM_SAFE_IMM_USE (imm_iter); + block_stmt_iterator tobsi; + tree newname; + tree newstmt; + + newstmt = unshare_expr (stmt); + tobsi = bsi_after_labels (bb_for_stmt (imm_stmt)); + newname = TREE_OPERAND (newstmt, 0); + newname = SSA_NAME_VAR (newname); + newname = make_ssa_name (newname, newstmt); + TREE_OPERAND (newstmt, 0) = newname; + SET_USE (use_p, TREE_OPERAND (newstmt, 0)); + bsi_insert_after (&tobsi, newstmt, BSI_SAME_STMT); + update_stmt (newstmt); + update_stmt (imm_stmt); } } + if (!bsi_end_p (bsi)) + bsi_prev (&bsi); } } else |