+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
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
&& 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);
}
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);
}
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";
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));
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);
}
}
{
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));
}
/* 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,
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 ®ion, 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
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);
}
}
+ delete seir_cache;
+ seir_cache = NULL;
+
if (changed)
{
mark_virtual_operands_for_renaming (cfun);
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 ();
+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
--- /dev/null
+! { 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