tree-flow.h (loop_only_exit_p): Declare.
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 3 Jul 2008 22:02:18 +0000 (22:02 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 3 Jul 2008 22:02:18 +0000 (22:02 +0000)
* 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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/loop_optimization3.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/loop_optimization3_pkg.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/loop_optimization3_pkg.ads [new file with mode: 0644]
gcc/tree-flow.h
gcc/tree-ssa-loop-ivopts.c
gcc/tree-ssa-loop-niter.c

index 917031f8a8a3a96bd0689d24057c5e739d18d052..42f0b325cc72928ce11ac3547fe4307f6d7d522d 100644 (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.
index 4f4e3b92fdf3e642ab7bce6a67acee6b892da3f2..51e89e577564fc2a731e19b569a944839c1a68d0 100644 (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
diff --git a/gcc/testsuite/gnat.dg/loop_optimization3.adb b/gcc/testsuite/gnat.dg/loop_optimization3.adb
new file mode 100644 (file)
index 0000000..e69f535
--- /dev/null
@@ -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 (file)
index 0000000..7a64815
--- /dev/null
@@ -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 (file)
index 0000000..90f4fc3
--- /dev/null
@@ -0,0 +1,5 @@
+package Loop_Optimization3_Pkg is
+
+  function F (n : Integer) return Integer;
+
+end Loop_Optimization3_Pkg;
index 961054703dba5414ee0f7064ffef2de38c2d943b..5479c3342c7f3ab13aa501ffb3d8531956079b95 100644 (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 *);
index 41c3794365690f7b393082970340ece467cb1435..ce5c05cd88f743d623106685dc7f0e296e8d38df 100644 (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);
index 74153fd294d1206dc3bd41688b1e8ca40fa0c979..80b45c298b7bfa27b498fc9a3cefebb6ed71e39c 100644 (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;