This PR shows another defect in path-splittings cost model which the
following patch tries to improve further.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2017-02-23  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/79389
        * gimple-ssa-split-paths.c (is_feasible_trace): Verify more
        properly that a threading opportunity exists.  Detect conditional
        copy/constant propagation opportunities.

        * gcc.dg/tree-ssa/split-path-10.c: New testcase.

Index: gcc/testsuite/gcc.dg/tree-ssa/split-path-10.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/split-path-10.c       (nonexistent)
+++ gcc/testsuite/gcc.dg/tree-ssa/split-path-10.c       (working copy)
@@ -0,0 +1,49 @@
+/* PR tree-optimization/79389  */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-split-paths-details" } */
+
+typedef struct
+{
+  int m[17];                        
+  int seed;                             
+  int i;
+  int j;
+  int haveRange;
+  double left;
+  double right;
+  double width;
+}
+Random_struct, *Random;
+
+Random new_Random_seed(int seed);
+double Random_nextDouble(Random R);
+void Random_delete(Random R);
+
+static const int SEED = 113;
+
+double MonteCarlo_integrate(int Num_samples)
+{
+
+
+  Random R = new_Random_seed(SEED);
+
+
+  int under_curve = 0;
+  int count;
+
+  for (count=0; count<Num_samples; count++)
+    {
+      double x= Random_nextDouble(R);
+      double y= Random_nextDouble(R);
+
+      if ( x*x + y*y <= 1.0)
+       under_curve ++;
+
+    }
+
+  Random_delete(R);
+
+  return ((double) under_curve / Num_samples) * 4.0;
+}
+
+/* { dg-final { scan-tree-dump-times "Duplicating join block" 0 "split-paths" 
} } */
Index: gcc/gimple-ssa-split-paths.c
===================================================================
--- gcc/gimple-ssa-split-paths.c        (revision 245681)
+++ gcc/gimple-ssa-split-paths.c        (working copy)
@@ -232,12 +232,32 @@ is_feasible_trace (basic_block bb)
              /* But for memory the PHI alone isn't good enough.  */
              && ! virtual_operand_p (gimple_phi_result (stmt)))
            {
+             bool found_unchanged_path = false;
              for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
                if (gimple_phi_arg_def (phi, i) == gimple_phi_result (stmt))
                  {
-                   found_useful_phi = true;
+                   found_unchanged_path = true;
                    break;
                  }
+             /* If we found an unchanged path this can only be a threading
+                opportunity if we have uses of the loop header PHI result
+                in a stmt dominating the merge block.  Otherwise the
+                splitting may prevent if-conversion.  */
+             if (found_unchanged_path)
+               {
+                 use_operand_p use2_p;
+                 imm_use_iterator iter2;
+                 FOR_EACH_IMM_USE_FAST (use2_p, iter2, gimple_phi_result 
(stmt))
+                   {
+                     basic_block use_bb = gimple_bb (USE_STMT (use2_p));
+                     if (use_bb != bb
+                         && dominated_by_p (CDI_DOMINATORS, bb, use_bb))
+                       {
+                         found_useful_phi = true;
+                         break;
+                       }
+                   }
+               }
              if (found_useful_phi)
                break;
            }
@@ -245,7 +265,32 @@ is_feasible_trace (basic_block bb)
       if (found_useful_phi)
        break;
     }
-  if (! found_useful_phi)
+  /* There is one exception namely a controlling condition we can propagate
+     an equivalence from to the joiner.  */
+  bool found_cprop_opportunity = false;
+  basic_block dom = get_immediate_dominator (CDI_DOMINATORS, bb);
+  gcond *cond = as_a <gcond *> (last_stmt (dom));
+  if (gimple_cond_code (cond) == EQ_EXPR
+      || gimple_cond_code (cond) == NE_EXPR)
+    for (unsigned i = 0; i < 2; ++i)
+      {
+       tree op = gimple_op (cond, i);
+       if (TREE_CODE (op) == SSA_NAME)
+         {
+           use_operand_p use_p;
+           imm_use_iterator iter;
+           FOR_EACH_IMM_USE_FAST (use_p, iter, op)
+             if (gimple_bb (USE_STMT (use_p)) == bb)
+               {
+                 found_cprop_opportunity = true;
+                 break;
+               }
+         }
+       if (found_cprop_opportunity)
+         break;
+      }
+
+  if (! found_useful_phi && ! found_cprop_opportunity)
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file,

Reply via email to