diff mbox

PR79389, path-splitting

Message ID alpine.LSU.2.20.1702231621150.8538@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Feb. 23, 2017, 3:22 p.m. UTC
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  <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.
diff mbox

Patch

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,