re PR tree-optimization/82451 ([GRAPHITE] codegen error in get_rename_from_scev)
authorRichard Biener <rguenther@suse.de>
Fri, 13 Oct 2017 07:02:55 +0000 (07:02 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 13 Oct 2017 07:02:55 +0000 (07:02 +0000)
2017-10-13  Richard Biener  <rguenther@suse.de>

PR tree-optimization/82451
Revert
2017-10-02  Richard Biener  <rguenther@suse.de>

PR tree-optimization/82355
* graphite-isl-ast-to-gimple.c (build_iv_mapping): Also build
a mapping for the enclosing loop but avoid generating one for
the loop tree root.
(copy_bb_and_scalar_dependences): Remove premature codegen
error on PHIs in blocks duplicated into multiple places.
* graphite-scop-detection.c
(scop_detection::stmt_has_simple_data_refs_p): For a loop not
in the region use it as loop and nest to analyze the DR in.
(try_generate_gimple_bb): Likewise.
* graphite-sese-to-poly.c (extract_affine_chrec): Adjust.
(add_loop_constraints): For blocks in a loop not in the region
create a dimension with a single iteration.
* sese.h (gbb_loop_at_index): Remove assert.

* cfgloop.c (loop_preheader_edge): For the loop tree root
return the single successor of the entry block.
* graphite-isl-ast-to-gimple.c (graphite_regenerate_ast_isl):
Reset the SCEV hashtable and niters.
* graphite-scop-detection.c
(scop_detection::graphite_can_represent_scev): Add SCOP parameter,
assert that we only have POLYNOMIAL_CHREC that vary in loops
contained in the region.
(scop_detection::graphite_can_represent_expr): Adjust.
(scop_detection::stmt_has_simple_data_refs_p): For loops
not in the region set loop to NULL.  The nest is now the
entry edge to the region.
(try_generate_gimple_bb): Likewise.
* sese.c (scalar_evolution_in_region): Adjust for
instantiate_scev change.
* tree-data-ref.h (graphite_find_data_references_in_stmt):
Make nest parameter the edge into the region.
(create_data_ref): Likewise.
* tree-data-ref.c (dr_analyze_indices): Make nest parameter an
entry edge into a region and adjust instantiate_scev calls.
(create_data_ref): Likewise.
(graphite_find_data_references_in_stmt): Likewise.
(find_data_references_in_stmt): Pass the loop preheader edge
from the nest argument.
* tree-scalar-evolution.h (instantiate_scev): Make instantiate_below
parameter the edge into the region.
(instantiate_parameters): Use the loop preheader edge as entry.
* tree-scalar-evolution.c (analyze_scalar_evolution): Handle
NULL loop.
(get_instantiated_value_entry): Make instantiate_below parameter
the edge into the region.
(instantiate_scev_name): Likewise.  Adjust dominance checks,
when we cannot use loop-based instantiation instantiate by
walking use-def chains.
(instantiate_scev_poly): Adjust.
(instantiate_scev_binary): Likewise.
(instantiate_scev_convert): Likewise.
(instantiate_scev_not): Likewise.
(instantiate_array_ref): Remove.
(instantiate_scev_3): Likewise.
(instantiate_scev_2): Likewise.
(instantiate_scev_1): Likewise.
(instantiate_scev_r): Do not blindly handle N-operand trees.
Do not instantiate array-refs.  Handle all constants and invariants.
(instantiate_scev): Make instantiate_below parameter
the edge into the region.
(resolve_mixers): Use the loop preheader edge for the region
parameter to instantiate_scev_r.
* tree-ssa-loop-prefetch.c (determine_loop_nest_reuse): Adjust.

* gcc.dg/graphite/pr82451.c: New testcase.
* gfortran.dg/graphite/id-27.f90: Likewise.
* gfortran.dg/graphite/pr82451.f: Likewise.

From-SVN: r253707

18 files changed:
gcc/ChangeLog
gcc/cfgloop.c
gcc/graphite-isl-ast-to-gimple.c
gcc/graphite-scop-detection.c
gcc/graphite-sese-to-poly.c
gcc/sese.c
gcc/sese.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/graphite/fuse-1.c
gcc/testsuite/gcc.dg/graphite/fuse-2.c
gcc/testsuite/gcc.dg/graphite/pr82451.c [new file with mode: 0644]
gcc/testsuite/gfortran.dg/graphite/id-27.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/graphite/pr82451.f [new file with mode: 0644]
gcc/tree-data-ref.c
gcc/tree-data-ref.h
gcc/tree-scalar-evolution.c
gcc/tree-scalar-evolution.h
gcc/tree-ssa-loop-prefetch.c

index 890ee0e5d0e848c6ab4392c11977f1947939fa2b..bff2a6fe00dc71b4e7e0b55834958a60c5e9db64 100644 (file)
@@ -1,3 +1,74 @@
+2017-10-13  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/82451
+       Revert
+       2017-10-02  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/82355
+       * graphite-isl-ast-to-gimple.c (build_iv_mapping): Also build
+       a mapping for the enclosing loop but avoid generating one for
+       the loop tree root.
+       (copy_bb_and_scalar_dependences): Remove premature codegen
+       error on PHIs in blocks duplicated into multiple places.
+       * graphite-scop-detection.c
+       (scop_detection::stmt_has_simple_data_refs_p): For a loop not
+       in the region use it as loop and nest to analyze the DR in.
+       (try_generate_gimple_bb): Likewise.
+       * graphite-sese-to-poly.c (extract_affine_chrec): Adjust.
+       (add_loop_constraints): For blocks in a loop not in the region
+       create a dimension with a single iteration.
+       * sese.h (gbb_loop_at_index): Remove assert.
+
+       * cfgloop.c (loop_preheader_edge): For the loop tree root
+       return the single successor of the entry block.
+       * graphite-isl-ast-to-gimple.c (graphite_regenerate_ast_isl):
+       Reset the SCEV hashtable and niters.
+       * graphite-scop-detection.c
+       (scop_detection::graphite_can_represent_scev): Add SCOP parameter,
+       assert that we only have POLYNOMIAL_CHREC that vary in loops
+       contained in the region.
+       (scop_detection::graphite_can_represent_expr): Adjust.
+       (scop_detection::stmt_has_simple_data_refs_p): For loops
+       not in the region set loop to NULL.  The nest is now the
+       entry edge to the region.
+       (try_generate_gimple_bb): Likewise.
+       * sese.c (scalar_evolution_in_region): Adjust for
+       instantiate_scev change.
+       * tree-data-ref.h (graphite_find_data_references_in_stmt):
+       Make nest parameter the edge into the region.
+       (create_data_ref): Likewise.
+       * tree-data-ref.c (dr_analyze_indices): Make nest parameter an
+       entry edge into a region and adjust instantiate_scev calls.
+       (create_data_ref): Likewise.
+       (graphite_find_data_references_in_stmt): Likewise.
+       (find_data_references_in_stmt): Pass the loop preheader edge
+       from the nest argument.
+       * tree-scalar-evolution.h (instantiate_scev): Make instantiate_below
+       parameter the edge into the region.
+       (instantiate_parameters): Use the loop preheader edge as entry.
+       * tree-scalar-evolution.c (analyze_scalar_evolution): Handle
+       NULL loop.
+       (get_instantiated_value_entry): Make instantiate_below parameter
+       the edge into the region.
+       (instantiate_scev_name): Likewise.  Adjust dominance checks,
+       when we cannot use loop-based instantiation instantiate by
+       walking use-def chains.
+       (instantiate_scev_poly): Adjust.
+       (instantiate_scev_binary): Likewise.
+       (instantiate_scev_convert): Likewise.
+       (instantiate_scev_not): Likewise.
+       (instantiate_array_ref): Remove.
+       (instantiate_scev_3): Likewise.
+       (instantiate_scev_2): Likewise.
+       (instantiate_scev_1): Likewise.
+       (instantiate_scev_r): Do not blindly handle N-operand trees.
+       Do not instantiate array-refs.  Handle all constants and invariants.
+       (instantiate_scev): Make instantiate_below parameter
+       the edge into the region.
+       (resolve_mixers): Use the loop preheader edge for the region
+       parameter to instantiate_scev_r.
+       * tree-ssa-loop-prefetch.c (determine_loop_nest_reuse): Adjust.
+
 2017-10-13  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/82525
index 6911426787b1f470119536c56bf75931f7493444..c3bd9c05013d81a197bfd659261e872c499c886a 100644 (file)
@@ -1713,12 +1713,19 @@ loop_preheader_edge (const struct loop *loop)
   edge e;
   edge_iterator ei;
 
-  gcc_assert (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS));
+  gcc_assert (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS)
+             && ! loops_state_satisfies_p (LOOPS_MAY_HAVE_MULTIPLE_LATCHES));
 
   FOR_EACH_EDGE (e, ei, loop->header->preds)
     if (e->src != loop->latch)
       break;
 
