This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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" } } */