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
This commit is contained in:
Daniel Berlin 2006-01-04 16:34:52 +00:00 committed by Daniel Berlin
parent bc4071dd66
commit dc006c709d
2 changed files with 67 additions and 28 deletions

View File

@ -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:

View File

@ -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