The following hooks the machinery into SSA propagators via
gimple_fold_stmt_to_constant[_1].  Unfortunately how SSA
propagators work doesn't allow us to walk SSA edges here
so to compensate for that shortcoming I am following
single-use SSA edges when substitute_and_fold calls fold_stmt
(as explained previously that doesn't necessarily fold all
stmts that are worth folding).

SCCVN on the other hand could deal fine with walking SSA
edges, but that's for another day (and maybe only next stage1).

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

(yeah, I hope that any of these patches make the AIX bootstrap
issue go latent again... - meanwhile trying to debug them
at the known failure point)

Richard.

2014-10-28  Richard Biener  <rguent...@suse.de>

        * gimple-fold.h (follow_single_use_edges): Declare.
        * gimple-fold.c (follow_single_use_edges): New function.
        (gimple_fold_stmt_to_constant_1): Dispatch to gimple_simplify.
        * tree-ssa-propagate.c
        (substitute_and_fold_dom_walker::before_dom_children): Allow
        following single-use edges when folding stmts we propagated into.

Index: gcc/gimple-fold.h
===================================================================
--- gcc/gimple-fold.h   
(svn+ssh://rgue...@gcc.gnu.org/svn/gcc/trunk/gcc/gimple-fold.h) (revision 
216771)
+++ gcc/gimple-fold.h   (.../gcc/gimple-fold.h) (working copy)
@@ -33,6 +33,7 @@ extern tree maybe_fold_and_comparisons (
 extern tree maybe_fold_or_comparisons (enum tree_code, tree, tree,
                                       enum tree_code, tree, tree);
 extern tree no_follow_ssa_edges (tree);
+extern tree follow_single_use_edges (tree);
 extern tree gimple_fold_stmt_to_constant_1 (gimple, tree (*) (tree));
 extern tree gimple_fold_stmt_to_constant (gimple, tree (*) (tree));
 extern tree fold_const_aggregate_ref_1 (tree, tree (*) (tree));
Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c   
(svn+ssh://rgue...@gcc.gnu.org/svn/gcc/trunk/gcc/gimple-fold.c) (revision 
216771)
+++ gcc/gimple-fold.c   (.../gcc/gimple-fold.c) (working copy)
@@ -65,6 +65,8 @@ along with GCC; see the file COPYING3.
 #include "output.h"
 #include "tree-eh.h"
 #include "gimple-match.h"
+#include "tree-phinodes.h"
+#include "ssa-iterators.h"
 
 /* Return true when DECL can be referenced from current unit.
    FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
@@ -3241,6 +3243,17 @@ no_follow_ssa_edges (tree)
   return NULL_TREE;
 }
 
+/* Valueization callback that ends up following single-use SSA edges only.  */
+
+tree
+follow_single_use_edges (tree val)
+{
+  if (TREE_CODE (val) == SSA_NAME
+      && !has_single_use (val))
+    return NULL_TREE;
+  return val;
+}
+
 /* Fold the statement pointed to by GSI.  In some cases, this function may
    replace the whole statement with a new one.  Returns true iff folding
    makes any changes.
@@ -4371,6 +4384,30 @@ maybe_fold_or_comparisons (enum tree_cod
 tree
 gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
 {
+  code_helper rcode;
+  tree ops[3] = {};
+  /* ???  The SSA propagators do not correctly deal with following SSA use-def
+     edges if there are intermediate VARYING defs.  For this reason
+     do not follow SSA edges here even though SCCVN can technically
+     just deal fine with that.  */
+  if (gimple_simplify (stmt, &rcode, ops, NULL, no_follow_ssa_edges)
+      && rcode.is_tree_code ()
+      && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
+         || ((tree_code) rcode) == ADDR_EXPR)
+      && is_gimple_val (ops[0]))
+    {
+      tree res = ops[0];
+      if (dump_file && dump_flags & TDF_DETAILS)
+       {
+         fprintf (dump_file, "Match-and-simplified ");
+         print_gimple_expr (dump_file, stmt, 0, TDF_SLIM);
+         fprintf (dump_file, " to ");
+         print_generic_expr (dump_file, res, 0);
+         fprintf (dump_file, "\n");
+       }
+      return res;
+    }
+
   location_t loc = gimple_location (stmt);
   switch (gimple_code (stmt))
     {
Index: gcc/tree-ssa-propagate.c
===================================================================
--- gcc/tree-ssa-propagate.c    
(svn+ssh://rgue...@gcc.gnu.org/svn/gcc/trunk/gcc/tree-ssa-propagate.c)  
(revision 216771)
+++ gcc/tree-ssa-propagate.c    (.../gcc/tree-ssa-propagate.c)  (working copy)
@@ -1150,7 +1150,7 @@ substitute_and_fold_dom_walker::before_d
 
       /* If we made a replacement, fold the statement.  */
       if (did_replace)
-       fold_stmt (&i);
+       fold_stmt (&i, follow_single_use_edges);
 
       /* Now cleanup.  */
       if (did_replace)

Reply via email to