summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2008-03-18 16:10:24 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2008-03-18 16:10:24 +0000
commitb9e98b8aaf6868b21168913ea3d82df38d4d1430 (patch)
tree1e20a972378312ce4158563ae53589c5b3dda789
parent4a1849e3a1e51cb463703ec17861392086dce70b (diff)
downloadgcc-b9e98b8aaf6868b21168913ea3d82df38d4d1430.tar.gz
2008-03-18 Richard Guenther <rguenther@suse.de>
* tree-ssa-sccvn.c (visit_reference_op_load): If the lookup found an expression with constants, note that in the VN for the lhs. * tree-ssa-pre.c (eliminate): Visit COND_EXPR statements and fold them to constants if possible. Run cleanup_cfg if done so. (execute_pre): Return todo. (do_pre): Likewise. (execute_fre): Likewise. * tree-ssa-forwprop.c (can_propagate_from): Allow propagation of constants. (get_prop_source_stmt): Look through pointer conversions. * gcc.dg/tree-ssa/forwprop-4.c: New testcase. * gcc.dg/tree-ssa/ssa-fre-16.c: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@133315 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/forwprop-4.c18
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-16.c18
-rw-r--r--gcc/tree-ssa-forwprop.c26
-rw-r--r--gcc/tree-ssa-pre.c56
-rw-r--r--gcc/tree-ssa-sccvn.c6
7 files changed, 130 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 82374258411..add3e25ad86 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2008-03-18 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-sccvn.c (visit_reference_op_load): If the lookup
+ found an expression with constants, note that in the VN for the lhs.
+ * tree-ssa-pre.c (eliminate): Visit COND_EXPR statements and
+ fold them to constants if possible. Run cleanup_cfg if done so.
+ (execute_pre): Return todo.
+ (do_pre): Likewise.
+ (execute_fre): Likewise.
+ * tree-ssa-forwprop.c (can_propagate_from): Allow propagation
+ of constants.
+ (get_prop_source_stmt): Look through pointer conversions.
+
2008-03-18 Jan Hubicka <jh@suse.cz>
* tree-pretty-print.c: Include predict.h.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d5543830532..d9bca3944e0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2008-03-18 Richard Guenther <rguenther@suse.de>
+ * gcc.dg/tree-ssa/forwprop-4.c: New testcase.
+ * gcc.dg/tree-ssa/ssa-fre-16.c: Likewise.
+
+2008-03-18 Richard Guenther <rguenther@suse.de>
+
* gcc.dg/tree-ssa/loop-19.c: Revert previous change.
2008-03-17 Jerry DeLisle <jvdelisle@gcc.gnu.org>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-4.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-4.c
new file mode 100644
index 00000000000..7eabd1a7bd8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-4.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop1" } */
+
+/* We should be able to fold the comparison at least with the
+ first forwprop pass, if not a ccp pass before. */
+
+extern void link_error (void);
+void foo()
+{
+ int i;
+ char *p = (char *)&i;
+ long *q = (long *)p;
+ if (q == 0)
+ link_error ();
+}
+
+/* { dg-final { scan-tree-dump-not "link_error" "forwprop1" } } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-16.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-16.c
new file mode 100644
index 00000000000..56d85e58e7f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-16.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre" } */
+
+/* FRE should be able to combine i and j and perform simplification
+ on the condition. */
+
+extern void link_error (void);
+int i;
+int foo(int b, int c)
+{
+ i = b + 1;
+ int j = i - 1;
+ if (b != j)
+ link_error ();
+}
+
+/* { dg-final { scan-tree-dump-not "link_error" "fre" } } */
+/* { dg-final { cleanup-tree-dump "fre" } } */
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 5108cfcd6f2..1766869d0c4 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -218,14 +218,28 @@ get_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p)
/* If name is not a simple copy destination, we found it. */
if (TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1)) != SSA_NAME)
{
+ tree rhs;
+
if (!single_use_only && single_use_p)
*single_use_p = single_use;
- return def_stmt;
+ /* We can look through pointer conversions in the search
+ for a useful stmt for the comparison folding. */
+ rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
+ if ((TREE_CODE (rhs) == NOP_EXPR
+ || TREE_CODE (rhs) == CONVERT_EXPR)
+ && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
+ && POINTER_TYPE_P (TREE_TYPE (rhs))
+ && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0))))
+ name = TREE_OPERAND (rhs, 0);
+ else
+ return def_stmt;
+ }
+ else
+ {
+ /* Continue searching the def of the copy source name. */
+ name = GIMPLE_STMT_OPERAND (def_stmt, 1);
}
-
- /* Continue searching the def of the copy source name. */
- name = GIMPLE_STMT_OPERAND (def_stmt, 1);
} while (1);
}
@@ -245,6 +259,10 @@ can_propagate_from (tree def_stmt)
if (REFERENCE_CLASS_P (rhs))
return false;
+ /* Constants can be always propagated. */
+ if (is_gimple_min_invariant (rhs))
+ return true;
+
/* We cannot propagate ssa names that occur in abnormal phi nodes. */
switch (TREE_CODE_LENGTH (TREE_CODE (rhs)))
{
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 616627ccb1b..ad628a31916 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -3605,10 +3605,11 @@ do_SCCVN_insertion (tree stmt, tree ssa_vn)
/* Eliminate fully redundant computations. */
-static void
+static unsigned int
eliminate (void)
{
basic_block b;
+ unsigned int todo = 0;
FOR_EACH_BB (b)
{
@@ -3689,8 +3690,46 @@ eliminate (void)
}
}
}
+ /* Visit COND_EXPRs and fold the comparison with the
+ available value-numbers. */
+ else if (TREE_CODE (stmt) == COND_EXPR
+ && COMPARISON_CLASS_P (COND_EXPR_COND (stmt)))
+ {
+ tree cond = COND_EXPR_COND (stmt);
+ tree op0 = TREE_OPERAND (cond, 0);
+ tree op1 = TREE_OPERAND (cond, 1);
+ tree result;
+
+ if (TREE_CODE (op0) == SSA_NAME)
+ op0 = VN_INFO (op0)->valnum;
+ if (TREE_CODE (op1) == SSA_NAME)
+ op1 = VN_INFO (op1)->valnum;
+ result = fold_binary (TREE_CODE (cond), TREE_TYPE (cond),
+ op0, op1);
+ if (result && TREE_CODE (result) == INTEGER_CST)
+ {
+ COND_EXPR_COND (stmt) = result;
+ update_stmt (stmt);
+ todo = TODO_cleanup_cfg;
+ }
+ }
+ else if (TREE_CODE (stmt) == COND_EXPR
+ && TREE_CODE (COND_EXPR_COND (stmt)) == SSA_NAME)
+ {
+ tree op = COND_EXPR_COND (stmt);
+ op = VN_INFO (op)->valnum;
+ if (TREE_CODE (op) == INTEGER_CST)
+ {
+ COND_EXPR_COND (stmt) = integer_zerop (op)
+ ? boolean_false_node : boolean_true_node;
+ update_stmt (stmt);
+ todo = TODO_cleanup_cfg;
+ }
+ }
}
}
+
+ return todo;
}
/* Borrow a bit of tree-ssa-dce.c for the moment.
@@ -3931,9 +3970,10 @@ fini_pre (void)
/* Main entry point to the SSA-PRE pass. DO_FRE is true if the caller
only wants to do full redundancy elimination. */
-static void
+static unsigned int
execute_pre (bool do_fre)
{
+ unsigned int todo = 0;
do_partial_partial = optimize > 2;
init_pre (do_fre);
@@ -3947,7 +3987,7 @@ execute_pre (bool do_fre)
if (!do_fre)
remove_dead_inserted_code ();
fini_pre ();
- return;
+ return 0;
}
switch_to_PRE_table ();
compute_avail ();
@@ -3978,7 +4018,7 @@ execute_pre (bool do_fre)
}
/* Remove all the redundant expressions. */
- eliminate ();
+ todo |= eliminate ();
if (dump_file && (dump_flags & TDF_STATS))
{
@@ -3999,6 +4039,8 @@ execute_pre (bool do_fre)
}
fini_pre ();
+
+ return todo;
}
/* Gate and execute functions for PRE. */
@@ -4006,8 +4048,7 @@ execute_pre (bool do_fre)
static unsigned int
do_pre (void)
{
- execute_pre (false);
- return TODO_rebuild_alias;
+ return TODO_rebuild_alias | execute_pre (false);
}
static bool
@@ -4041,8 +4082,7 @@ struct tree_opt_pass pass_pre =
static unsigned int
execute_fre (void)
{
- execute_pre (true);
- return 0;
+ return execute_pre (true);
}
static bool
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index b10d3e31a85..b613b2ba21f 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1251,6 +1251,12 @@ visit_reference_op_load (tree lhs, tree op, tree stmt)
if (result)
{
changed = set_ssa_val_to (lhs, result);
+ if (TREE_CODE (result) == SSA_NAME
+ && VN_INFO (result)->has_constants)
+ {
+ VN_INFO (lhs)->expr = VN_INFO (result)->expr;
+ VN_INFO (lhs)->has_constants = true;
+ }
}
else
{