re PR tree-optimization/89182 ([graphite] ICE in extract_affine, at graphite-sese...
authorRichard Biener <rguenther@suse.de>
Wed, 6 Feb 2019 11:18:33 +0000 (11:18 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 6 Feb 2019 11:18:33 +0000 (11:18 +0000)
2019-02-06  Richard Biener  <rguenther@suse.de>

PR tree-optimization/89182
* graphite.h (cached_scalar_evolution_in_region): Declare.
* graphite.c (struct seir_cache_key): New.
(struct sese_scev_hash): Likewise.
(seir_cache): New global.
(cached_scalar_evolution_in_region): New function.
(graphite_transform_loops): Allocate and release seir_cache.
* graphite-isl-ast-to-gimple.c (get_rename_from_scev): Use
cached_scalar_evolution_in_region.
* graphite-scop-detection.c (scop_detection::can_represent_loop):
Simplify.
(scop_detection::graphite_can_represent_expr: Use
cached_scalar_evolution_in_region.
(scop_detection::stmt_simple_for_scop_p): Likewise.
(find_params_in_bb): Likewise.
(gather_bbs::before_dom_children): Likewise.
* graphite-sese-to-poly.c (create_pw_aff_from_tree): Likewise.
(add_loop_constraints): Likewise.

* gfortran.dg/graphite/pr89182.f90: New testcase.

From-SVN: r268575

gcc/ChangeLog
gcc/graphite-isl-ast-to-gimple.c
gcc/graphite-scop-detection.c
gcc/graphite-sese-to-poly.c
gcc/graphite.c
gcc/graphite.h
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/graphite/pr89182.f90 [new file with mode: 0644]

index 5e2d7e7..712e768 100644 (file)
@@ -1,3 +1,24 @@
+2019-02-06  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/89182
+       * graphite.h (cached_scalar_evolution_in_region): Declare.
+       * graphite.c (struct seir_cache_key): New.
+       (struct sese_scev_hash): Likewise.
+       (seir_cache): New global.
+       (cached_scalar_evolution_in_region): New function.
+       (graphite_transform_loops): Allocate and release seir_cache.
+       * graphite-isl-ast-to-gimple.c (get_rename_from_scev): Use
+       cached_scalar_evolution_in_region.
+       * graphite-scop-detection.c (scop_detection::can_represent_loop):
+       Simplify.
+       (scop_detection::graphite_can_represent_expr: Use
+       cached_scalar_evolution_in_region.
+       (scop_detection::stmt_simple_for_scop_p): Likewise.
+       (find_params_in_bb): Likewise.
+       (gather_bbs::before_dom_children): Likewise.
+       * graphite-sese-to-poly.c (create_pw_aff_from_tree): Likewise.
+       (add_loop_constraints): Likewise.
+
 2019-02-06  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/89210
index f1619e7..40d1e8d 100644 (file)
@@ -1092,7 +1092,8 @@ tree translate_isl_ast_to_gimple::
 get_rename_from_scev (tree old_name, gimple_seq *stmts, loop_p loop,
                      vec<tree> iv_map)
 {
-  tree scev = scalar_evolution_in_region (region->region, loop, old_name);
+  tree scev = cached_scalar_evolution_in_region (region->region,
+                                                loop, old_name);
 
   /* At this point we should know the exact scev for each
      scalar SSA_NAME used in the scop: all the other scalar
index 7e8d42c..45f459a 100644 (file)
@@ -568,8 +568,6 @@ scop_detection::can_represent_loop (loop_p loop, sese_l scop)
     && niter_desc.control.no_overflow
     && (niter = number_of_latch_executions (loop))
     && !chrec_contains_undetermined (niter)
-    && !chrec_contains_undetermined (scalar_evolution_in_region (scop,
-                                                                loop, niter))
     && graphite_can_represent_expr (scop, loop, niter);
 }
 
@@ -924,7 +922,7 @@ bool
 scop_detection::graphite_can_represent_expr (sese_l scop, loop_p loop,
                                             tree expr)
 {
-  tree scev = scalar_evolution_in_region (scop, loop, expr);
+  tree scev = cached_scalar_evolution_in_region (scop, loop, expr);
   return graphite_can_represent_scev (scop, scev);
 }
 
@@ -1061,7 +1059,8 @@ scop_detection::stmt_simple_for_scop_p (sese_l scop, gimple *stmt,
        FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
          if (scev_analyzable_p (op, scop)
              && chrec_contains_undetermined
-                  (scalar_evolution_in_region (scop, bb->loop_father, op)))
+                  (cached_scalar_evolution_in_region (scop,
+                                                      bb->loop_father, op)))
            {
              DEBUG_PRINT (dp << "[scop-detection-fail] "
                           << "Graphite cannot code-gen stmt:\n";
@@ -1190,10 +1189,10 @@ find_params_in_bb (sese_info_p region, gimple_poly_bb_p gbb)
   FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
     {
       loop_p loop = gimple_bb (stmt)->loop_father;
-      tree lhs = scalar_evolution_in_region (region->region, loop,
-                                            gimple_cond_lhs (stmt));
-      tree rhs = scalar_evolution_in_region (region->region, loop,
-                                            gimple_cond_rhs (stmt));
+      tree lhs = cached_scalar_evolution_in_region (region->region, loop,
+                                                   gimple_cond_lhs (stmt));
+      tree rhs = cached_scalar_evolution_in_region (region->region, loop,
+                                                   gimple_cond_rhs (stmt));
       gcc_assert (!chrec_contains_undetermined (lhs)
                  && !chrec_contains_undetermined (rhs));
 
@@ -1492,8 +1491,8 @@ gather_bbs::before_dom_children (basic_block bb)
       tree nb_iters = number_of_latch_executions (loop);
       if (chrec_contains_symbols (nb_iters))
        {
-         nb_iters = scalar_evolution_in_region (region->region,
-                                                loop, nb_iters);
+         nb_iters = cached_scalar_evolution_in_region (region->region,
+                                                       loop, nb_iters);
          scan_tree_for_params (region, nb_iters);
        }
     }
index 62572dd..08f17db 100644 (file)
@@ -328,7 +328,7 @@ create_pw_aff_from_tree (poly_bb_p pbb, loop_p loop, tree t)
 {
   scop_p scop = PBB_SCOP (pbb);
 
-  t = scalar_evolution_in_region (scop->scop_info->region, loop, t);
+  t = cached_scalar_evolution_in_region (scop->scop_info->region, loop, t);
 
   gcc_assert (!chrec_contains_undetermined (t));
   gcc_assert (!automatically_generated_chrec_p (t));
@@ -782,7 +782,7 @@ add_loop_constraints (scop_p scop, __isl_take isl_set *domain, loop_p loop,
     }
   /* loop_i <= expr_nb_iters */
   gcc_assert (!chrec_contains_undetermined (nb_iters));
-  nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
+  nb_iters = cached_scalar_evolution_in_region (region, loop, nb_iters);
   gcc_assert (!chrec_contains_undetermined (nb_iters));
 
   isl_pw_aff *aff_nb_iters = extract_affine (scop, nb_iters,
index 7b52c16..67202e2 100644 (file)
@@ -210,6 +210,63 @@ print_graphite_statistics (FILE* file, vec<scop_p> scops)
     print_graphite_scop_statistics (file, scop);
 }
 
+struct seir_cache_key
+{
+  hashval_t hash;
+  int entry_dest;
+  int exit_src;
+  int loop_num;
+  tree expr;
+};
+
+struct sese_scev_hash : typed_noop_remove <seir_cache_key>
+{
+  typedef seir_cache_key value_type;
+  typedef seir_cache_key compare_type;
+  static hashval_t hash (const seir_cache_key &key) { return key.hash; }
+  static bool
+  equal (const seir_cache_key &key1, const seir_cache_key &key2)
+  {
+    return (key1.hash == key2.hash
+           && key1.entry_dest == key2.entry_dest
+           && key1.exit_src == key2.exit_src
+           && key1.loop_num == key2.loop_num
+           && operand_equal_p (key1.expr, key2.expr, 0));
+  }
+  static void mark_deleted (seir_cache_key &key) { key.expr = NULL_TREE; }
+  static void mark_empty (seir_cache_key &key) { key.entry_dest = 0; }
+  static bool is_deleted (const seir_cache_key &key) { return !key.expr; }
+  static bool is_empty (const seir_cache_key &key) { return key.entry_dest == 0; }
+};
+
+static hash_map<sese_scev_hash, tree> *seir_cache;
+
+/* Same as scalar_evolution_in_region but caches results so we avoid
+   re-computing evolutions during transform phase.  */
+
+tree
+cached_scalar_evolution_in_region (const sese_l &region, loop_p loop,
+                                  tree expr)
+{
+  seir_cache_key key;
+  key.entry_dest = region.entry->dest->index;
+  key.exit_src = region.exit->src->index;
+  key.loop_num = loop->num;
+  key.expr = expr;
+  inchash::hash hstate (0);
+  hstate.add_int (key.entry_dest);
+  hstate.add_int (key.exit_src);
+  hstate.add_int (key.loop_num);
+  inchash::add_expr (key.expr, hstate);
+  key.hash = hstate.end ();
+  
+  bool existed;
+  tree &chrec = seir_cache->get_or_insert (key, &existed);
+  if (!existed)
+    chrec = scalar_evolution_in_region (region, loop, expr);
+  return chrec;
+}
+
 /* Deletes all scops in SCOPS.  */
 
 static void
@@ -385,6 +442,8 @@ graphite_transform_loops (void)
       print_loops (dump_file, 3);
     }
 
+  seir_cache = new hash_map<sese_scev_hash, tree>;
+
   calculate_dominance_info (CDI_POST_DOMINATORS);
   build_scops (&scops);
   free_dominance_info (CDI_POST_DOMINATORS);
@@ -420,6 +479,9 @@ graphite_transform_loops (void)
          }
       }
 
+  delete seir_cache;
+  seir_cache = NULL;
+
   if (changed)
     {
       mark_virtual_operands_for_renaming (cfun);
index fa0c351..dc4b15d 100644 (file)
@@ -460,6 +460,7 @@ carries_deps (__isl_keep isl_union_map *schedule,
 extern bool build_poly_scop (scop_p);
 extern bool graphite_regenerate_ast_isl (scop_p);
 extern void build_scops (vec<scop_p> *);
+extern tree cached_scalar_evolution_in_region (const sese_l &, loop_p, tree);
 extern void dot_all_sese (FILE *, vec<sese_l> &);
 extern void dot_sese (sese_l &);
 extern void dot_cfg ();
index e37a948..5763b9b 100644 (file)
@@ -1,3 +1,8 @@
+2019-02-06  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/89182
+       * gfortran.dg/graphite/pr89182.f90: New testcase.
+
 2019-02-06  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/89211
diff --git a/gcc/testsuite/gfortran.dg/graphite/pr89182.f90 b/gcc/testsuite/gfortran.dg/graphite/pr89182.f90
new file mode 100644 (file)
index 0000000..73ca735
--- /dev/null
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O3 -fgraphite-identity --param max-completely-peeled-insns=8" }
+
+MODULE hfx_contract_block
+  INTEGER, PARAMETER :: dp=8
+CONTAINS
+  SUBROUTINE contract_block(mb_max,mc_max,kbc,ks_bc)
+    REAL(KIND=dp) :: kbc(mb_max*mc_max), ks_bc
+    CALL block_1_2_1_2(kbc,ks_bc)
+    CALL block_1_2_1_3(kbc,ks_bc)
+    CALL block_1_2_1_3(kbc,ks_bc)
+  END SUBROUTINE contract_block
+  SUBROUTINE block_1_2_1_2(kbc,ks_bc)
+    REAL(KIND=dp) :: kbc(2*1), ks_bc
+    DO mc = 1,2
+       DO mb = 1,2
+          kbc((mc-1)*2+mb) = ks_bc
+       END DO
+    END DO
+  END SUBROUTINE block_1_2_1_2
+  SUBROUTINE block_1_2_1_3(kbc,ks_bc)
+    REAL(KIND=dp) :: kbc(2*1), ks_bc
+    DO md = 1,3
+       DO mc = 1,1
+          DO mb = 1,2
+             kbc((mc-1)*2+mb) = kbc((mc-1)*2+mb) - ks_bc
+          END DO
+       END DO
+    END DO
+  END SUBROUTINE block_1_2_1_3
+END MODULE hfx_contract_block