This refactors the code I added to fold_stmt to dispatch to
pattern-based folding to avoid long lines and make error
handling easier (no goto).  It also uses the newly introduced
gimple_seq_discard to properly discard an unused simplification
result.

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

This piece will land in trunk with the next merge piece.

Richard.

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

        * gimple-fold.c (replace_stmt_with_simplification): New helper
        split out from ...
        (fold_stmt_1): ... here.  Discard the simplified sequence if
        replacement failed.

Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c   (revision 216505)
+++ gcc/gimple-fold.c   (working copy)
@@ -2794,6 +2794,121 @@ gimple_fold_call (gimple_stmt_iterator *
   return changed;
 }
 
+
+/* Worker for fold_stmt_1 dispatch to pattern based folding with
+   gimple_simplify.
+
+   Replaces *GSI with the simplification result in RCODE and OPS
+   and the associated statements in *SEQ.  Does the replacement
+   according to INPLACE and returns true if the operation succeeded.  */
+
+static bool
+replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
+                                 code_helper rcode, tree *ops,
+                                 gimple_seq *seq, bool inplace)
+{
+  gimple stmt = gsi_stmt (*gsi);
+
+  /* Play safe and do not allow abnormals to be mentioned in
+     newly created statements.  See also maybe_push_res_to_seq.  */
+  if ((TREE_CODE (ops[0]) == SSA_NAME
+       && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
+      || (ops[1]
+         && TREE_CODE (ops[1]) == SSA_NAME
+         && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
+      || (ops[2]
+         && TREE_CODE (ops[2]) == SSA_NAME
+         && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
+    return false;
+
+  if (gimple_code (stmt) == GIMPLE_COND)
+    {
+      gcc_assert (rcode.is_tree_code ());
+      if (TREE_CODE_CLASS ((enum tree_code)rcode) == tcc_comparison
+         /* GIMPLE_CONDs condition may not throw.  */
+         && (!flag_exceptions
+             || !cfun->can_throw_non_call_exceptions
+             || !operation_could_trap_p (rcode,
+                                         FLOAT_TYPE_P (TREE_TYPE (ops[0])),
+                                         false, NULL_TREE)))
+       gimple_cond_set_condition (stmt, rcode, ops[0], ops[1]);
+      else if (rcode == SSA_NAME)
+       gimple_cond_set_condition (stmt, NE_EXPR, ops[0],
+                                  build_zero_cst (TREE_TYPE (ops[0])));
+      else if (rcode == INTEGER_CST)
+       {
+         if (integer_zerop (ops[0]))
+           gimple_cond_make_false (stmt);
+         else
+           gimple_cond_make_true (stmt);
+       }
+      else if (!inplace)
+       {
+         tree res = maybe_push_res_to_seq (rcode, boolean_type_node,
+                                           ops, seq);
+         if (!res)
+           return false;
+         gimple_cond_set_condition (stmt, NE_EXPR, res,
+                                    build_zero_cst (TREE_TYPE (res)));
+       }
+      else
+       return false;
+      if (dump_file && (dump_flags & TDF_DETAILS))
+       {
+         fprintf (dump_file, "gimple_simplified to ");
+         if (!gimple_seq_empty_p (*seq))
+           print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
+         print_gimple_stmt (dump_file, gsi_stmt (*gsi),
+                            0, TDF_SLIM);
+       }
+      gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
+      return true;
+    }
+  else if (is_gimple_assign (stmt)
+          && rcode.is_tree_code ())
+    {
+      if (!inplace
+         || gimple_num_ops (stmt) <= get_gimple_rhs_num_ops (rcode))
+       {
+         maybe_build_generic_op (rcode,
+                                 TREE_TYPE (gimple_assign_lhs (stmt)),
+                                 &ops[0], ops[1], ops[2]);
+         gimple_assign_set_rhs_with_ops_1 (gsi, rcode,
+                                           ops[0], ops[1], ops[2]);
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           {
+             fprintf (dump_file, "gimple_simplified to ");
+             if (!gimple_seq_empty_p (*seq))
+               print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
+             print_gimple_stmt (dump_file, gsi_stmt (*gsi),
+                                0, TDF_SLIM);
+           }
+         gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
+         return true;
+       }
+    }
+  else if (!inplace)
+    {
+      if (gimple_has_lhs (stmt))
+       {
+         tree lhs = gimple_get_lhs (stmt);
+         maybe_push_res_to_seq (rcode, TREE_TYPE (lhs),
+                                ops, seq, lhs);
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           {
+             fprintf (dump_file, "gimple_simplified to ");
+             print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
+           }
+         gsi_replace_with_seq_vops (gsi, *seq);
+         return true;
+       }
+      else
+       gcc_unreachable ();
+    }
+
+  return false;
+}
+
 /* Canonicalize MEM_REFs invariant address operand after propagation.  */
 
 static bool
@@ -2959,9 +3074,6 @@ fold_stmt_1 (gimple_stmt_iterator *gsi,
     }
 
   /* Dispatch to pattern-based folding.  */
-  /* ???  Change "inplace" semantics to allow replacing a stmt if
-     no further stmts need to be inserted (basically disallow
-     creating of new SSA names).  */
   if (!inplace
       || is_gimple_assign (stmt)
       || gimple_code (stmt) == GIMPLE_COND)
@@ -2971,108 +3083,10 @@ fold_stmt_1 (gimple_stmt_iterator *gsi,
       tree ops[3] = {};
       if (gimple_simplify (stmt, &rcode, ops, inplace ? NULL : &seq, valueize))
        {
-         if (gimple_code (stmt) == GIMPLE_COND)
-           {
-             gcc_assert (rcode.is_tree_code ());
-             if (TREE_CODE_CLASS ((enum tree_code)rcode) == tcc_comparison
-                 /* GIMPLE_CONDs condition may not throw.  */
-                 /* ???  Not sure how we want to deal with combining
-                    from possibly throwing statements.  Trivial
-                    simplifications may lead to DCEing an internal
-                    throw.  But we probably still want to simplify
-                    things to a constant for example?  Similar to
-                    abnormals we could discard the simplification
-                    result if we ever push a could-throw stmt to
-                    the sequence.  */
-                 && (!flag_exceptions
-                     || !cfun->can_throw_non_call_exceptions
-                     || !operation_could_trap_p (rcode, FLOAT_TYPE_P 
(TREE_TYPE (ops[0])), false, NULL_TREE)))
-               gimple_cond_set_condition (stmt, rcode, ops[0], ops[1]);
-             else if (rcode == SSA_NAME)
-               gimple_cond_set_condition (stmt, NE_EXPR, ops[0],
-                                          build_zero_cst (TREE_TYPE (ops[0])));
-             else if (rcode == INTEGER_CST)
-               {
-                 if (integer_zerop (ops[0]))
-                   gimple_cond_make_false (stmt);
-                 else
-                   gimple_cond_make_true (stmt);
-               }
-             else if (!inplace)
-               {
-                 tree res = maybe_push_res_to_seq (rcode, boolean_type_node,
-                                                   ops, &seq);
-                 if (!res)
-                   goto fail;
-                 gimple_cond_set_condition (stmt, NE_EXPR, res,
-                                            build_zero_cst (TREE_TYPE (res)));
-               }
-             else
-               goto fail;
-             if (dump_file && (dump_flags & TDF_DETAILS))
-               {
-                 fprintf (dump_file, "gimple_simplified to ");
-                 if (!gimple_seq_empty_p (seq))
-                   print_gimple_seq (dump_file, seq, 0, TDF_SLIM);
-                 print_gimple_stmt (dump_file, gsi_stmt (*gsi),
-                                    0, TDF_SLIM);
-               }
-             gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
-             changed = true;
-fail:
-             ;
-           }
-         else if (is_gimple_assign (stmt)
-                  && rcode.is_tree_code ())
-           {
-             if ((!inplace
-                  || gimple_num_ops (stmt) <= get_gimple_rhs_num_ops (rcode))
-                 /* Play safe and do not allow abnormals to be mentioned in
-                    newly created statements.  */
-                 && !((TREE_CODE (ops[0]) == SSA_NAME
-                       && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
-                      || (ops[1]
-                          && TREE_CODE (ops[1]) == SSA_NAME
-                          && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
-                      || (ops[2]
-                          && TREE_CODE (ops[2]) == SSA_NAME
-                          && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2]))))
-               {
-                 maybe_build_generic_op (rcode,
-                                         TREE_TYPE (gimple_assign_lhs (stmt)),
-                                         &ops[0], ops[1], ops[2]);
-                 gimple_assign_set_rhs_with_ops_1 (gsi, rcode,
-                                                   ops[0], ops[1], ops[2]);
-                 if (dump_file && (dump_flags & TDF_DETAILS))
-                   {
-                     fprintf (dump_file, "gimple_simplified to ");
-                     if (!gimple_seq_empty_p (seq))
-                       print_gimple_seq (dump_file, seq, 0, TDF_SLIM);
-                     print_gimple_stmt (dump_file, gsi_stmt (*gsi),
-                                        0, TDF_SLIM);
-                   }
-                 gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
-                 changed = true;
-               }
-           }
-         else if (!inplace)
-           {
-             if (gimple_has_lhs (stmt))
-               {
-                 tree lhs = gimple_get_lhs (stmt);
-                 maybe_push_res_to_seq (rcode, TREE_TYPE (lhs),
-                                        ops, &seq, lhs);
-                 if (dump_file && (dump_flags & TDF_DETAILS))
-                   {
-                     fprintf (dump_file, "gimple_simplified to ");
-                     print_gimple_seq (dump_file, seq, 0, TDF_SLIM);
-                   }
-                 gsi_replace_with_seq_vops (gsi, seq);
-                 changed = true;
-               }
-             else
-               gcc_unreachable ();
-           }
+         if (replace_stmt_with_simplification (gsi, rcode, ops, &seq, inplace))
+           changed = true;
+         else
+           gimple_seq_discard (seq);
        }
     }
 

Reply via email to