gimple-fold.h (gimple_fold_stmt_to_constant_1): Add 2nd valueization hook defaulted...
authorRichard Biener <rguenther@suse.de>
Fri, 14 Nov 2014 13:32:56 +0000 (13:32 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 14 Nov 2014 13:32:56 +0000 (13:32 +0000)
2014-11-14  Richard Biener  <rguenther@suse.de>

* gimple-fold.h (gimple_fold_stmt_to_constant_1): Add 2nd
valueization hook defaulted to no_follow_ssa_edges.
* gimple-fold.c (gimple_fold_stmt_to_constant_1): Pass
2nd valueization hook to gimple_simplify.
* tree-ssa-ccp.c (valueize_op_1): New function to be
used for gimple_simplify called via gimple_fold_stmt_to_constant_1.
(ccp_fold): Adjust.
* tree-vrp.c (vrp_valueize_1): New function to be
used for gimple_simplify called via gimple_fold_stmt_to_constant_1.
(vrp_visit_assignment_or_call): Adjust.

From-SVN: r217560

gcc/ChangeLog
gcc/gimple-fold.c
gcc/gimple-fold.h
gcc/tree-ssa-ccp.c
gcc/tree-vrp.c

index 976dd3bf51dabe3434d54fcbf82853b4310849e8..7a1a54aac5c59f225fdaf61448730e699945ac67 100644 (file)
@@ -1,3 +1,16 @@
+2014-11-14  Richard Biener  <rguenther@suse.de>
+
+       * gimple-fold.h (gimple_fold_stmt_to_constant_1): Add 2nd
+       valueization hook defaulted to no_follow_ssa_edges.
+       * gimple-fold.c (gimple_fold_stmt_to_constant_1): Pass
+       2nd valueization hook to gimple_simplify.
+       * tree-ssa-ccp.c (valueize_op_1): New function to be
+       used for gimple_simplify called via gimple_fold_stmt_to_constant_1.
+       (ccp_fold): Adjust.
+       * tree-vrp.c (vrp_valueize_1): New function to be
+       used for gimple_simplify called via gimple_fold_stmt_to_constant_1.
+       (vrp_visit_assignment_or_call): Adjust.
+
 2014-11-14  Marek Polacek  <polacek@redhat.com>
 
        * fold-const.c (fold_negate_expr): Don't fold INTEGER_CST if
index aeb180370d8185903cca2676e046462de1eb37ad..acdadcd88272229d75ddf7e9c2a81a5eebfed969 100644 (file)
@@ -4467,7 +4467,8 @@ maybe_fold_or_comparisons (enum tree_code code1, tree op1a, tree op1b,
    to avoid the indirect function call overhead.  */
 
 tree
-gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
+gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree),
+                               tree (*gvalueize) (tree))
 {
   code_helper rcode;
   tree ops[3] = {};
@@ -4475,7 +4476,7 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
      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)
+  if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize)
       && rcode.is_tree_code ()
       && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
          || ((tree_code) rcode) == ADDR_EXPR)
index f42ff0264e34177e46e62dfb87fc42d25eba380d..a38848f3396c0107b7bfd6a950dd15e54a0cd96a 100644 (file)
@@ -36,7 +36,8 @@ extern bool arith_overflowed_p (enum tree_code, const_tree, const_tree,
                                const_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_1 (gimple, tree (*) (tree),
+                                           tree (*) (tree) = no_follow_ssa_edges);
 extern tree gimple_fold_stmt_to_constant (gimple, tree (*) (tree));
 extern tree fold_const_aggregate_ref_1 (tree, tree (*) (tree));
 extern tree fold_const_aggregate_ref (tree);
index 31ca0e120e3e70f0f9e7e3b3ec15f4866b2a066a..b3efa99f6f65dd54e1ae6e0e392378087f1b9c18 100644 (file)
@@ -1126,6 +1126,27 @@ valueize_op (tree op)
   return op;
 }
 
+/* Return the constant value for OP, but signal to not follow SSA
+   edges if the definition may be simulated again.  */
+
+static tree
+valueize_op_1 (tree op)
+{
+  if (TREE_CODE (op) == SSA_NAME)
+    {
+      tree tem = get_constant_value (op);
+      if (tem)
+       return tem;
+      /* If the definition may be simulated again we cannot follow
+         this SSA edge as the SSA propagator does not necessarily
+        re-visit the use.  */
+      gimple def_stmt = SSA_NAME_DEF_STMT (op);
+      if (prop_simulate_again_p (def_stmt))
+       return NULL_TREE;
+    }
+  return op;
+}
+
 /* CCP specific front-end to the non-destructive constant folding
    routines.
 
@@ -1158,7 +1179,8 @@ ccp_fold (gimple stmt)
 
     case GIMPLE_ASSIGN:
     case GIMPLE_CALL:
-      return gimple_fold_stmt_to_constant_1 (stmt, valueize_op);
+      return gimple_fold_stmt_to_constant_1 (stmt,
+                                            valueize_op, valueize_op_1);
 
     default:
       gcc_unreachable ();
index b2872828334b86aedc05c1eb904b94e3de86cc7d..13b7c791eea5388a862d872e04235c1a301be1c7 100644 (file)
@@ -7025,6 +7025,27 @@ vrp_valueize (tree name)
   return name;
 }
 
+/* Return the singleton value-range for NAME if that is a constant
+   but signal to not follow SSA edges.  */
+
+static inline tree
+vrp_valueize_1 (tree name)
+{
+  if (TREE_CODE (name) == SSA_NAME)
+    {
+      value_range_t *vr = get_value_range (name);
+      if (range_int_cst_singleton_p (vr))
+       return vr->min;
+      /* If the definition may be simulated again we cannot follow
+         this SSA edge as the SSA propagator does not necessarily
+        re-visit the use.  */
+      gimple def_stmt = SSA_NAME_DEF_STMT (name);
+      if (prop_simulate_again_p (def_stmt))
+       return NULL_TREE;
+    }
+  return name;
+}
+
 /* Visit assignment STMT.  If it produces an interesting range, record
    the SSA name in *OUTPUT_P.  */
 
@@ -7048,8 +7069,9 @@ vrp_visit_assignment_or_call (gimple stmt, tree *output_p)
       value_range_t new_vr = VR_INITIALIZER;
 
       /* Try folding the statement to a constant first.  */
-      tree tem = gimple_fold_stmt_to_constant (stmt, vrp_valueize);
-      if (tem)
+      tree tem = gimple_fold_stmt_to_constant_1 (stmt, vrp_valueize,
+                                                vrp_valueize_1);
+      if (tem && is_gimple_min_invariant (tem))
        set_value_range_to_value (&new_vr, tem, NULL);
       /* Then dispatch to value-range extracting functions.  */
       else if (code == GIMPLE_CALL)