re PR tree-optimization/35229 (Vectorizer doesn't support dependence created by...
authorMichael Matz <matz@suse.de>
Wed, 22 Jul 2009 15:30:50 +0000 (15:30 +0000)
committerMichael Matz <matz@gcc.gnu.org>
Wed, 22 Jul 2009 15:30:50 +0000 (15:30 +0000)
        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.

From-SVN: r149942

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/vect-pre-interact.c [new file with mode: 0644]
gcc/tree-ssa-pre.c

index bfafc2a56db0dae3d499998e3484bbe3562ff832..018e805b90035990a6570d63257be75886b82b69 100644 (file)
@@ -1,3 +1,14 @@
+2009-07-22  Michael Matz  <matz@suse.de>
+
+       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  <ubizjak@gmail.com>
 
        * config/i386/predicates.md (zero_extended_scalar_load_operand):
index f16cfe6c7141acac84e54b4d3498731f64457a3f..efad8ee55e605becbfe31560ff0762237323c9f8 100644 (file)
@@ -1,3 +1,9 @@
+2009-07-22  Michael Matz  <matz@suse.de>
+
+       PR tree-optimization/35229
+       PR tree-optimization/39300
+       * gcc.dg/vect/vect-pre-interact.c: New test.
+
 2009-07-22  Richard Guenther  <rguenther@suse.de>
 
        * 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 (file)
index 0000000..96d50e9
--- /dev/null
@@ -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 96ca5edb0f3fb46255d3de28cd9126e4e37079b0..9e3754b37fcf2c82e4bbfe00922bb86733b17f9d 100644 (file)
@@ -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;