+  if (! e)
+    {
+      gcc_assert (! loop_outer (loop));
+      return single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+    }
+
   return e;
 }
 
index 9a9f8c86726f951ec7d036309f95b4a15f43ae46..874941824cd98ed505de5930b5ebf16e46e0de46 100644 (file)
@@ -750,10 +750,8 @@ build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
       if (codegen_error_p ())
        t = integer_zero_node;
 
-      loop_p old_loop = gbb_loop_at_index (gbb, region, i - 2);
-      /* Record sth only for real loops.  */
-      if (loop_in_sese_p (old_loop, region))
-       iv_map[old_loop->num] = t;
+      loop_p old_loop = gbb_loop_at_index (gbb, region, i - 1);
+      iv_map[old_loop->num] = t;
     }
 }
 
@@ -1571,6 +1569,12 @@ graphite_regenerate_ast_isl (scop_p scop)
       update_ssa (TODO_update_ssa);
       checking_verify_ssa (true, true);
       rewrite_into_loop_closed_ssa (NULL, 0);
+      /* We analyzed evolutions of all SCOPs during SCOP detection
+         which cached evolutions.  Now we've introduced PHIs for
+        liveouts which causes those cached solutions to be invalid
+        for code-generation purposes given we'd insert references
+        to SSA names not dominating their new use.  */
+      scev_reset ();
     }
 
   if (t.codegen_error_p ())
index 3cd99322b77d941be812fb3a84d4729d9a3a9601..c7e1dba9423a177b5e1806391112c7a0ada9d79a 100644 (file)
@@ -381,7 +381,7 @@ public:
 
      Something like "i * n" or "n * m" is not allowed.  */
 
-  static bool graphite_can_represent_scev (tree scev);
+  static bool graphite_can_represent_scev (sese_l scop, tree scev);
 
   /* Return true when EXPR can be represented in the polyhedral model.
 
@@ -934,7 +934,7 @@ scop_detection::graphite_can_represent_init (tree e)
    Something like "i * n" or "n * m" is not allowed.  */
 
 bool
-scop_detection::graphite_can_represent_scev (tree scev)
+scop_detection::graphite_can_represent_scev (sese_l scop, tree scev)
 {
   if (chrec_contains_undetermined (scev))
     return false;
@@ -945,13 +945,13 @@ scop_detection::graphite_can_represent_scev (tree scev)
     case BIT_NOT_EXPR:
     CASE_CONVERT:
     case NON_LVALUE_EXPR:
-      return graphite_can_represent_scev (TREE_OPERAND (scev, 0));
+      return graphite_can_represent_scev (scop, TREE_OPERAND (scev, 0));
 
     case PLUS_EXPR:
     case POINTER_PLUS_EXPR:
     case MINUS_EXPR:
-      return graphite_can_represent_scev (TREE_OPERAND (scev, 0))
-       && graphite_can_represent_scev (TREE_OPERAND (scev, 1));
+      return graphite_can_represent_scev (scop, TREE_OPERAND (scev, 0))
+       && graphite_can_represent_scev (scop, TREE_OPERAND (scev, 1));
 
     case MULT_EXPR:
       return !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 0)))
@@ -959,18 +959,20 @@ scop_detection::graphite_can_represent_scev (tree scev)
        && !(chrec_contains_symbols (TREE_OPERAND (scev, 0))
             && chrec_contains_symbols (TREE_OPERAND (scev, 1)))
        && graphite_can_represent_init (scev)
-       && graphite_can_represent_scev (TREE_OPERAND (scev, 0))
-       && graphite_can_represent_scev (TREE_OPERAND (scev, 1));
+       && graphite_can_represent_scev (scop, TREE_OPERAND (scev, 0))
+       && graphite_can_represent_scev (scop, TREE_OPERAND (scev, 1));
 
     case POLYNOMIAL_CHREC:
       /* Check for constant strides.  With a non constant stride of
         'n' we would have a value of 'iv * n'.  Also check that the
         initial value can represented: for example 'n * m' cannot be
         represented.  */
