re PR tree-optimization/79389 (30% performance regression in SciMark2 MonteCarlo)
authorRichard Biener <rguenther@suse.de>
Fri, 24 Feb 2017 08:04:31 +0000 (08:04 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 24 Feb 2017 08:04:31 +0000 (08:04 +0000)
2017-02-24  Richard Biener  <rguenther@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.

From-SVN: r245696

gcc/ChangeLog
gcc/gimple-ssa-split-paths.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/split-path-10.c [new file with mode: 0644]

index 68cd88f1ff203b1586d1ff233d4124992685a4f3..f90686c2d98914adc36d78d33515d6e5fe65b72c 100644 (file)
@@ -1,3 +1,10 @@
+2017-02-24  Richard Biener  <rguenther@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.
+
 2017-02-23  Eric Botcazou  <ebotcazou@adacore.com>
 
        * config/visium/visium.md (type): Add trap.
index f1bf7ec604c0d0ce41cc329ab36c7267040c2e04..0f6b2417d2c0b0237e46cfdfe400e6e204995d31 100644 (file)
@@ -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,
index 6efe58d151dbe741884cb3ef1a04349e8aca6d4f..6b62ae8dc0eb25bbf8e9d78c1edd102f7dcd5fd2 100644 (file)
@@ -1,3 +1,8 @@
+2017-02-24  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/79389
+       * gcc.dg/tree-ssa/split-path-10.c: New testcase.
+
 2017-02-23  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/79361
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-10.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-10.c
new file mode 100644 (file)
index 0000000..ed20879
--- /dev/null
@@ -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" } } */