tree-ssa-sccvn.c (visit_reference_op_load): If the lookup found an expression with...
authorRichard Guenther <rguenther@suse.de>
Tue, 18 Mar 2008 16:10:24 +0000 (16:10 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 18 Mar 2008 16:10:24 +0000 (16:10 +0000)
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.

From-SVN: r133315

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/forwprop-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-16.c [new file with mode: 0644]
gcc/tree-ssa-forwprop.c
gcc/tree-ssa-pre.c
gcc/tree-ssa-sccvn.c

index 823742584112a4b0c0f79b78240fe4f36cc4dadf..add3e25ad86b821e1498bcdfd0e11ab3035270b7 100644 (file)
@@ -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.
index d5543830532554aac34b5c752ce14dd90cce9508..d9bca3944e0f01c262af76e510fb3e6e93a0021f 100644 (file)
@@ -1,3 +1,8 @@
+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.
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 (file)
index 0000000..7eabd1a
--- /dev/null
@@ -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 (file)
index 0000000..56d85e5
--- /dev/null
@@ -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" } } */
index 5108cfcd6f20646dbacfcd0c6aab50650a439883..1766869d0c46e19e512d1b4207478347caf0f057 100644 (file)
@@ -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)))
     {
index 616627ccb1bea46b8bea3d2eb632474142b67124..ad628a3191600bcf754f5291b543aff0da552bcc 100644 (file)
@@ -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
index b10d3e31a85dadf465d889b522afa6e51f55fc89..b613b2ba21fbecaa765e5548208568404801b49b 100644 (file)
@@ -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
     {