+      gcc_assert (loop_in_sese_p (get_loop (cfun,
+                                           CHREC_VARIABLE (scev)), scop));
       if (!evolution_function_right_is_integer_cst (scev)
          || !graphite_can_represent_init (scev))
        return false;
-      return graphite_can_represent_scev (CHREC_LEFT (scev));
+      return graphite_can_represent_scev (scop, CHREC_LEFT (scev));
 
     default:
       break;
@@ -994,7 +996,7 @@ scop_detection::graphite_can_represent_expr (sese_l scop, loop_p loop,
                                             tree expr)
 {
   tree scev = scalar_evolution_in_region (scop, loop, expr);
-  return graphite_can_represent_scev (scev);
+  return graphite_can_represent_scev (scop, scev);
 }
 
 /* Return true if the data references of STMT can be represented by Graphite.
@@ -1003,12 +1005,15 @@ scop_detection::graphite_can_represent_expr (sese_l scop, loop_p loop,
 bool
 scop_detection::stmt_has_simple_data_refs_p (sese_l scop, gimple *stmt)
 {
-  loop_p nest;
+  edge nest;
   loop_p loop = loop_containing_stmt (stmt);
   if (!loop_in_sese_p (loop, scop))
-    nest = loop;
+    {
+      nest = scop.entry;
+      loop = NULL;
+    }
   else
-    nest = outermost_loop_in_sese (scop, gimple_bb (stmt));
+    nest = loop_preheader_edge (outermost_loop_in_sese (scop, gimple_bb (stmt)));
 
   auto_vec<data_reference_p> drs;
   if (! graphite_find_data_references_in_stmt (nest, loop, stmt, &drs))
@@ -1019,7 +1024,7 @@ scop_detection::stmt_has_simple_data_refs_p (sese_l scop, gimple *stmt)
   FOR_EACH_VEC_ELT (drs, j, dr)
     {
       for (unsigned i = 0; i < DR_NUM_DIMENSIONS (dr); ++i)
-       if (! graphite_can_represent_scev (DR_ACCESS_FN (dr, i)))
+       if (! graphite_can_represent_scev (scop, DR_ACCESS_FN (dr, i)))
          return false;
     }
 
@@ -1376,12 +1381,15 @@ try_generate_gimple_bb (scop_p scop, basic_block bb)
   vec<scalar_use> reads = vNULL;
 
   sese_l region = scop->scop_info->region;
-  loop_p nest;
+  edge nest;
   loop_p loop = bb->loop_father;
   if (!loop_in_sese_p (loop, region))
-    nest = loop;
+    {
+      nest = region.entry;
+      loop = NULL;
+    }
   else
-    nest = outermost_loop_in_sese (region, bb);
+    nest = loop_preheader_edge (outermost_loop_in_sese (region, bb));
 
   for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
        gsi_next (&gsi))
index 50b6fe8dbb29c570931e82ef8268448e54b088df..ed6cbeccca1f6f5a97d3924313fe1da0e842a789 100644 (file)
@@ -86,7 +86,7 @@ extract_affine_chrec (scop_p s, tree e, __isl_take isl_space *space)
   isl_pw_aff *lhs = extract_affine (s, CHREC_LEFT (e), isl_space_copy (space));
   isl_pw_aff *rhs = extract_affine (s, CHREC_RIGHT (e), isl_space_copy (space));
   isl_local_space *ls = isl_local_space_from_space (space);
-  unsigned pos = sese_loop_depth (s->scop_info->region, get_chrec_loop (e));
+  unsigned pos = sese_loop_depth (s->scop_info->region, get_chrec_loop (e)) - 1;
   isl_aff *loop = isl_aff_set_coefficient_si
     (isl_aff_zero_on_domain (ls), isl_dim_in, pos, 1);
   isl_pw_aff *l = isl_pw_aff_from_aff (loop);
@@ -763,10 +763,10 @@ add_loop_constraints (scop_p scop, __isl_take isl_set *domain, loop_p loop,
     return domain;
   const sese_l &region = scop->scop_info->region;
   if (!loop_in_sese_p (loop, region))
-    ;
-  else
-    /* Recursion all the way up to the context loop.  */
-    domain = add_loop_constraints (scop, domain, loop_outer (loop), context);
+    return domain;
+
+  /* Recursion all the way up to the context loop.  */
+  domain = add_loop_constraints (scop, domain, loop_outer (loop), context);
 
   /* Then, build constraints over the loop in post-order: outer to inner.  */
 
