aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorZdenek Dvorak <dvorakz@suse.cz>2005-11-18 11:27:50 +0100
committerZdenek Dvorak <rakdver@gcc.gnu.org>2005-11-18 10:27:50 +0000
commit925196ed525e3f05b74d54391edd3a198986e035 (patch)
treefeca6fb50fea0f4ac734005b28fa6601460c13b5 /gcc
parentd087f5fe3148044f40866d6f0d307db52c3d64ec (diff)
downloadgcc-925196ed525e3f05b74d54391edd3a198986e035.zip
gcc-925196ed525e3f05b74d54391edd3a198986e035.tar.gz
gcc-925196ed525e3f05b74d54391edd3a198986e035.tar.bz2
tree-scalar-evolution.c (expression_expensive_p): New function.
* tree-scalar-evolution.c (expression_expensive_p): New function. (scev_const_prop): Use compute_overall_effect_of_inner_loop. * gcc.dg/tree-ssa/loop-14.c: New test. From-SVN: r107170
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-14.c19
-rw-r--r--gcc/tree-scalar-evolution.c63
4 files changed, 66 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fc9df6a..7774bda 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9eafe7e..dc1c727 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..ff96e12
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-14.c
@@ -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" } } */
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index c2fa2ef..c35298e 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -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);
}
}
}