tree-flow.h (loop_only_exit_p): Declare.

* tree-flow.h (loop_only_exit_p): Declare.
	* tree-ssa-loop-niter.c (loop_only_exit_p): Make public.
	* tree-ssa-loop-ivopts.c (may_eliminate_iv): Reinstate direct check on
	the number of iterations if it is constant.  Otherwise, if this is the
	only possible exit of the loop, use the conservative estimate on the
	number of iterations of the entire loop if available.

From-SVN: r137437
This commit is contained in:
Eric Botcazou 2008-07-03 22:02:18 +00:00 committed by Eric Botcazou
parent b8fff07918
commit 52778e2a62
8 changed files with 71 additions and 15 deletions

View File

@ -1,3 +1,12 @@
2008-07-03 Eric Botcazou <ebotcazou@adacore.com>
* tree-flow.h (loop_only_exit_p): Declare.
* tree-ssa-loop-niter.c (loop_only_exit_p): Make public.
* tree-ssa-loop-ivopts.c (may_eliminate_iv): Reinstate direct check on
the number of iterations if it is constant. Otherwise, if this is the
only possible exit of the loop, use the conservative estimate on the
number of iterations of the entire loop if available.
2008-07-03 Richard Sandiford <rdsandiford@googlemail.com>
* Makefile.in (libgcc.mvars): Add LIBGCC_SYNC and LIBGCC_SYNC_CFLAGS.

View File

@ -1,3 +1,8 @@
2008-07-03 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/loop_optimization3.adb: New test.
* gnat.dg/loop_optimization3_pkg.ad[sb]: New helper.
2008-07-03 Uros Bizjak <ubizjak@gmail.com>
PR target/36710

View File

@ -0,0 +1,15 @@
-- { dg-do run }
-- { dg-options "-O" }
with Loop_Optimization3_Pkg; use Loop_Optimization3_Pkg;
procedure Loop_Optimization3 is
type Arr is array (Integer range -3 .. 3) of Integer;
C : constant Arr := (1, others => F(2));
begin
if C /= (1, 2, 2, 2, 2, 2, 2) then
raise Program_Error;
end if;
end;

View File

@ -0,0 +1,8 @@
package body Loop_Optimization3_Pkg is
function F (n : Integer) return Integer is
begin
return n;
end;
end Loop_Optimization3_Pkg;

View File

@ -0,0 +1,5 @@
package Loop_Optimization3_Pkg is
function F (n : Integer) return Integer;
end Loop_Optimization3_Pkg;

View File

@ -1039,6 +1039,7 @@ void tree_ssa_iv_optimize (void);
unsigned tree_predictive_commoning (void);
bool parallelize_loops (void);
bool loop_only_exit_p (const struct loop *, const_edge);
bool number_of_iterations_exit (struct loop *, edge,
struct tree_niter_desc *niter, bool);
tree find_loop_niter (struct loop *, edge *);

View File

@ -3745,13 +3745,12 @@ may_eliminate_iv (struct ivopts_data *data,
tree nit, period;
struct loop *loop = data->current_loop;
aff_tree bnd;
double_int period_value, max_niter;
if (TREE_CODE (cand->iv->step) != INTEGER_CST)
return false;
/* For now works only for exits that dominate the loop latch. TODO -- extend
for other conditions inside loop body. */
/* For now works only for exits that dominate the loop latch.
TODO: extend to other conditions inside loop body. */
ex_bb = bb_for_stmt (use->stmt);
if (use->stmt != last_stmt (ex_bb)
|| TREE_CODE (use->stmt) != COND_EXPR)
@ -3769,19 +3768,33 @@ may_eliminate_iv (struct ivopts_data *data,
if (!nit)
return false;
/* Determine whether we may use the variable to test whether niter iterations
elapsed. This is the case iff the period of the induction variable is
greater than the number of iterations. */
/* Determine whether we can use the variable to test the exit condition.
This is the case iff the period of the induction variable is greater
than the number of iterations for which the exit condition is true. */
period = iv_period (cand->iv);
if (!period)
return false;
/* Compare the period with the estimate on the number of iterations of the
loop. */
if (!estimated_loop_iterations (loop, true, &max_niter))
return false;
period_value = tree_to_double_int (period);
if (double_int_ucmp (period_value, max_niter) <= 0)
/* If the number of iterations is constant, compare against it directly. */
if (TREE_CODE (nit) == INTEGER_CST)
{
if (!tree_int_cst_lt (nit, period))
return false;
}
/* If not, and if this is the only possible exit of the loop, see whether
we can get a conservative estimate on the number of iterations of the
entire loop and compare against that instead. */
else if (loop_only_exit_p (loop, exit))
{
double_int period_value, max_niter;
if (!estimated_loop_iterations (loop, true, &max_niter))
return false;
period_value = tree_to_double_int (period);
if (double_int_ucmp (max_niter, period_value) >= 0)
return false;
}
/* Otherwise, punt. */
else
return false;
cand_value_at (loop, cand, use->stmt, nit, &bnd);

View File

@ -1672,7 +1672,7 @@ simplify_using_outer_evolutions (struct loop *loop, tree expr)
/* Returns true if EXIT is the only possible exit from LOOP. */
static bool
bool
loop_only_exit_p (const struct loop *loop, const_edge exit)
{
basic_block *body;