aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization3.adb15
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization3_pkg.adb8
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization3_pkg.ads5
-rw-r--r--gcc/tree-flow.h1
-rw-r--r--gcc/tree-ssa-loop-ivopts.c41
-rw-r--r--gcc/tree-ssa-loop-niter.c2
8 files changed, 71 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 917031f..42f0b32 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4f4e3b9..51e89e5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gnat.dg/loop_optimization3.adb b/gcc/testsuite/gnat.dg/loop_optimization3.adb
new file mode 100644
index 0000000..e69f535
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization3.adb
@@ -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;
diff --git a/gcc/testsuite/gnat.dg/loop_optimization3_pkg.adb b/gcc/testsuite/gnat.dg/loop_optimization3_pkg.adb
new file mode 100644
index 0000000..7a64815
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization3_pkg.adb
@@ -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;
diff --git a/gcc/testsuite/gnat.dg/loop_optimization3_pkg.ads b/gcc/testsuite/gnat.dg/loop_optimization3_pkg.ads
new file mode 100644
index 0000000..90f4fc3
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization3_pkg.ads
@@ -0,0 +1,5 @@
+package Loop_Optimization3_Pkg is
+
+ function F (n : Integer) return Integer;
+
+end Loop_Optimization3_Pkg;
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 9610547..5479c33 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -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 *);
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 41c3794..ce5c05c 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -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);
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 74153fd..80b45c2 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -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;