@@ -777,21 +777,6 @@ add_loop_constraints (scop_p scop, __isl_take isl_set *domain, loop_p loop,
   domain = add_iter_domain_dimension (domain, loop, scop);
   isl_space *space = isl_set_get_space (domain);
 
-  if (!loop_in_sese_p (loop, region))
-    {
-      /* 0 == loop_i */
-      isl_local_space *ls = isl_local_space_from_space (space);
-      isl_constraint *c = isl_equality_alloc (ls);
-      c = isl_constraint_set_coefficient_si (c, isl_dim_set, loop_index, 1);
-      if (dump_file)
-       {
-         fprintf (dump_file, "[sese-to-poly] adding constraint to the domain: ");
-         print_isl_constraint (dump_file, c);
-       }
-      domain = isl_set_add_constraint (domain, c);
-      return domain;
-    }
-
   /* 0 <= loop_i */
   isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
   isl_constraint *c = isl_inequality_alloc (ls);
index d6702ada5f4ac2f1a2294bfe9df7489489623f53..8aa8015290ddacd6c8c3bda425fc9f669b824e3d 100644 (file)
@@ -461,7 +461,6 @@ scalar_evolution_in_region (const sese_l &region, loop_p loop, tree t)
 {
   gimple *def;
   struct loop *def_loop;
-  basic_block before = region.entry->src;
 
   /* SCOP parameters.  */
   if (TREE_CODE (t) == SSA_NAME
@@ -472,7 +471,7 @@ scalar_evolution_in_region (const sese_l &region, loop_p loop, tree t)
       || loop_in_sese_p (loop, region))
     /* FIXME: we would need instantiate SCEV to work on a region, and be more
        flexible wrt. memory loads that may be invariant in the region.  */
-    return instantiate_scev (before, loop,
+    return instantiate_scev (region.entry, loop,
                             analyze_scalar_evolution (loop, t));
 
   def = SSA_NAME_DEF_STMT (t);
@@ -494,7 +493,7 @@ scalar_evolution_in_region (const sese_l &region, loop_p loop, tree t)
   if (has_vdefs)
     return chrec_dont_know;
 
-  return instantiate_scev (before, loop, t);
+  return instantiate_scev (region.entry, loop, t);
 }
 
 /* Return true if BB is empty, contains only DEBUG_INSNs.  */
index 190deeda8afe75df075569b8e212ba9a0867d300..faefd806d9da788b0ae7685e9c6020a77c1e80ed 100644 (file)
@@ -334,6 +334,8 @@ gbb_loop_at_index (gimple_poly_bb_p gbb, sese_l &region, int index)
   while (--depth > index)
     loop = loop_outer (loop);
 
+  gcc_assert (loop_in_sese_p (loop, region));
+
   return loop;
 }
 
index 874ede28bd333d04d462baf07567e0dcd2092f6c..a830453eabdf646605119acc34344814d7be8ed3 100644 (file)
@@ -1,3 +1,10 @@
+2017-10-13  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/82451
+       * gcc.dg/graphite/pr82451.c: New testcase.
+       * gfortran.dg/graphite/id-27.f90: Likewise.
+       * gfortran.dg/graphite/pr82451.f: Likewise.
+
 2017-10-13  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/82525
index e3bf7bcf99b897365b6de276702b2f0b328d6cf3..204d3b20703e18098e023e537f539bb63db3fd16 100644 (file)
@@ -1,15 +1,15 @@
 /* Check that the two loops are fused and that we manage to fold the two xor
    operations.  */
-/* { dg-options "-O2 -floop-nest-optimize -fdump-tree-forwprop4-all -fdump-tree-graphite-all" } */
+/* { dg-options "-O2 -floop-nest-optimize -fdump-tree-forwprop-all -fdump-tree-graphite-all" } */
 
 /* Make sure we fuse the loops like this:
 AST generated by isl:
 for (int c0 = 0; c0 <= 99; c0 += 1) {
-  S_3(0, c0);
-  S_6(0, c0);
-  S_9(0, c0);
+  S_3(c0);
+  S_6(c0);
+  S_9(c0);
 } */
-/* { dg-final { scan-tree-dump-times "AST generated by isl:.*for \\(int c0 = 0; c0 <= 99; c0 \\+= 1\\) \\{.*S_.*\\(0, c0\\);.*S_.*\\(0, c0\\);.*S_.*\\(0, c0\\);.*\\}" 1 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "AST generated by isl:.*for \\(int c0 = 0; c0 <= 99; c0 \\+= 1\\) \\{.*S_.*\\(c0\\);.*S_.*\\(c0\\);.*S_.*\\(c0\\);.*\\}" 1 "graphite" } } */
 
 /* Check that after fusing the loops, the scalar computation is also fused.  */
 /* { dg-final { scan-tree-dump-times "gimple_simplified to\[^\\n\]*\\^ 12" 1 "forwprop4" } } */
index dc0a9b2b61c07bb6175825943ea814b3c504e5af..f4cea4360d9e5deb8a73ff5c145b8e9cfb243995 100644 (file)
@@ -3,13 +3,13 @@
 /* Make sure we fuse the loops like this:
 AST generated by isl:
 for (int c0 = 0; c0 <= 99; c0 += 1) {
-  S_3(0, c0);
-  S_6(0, c0);
-  S_9(0, c0);
+  S_3(c0);
+  S_6(c0);
+  S_9(c0);
 }
 */
 
-/* { dg-final { scan-tree-dump-times "AST generated by isl:.*for \\(int c0 = 0; c0 <= 99; c0 \\+= 1\\) \\{.*S_.*\\(0, c0\\);.*S_.*\\(0, c0\\);.*S_.*\\(0, c0\\);.*\\}" 1 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "AST generated by isl:.*for \\(int c0 = 0; c0 <= 99; c0 \\+= 1\\) \\{.*S_.*\\(c0\\);.*S_.*\\(c0\\);.*S_.*\\(c0\\);.*\\}" 1 "graphite" } } */
 
 #define MAX 100
 int A[MAX], B[MAX], C[MAX];
diff --git a/gcc/testsuite/gcc.dg/graphite/pr82451.c b/gcc/testsuite/gcc.dg/graphite/pr82451.c
new file mode 100644 (file)
index 0000000..802b931
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O -floop-parallelize-all" } */
+
+static int a[];
+int b[1];
+int c;
+static void
+d (int *f, int *g)
+{
+  int e;
+  for (e = 0; e < 2; e++)
+    g[e] = 1;
+  for (e = 0; e < 2; e++)
+    g[e] = f[e] + f[e + 1];
+}
+void
+h ()
+{
+  for (;; c += 8)
+    d (&a[c], b);
+}
diff --git a/gcc/testsuite/gfortran.dg/graphite/id-27.f90 b/gcc/testsuite/gfortran.dg/graphite/id-27.f90
new file mode 100644 (file)
index 0000000..e1e7ec0
--- /dev/null
@@ -0,0 +1,40 @@
+! { dg-additional-options "-Ofast" }
+MODULE module_ra_gfdleta
+      INTEGER, PARAMETER              :: NBLY=15
+      REAL   , SAVE :: EM1(28,180),EM1WDE(28,180),TABLE1(28,180),     &
+                           TABLE2(28,180),TABLE3(28,180),EM3(28,180), &
+                           SOURCE(28,NBLY), DSRCE(28,NBLY)
+CONTAINS
+      SUBROUTINE TABLE 
+ INTEGER, PARAMETER :: NBLX=47
+ INTEGER , PARAMETER:: NBLW = 163
+      REAL ::  &
+               SUM(28,180),PERTSM(28,180),SUM3(28,180),       &
+               SUMWDE(28,180),SRCWD(28,NBLX),SRC1NB(28,NBLW), &
+               DBDTNB(28,NBLW)
+      REAL ::  &
+               ZMASS(181),ZROOT(181),SC(28),DSC(28),XTEMV(28), &
+               TFOUR(28),FORTCU(28),X(28),X1(28),X2(180),SRCS(28), &
+               R1T(28),R2(28),S2(28),T3(28),R1WD(28)
+      REAL ::  EXPO(180),FAC(180)
+      I = 0
+      DO 417 J=121,180
+      FAC(J)=ZMASS(J)*(ONE-(ONE+X2(J))*EXPO(J))/(X2(J)*X2(J))
+417   CONTINUE
+      DO 421 J=121,180
+      SUM3(I,J)=SUM3(I,J)+DBDTNB(I,N)*FAC(J)
+421   CONTINUE
+      IF (CENT.GT.160. .AND. CENT.LT.560.) THEN
+         DO 420 J=1,180
+         DO 420 I=1,28
+         SUMWDE(I,J)=SUMWDE(I,J)+SRC1NB(I,N)*EXPO(J)
+420      CONTINUE
+      ENDIF
+      DO 433 J=121,180
+      EM3(I,J)=SUM3(I,J)/FORTCU(I)
+433   CONTINUE
+      DO 501 I=1,28
+      EM1WDE(I,J)=SUMWDE(I,J)/TFOUR(I)
+501   CONTINUE
+      END SUBROUTINE TABLE
+      END MODULE module_RA_GFDLETA
diff --git a/gcc/testsuite/gfortran.dg/graphite/pr82451.f b/gcc/testsuite/gfortran.dg/graphite/pr82451.f
new file mode 100644 (file)
index 0000000..88ff85b
--- /dev/null
@@ -0,0 +1,39 @@
+! { dg-do compile }
+! { dg-options "-O2 -floop-nest-optimize" }
+      MODULE LES3D_DATA
+      PARAMETER ( NSCHEME = 4, ICHEM = 0, ISGSK = 0, IVISC = 1 )
+      DOUBLE PRECISION DT, TIME, STATTIME, CFL, RELNO, TSTND, ALREF
+      INTEGER IDYN, IMAX, JMAX, KMAX
+      PARAMETER( RUNIV =  8.3145D3,
+     >        TPRANDLT =    0.91D0)
+      DOUBLE PRECISION,ALLOCATABLE,DIMENSION(:,:,:) ::
+     >             U, V, W, P, T, H, EK,
+     >         UAV, VAV, WAV, PAV, TAV, HAV, EKAV
+      DOUBLE PRECISION,ALLOCATABLE,DIMENSION(:,:,:,:) ::
+     >             CONC, HF, QAV, COAV, HFAV, DU
+      DOUBLE PRECISION,ALLOCATABLE,DIMENSION(:,:,:,:,:) ::
+     >             Q
+      END MODULE LES3D_DATA
+      SUBROUTINE FLUXJ()
+      USE LES3D_DATA
+      ALLOCATABLE QS(:), FSJ(:,:,:)
+      ALLOCATABLE DWDX(:),DWDY(:),DWDZ(:)
+      ALLOCATABLE DHDY(:), DKDY(:)
+      PARAMETER (  R12I = 1.0D0 / 12.0D0,
+     >             TWO3 = 2.0D0 / 3.0D0 )
+      ALLOCATE( QS(IMAX-1), FSJ(IMAX-1,0:JMAX-1,ND))
+      ALLOCATE( DWDX(IMAX-1),DWDY(IMAX-1),DWDZ(IMAX-1))
+      I1 = 1
+      DO K = K1,K2
+         DO J = J1,J2
+            DO I = I1, I2
+               FSJ(I,J,5) = FSJ(I,J,5) + PAV(I,J,K) * QS(I)
+            END DO
+            DO I = I1, I2
+               DWDX(I) = DXI * R12I * (WAV(I-2,J,K) - WAV(I+2,J,K) +
+     >                        8.0D0 * (WAV(I+1,J,K) - WAV(I-1,J,K)))
+            END DO
+         END DO
+      END DO
+      DEALLOCATE( QS, FSJ, DHDY, DKDY)
+      END
index 19cceb8dfd95012bce2b061c32aed8183e24e955..559a8e4b8457208c4c8200cd686fb02015c6fb1a 100644 (file)
@@ -957,15 +957,14 @@ access_fn_component_p (tree op)
 }
 
 /* Determines the base object and the list of indices of memory reference
-   DR, analyzed in LOOP and instantiated in loop nest NEST.  */
+   DR, analyzed in LOOP and instantiated before NEST.  */
 
 static void
-dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
+dr_analyze_indices (struct data_reference *dr, edge nest, loop_p loop)
 {
   vec<tree> access_fns = vNULL;
   tree ref, op;
   tree base, off, access_fn;
-  basic_block before_loop;
 
   /* If analyzing a basic-block there are no indices to analyze
      and thus no access functions.  */
@@ -977,7 +976,6 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
     }
 
   ref = DR_REF (dr);
-  before_loop = block_before_loop (nest);
 
   /* REALPART_EXPR and IMAGPART_EXPR can be handled like accesses
      into a two element array with a constant index.  The base is
@@ -1002,7 +1000,7 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
        {
          op = TREE_OPERAND (ref, 1);
          access_fn = analyze_scalar_evolution (loop, op);
-         access_fn = instantiate_scev (before_loop, loop, access_fn);
+         access_fn = instantiate_scev (nest, loop, access_fn);
          access_fns.safe_push (access_fn);
        }
       else if (TREE_CODE (ref) == COMPONENT_REF
@@ -1034,7 +1032,7 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
     {
       op = TREE_OPERAND (ref, 0);
       access_fn = analyze_scalar_evolution (loop, op);
-      access_fn = instantiate_scev (before_loop, loop, access_fn);
+      access_fn = instantiate_scev (nest, loop, access_fn);
       if (TREE_CODE (access_fn) == POLYNOMIAL_CHREC)
        {
          tree orig_type;
@@ -1139,7 +1137,7 @@ free_data_ref (data_reference_p dr)
    in which the data reference should be analyzed.  */
 
 struct data_reference *
