* tree-scalar-evolution.c (expression_expensive_p): New function.
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Nov 2005 10:27:50 +0000 (10:27 +0000)
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Nov 2005 10:27:50 +0000 (10:27 +0000)
(scev_const_prop): Use compute_overall_effect_of_inner_loop.

* gcc.dg/tree-ssa/loop-14.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@107170 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/loop-14.c [new file with mode: 0644]
gcc/tree-scalar-evolution.c

index fc9df6a..7774bda 100644 (file)
@@ -1,3 +1,8 @@
+2005-11-18  Zdenek Dvorak  <dvorakz@suse.cz>
+
+       * tree-scalar-evolution.c (expression_expensive_p): New function.
+       (scev_const_prop): Use compute_overall_effect_of_inner_loop.
+
 2005-11-18  Bernd Schmidt  <bernd.schmidt@analog.com>
 
        * config/bfin/crtlibid.s: New file.
index 9eafe7e..dc1c727 100644 (file)
@@ -1,3 +1,7 @@
+2005-11-18  Zdenek Dvorak  <dvorakz@suse.cz>
+
+       * gcc.dg/tree-ssa/loop-14.c: New test.
+
 2005-11-17  James A. Morrison  <phython@gcc.gnu.org>
             Michael Chamberlain <michael@chamberlain.net.au>
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-14.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-14.c
new file mode 100644 (file)
index 0000000..ff96e12
--- /dev/null
@@ -0,0 +1,19 @@
+/* A test for final value replacement.  */
+
+/* { dg-options "-O2 -fdump-tree-vars" } */
+
+int foo(void);
+
+int bla(void)
+{
+  int i, j = foo ();
+
+  for (i = 0; i < 100; i++, j++)
+    foo ();
+
+  /* Should be replaced with return j0 + 100;  */
+  return j;
+}
+
+/* { dg-final { scan-tree-dump-times "\\+ 100" 1 "vars" } } */
+/* { dg-final { cleanup-tree-dump "vars" } } */
index c2fa2ef..c35298e 100644 (file)
@@ -2700,6 +2700,14 @@ scev_finalize (void)
   BITMAP_FREE (already_instantiated);
 }
 
+/* Returns true if EXPR looks expensive.  */
+
+static bool
+expression_expensive_p (tree expr)
+{
+  return force_expr_to_var_cost (expr) >= target_spill_cost;
+}
+
 /* Replace ssa names for that scev can prove they are constant by the
    appropriate constants.  Also perform final value replacement in loops,
    in case the replacement expressions are cheap.
@@ -2775,7 +2783,8 @@ scev_const_prop (void)
   for (i = current_loops->num - 1; i > 0; i--)
     {
       edge exit;
-      tree def, stmts;
+      tree def, rslt, ass;
+      block_stmt_iterator bsi;
 
       loop = current_loops->parray[i];
       if (!loop)
@@ -2787,46 +2796,50 @@ scev_const_prop (void)
       if (!exit
          || number_of_iterations_in_loop (loop) == chrec_dont_know)
        continue;
-      ex_loop = exit->dest->loop_father;
+
+      /* Ensure that it is possible to insert new statements somewhere.  */
+      if (!single_pred_p (exit->dest))
+       split_loop_exit_edge (exit);
+      tree_block_label (exit->dest);
+      bsi = bsi_after_labels (exit->dest);
+
+      ex_loop = superloop_at_depth (loop, exit->dest->loop_father->depth + 1);
 
       for (phi = phi_nodes (exit->dest); phi; phi = next_phi)
        {
          next_phi = PHI_CHAIN (phi);
+         rslt = PHI_RESULT (phi);
          def = PHI_ARG_DEF_FROM_EDGE (phi, exit);
-         if (!is_gimple_reg (def)
-             || expr_invariant_in_loop_p (loop, def))
+         if (!is_gimple_reg (def))
            continue;
 
          if (!POINTER_TYPE_P (TREE_TYPE (def))
              && !INTEGRAL_TYPE_P (TREE_TYPE (def)))
            continue;
 
-         def = analyze_scalar_evolution_in_loop (ex_loop, ex_loop, def);
+         def = analyze_scalar_evolution_in_loop (ex_loop, loop, def);
+         def = compute_overall_effect_of_inner_loop (ex_loop, def);
          if (!tree_does_not_contain_chrecs (def)
-             || chrec_contains_symbols_defined_in_loop (def, loop->num)
-             || def == PHI_RESULT (phi)
-             || (TREE_CODE (def) == SSA_NAME
-                 && loop_containing_stmt (SSA_NAME_DEF_STMT (def))
-                 && loop_containing_stmt (phi)
-                 && loop_containing_stmt (SSA_NAME_DEF_STMT (def))
-                 == loop_containing_stmt (phi)))
+             || chrec_contains_symbols_defined_in_loop (def, ex_loop->num))
            continue;
 
-         /* If computing the expression is expensive, let it remain in
-            loop.  TODO -- we should take the cost of computing the expression
-            in loop into account.  */
-         if (force_expr_to_var_cost (def) >= target_spill_cost)
+         /* If computing the expression is expensive, let it remain in the
+            loop.  */
+         if (expression_expensive_p (def))
            continue;
-         def = unshare_expr (def);
 
-         if (is_gimple_val (def))
-           stmts = NULL_TREE;
-         else
-           def = force_gimple_operand (def, &stmts, true,
-                                       SSA_NAME_VAR (PHI_RESULT (phi)));
-         SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, exit), def);
-         if (stmts)
-           compute_phi_arg_on_exit (exit, stmts, def);
+         /* Eliminate the phi node and replace it by a computation outside
+            the loop.  */
+         def = unshare_expr (def);
+         SET_PHI_RESULT (phi, NULL_TREE);
+         remove_phi_node (phi, NULL_TREE);
+
+         ass = build2 (MODIFY_EXPR, void_type_node, rslt, NULL_TREE);
+         SSA_NAME_DEF_STMT (rslt) = ass;
+         bsi_insert_after (&bsi, ass, BSI_NEW_STMT);
+         def = force_gimple_operand_bsi (&bsi, def, false, NULL_TREE);
+         TREE_OPERAND (ass, 1) = def;
+         update_stmt (ass);
        }
     }
 }