This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [fix] PR39300: make PRE not disturb vectorizer


Hi,

On Tue, 21 Jul 2009, Richard Guenther wrote:

> IMHO the performance numbers speak for themselves.  Can you re-check 
> with the above change (and also throw it onto the C++ tester once) and 
> add a vectorization testcase as HJ suggests?

I did the requested changes, regstrapped without regression.  The c++ 
tester and spec2000 are unimpressed by the patch, except applu, which 
regressed on the testrun, but I can't reproduce any regression, so it 
hopefully was just a hickup on the machine.

> Ok with that changes.

Checked in a r149942.  For reference the patch is below.  (I included 
-ftree-pre explicitely in the dg-options in case anybody would like to 
"fix" a problem by removing PRE from -O3 ).


Ciao,
Michael.
-- 
	PR tree-optimization/35229
	PR tree-optimization/39300

	* tree-ssa-pre.c (includes): Include tree-scalar-evolution.h.
	(inhibit_phi_insertion): New function.
	(insert_into_preds_of_block): Call it for REFERENCEs.
	(init_pre): Initialize and finalize scalar evolutions.
	* Makefile.in (tree-ssa-pre.o): Depend on tree-scalar-evolution.h .

testsuite/
	* gcc.dg/vect/vect-pre-interact.c: New test.

Index: Makefile.in
===================================================================
--- Makefile.in	(revision 149941)
+++ Makefile.in	(working copy)
@@ -2248,7 +2248,7 @@ tree-ssa-pre.o : tree-ssa-pre.c $(TREE_F
    $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(FLAGS_H) langhooks.h \
    $(CFGLOOP_H) alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASHTAB_H) \
    $(GIMPLE_H) $(TREE_INLINE_H) tree-iterator.h tree-ssa-sccvn.h $(PARAMS_H) \
-   $(DBGCNT_H)
+   $(DBGCNT_H) tree-scalar-evolution.h
 tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \
    $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(FIBHEAP_H) \
    $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(FLAGS_H) $(CFGLOOP_H) \
Index: tree-ssa-pre.c
===================================================================
--- tree-ssa-pre.c	(revision 149941)
+++ tree-ssa-pre.c	(working copy)
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.
 #include "langhooks.h"
 #include "cfgloop.h"
 #include "tree-ssa-sccvn.h"
+#include "tree-scalar-evolution.h"
 #include "params.h"
 #include "dbgcnt.h"
 
@@ -3081,6 +3082,62 @@ create_expression_by_pieces (basic_block
 }
 
 
+/* Returns true if we want to inhibit the insertions of PHI nodes
+   for the given EXPR for basic block BB (a member of a loop).
+   We want to do this, when we fear that the induction variable we
+   create might inhibit vectorization.  */
+
+static bool
+inhibit_phi_insertion (basic_block bb, pre_expr expr)
+{
+  vn_reference_t vr = PRE_EXPR_REFERENCE (expr);
+  VEC (vn_reference_op_s, heap) *ops = vr->operands;
+  vn_reference_op_t op;
+  unsigned i;
+
+  /* If we aren't going to vectorize we don't inhibit anything.  */
+  if (!flag_tree_vectorize)
+    return false;
+
+  /* Otherwise we inhibit the insertion when the address of the
+     memory reference is a simple induction variable.  In other
+     cases the vectorizer won't do anything anyway (either it's
+     loop invariant or a complicated expression).  */
+  for (i = 0; VEC_iterate (vn_reference_op_s, ops, i, op); ++i)
+    {
+      switch (op->opcode)
+	{
+	case ARRAY_REF:
+	case ARRAY_RANGE_REF:
+	  if (TREE_CODE (op->op0) != SSA_NAME)
+	    break;
+	  /* Fallthru.  */
+	case SSA_NAME:
+	  {
+	    basic_block defbb = gimple_bb (SSA_NAME_DEF_STMT (op->op0));
+	    affine_iv iv;
+	    /* Default defs are loop invariant.  */
+	    if (!defbb)
+	      break;
+	    /* Defined outside this loop, also loop invariant.  */
+	    if (!flow_bb_inside_loop_p (bb->loop_father, defbb))
+	      break;
+	    /* If it's a simple induction variable inhibit insertion,
+	       the vectorizer might be interested in this one.  */
+	    if (simple_iv (bb->loop_father, bb->loop_father,
+			   op->op0, &iv, true))
+	      return true;
+	    /* No simple IV, vectorizer can't do anything, hence no
+	       reason to inhibit the transformation for this operand.  */
+	    break;
+	  }
+	default:
+	  break;
+	}
+    }
+  return false;
+}
+
 /* Insert the to-be-made-available values of expression EXPRNUM for each
    predecessor, stored in AVAIL, into the predecessors of BLOCK, and
    merge the result with a phi node, given the same value number as
@@ -3111,8 +3168,7 @@ insert_into_preds_of_block (basic_block
     }
 
   /* Make sure we aren't creating an induction variable.  */
-  if (block->loop_depth > 0 && EDGE_COUNT (block->preds) == 2
-      && expr->kind != REFERENCE)
+  if (block->loop_depth > 0 && EDGE_COUNT (block->preds) == 2)
     {
       bool firstinsideloop = false;
       bool secondinsideloop = false;
@@ -3121,7 +3177,9 @@ insert_into_preds_of_block (basic_block
       secondinsideloop = flow_bb_inside_loop_p (block->loop_father,
 						EDGE_PRED (block, 1)->src);
       /* Induction variables only have one edge inside the loop.  */
-      if (firstinsideloop ^ secondinsideloop)
+      if ((firstinsideloop ^ secondinsideloop)
+	  && (expr->kind != REFERENCE
+	      || inhibit_phi_insertion (block, expr)))
 	{
 	  if (dump_file && (dump_flags & TDF_DETAILS))
 	    fprintf (dump_file, "Skipping insertion of phi for partial redundancy: Looks like an induction variable\n");
@@ -4504,6 +4562,7 @@ execute_pre (bool do_fre ATTRIBUTE_UNUSE
       return 0;
     }
   init_pre (do_fre);
+  scev_initialize ();
 
 
   /* Collect and value number expressions computed in each basic block.  */
@@ -4555,6 +4614,7 @@ execute_pre (bool do_fre ATTRIBUTE_UNUSE
   if (!do_fre)
     remove_dead_inserted_code ();
 
+  scev_finalize ();
   fini_pre (do_fre);
 
   return todo;
Index: testsuite/gcc.dg/vect/vect-pre-interact.c
===================================================================
--- testsuite/gcc.dg/vect/vect-pre-interact.c	(revision 0)
+++ testsuite/gcc.dg/vect/vect-pre-interact.c	(revision 0)
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-options "-O3 -ftree-pre -fdump-tree-vect-details" } */
+
+/* This checks that PRE doesn't create situations that prevent vectorization.
+   I.e. PR39300, PR35229.  */
+float res[1024], data[1025];
+
+void foo (void)
+{
+  int i;
+  for (i = 0; i < 1024; ++i)
+    res[i] = data[i] + data[i + 1];
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]