-create_data_ref (loop_p nest, loop_p loop, tree memref, gimple *stmt,
+create_data_ref (edge nest, loop_p loop, tree memref, gimple *stmt,
                 bool is_read, bool is_conditional_in_stmt)
 {
   struct data_reference *dr;
@@ -4970,7 +4968,8 @@ find_data_references_in_stmt (struct loop *nest, gimple *stmt,
 
   FOR_EACH_VEC_ELT (references, i, ref)
     {
-      dr = create_data_ref (nest, loop_containing_stmt (stmt), ref->ref,
+      dr = create_data_ref (nest ? loop_preheader_edge (nest) : NULL,
+                           loop_containing_stmt (stmt), ref->ref,
                            stmt, ref->is_read, ref->is_conditional_in_stmt);
       gcc_assert (dr != NULL);
       datarefs->safe_push (dr);
@@ -4986,7 +4985,7 @@ find_data_references_in_stmt (struct loop *nest, gimple *stmt,
    should be analyzed.  */
 
 bool
-graphite_find_data_references_in_stmt (loop_p nest, loop_p loop, gimple *stmt,
+graphite_find_data_references_in_stmt (edge nest, loop_p loop, gimple *stmt,
                                       vec<data_reference_p> *datarefs)
 {
   unsigned i;
index a66d335f4a0ee5a655446c8164e8c090d9d3eab6..d9d297ad9709ef6357c33079d2a656996206fad0 100644 (file)
@@ -436,11 +436,11 @@ extern void free_data_ref (data_reference_p);
 extern void free_data_refs (vec<data_reference_p> );
 extern bool find_data_references_in_stmt (struct loop *, gimple *,
                                          vec<data_reference_p> *);
-extern bool graphite_find_data_references_in_stmt (loop_p, loop_p, gimple *,
+extern bool graphite_find_data_references_in_stmt (edge, loop_p, gimple *,
                                                   vec<data_reference_p> *);
 tree find_data_references_in_loop (struct loop *, vec<data_reference_p> *);
 bool loop_nest_has_data_refs (loop_p loop);
-struct data_reference *create_data_ref (loop_p, loop_p, tree, gimple *, bool,
+struct data_reference *create_data_ref (edge, loop_p, tree, gimple *, bool,
                                        bool);
 extern bool find_loop_nest (struct loop *, vec<loop_p> *);
 extern struct data_dependence_relation *initialize_data_dependence_relation
index c693be9fe28c9ebdff7876884e87dbfa1d5d70c4..b6c1fcef6a18790bca35b38e8a135b445770c7c4 100644 (file)
@@ -2095,6 +2095,10 @@ analyze_scalar_evolution (struct loop *loop, tree var)
 {
   tree res;
 
+  /* ???  Fix callers.  */
+  if (! loop)
+    return var;
+
   if (dump_file && (dump_flags & TDF_SCEV))
     {
       fprintf (dump_file, "(analyze_scalar_evolution \n");
@@ -2271,7 +2275,7 @@ eq_idx_scev_info (const void *e1, const void *e2)
 
 static unsigned
 get_instantiated_value_entry (instantiate_cache_type &cache,
-                             tree name, basic_block instantiate_below)
+                             tree name, edge instantiate_below)
 {
   if (!cache.map)
     {
@@ -2281,7 +2285,7 @@ get_instantiated_value_entry (instantiate_cache_type &cache,
 
   scev_info_str e;
   e.name_version = SSA_NAME_VERSION (name);
-  e.instantiated_below = instantiate_below->index;
+  e.instantiated_below = instantiate_below->dest->index;
   void **slot = htab_find_slot_with_hash (cache.map, &e,
                                          scev_info_hasher::hash (&e), INSERT);
   if (!*slot)
@@ -2325,7 +2329,7 @@ loop_closed_phi_def (tree var)
   return NULL_TREE;
 }
 
-static tree instantiate_scev_r (basic_block, struct loop *, struct loop *,
+static tree instantiate_scev_r (edge, struct loop *, struct loop *,
                                tree, bool *, int);
 
 /* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
@@ -2344,7 +2348,7 @@ static tree instantiate_scev_r (basic_block, struct loop *, struct loop *,
    instantiated, and to stop if it exceeds some limit.  */
 
 static tree
-instantiate_scev_name (basic_block instantiate_below,
+instantiate_scev_name (edge instantiate_below,
                       struct loop *evolution_loop, struct loop *inner_loop,
                       tree chrec,
                       bool *fold_conversions,
@@ -2358,7 +2362,7 @@ instantiate_scev_name (basic_block instantiate_below,
      evolutions in outer loops), nothing to do.  */
   if (!def_bb
       || loop_depth (def_bb->loop_father) == 0
-      || dominated_by_p (CDI_DOMINATORS, instantiate_below, def_bb))
+      || ! dominated_by_p (CDI_DOMINATORS, def_bb, instantiate_below->dest))
     return chrec;
 
   /* We cache the value of instantiated variable to avoid exponential
@@ -2380,6 +2384,51 @@ instantiate_scev_name (basic_block instantiate_below,
 
   def_loop = find_common_loop (evolution_loop, def_bb->loop_father);
 
+  if (! dominated_by_p (CDI_DOMINATORS,
+                       def_loop->header, instantiate_below->dest))
+    {
+      gimple *def = SSA_NAME_DEF_STMT (chrec);
+      if (gassign *ass = dyn_cast <gassign *> (def))
+       {
+         switch (gimple_assign_rhs_class (ass))
+           {
+           case GIMPLE_UNARY_RHS:
+             {
+               tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
+                                              inner_loop, gimple_assign_rhs1 (ass),
+                                              fold_conversions, size_expr);
+               if (op0 == chrec_dont_know)
+                 return chrec_dont_know;
+               res = fold_build1 (gimple_assign_rhs_code (ass),
+                                  TREE_TYPE (chrec), op0);
+               break;
+             }
+           case GIMPLE_BINARY_RHS:
+             {
+               tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
+                                              inner_loop, gimple_assign_rhs1 (ass),
+                                              fold_conversions, size_expr);
+               if (op0 == chrec_dont_know)
+                 return chrec_dont_know;
+               tree op1 = instantiate_scev_r (instantiate_below, evolution_loop,
+                                              inner_loop, gimple_assign_rhs2 (ass),
+                                              fold_conversions, size_expr);
+               if (op1 == chrec_dont_know)
+                 return chrec_dont_know;
+               res = fold_build2 (gimple_assign_rhs_code (ass),
+                                  TREE_TYPE (chrec), op0, op1);
+               break;
+             }
+           default:
+             res = chrec_dont_know;
+           }
+       }
+      else
+       res = chrec_dont_know;
+      global_cache->set (si, res);
+      return res;
+    }
+
   /* If the analysis yields a parametric chrec, instantiate the
      result again.  */
   res = analyze_scalar_evolution (def_loop, chrec);
@@ -2411,8 +2460,9 @@ instantiate_scev_name (basic_block instantiate_below,
                                    inner_loop, res,
                                    fold_conversions, size_expr);
        }
-      else if (!dominated_by_p (CDI_DOMINATORS, instantiate_below,
-                               gimple_bb (SSA_NAME_DEF_STMT (res))))
+      else if (dominated_by_p (CDI_DOMINATORS,
+                               gimple_bb (SSA_NAME_DEF_STMT (res)),
+                               instantiate_below->dest))
        res = chrec_dont_know;
     }
 
@@ -2450,7 +2500,7 @@ instantiate_scev_name (basic_block instantiate_below,
    instantiated, and to stop if it exceeds some limit.  */
 
 static tree
-instantiate_scev_poly (basic_block instantiate_below,
+instantiate_scev_poly (edge instantiate_below,
                       struct loop *evolution_loop, struct loop *,
                       tree chrec, bool *fold_conversions, int size_expr)
 {
@@ -2495,7 +2545,7 @@ instantiate_scev_poly (basic_block instantiate_below,
    instantiated, and to stop if it exceeds some limit.  */
 
 static tree
-instantiate_scev_binary (basic_block instantiate_below,
+instantiate_scev_binary (edge instantiate_below,
                         struct loop *evolution_loop, struct loop *inner_loop,
                         tree chrec, enum tree_code code,
                         tree type, tree c0, tree c1,
@@ -2538,43 +2588,6 @@ instantiate_scev_binary (basic_block instantiate_below,
   return chrec ? chrec : fold_build2 (code, type, c0, c1);
 }
 
-/* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
-   and EVOLUTION_LOOP, that were left under a symbolic form.
-
-   "CHREC" is an array reference to be instantiated.
-
-   CACHE is the cache of already instantiated values.
-
-   Variable pointed by FOLD_CONVERSIONS is set to TRUE when the
-   conversions that may wrap in signed/pointer type are folded, as long
-   as the value of the chrec is preserved.  If FOLD_CONVERSIONS is NULL
-   then we don't do such fold.
-
-   SIZE_EXPR is used for computing the size of the expression to be
-   instantiated, and to stop if it exceeds some limit.  */
-
-static tree
-instantiate_array_ref (basic_block instantiate_below,
-                      struct loop *evolution_loop, struct loop *inner_loop,
-                      tree chrec, bool *fold_conversions, int size_expr)
-{
-  tree res;
-  tree index = TREE_OPERAND (chrec, 1);
-  tree op1 = instantiate_scev_r (instantiate_below, evolution_loop,
-                                inner_loop, index,
-                                fold_conversions, size_expr);
-
-  if (op1 == chrec_dont_know)
-    return chrec_dont_know;
-
-  if (chrec && op1 == index)
-    return chrec;
-
-  res = unshare_expr (chrec);
-  TREE_OPERAND (res, 1) = op1;
-  return res;
-}
-
 /* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
    and EVOLUTION_LOOP, that were left under a symbolic form.
 
@@ -2592,7 +2605,7 @@ instantiate_array_ref (basic_block instantiate_below,
    instantiated, and to stop if it exceeds some limit.  */
 
 static tree
-instantiate_scev_convert (basic_block instantiate_below,
+instantiate_scev_convert (edge instantiate_below,
                          struct loop *evolution_loop, struct loop *inner_loop,
                          tree chrec, tree type, tree op,
                          bool *fold_conversions, int size_expr)
@@ -2643,7 +2656,7 @@ instantiate_scev_convert (basic_block instantiate_below,
    instantiated, and to stop if it exceeds some limit.  */
 
 static tree
-instantiate_scev_not (basic_block instantiate_below,
+instantiate_scev_not (edge instantiate_below,
                      struct loop *evolution_loop, struct loop *inner_loop,
                      tree chrec,
                      enum tree_code code, tree type, tree op,
@@ -2678,130 +2691,6 @@ instantiate_scev_not (basic_block instantiate_below,
   return chrec ? chrec : fold_build1 (code, type, op0);
 }
 
-/* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
-   and EVOLUTION_LOOP, that were left under a symbolic form.
-
-   CHREC is an expression with 3 operands to be instantiated.
-
-   CACHE is the cache of already instantiated values.
-
-   Variable pointed by FOLD_CONVERSIONS is set to TRUE when the
-   conversions that may wrap in signed/pointer type are folded, as long
-   as the value of the chrec is preserved.  If FOLD_CONVERSIONS is NULL
-   then we don't do such fold.
-
-   SIZE_EXPR is used for computing the size of the expression to be
-   instantiated, and to stop if it exceeds some limit.  */
-
-static tree
-instantiate_scev_3 (basic_block instantiate_below,
-                   struct loop *evolution_loop, struct loop *inner_loop,
-                   tree chrec,
-                   bool *fold_conversions, int size_expr)
-{
-  tree op1, op2;
-  tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
-                                inner_loop, TREE_OPERAND (chrec, 0),
-                                fold_conversions, size_expr);
-  if (op0 == chrec_dont_know)
-    return chrec_dont_know;
-
-  op1 = instantiate_scev_r (instantiate_below, evolution_loop,
-                           inner_loop, TREE_OPERAND (chrec, 1),
-                           fold_conversions, size_expr);
-  if (op1 == chrec_dont_know)
-    return chrec_dont_know;
-
-  op2 = instantiate_scev_r (instantiate_below, evolution_loop,
-                           inner_loop, TREE_OPERAND (chrec, 2),
-                           fold_conversions, size_expr);
-  if (op2 == chrec_dont_know)
-    return chrec_dont_know;
-
-  if (op0 == TREE_OPERAND (chrec, 0)
-      && op1 == TREE_OPERAND (chrec, 1)
-      && op2 == TREE_OPERAND (chrec, 2))
-    return chrec;
-
-  return fold_build3 (TREE_CODE (chrec),
-                     TREE_TYPE (chrec), op0, op1, op2);
-}
-
-/* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
-   and EVOLUTION_LOOP, that were left under a symbolic form.
-
-   CHREC is an expression with 2 operands to be instantiated.
-
-   CACHE is the cache of already instantiated values.
-
-   Variable pointed by FOLD_CONVERSIONS is set to TRUE when the
-   conversions that may wrap in signed/pointer type are folded, as long
-   as the value of the chrec is preserved.  If FOLD_CONVERSIONS is NULL
-   then we don't do such fold.
-
-   SIZE_EXPR is used for computing the size of the expression to be
-   instantiated, and to stop if it exceeds some limit.  */
-
-static tree
-instantiate_scev_2 (basic_block instantiate_below,
-                   struct loop *evolution_loop, struct loop *inner_loop,
-                   tree chrec,
-                   bool *fold_conversions, int size_expr)
-{
-  tree op1;
-  tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
-                                inner_loop, TREE_OPERAND (chrec, 0),
-                                fold_conversions, size_expr);
-  if (op0 == chrec_dont_know)
-    return chrec_dont_know;
-
-  op1 = instantiate_scev_r (instantiate_below, evolution_loop,
-                           inner_loop, TREE_OPERAND (chrec, 1),
-                           fold_conversions, size_expr);
-  if (op1 == chrec_dont_know)
-    return chrec_dont_know;
-
-  if (op0 == TREE_OPERAND (chrec, 0)
-      && op1 == TREE_OPERAND (chrec, 1))
-    return chrec;
-
-  return fold_build2 (TREE_CODE (chrec), TREE_TYPE (chrec), op0, op1);
-}
-
-/* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
-   and EVOLUTION_LOOP, that were left under a symbolic form.
-
-   CHREC is an expression with 2 operands to be instantiated.
-
-   CACHE is the cache of already instantiated values.
-
-   Variable pointed by FOLD_CONVERSIONS is set to TRUE when the
-   conversions that may wrap in signed/pointer type are folded, as long
-   as the value of the chrec is preserved.  If FOLD_CONVERSIONS is NULL
-   then we don't do such fold.
-
-   SIZE_EXPR is used for computing the size of the expression to be
-   instantiated, and to stop if it exceeds some limit.  */
-
-static tree
-instantiate_scev_1 (basic_block instantiate_below,
-                   struct loop *evolution_loop, struct loop *inner_loop,
-                   tree chrec,
-                   bool *fold_conversions, int size_expr)
-{
-  tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
-                                inner_loop, TREE_OPERAND (chrec, 0),
-                                fold_conversions, size_expr);
-
-  if (op0 == chrec_dont_know)
-    return chrec_dont_know;
-
-  if (op0 == TREE_OPERAND (chrec, 0))
-    return chrec;
-
-  return fold_build1 (TREE_CODE (chrec), TREE_TYPE (chrec), op0);
-}
-
 /* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
    and EVOLUTION_LOOP, that were left under a symbolic form.
 
@@ -2818,7 +2707,7 @@ instantiate_scev_1 (basic_block instantiate_below,
    instantiated, and to stop if it exceeds some limit.  */
 
 static tree
-instantiate_scev_r (basic_block instantiate_below,
+instantiate_scev_r (edge instantiate_below,
                    struct loop *evolution_loop, struct loop *inner_loop,
                    tree chrec,
                    bool *fold_conversions, int size_expr)
@@ -2870,50 +2759,20 @@ instantiate_scev_r (basic_block instantiate_below,
                                   fold_conversions, size_expr);
 
     case ADDR_EXPR:
+      if (is_gimple_min_invariant (chrec))
+       return chrec;
+      /* Fallthru.  */
     case SCEV_NOT_KNOWN:
       return chrec_dont_know;
 
     case SCEV_KNOWN:
       return chrec_known;
 
-    case ARRAY_REF:
-      return instantiate_array_ref (instantiate_below, evolution_loop,
-                                   inner_loop, chrec,
-                                   fold_conversions, size_expr);
-
     default:
-      break;
-    }
-
-  if (VL_EXP_CLASS_P (chrec))
-    return chrec_dont_know;
-
-  switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
-    {
-    case 3:
-      return instantiate_scev_3 (instantiate_below, evolution_loop,
-                                inner_loop, chrec,
-                                fold_conversions, size_expr);
-
-    case 2:
-      return instantiate_scev_2 (instantiate_below, evolution_loop,
-                                inner_loop, chrec,
-                                fold_conversions, size_expr);
-
-    case 1:
-      return instantiate_scev_1 (instantiate_below, evolution_loop,
-                                inner_loop, chrec,
-                                fold_conversions, size_expr);
-
-    case 0:
-      return chrec;
-
-    default:
-      break;
+      if (CONSTANT_CLASS_P (chrec))
+       return chrec;
+      return chrec_dont_know;
     }
-
-  /* Too complicated to handle.  */
-  return chrec_dont_know;
 }
 
 /* Analyze all the parameters of the chrec that were left under a
@@ -2923,7 +2782,7 @@ instantiate_scev_r (basic_block instantiate_below,
    a function parameter.  */
 
 tree
-instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop,
+instantiate_scev (edge instantiate_below, struct loop *evolution_loop,
                  tree chrec)
 {
   tree res;
@@ -2931,8 +2790,10 @@ instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop,
   if (dump_file && (dump_flags & TDF_SCEV))
     {
       fprintf (dump_file, "(instantiate_scev \n");
-      fprintf (dump_file, "  (instantiate_below = %d)\n", instantiate_below->index);
-      fprintf (dump_file, "  (evolution_loop = %d)\n", evolution_loop->num);
+      fprintf (dump_file, "  (instantiate_below = %d -> %d)\n",
+              instantiate_below->src->index, instantiate_below->dest->index);
+      if (evolution_loop)
+       fprintf (dump_file, "  (evolution_loop = %d)\n", evolution_loop->num);
       fprintf (dump_file, "  (chrec = ");
       print_generic_expr (dump_file, chrec);
       fprintf (dump_file, ")\n");
@@ -2980,7 +2841,7 @@ resolve_mixers (struct loop *loop, tree chrec, bool *folded_casts)
       destr = true;
     }
 
-  tree ret = instantiate_scev_r (block_before_loop (loop), loop, NULL,
+  tree ret = instantiate_scev_r (loop_preheader_edge (loop), loop, NULL,
                                 chrec, &fold_conversions, 0);
 
   if (folded_casts && !*folded_casts)
index c3980d0fbb2bf46382d90587a15f5dad7de0f8a4..55b8ca49faea465706bf938d600a47fbf3756e01 100644 (file)
@@ -30,7 +30,7 @@ extern void scev_reset (void);
 extern void scev_reset_htab (void);
 extern void scev_finalize (void);
 extern tree analyze_scalar_evolution (struct loop *, tree);
-extern tree instantiate_scev (basic_block, struct loop *, tree);
+extern tree instantiate_scev (edge, struct loop *, tree);
 extern tree resolve_mixers (struct loop *, tree, bool *);
 extern void gather_stats_on_scev_database (void);
 extern void final_value_replacement_loop (struct loop *);
@@ -60,7 +60,7 @@ block_before_loop (loop_p loop)
 static inline tree
 instantiate_parameters (struct loop *loop, tree chrec)
 {
-  return instantiate_scev (block_before_loop (loop), loop, chrec);
+  return instantiate_scev (loop_preheader_edge (loop), loop, chrec);
 }
 
 /* Returns the loop of the polynomial chrec CHREC.  */
index ecf14d108fe3b4141f770f5ffabb6452de7038d9..67767e1516a67e6f20aded15042df56fbe524b45 100644 (file)
@@ -1632,7 +1632,8 @@ determine_loop_nest_reuse (struct loop *loop, struct mem_ref_group *refs,
   for (gr = refs; gr; gr = gr->next)
     for (ref = gr->refs; ref; ref = ref->next)
       {
-       dr = create_data_ref (nest, loop_containing_stmt (ref->stmt),
+       dr = create_data_ref (loop_preheader_edge (nest),
+                             loop_containing_stmt (ref->stmt),
                              ref->mem, ref->stmt, !ref->write_p, false);
 
        if (dr)