From 38fcb532ca028a39c69b4a6786e7efcef758b679 Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 22 Jul 2009 15:30:50 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149942 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 +++++ gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/gcc.dg/vect/vect-pre-interact.c | 17 +++++++ gcc/tree-ssa-pre.c | 66 +++++++++++++++++++++++++-- 4 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/vect-pre-interact.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bfafc2a..018e805 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2009-07-22 Michael Matz + + 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 . + 2009-07-22 Uros Bizjak * config/i386/predicates.md (zero_extended_scalar_load_operand): diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f16cfe6..efad8ee 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-07-22 Michael Matz + + PR tree-optimization/35229 + PR tree-optimization/39300 + * gcc.dg/vect/vect-pre-interact.c: New test. + 2009-07-22 Richard Guenther * g++.dg/lookup/using21.C: Fix duplicate paste. diff --git a/gcc/testsuite/gcc.dg/vect/vect-pre-interact.c b/gcc/testsuite/gcc.dg/vect/vect-pre-interact.c new file mode 100644 index 0000000..96d50e9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-pre-interact.c @@ -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" } } */ diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 96ca5ed..9e3754b 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #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 block, pre_expr expr, } +/* 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 block, unsigned int exprnum, } /* 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 block, unsigned int exprnum, 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_UNUSED) 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_UNUSED) if (!do_fre) remove_dead_inserted_code (); + scev_finalize (); fini_pre (do_fre); return todo; -- 2.7.4