Commit adba512d by Aditya Kumar Committed by Sebastian Pop

new scop schedule for isl-0.15

Keep unchanged the implementation for isl-0.14.

	* graphite-poly.c (apply_poly_transforms): Simplify.
	(print_isl_set): Use more readable format: ISL_YAML_STYLE_BLOCK.
	(print_isl_map): Same.
	(print_isl_union_map): Same.
	(print_isl_schedule): New.
	(debug_isl_schedule): New.
	* graphite-dependences.c (scop_get_reads): Do not call
	isl_union_map_add_map that is undocumented isl functionality.
	(scop_get_must_writes): Same.
	(scop_get_may_writes): Same.
	(scop_get_original_schedule): Remove.
	(scop_get_dependences): Do not call isl_union_map_compute_flow that
	is deprecated in isl 0.15.  Instead, use isl_union_access_* interface.
	(compute_deps): Remove.
	* graphite-isl-ast-to-gimple.c (print_schedule_ast): New.
	(debug_schedule_ast): New.
	(translate_isl_ast_to_gimple::scop_to_isl_ast): Call set_separate_option.
	(graphite_regenerate_ast_isl): Add dump.
	(translate_isl_ast_to_gimple::scop_to_isl_ast): Generate code
	from scop->transformed_schedule.
	(graphite_regenerate_ast_isl): Add more dump.
	* graphite-optimize-isl.c (optimize_isl): Set
	scop->transformed_schedule.  Check whether schedules are equal.
	(apply_poly_transforms): Move here.
	* graphite-poly.c (apply_poly_transforms): ... from here.
	(free_poly_bb): Static.
	(free_scop): Static.
	(pbb_number_of_iterations_at_time): Remove.
	(print_isl_ast): New.
	(debug_isl_ast): New.
	(debug_scop_pbb): New.
	* graphite-scop-detection.c (print_edge): Move.
	(print_sese): Move.
	* graphite-sese-to-poly.c (build_pbb_scattering_polyhedrons): Remove.
	(build_scop_scattering): Remove.
	(create_pw_aff_from_tree): Assert instead of bailing out.
	(add_condition_to_pbb): Remove unused code, do not fail.
	(add_conditions_to_domain): Same.
	(add_conditions_to_constraints): Remove.
	(build_scop_context): New.
	(add_iter_domain_dimension): New.
	(build_iteration_domains): Initialize pbb->iterators.
	Call add_conditions_to_domain.
	(nested_in): New.
	(loop_at): New.
	(index_outermost_in_loop): New.
	(index_pbb_in_loop): New.
	(outermost_pbb_in): New.
	(add_in_sequence): New.
	(add_outer_projection): New.
	(outer_projection_mupa): New.
	(add_loop_schedule): New.
	(build_schedule_pbb): New.
	(build_schedule_loop): New.
	(embed_in_surrounding_loops): New.
	(build_schedule_loop_nest): New.
	(build_original_schedule): New.
	(build_poly_scop): Call build_original_schedule.
	* graphite.h: Declare print_isl_schedule and debug_isl_schedule.
	(free_poly_dr): Remove.
	(struct poly_bb): Add iterators.  Remove schedule, transformed, saved.
	(free_poly_bb): Remove.
	(debug_loop_vec): Remove.
	(print_isl_ast): Declare.
	(debug_isl_ast): Declare.
	(scop_do_interchange): Remove.
	(scop_do_strip_mine): Remove.
	(scop_do_block): Remove.
	(flatten_all_loops): Remove.
	(optimize_isl): Remove.
	(pbb_number_of_iterations_at_time): Remove.
	(debug_scop_pbb): Declare.
	(print_schedule_ast): Declare.
	(debug_schedule_ast): Declare.
	(struct scop): Remove schedule.  Add original_schedule,
	transformed_schedule.
	(free_gimple_poly_bb): Remove.
	(print_generated_program): Remove.
	(debug_generated_program): Remove.
	(unify_scattering_dimensions): Remove.
	* sese.c (print_edge): ... here.
	(print_sese): ... here.
	(debug_edge): ... here.
	(debug_sese): ... here.
	* sese.h (print_edge): Declare.
	(print_sese): Declare.
	(dump_edge): Declare.
	(dump_sese): Declare.

Co-Authored-By: Sebastian Pop <s.pop@samsung.com>

From-SVN: r232812
parent 1e050c90
2016-01-25 Aditya Kumar <aditya.k7@samsung.com> 2016-01-25 Aditya Kumar <aditya.k7@samsung.com>
Sebastian Pop <s.pop@samsung.com> Sebastian Pop <s.pop@samsung.com>
* graphite-poly.c (apply_poly_transforms): Simplify.
(print_isl_set): Use more readable format: ISL_YAML_STYLE_BLOCK.
(print_isl_map): Same.
(print_isl_union_map): Same.
(print_isl_schedule): New.
(debug_isl_schedule): New.
* graphite-dependences.c (scop_get_reads): Do not call
isl_union_map_add_map that is undocumented isl functionality.
(scop_get_must_writes): Same.
(scop_get_may_writes): Same.
(scop_get_original_schedule): Remove.
(scop_get_dependences): Do not call isl_union_map_compute_flow that
is deprecated in isl 0.15. Instead, use isl_union_access_* interface.
(compute_deps): Remove.
* graphite-isl-ast-to-gimple.c (print_schedule_ast): New.
(debug_schedule_ast): New.
(translate_isl_ast_to_gimple::scop_to_isl_ast): Call set_separate_option.
(graphite_regenerate_ast_isl): Add dump.
(translate_isl_ast_to_gimple::scop_to_isl_ast): Generate code
from scop->transformed_schedule.
(graphite_regenerate_ast_isl): Add more dump.
* graphite-optimize-isl.c (optimize_isl): Set
scop->transformed_schedule. Check whether schedules are equal.
(apply_poly_transforms): Move here.
* graphite-poly.c (apply_poly_transforms): ... from here.
(free_poly_bb): Static.
(free_scop): Static.
(pbb_number_of_iterations_at_time): Remove.
(print_isl_ast): New.
(debug_isl_ast): New.
(debug_scop_pbb): New.
* graphite-scop-detection.c (print_edge): Move.
(print_sese): Move.
* graphite-sese-to-poly.c (build_pbb_scattering_polyhedrons): Remove.
(build_scop_scattering): Remove.
(create_pw_aff_from_tree): Assert instead of bailing out.
(add_condition_to_pbb): Remove unused code, do not fail.
(add_conditions_to_domain): Same.
(add_conditions_to_constraints): Remove.
(build_scop_context): New.
(add_iter_domain_dimension): New.
(build_iteration_domains): Initialize pbb->iterators.
Call add_conditions_to_domain.
(nested_in): New.
(loop_at): New.
(index_outermost_in_loop): New.
(index_pbb_in_loop): New.
(outermost_pbb_in): New.
(add_in_sequence): New.
(add_outer_projection): New.
(outer_projection_mupa): New.
(add_loop_schedule): New.
(build_schedule_pbb): New.
(build_schedule_loop): New.
(embed_in_surrounding_loops): New.
(build_schedule_loop_nest): New.
(build_original_schedule): New.
(build_poly_scop): Call build_original_schedule.
* graphite.h: Declare print_isl_schedule and debug_isl_schedule.
(free_poly_dr): Remove.
(struct poly_bb): Add iterators. Remove schedule, transformed, saved.
(free_poly_bb): Remove.
(debug_loop_vec): Remove.
(print_isl_ast): Declare.
(debug_isl_ast): Declare.
(scop_do_interchange): Remove.
(scop_do_strip_mine): Remove.
(scop_do_block): Remove.
(flatten_all_loops): Remove.
(optimize_isl): Remove.
(pbb_number_of_iterations_at_time): Remove.
(debug_scop_pbb): Declare.
(print_schedule_ast): Declare.
(debug_schedule_ast): Declare.
(struct scop): Remove schedule. Add original_schedule,
transformed_schedule.
(free_gimple_poly_bb): Remove.
(print_generated_program): Remove.
(debug_generated_program): Remove.
(unify_scattering_dimensions): Remove.
* sese.c (print_edge): ... here.
(print_sese): ... here.
(debug_edge): ... here.
(debug_sese): ... here.
* sese.h (print_edge): Declare.
(print_sese): Declare.
(dump_edge): Declare.
(dump_sese): Declare.
2016-01-25 Aditya Kumar <aditya.k7@samsung.com>
Sebastian Pop <s.pop@samsung.com>
* Makefile.in: Set ISLVER in site.exp. * Makefile.in: Set ISLVER in site.exp.
2016-01-25 Jakub Jelinek <jakub@redhat.com> 2016-01-25 Jakub Jelinek <jakub@redhat.com>
......
...@@ -66,7 +66,7 @@ add_pdr_constraints (poly_dr_p pdr, poly_bb_p pbb) ...@@ -66,7 +66,7 @@ add_pdr_constraints (poly_dr_p pdr, poly_bb_p pbb)
/* Returns all the memory reads in SCOP. */ /* Returns all the memory reads in SCOP. */
static isl_union_map * static isl_union_map *
scop_get_reads (scop_p scop, vec<poly_bb_p> pbbs) scop_get_reads (scop_p scop)
{ {
int i, j; int i, j;
poly_bb_p pbb; poly_bb_p pbb;
...@@ -74,7 +74,7 @@ scop_get_reads (scop_p scop, vec<poly_bb_p> pbbs) ...@@ -74,7 +74,7 @@ scop_get_reads (scop_p scop, vec<poly_bb_p> pbbs)
isl_space *space = isl_set_get_space (scop->param_context); isl_space *space = isl_set_get_space (scop->param_context);
isl_union_map *res = isl_union_map_empty (space); isl_union_map *res = isl_union_map_empty (space);
FOR_EACH_VEC_ELT (pbbs, i, pbb) FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
{ {
FOR_EACH_VEC_ELT (PBB_DRS (pbb), j, pdr) FOR_EACH_VEC_ELT (PBB_DRS (pbb), j, pdr)
if (pdr_read_p (pdr)) if (pdr_read_p (pdr))
...@@ -84,7 +84,9 @@ scop_get_reads (scop_p scop, vec<poly_bb_p> pbbs) ...@@ -84,7 +84,9 @@ scop_get_reads (scop_p scop, vec<poly_bb_p> pbbs)
fprintf (dump_file, "Adding read to depedence graph: "); fprintf (dump_file, "Adding read to depedence graph: ");
print_pdr (dump_file, pdr); print_pdr (dump_file, pdr);
} }
res = isl_union_map_add_map (res, add_pdr_constraints (pdr, pbb)); isl_union_map *um
= isl_union_map_from_map (add_pdr_constraints (pdr, pbb));
res = isl_union_map_union (res, um);
if (dump_file) if (dump_file)
{ {
fprintf (dump_file, "Reads depedence graph: "); fprintf (dump_file, "Reads depedence graph: ");
...@@ -99,7 +101,7 @@ scop_get_reads (scop_p scop, vec<poly_bb_p> pbbs) ...@@ -99,7 +101,7 @@ scop_get_reads (scop_p scop, vec<poly_bb_p> pbbs)
/* Returns all the memory must writes in SCOP. */ /* Returns all the memory must writes in SCOP. */
static isl_union_map * static isl_union_map *
scop_get_must_writes (scop_p scop, vec<poly_bb_p> pbbs) scop_get_must_writes (scop_p scop)
{ {
int i, j; int i, j;
poly_bb_p pbb; poly_bb_p pbb;
...@@ -107,7 +109,7 @@ scop_get_must_writes (scop_p scop, vec<poly_bb_p> pbbs) ...@@ -107,7 +109,7 @@ scop_get_must_writes (scop_p scop, vec<poly_bb_p> pbbs)
isl_space *space = isl_set_get_space (scop->param_context); isl_space *space = isl_set_get_space (scop->param_context);
isl_union_map *res = isl_union_map_empty (space); isl_union_map *res = isl_union_map_empty (space);
FOR_EACH_VEC_ELT (pbbs, i, pbb) FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
{ {
FOR_EACH_VEC_ELT (PBB_DRS (pbb), j, pdr) FOR_EACH_VEC_ELT (PBB_DRS (pbb), j, pdr)
if (pdr_write_p (pdr)) if (pdr_write_p (pdr))
...@@ -117,7 +119,9 @@ scop_get_must_writes (scop_p scop, vec<poly_bb_p> pbbs) ...@@ -117,7 +119,9 @@ scop_get_must_writes (scop_p scop, vec<poly_bb_p> pbbs)
fprintf (dump_file, "Adding must write to depedence graph: "); fprintf (dump_file, "Adding must write to depedence graph: ");
print_pdr (dump_file, pdr); print_pdr (dump_file, pdr);
} }
res = isl_union_map_add_map (res, add_pdr_constraints (pdr, pbb)); isl_union_map *um
= isl_union_map_from_map (add_pdr_constraints (pdr, pbb));
res = isl_union_map_union (res, um);
if (dump_file) if (dump_file)
{ {
fprintf (dump_file, "Must writes depedence graph: "); fprintf (dump_file, "Must writes depedence graph: ");
...@@ -132,7 +136,7 @@ scop_get_must_writes (scop_p scop, vec<poly_bb_p> pbbs) ...@@ -132,7 +136,7 @@ scop_get_must_writes (scop_p scop, vec<poly_bb_p> pbbs)
/* Returns all the memory may writes in SCOP. */ /* Returns all the memory may writes in SCOP. */
static isl_union_map * static isl_union_map *
scop_get_may_writes (scop_p scop, vec<poly_bb_p> pbbs) scop_get_may_writes (scop_p scop)
{ {
int i, j; int i, j;
poly_bb_p pbb; poly_bb_p pbb;
...@@ -140,7 +144,7 @@ scop_get_may_writes (scop_p scop, vec<poly_bb_p> pbbs) ...@@ -140,7 +144,7 @@ scop_get_may_writes (scop_p scop, vec<poly_bb_p> pbbs)
isl_space *space = isl_set_get_space (scop->param_context); isl_space *space = isl_set_get_space (scop->param_context);
isl_union_map *res = isl_union_map_empty (space); isl_union_map *res = isl_union_map_empty (space);
FOR_EACH_VEC_ELT (pbbs, i, pbb) FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
{ {
FOR_EACH_VEC_ELT (PBB_DRS (pbb), j, pdr) FOR_EACH_VEC_ELT (PBB_DRS (pbb), j, pdr)
if (pdr_may_write_p (pdr)) if (pdr_may_write_p (pdr))
...@@ -150,7 +154,9 @@ scop_get_may_writes (scop_p scop, vec<poly_bb_p> pbbs) ...@@ -150,7 +154,9 @@ scop_get_may_writes (scop_p scop, vec<poly_bb_p> pbbs)
fprintf (dump_file, "Adding may write to depedence graph: "); fprintf (dump_file, "Adding may write to depedence graph: ");
print_pdr (dump_file, pdr); print_pdr (dump_file, pdr);
} }
res = isl_union_map_add_map (res, add_pdr_constraints (pdr, pbb)); isl_union_map *um
= isl_union_map_from_map (add_pdr_constraints (pdr, pbb));
res = isl_union_map_union (res, um);
if (dump_file) if (dump_file)
{ {
fprintf (dump_file, "May writes depedence graph: "); fprintf (dump_file, "May writes depedence graph: ");
...@@ -162,6 +168,7 @@ scop_get_may_writes (scop_p scop, vec<poly_bb_p> pbbs) ...@@ -162,6 +168,7 @@ scop_get_may_writes (scop_p scop, vec<poly_bb_p> pbbs)
return isl_union_map_coalesce (res); return isl_union_map_coalesce (res);
} }
#ifndef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
/* Returns all the original schedules in SCOP. */ /* Returns all the original schedules in SCOP. */
static isl_union_map * static isl_union_map *
...@@ -181,6 +188,7 @@ scop_get_original_schedule (scop_p scop, vec<poly_bb_p> pbbs) ...@@ -181,6 +188,7 @@ scop_get_original_schedule (scop_p scop, vec<poly_bb_p> pbbs)
return isl_union_map_coalesce (res); return isl_union_map_coalesce (res);
} }
#endif
/* Helper function used on each MAP of a isl_union_map. Computes the /* Helper function used on each MAP of a isl_union_map. Computes the
maximal output dimension. */ maximal output dimension. */
...@@ -303,6 +311,95 @@ carries_deps (__isl_keep isl_union_map *schedule, ...@@ -303,6 +311,95 @@ carries_deps (__isl_keep isl_union_map *schedule,
return res; return res;
} }
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
/* Compute the dependence relations for the SCOP:
RAW are read after write dependences,
WAR are write after read dependences,
WAW are write after write dependences. */
void
scop_get_dependences (scop_p scop)
{
if (scop->dependence)
return;
isl_union_map *reads = scop_get_reads (scop);
isl_union_map *must_writes = scop_get_must_writes (scop);
isl_union_map *may_writes = scop_get_may_writes (scop);
if (dump_file)
{
fprintf (dump_file, "\n--- Documentation for datarefs dump: ---\n");
fprintf (dump_file, "Statements on the iteration domain are mapped to"
" array references.\n");
fprintf (dump_file, " To read the following data references:\n\n");
fprintf (dump_file, " S_5[i0] -> [106] : i0 >= 0 and i0 <= 3\n");
fprintf (dump_file, " S_8[i0] -> [1, i0] : i0 >= 0 and i0 <= 3\n\n");
fprintf (dump_file, " S_5[i0] is the dynamic instance of statement"
" bb_5 in a loop that accesses all iterations 0 <= i0 <= 3.\n");
fprintf (dump_file, " [1, i0] is a 'memref' with alias set 1"
" and first subscript access i0.\n");
fprintf (dump_file, " [106] is a 'scalar reference' which is the sum of"
" SSA_NAME_VERSION 6"
" and --param graphite-max-arrays-per-scop=100\n");
fprintf (dump_file, "-----------------------\n\n");
fprintf (dump_file, "data references (\n");
fprintf (dump_file, " reads: ");
print_isl_union_map (dump_file, reads);
fprintf (dump_file, " must_writes: ");
print_isl_union_map (dump_file, must_writes);
fprintf (dump_file, " may_writes: ");
print_isl_union_map (dump_file, may_writes);
fprintf (dump_file, ")\n");
}
gcc_assert (scop->original_schedule);
isl_union_access_info *ai;
ai = isl_union_access_info_from_sink (isl_union_map_copy (reads));
ai = isl_union_access_info_set_must_source (ai, isl_union_map_copy (must_writes));
ai = isl_union_access_info_set_may_source (ai, may_writes);
ai = isl_union_access_info_set_schedule
(ai, isl_schedule_copy (scop->original_schedule));
isl_union_flow *flow = isl_union_access_info_compute_flow (ai);
isl_union_map *raw = isl_union_flow_get_must_dependence (flow);
isl_union_flow_free (flow);
ai = isl_union_access_info_from_sink (isl_union_map_copy (must_writes));
ai = isl_union_access_info_set_must_source (ai, must_writes);
ai = isl_union_access_info_set_may_source (ai, reads);
ai = isl_union_access_info_set_schedule
(ai, isl_schedule_copy (scop->original_schedule));
flow = isl_union_access_info_compute_flow (ai);
isl_union_map *waw = isl_union_flow_get_must_dependence (flow);
isl_union_map *war = isl_union_flow_get_may_dependence (flow);
war = isl_union_map_subtract (war, isl_union_map_copy (waw));
isl_union_flow_free (flow);
raw = isl_union_map_coalesce (raw);
waw = isl_union_map_coalesce (waw);
war = isl_union_map_coalesce (war);
isl_union_map *dependences = raw;
dependences = isl_union_map_union (dependences, war);
dependences = isl_union_map_union (dependences, waw);
dependences = isl_union_map_coalesce (dependences);
if (dump_file)
{
fprintf (dump_file, "data dependences (\n");
print_isl_union_map (dump_file, dependences);
fprintf (dump_file, ")\n");
}
scop->dependence = dependences;
}
#else
/* Compute the original data dependences in SCOP for all the reads and /* Compute the original data dependences in SCOP for all the reads and
writes in PBBS. */ writes in PBBS. */
...@@ -321,9 +418,9 @@ compute_deps (scop_p scop, vec<poly_bb_p> pbbs, ...@@ -321,9 +418,9 @@ compute_deps (scop_p scop, vec<poly_bb_p> pbbs,
isl_union_map **must_waw_no_source, isl_union_map **must_waw_no_source,
isl_union_map **may_waw_no_source) isl_union_map **may_waw_no_source)
{ {
isl_union_map *reads = scop_get_reads (scop, pbbs); isl_union_map *reads = scop_get_reads (scop);
isl_union_map *must_writes = scop_get_must_writes (scop, pbbs); isl_union_map *must_writes = scop_get_must_writes (scop);
isl_union_map *may_writes = scop_get_may_writes (scop, pbbs); isl_union_map *may_writes = scop_get_may_writes (scop);
isl_union_map *all_writes = isl_union_map_union isl_union_map *all_writes = isl_union_map_union
(isl_union_map_copy (must_writes), isl_union_map_copy (may_writes)); (isl_union_map_copy (must_writes), isl_union_map_copy (may_writes));
all_writes = isl_union_map_coalesce (all_writes); all_writes = isl_union_map_coalesce (all_writes);
...@@ -428,4 +525,6 @@ scop_get_dependences (scop_p scop) ...@@ -428,4 +525,6 @@ scop_get_dependences (scop_p scop)
return dependences; return dependences;
} }
#endif /* HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS */
#endif /* HAVE_isl */ #endif /* HAVE_isl */
...@@ -105,7 +105,7 @@ typedef std::map<isl_id *, tree> ivs_params; ...@@ -105,7 +105,7 @@ typedef std::map<isl_id *, tree> ivs_params;
/* Free all memory allocated for isl's identifiers. */ /* Free all memory allocated for isl's identifiers. */
void ivs_params_clear (ivs_params &ip) static void ivs_params_clear (ivs_params &ip)
{ {
std::map<isl_id *, tree>::iterator it; std::map<isl_id *, tree>::iterator it;
for (it = ip.begin (); for (it = ip.begin ();
...@@ -119,7 +119,7 @@ void ivs_params_clear (ivs_params &ip) ...@@ -119,7 +119,7 @@ void ivs_params_clear (ivs_params &ip)
/* Set the "separate" option for the schedule node. */ /* Set the "separate" option for the schedule node. */
static __isl_give isl_schedule_node * static isl_schedule_node *
set_separate_option (__isl_take isl_schedule_node *node, void *user) set_separate_option (__isl_take isl_schedule_node *node, void *user)
{ {
if (user) if (user)
...@@ -136,6 +136,27 @@ set_separate_option (__isl_take isl_schedule_node *node, void *user) ...@@ -136,6 +136,27 @@ set_separate_option (__isl_take isl_schedule_node *node, void *user)
return node; return node;
} }
/* Print SCHEDULE under an AST form on file F. */
void
print_schedule_ast (FILE *f, __isl_keep isl_schedule *schedule, scop_p scop)
{
isl_set *set = isl_set_params (isl_set_copy (scop->param_context));
isl_ast_build *context = isl_ast_build_from_context (set);
isl_ast_node *ast
= isl_ast_build_node_from_schedule (context, isl_schedule_copy (schedule));
isl_ast_build_free (context);
print_isl_ast (f, ast);
isl_ast_node_free (ast);
}
DEBUG_FUNCTION void
debug_schedule_ast (__isl_keep isl_schedule *s, scop_p scop)
{
print_schedule_ast (stderr, s, scop);
}
#endif #endif
enum phi_node_kind enum phi_node_kind
...@@ -288,48 +309,50 @@ class translate_isl_ast_to_gimple ...@@ -288,48 +309,50 @@ class translate_isl_ast_to_gimple
void add_parameters_to_ivs_params (scop_p scop, ivs_params &ip); void add_parameters_to_ivs_params (scop_p scop, ivs_params &ip);
/* Get the maximal number of schedule dimensions in the scop SCOP. */
int get_max_schedule_dimensions (scop_p scop);
/* Generates a build, which specifies the constraints on the parameters. */ /* Generates a build, which specifies the constraints on the parameters. */
__isl_give isl_ast_build *generate_isl_context (scop_p scop); __isl_give isl_ast_build *generate_isl_context (scop_p scop);
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
/* Generate isl AST from schedule of SCOP. */
__isl_give isl_ast_node * scop_to_isl_ast (scop_p scop);
#else
/* Get the maximal number of schedule dimensions in the scop SCOP. */
int get_max_schedule_dimensions (scop_p scop);
/* Extend the schedule to NB_SCHEDULE_DIMS schedule dimensions. /* Extend the schedule to NB_SCHEDULE_DIMS schedule dimensions.
For schedules with different dimensionality, the isl AST generator can not For schedules with different dimensionality, the isl AST generator can not
define an order and will just randomly choose an order. The solution to define an order and will just randomly choose an order. The solution to
this problem is to extend all schedules to the maximal number of schedule this problem is to extend all schedules to the maximal number of schedule
dimensions (using '0's for the remaining values). */ dimensions (using '0's for the remaining values). */
__isl_give isl_map *extend_schedule (__isl_take isl_map *schedule, __isl_give isl_map *extend_schedule (__isl_take isl_map *schedule,
int nb_schedule_dims); int nb_schedule_dims);
/* Generates a schedule, which specifies an order used to /* Generates a schedule, which specifies an order used to
visit elements in a domain. */ visit elements in a domain. */
__isl_give isl_union_map *generate_isl_schedule (scop_p scop); __isl_give isl_union_map *generate_isl_schedule (scop_p scop);
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
/* Set the "separate" option for all schedules. This helps reducing control
overhead. */
__isl_give isl_schedule *
set_options_for_schedule_tree (__isl_take isl_schedule *schedule);
#endif
/* Set the separate option for all dimensions. /* Set the separate option for all dimensions.
This helps to reduce control overhead. */ This helps to reduce control overhead. */
__isl_give isl_ast_build *set_options (__isl_take isl_ast_build *control,
__isl_give isl_ast_build * set_options (__isl_take isl_ast_build *control,
__isl_keep isl_union_map *schedule); __isl_keep isl_union_map *schedule);
/* Generate isl AST from schedule of SCOP. Also, collects IVS_PARAMS in /* Generate isl AST from schedule of SCOP. Also, collects IVS_PARAMS in
IP. */ IP. */
__isl_give isl_ast_node *scop_to_isl_ast (scop_p scop, ivs_params &ip);
__isl_give isl_ast_node * scop_to_isl_ast (scop_p scop, ivs_params &ip); /* Prints NODE to FILE. */
void print_isl_ast_node (FILE *file, __isl_keep isl_ast_node *node,
__isl_keep isl_ctx *ctx) const
{
isl_printer *prn = isl_printer_to_file (ctx, file);
prn = isl_printer_set_output_format (prn, ISL_FORMAT_C);
prn = isl_printer_print_ast_node (prn, node);
prn = isl_printer_print_str (prn, "\n");
isl_printer_free (prn);
}
#endif
/* Return true if RENAME (defined in BB) is a valid use in NEW_BB. The /* Return true if RENAME (defined in BB) is a valid use in NEW_BB. The
definition should flow into use, and the use should respect the loop-closed definition should flow into use, and the use should respect the loop-closed
...@@ -485,11 +508,6 @@ class translate_isl_ast_to_gimple ...@@ -485,11 +508,6 @@ class translate_isl_ast_to_gimple
bool codegen_error_p () const bool codegen_error_p () const
{ return codegen_error; } { return codegen_error; }
/* Prints NODE to FILE. */
void print_isl_ast_node (FILE *file, __isl_keep isl_ast_node *node,
__isl_keep isl_ctx *ctx) const;
/* Return true when OP is a constant tree. */ /* Return true when OP is a constant tree. */
bool is_constant (tree op) const bool is_constant (tree op) const
...@@ -1389,7 +1407,7 @@ is_valid_rename (tree rename, basic_block def_bb, basic_block use_bb, ...@@ -1389,7 +1407,7 @@ is_valid_rename (tree rename, basic_block def_bb, basic_block use_bb,
{ {
if (dump_file) if (dump_file)
{ {
fprintf (dump_file, "[codegen] rename not in loop closed ssa:"); fprintf (dump_file, "[codegen] rename not in loop closed ssa: ");
print_generic_expr (dump_file, rename, 0); print_generic_expr (dump_file, rename, 0);
fprintf (dump_file, "\n"); fprintf (dump_file, "\n");
} }
...@@ -3110,20 +3128,6 @@ translate_isl_ast_to_gimple::translate_pending_phi_nodes () ...@@ -3110,20 +3128,6 @@ translate_isl_ast_to_gimple::translate_pending_phi_nodes ()
} }
} }
/* Prints NODE to FILE. */
void
translate_isl_ast_to_gimple::print_isl_ast_node (FILE *file,
__isl_keep isl_ast_node *node,
__isl_keep isl_ctx *ctx) const
{
isl_printer *prn = isl_printer_to_file (ctx, file);
prn = isl_printer_set_output_format (prn, ISL_FORMAT_C);
prn = isl_printer_print_ast_node (prn, node);
prn = isl_printer_print_str (prn, "\n");
isl_printer_free (prn);
}
/* Add isl's parameter identifiers and corresponding trees to ivs_params. */ /* Add isl's parameter identifiers and corresponding trees to ivs_params. */
void void
...@@ -3152,6 +3156,52 @@ translate_isl_ast_to_gimple::generate_isl_context (scop_p scop) ...@@ -3152,6 +3156,52 @@ translate_isl_ast_to_gimple::generate_isl_context (scop_p scop)
return isl_ast_build_from_context (context_isl); return isl_ast_build_from_context (context_isl);
} }
/* This method is executed before the construction of a for node. */
__isl_give isl_id *
ast_build_before_for (__isl_keep isl_ast_build *build, void *user)
{
isl_union_map *dependences = (isl_union_map *) user;
ast_build_info *for_info = XNEW (struct ast_build_info);
isl_union_map *schedule = isl_ast_build_get_schedule (build);
isl_space *schedule_space = isl_ast_build_get_schedule_space (build);
int dimension = isl_space_dim (schedule_space, isl_dim_out);
for_info->is_parallelizable =
!carries_deps (schedule, dependences, dimension);
isl_union_map_free (schedule);
isl_space_free (schedule_space);
isl_id *id = isl_id_alloc (isl_ast_build_get_ctx (build), "", for_info);
return id;
}
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
/* Generate isl AST from schedule of SCOP. */
__isl_give isl_ast_node *
translate_isl_ast_to_gimple::scop_to_isl_ast (scop_p scop)
{
gcc_assert (scop->transformed_schedule);
/* Set the separate option to reduce control flow overhead. */
isl_schedule *schedule = isl_schedule_map_schedule_node_bottom_up
(isl_schedule_copy (scop->transformed_schedule), set_separate_option, NULL);
isl_ast_build *context_isl = generate_isl_context (scop);
if (flag_loop_parallelize_all)
{
scop_get_dependences (scop);
context_isl =
isl_ast_build_set_before_each_for (context_isl, ast_build_before_for,
scop->dependence);
}
isl_ast_node *ast_isl = isl_ast_build_node_from_schedule
(context_isl, schedule);
isl_ast_build_free (context_isl);
return ast_isl;
}
#else
/* Get the maximal number of schedule dimensions in the scop SCOP. */ /* Get the maximal number of schedule dimensions in the scop SCOP. */
int int
...@@ -3229,36 +3279,6 @@ translate_isl_ast_to_gimple::generate_isl_schedule (scop_p scop) ...@@ -3229,36 +3279,6 @@ translate_isl_ast_to_gimple::generate_isl_schedule (scop_p scop)
return schedule_isl; return schedule_isl;
} }
/* This method is executed before the construction of a for node. */
__isl_give isl_id *
ast_build_before_for (__isl_keep isl_ast_build *build, void *user)
{
isl_union_map *dependences = (isl_union_map *) user;
ast_build_info *for_info = XNEW (struct ast_build_info);
isl_union_map *schedule = isl_ast_build_get_schedule (build);
isl_space *schedule_space = isl_ast_build_get_schedule_space (build);
int dimension = isl_space_dim (schedule_space, isl_dim_out);
for_info->is_parallelizable =
!carries_deps (schedule, dependences, dimension);
isl_union_map_free (schedule);
isl_space_free (schedule_space);
isl_id *id = isl_id_alloc (isl_ast_build_get_ctx (build), "", for_info);
return id;
}
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
/* Set the separate option for all schedules. This helps reducing control
overhead. */
__isl_give isl_schedule *
translate_isl_ast_to_gimple::set_options_for_schedule_tree
(__isl_take isl_schedule *schedule)
{
return isl_schedule_map_schedule_node_bottom_up
(schedule, set_separate_option, NULL);
}
#endif
/* Set the separate option for all dimensions. /* Set the separate option for all dimensions.
This helps to reduce control overhead. */ This helps to reduce control overhead. */
...@@ -3283,7 +3303,6 @@ translate_isl_ast_to_gimple::set_options (__isl_take isl_ast_build *control, ...@@ -3283,7 +3303,6 @@ translate_isl_ast_to_gimple::set_options (__isl_take isl_ast_build *control,
__isl_give isl_ast_node * __isl_give isl_ast_node *
translate_isl_ast_to_gimple::scop_to_isl_ast (scop_p scop, ivs_params &ip) translate_isl_ast_to_gimple::scop_to_isl_ast (scop_p scop, ivs_params &ip)
{ {
isl_ast_node *ast_isl = NULL;
/* Generate loop upper bounds that consist of the current loop iterator, an /* Generate loop upper bounds that consist of the current loop iterator, an
operator (< or <=) and an expression not involving the iterator. If this operator (< or <=) and an expression not involving the iterator. If this
option is not set, then the current loop iterator may appear several times option is not set, then the current loop iterator may appear several times
...@@ -3302,23 +3321,18 @@ translate_isl_ast_to_gimple::scop_to_isl_ast (scop_p scop, ivs_params &ip) ...@@ -3302,23 +3321,18 @@ translate_isl_ast_to_gimple::scop_to_isl_ast (scop_p scop, ivs_params &ip)
dependence); dependence);
} }
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS isl_ast_node *ast_isl = isl_ast_build_ast_from_schedule (context_isl,
schedule_isl);
if (scop->schedule) if (scop->schedule)
{ {
scop->schedule = set_options_for_schedule_tree (scop->schedule);
ast_isl = isl_ast_build_node_from_schedule (context_isl, scop->schedule);
isl_union_map_free(schedule_isl);
}
else
ast_isl = isl_ast_build_ast_from_schedule (context_isl, schedule_isl);
#else
ast_isl = isl_ast_build_ast_from_schedule (context_isl, schedule_isl);
isl_schedule_free (scop->schedule); isl_schedule_free (scop->schedule);
#endif scop->schedule = NULL;
}
isl_ast_build_free (context_isl); isl_ast_build_free (context_isl);
return ast_isl; return ast_isl;
} }
#endif
/* Copy def from sese REGION to the newly created TO_REGION. TR is defined by /* Copy def from sese REGION to the newly created TO_REGION. TR is defined by
DEF_STMT. GSI points to entry basic block of the TO_REGION. */ DEF_STMT. GSI points to entry basic block of the TO_REGION. */
...@@ -3401,12 +3415,26 @@ graphite_regenerate_ast_isl (scop_p scop) ...@@ -3401,12 +3415,26 @@ graphite_regenerate_ast_isl (scop_p scop)
ivs_params ip; ivs_params ip;
timevar_push (TV_GRAPHITE_CODE_GEN); timevar_push (TV_GRAPHITE_CODE_GEN);
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
t.add_parameters_to_ivs_params (scop, ip);
root_node = t.scop_to_isl_ast (scop);
#else
root_node = t.scop_to_isl_ast (scop, ip); root_node = t.scop_to_isl_ast (scop, ip);
#endif
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
fprintf (dump_file, "AST generated by isl: \n"); #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
t.print_isl_ast_node (dump_file, root_node, scop->isl_context); fprintf (dump_file, "[scheduler] original schedule:\n");
print_isl_schedule (dump_file, scop->original_schedule);
fprintf (dump_file, "[scheduler] isl transformed schedule:\n");
print_isl_schedule (dump_file, scop->transformed_schedule);
fprintf (dump_file, "[scheduler] original ast:\n");
print_schedule_ast (dump_file, scop->original_schedule, scop);
#endif
fprintf (dump_file, "[scheduler] AST generated by isl:\n");
print_isl_ast (dump_file, root_node);
} }
recompute_all_dominators (); recompute_all_dominators ();
...@@ -3431,8 +3459,8 @@ graphite_regenerate_ast_isl (scop_p scop) ...@@ -3431,8 +3459,8 @@ graphite_regenerate_ast_isl (scop_p scop)
if (t.codegen_error_p ()) if (t.codegen_error_p ())
{ {
if (dump_file) if (dump_file)
fprintf (dump_file, "[codegen] unsuccessful," fprintf (dump_file, "codegen error: "
" reverting back to the original code.\n"); "reverting back to the original code.\n");
set_ifsese_condition (if_region, integer_zero_node); set_ifsese_condition (if_region, integer_zero_node);
} }
else else
...@@ -3452,6 +3480,9 @@ graphite_regenerate_ast_isl (scop_p scop) ...@@ -3452,6 +3480,9 @@ graphite_regenerate_ast_isl (scop_p scop)
scev_reset (); scev_reset ();
recompute_all_dominators (); recompute_all_dominators ();
graphite_verify (); graphite_verify ();
if (dump_file)
fprintf (dump_file, "[codegen] isl AST to Gimple succeeded.\n");
} }
else else
{ {
......
...@@ -92,24 +92,120 @@ get_schedule_for_node_st (__isl_take isl_schedule_node *node, void *user) ...@@ -92,24 +92,120 @@ get_schedule_for_node_st (__isl_take isl_schedule_node *node, void *user)
return node; return node;
} }
/* get_schedule_map_st - Improve the schedule by performing other loop static isl_union_set *
optimizations. _st ending is for schedule tree version of this scop_get_domains (scop_p scop)
function (see get_schedule_map below for the band forest version). {
int i;
poly_bb_p pbb;
isl_space *space = isl_set_get_space (scop->param_context);
isl_union_set *res = isl_union_set_empty (space);
Do a depth-first post-order traversal of the nodes in a schedule FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
tree and apply get_schedule_for_node_st on them to improve the schedule. res = isl_union_set_add_set (res, isl_set_copy (pbb->domain));
*/
return res;
}
/* Compute the schedule for SCOP based on its parameters, domain and set of
constraints. Then apply the schedule to SCOP. */
static __isl_give isl_union_map * static bool
get_schedule_map_st (__isl_keep isl_schedule *schedule) optimize_isl (scop_p scop)
{ {
int old_max_operations = isl_ctx_get_max_operations (scop->isl_context);
int max_operations = PARAM_VALUE (PARAM_MAX_ISL_OPERATIONS);
if (max_operations)
isl_ctx_set_max_operations (scop->isl_context, max_operations);
isl_options_set_on_error (scop->isl_context, ISL_ON_ERROR_CONTINUE);
schedule = isl_schedule_map_schedule_node_bottom_up (schedule, isl_union_set *domain = scop_get_domains (scop);
get_schedule_for_node_st,
NULL); /* Simplify the dependences on the domain. */
isl_union_map *schedule_map = isl_schedule_get_map (schedule); scop_get_dependences (scop);
return schedule_map; isl_union_map *dependences
= isl_union_map_gist_domain (isl_union_map_copy (scop->dependence),
isl_union_set_copy (domain));
isl_union_map *validity
= isl_union_map_gist_range (dependences, isl_union_set_copy (domain));
/* FIXME: proximity should not be validity. */
isl_union_map *proximity = isl_union_map_copy (validity);
isl_schedule_constraints *sc = isl_schedule_constraints_on_domain (domain);
sc = isl_schedule_constraints_set_proximity (sc, proximity);
sc = isl_schedule_constraints_set_validity (sc, isl_union_map_copy (validity));
sc = isl_schedule_constraints_set_coincidence (sc, validity);
isl_options_set_schedule_serialize_sccs (scop->isl_context, 0);
isl_options_set_schedule_maximize_band_depth (scop->isl_context, 1);
isl_options_set_schedule_max_constant_term (scop->isl_context, 20);
isl_options_set_schedule_max_coefficient (scop->isl_context, 20);
isl_options_set_tile_scale_tile_loops (scop->isl_context, 0);
/* Generate loop upper bounds that consist of the current loop iterator, an
operator (< or <=) and an expression not involving the iterator. If this
option is not set, then the current loop iterator may appear several times
in the upper bound. See the isl manual for more details. */
isl_options_set_ast_build_atomic_upper_bound (scop->isl_context, 1);
scop->transformed_schedule = isl_schedule_constraints_compute_schedule (sc);
scop->transformed_schedule =
isl_schedule_map_schedule_node_bottom_up (scop->transformed_schedule,
get_schedule_for_node_st, NULL);
isl_options_set_on_error (scop->isl_context, ISL_ON_ERROR_ABORT);
isl_ctx_reset_operations (scop->isl_context);
isl_ctx_set_max_operations (scop->isl_context, old_max_operations);
if (!scop->transformed_schedule
|| isl_ctx_last_error (scop->isl_context) == isl_error_quota)
{
if (dump_file && dump_flags)
fprintf (dump_file, "isl timed out --param max-isl-operations=%d\n",
max_operations);
return false;
}
gcc_assert (scop->original_schedule);
isl_union_map *original = isl_schedule_get_map (scop->original_schedule);
isl_union_map *transformed = isl_schedule_get_map (scop->transformed_schedule);
bool same_schedule = isl_union_map_is_equal (original, transformed);
isl_union_map_free (original);
isl_union_map_free (transformed);
if (same_schedule)
{
if (dump_file)
{
fprintf (dump_file, "[scheduler] isl optimized schedule is "
"identical to the original schedule.\n");
print_schedule_ast (dump_file, scop->original_schedule, scop);
}
isl_schedule_free (scop->transformed_schedule);
scop->transformed_schedule = isl_schedule_copy (scop->original_schedule);
return false;
}
return true;
}
/* Apply graphite transformations to all the basic blocks of SCOP. */
bool
apply_poly_transforms (scop_p scop)
{
if (flag_loop_nest_optimize)
return optimize_isl (scop);
if (!flag_graphite_identity && !flag_loop_parallelize_all)
return false;
/* Generate code even if we did not apply any real transformation.
This also allows to check the performance for the identity
transformation: GIMPLE -> GRAPHITE -> GIMPLE. */
gcc_assert (scop->original_schedule);
scop->transformed_schedule = isl_schedule_copy (scop->original_schedule);
return true;
} }
#else #else
/* get_tile_map - Create a map that describes a n-dimensonal tiling. /* get_tile_map - Create a map that describes a n-dimensonal tiling.
...@@ -304,7 +400,6 @@ get_schedule_map (isl_schedule *schedule) ...@@ -304,7 +400,6 @@ get_schedule_map (isl_schedule *schedule)
isl_band_list_free (band_list); isl_band_list_free (band_list);
return schedule_map; return schedule_map;
} }
#endif
static isl_stat static isl_stat
get_single_map (__isl_take isl_map *map, void *user) get_single_map (__isl_take isl_map *map, void *user)
...@@ -350,12 +445,10 @@ scop_get_domains (scop_p scop) ...@@ -350,12 +445,10 @@ scop_get_domains (scop_p scop)
return res; return res;
} }
static const int CONSTANT_BOUND = 20;
/* Compute the schedule for SCOP based on its parameters, domain and set of /* Compute the schedule for SCOP based on its parameters, domain and set of
constraints. Then apply the schedule to SCOP. */ constraints. Then apply the schedule to SCOP. */
bool static bool
optimize_isl (scop_p scop) optimize_isl (scop_p scop)
{ {
int old_max_operations = isl_ctx_get_max_operations (scop->isl_context); int old_max_operations = isl_ctx_get_max_operations (scop->isl_context);
...@@ -373,24 +466,10 @@ optimize_isl (scop_p scop) ...@@ -373,24 +466,10 @@ optimize_isl (scop_p scop)
isl_union_map *validity = isl_union_map_copy (scop->dependence); isl_union_map *validity = isl_union_map_copy (scop->dependence);
isl_union_map *proximity = isl_union_map_copy (validity); isl_union_map *proximity = isl_union_map_copy (validity);
isl_options_set_schedule_max_constant_term (scop->isl_context, CONSTANT_BOUND);
isl_options_set_schedule_maximize_band_depth (scop->isl_context, 1);
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
/* isl 0.15 or later. */
isl_options_set_schedule_serialize_sccs (scop->isl_context, 0);
isl_options_set_schedule_maximize_band_depth (scop->isl_context, 1);
isl_options_set_schedule_max_constant_term (scop->isl_context, 20);
isl_options_set_schedule_max_coefficient (scop->isl_context, 20);
isl_options_set_tile_scale_tile_loops (scop->isl_context, 0);
isl_options_set_coalesce_bounded_wrapping (scop->isl_context, 1);
isl_options_set_ast_build_exploit_nested_bounds (scop->isl_context, 1);
isl_options_set_ast_build_atomic_upper_bound (scop->isl_context, 1);
#else
isl_options_set_schedule_fuse (scop->isl_context, ISL_SCHEDULE_FUSE_MIN); isl_options_set_schedule_fuse (scop->isl_context, ISL_SCHEDULE_FUSE_MIN);
#endif
isl_schedule *schedule isl_schedule *schedule
= isl_union_set_compute_schedule (domain, validity, proximity); = isl_union_set_compute_schedule (domain, validity, proximity);
isl_options_set_on_error (scop->isl_context, ISL_ON_ERROR_ABORT); isl_options_set_on_error (scop->isl_context, ISL_ON_ERROR_ABORT);
isl_ctx_reset_operations (scop->isl_context); isl_ctx_reset_operations (scop->isl_context);
...@@ -405,20 +484,38 @@ optimize_isl (scop_p scop) ...@@ -405,20 +484,38 @@ optimize_isl (scop_p scop)
return false; return false;
} }
/* Attach the schedule to scop so that it can be used in code generation.
schedule freeing will occur in code generation. */
scop->schedule = schedule; scop->schedule = schedule;
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
/* isl 0.15 or later. */
isl_union_map *schedule_map = get_schedule_map_st (schedule);
#else
isl_union_map *schedule_map = get_schedule_map (schedule); isl_union_map *schedule_map = get_schedule_map (schedule);
#endif
apply_schedule_map_to_scop (scop, schedule_map); apply_schedule_map_to_scop (scop, schedule_map);
isl_union_map_free (schedule_map); isl_union_map_free (schedule_map);
if (dump_file)
{
fprintf (dump_file, "isl end schedule:\n");
print_isl_schedule (dump_file, scop->schedule);
}
return true;
}
/* Apply graphite transformations to all the basic blocks of SCOP. */
bool
apply_poly_transforms (scop_p scop)
{
if (flag_loop_nest_optimize)
return optimize_isl (scop);
if (!flag_graphite_identity && !flag_loop_parallelize_all)
return false;
/* Generate code even if we did not apply any real transformation.
This also allows to check the performance for the identity
transformation: GIMPLE -> GRAPHITE -> GIMPLE. */
return true; return true;
} }
#endif /* HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS */
#endif /* HAVE_isl */ #endif /* HAVE_isl */
...@@ -86,28 +86,6 @@ debug_iteration_domains (scop_p scop) ...@@ -86,28 +86,6 @@ debug_iteration_domains (scop_p scop)
print_iteration_domains (stderr, scop); print_iteration_domains (stderr, scop);
} }
/* Apply graphite transformations to all the basic blocks of SCOP. */
bool
apply_poly_transforms (scop_p scop)
{
bool transform_done = false;
/* Generate code even if we did not apply any real transformation.
This also allows to check the performance for the identity
transformation: GIMPLE -> GRAPHITE -> GIMPLE. */
if (flag_graphite_identity)
transform_done = true;
if (flag_loop_parallelize_all)
transform_done = true;
if (flag_loop_nest_optimize)
transform_done |= optimize_isl (scop);
return transform_done;
}
/* Create a new polyhedral data reference and add it to PBB. It is /* Create a new polyhedral data reference and add it to PBB. It is
defined by its ACCESSES, its TYPE, and the number of subscripts defined by its ACCESSES, its TYPE, and the number of subscripts
NB_SUBSCRIPTS. */ NB_SUBSCRIPTS. */
...@@ -142,7 +120,7 @@ new_poly_dr (poly_bb_p pbb, gimple *stmt, enum poly_dr_type type, ...@@ -142,7 +120,7 @@ new_poly_dr (poly_bb_p pbb, gimple *stmt, enum poly_dr_type type,
/* Free polyhedral data reference PDR. */ /* Free polyhedral data reference PDR. */
void static void
free_poly_dr (poly_dr_p pdr) free_poly_dr (poly_dr_p pdr)
{ {
isl_map_free (pdr->accesses); isl_map_free (pdr->accesses);
...@@ -158,9 +136,13 @@ new_poly_bb (scop_p scop, gimple_poly_bb_p black_box) ...@@ -158,9 +136,13 @@ new_poly_bb (scop_p scop, gimple_poly_bb_p black_box)
poly_bb_p pbb = XNEW (struct poly_bb); poly_bb_p pbb = XNEW (struct poly_bb);
pbb->domain = NULL; pbb->domain = NULL;
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
pbb->iterators = NULL;
#else
pbb->schedule = NULL; pbb->schedule = NULL;
pbb->transformed = NULL; pbb->transformed = NULL;
pbb->saved = NULL; pbb->saved = NULL;
#endif
PBB_SCOP (pbb) = scop; PBB_SCOP (pbb) = scop;
pbb_set_black_box (pbb, black_box); pbb_set_black_box (pbb, black_box);
PBB_DRS (pbb).create (3); PBB_DRS (pbb).create (3);
...@@ -171,16 +153,25 @@ new_poly_bb (scop_p scop, gimple_poly_bb_p black_box) ...@@ -171,16 +153,25 @@ new_poly_bb (scop_p scop, gimple_poly_bb_p black_box)
/* Free polyhedral black box. */ /* Free polyhedral black box. */
void static void
free_poly_bb (poly_bb_p pbb) free_poly_bb (poly_bb_p pbb)
{ {
int i; int i;
poly_dr_p pdr; poly_dr_p pdr;
isl_set_free (pbb->domain); isl_set_free (pbb->domain);
pbb->domain = NULL;
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
isl_set_free (pbb->iterators);
pbb->iterators = NULL;
#else
isl_map_free (pbb->schedule); isl_map_free (pbb->schedule);
pbb->schedule = NULL;
isl_map_free (pbb->transformed); isl_map_free (pbb->transformed);
pbb->transformed = NULL;
isl_map_free (pbb->saved); isl_map_free (pbb->saved);
pbb->saved = NULL;
#endif
if (PBB_DRS (pbb).exists ()) if (PBB_DRS (pbb).exists ())
FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr) FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr)
...@@ -251,7 +242,7 @@ new_gimple_poly_bb (basic_block bb, vec<data_reference_p> drs, ...@@ -251,7 +242,7 @@ new_gimple_poly_bb (basic_block bb, vec<data_reference_p> drs,
/* Frees GBB. */ /* Frees GBB. */
void static void
free_gimple_poly_bb (gimple_poly_bb_p gbb) free_gimple_poly_bb (gimple_poly_bb_p gbb)
{ {
free_data_refs (GBB_DATA_REFS (gbb)); free_data_refs (GBB_DATA_REFS (gbb));
...@@ -282,7 +273,12 @@ new_scop (edge entry, edge exit) ...@@ -282,7 +273,12 @@ new_scop (edge entry, edge exit)
sese_info_p region = new_sese_info (entry, exit); sese_info_p region = new_sese_info (entry, exit);
scop_p s = XNEW (struct scop); scop_p s = XNEW (struct scop);
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
s->original_schedule = NULL;
s->transformed_schedule = NULL;
#else
s->schedule = NULL; s->schedule = NULL;
#endif
s->param_context = NULL; s->param_context = NULL;
scop_set_region (s, region); scop_set_region (s, region);
s->pbbs.create (3); s->pbbs.create (3);
...@@ -309,8 +305,17 @@ free_scop (scop_p scop) ...@@ -309,8 +305,17 @@ free_scop (scop_p scop)
scop->drs.release (); scop->drs.release ();
isl_set_free (scop->param_context); isl_set_free (scop->param_context);
scop->param_context = NULL;
isl_union_map_free (scop->dependence); isl_union_map_free (scop->dependence);
scop->dependence = NULL; scop->dependence = NULL;
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
isl_schedule_free (scop->original_schedule);
scop->original_schedule = NULL;
isl_schedule_free (scop->transformed_schedule);
scop->transformed_schedule = NULL;
#else
#endif
XDELETE (scop); XDELETE (scop);
} }
...@@ -535,53 +540,61 @@ debug_scop_params (scop_p scop) ...@@ -535,53 +540,61 @@ debug_scop_params (scop_p scop)
extern isl_ctx *the_isl_ctx; extern isl_ctx *the_isl_ctx;
void void
print_isl_set (FILE *f, isl_set *set) print_isl_set (FILE *f, __isl_keep isl_set *set)
{ {
isl_printer *p = isl_printer_to_file (the_isl_ctx, f); isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
p = isl_printer_set_yaml_style (p, ISL_YAML_STYLE_BLOCK);
#endif
p = isl_printer_print_set (p, set); p = isl_printer_print_set (p, set);
p = isl_printer_print_str (p, "\n"); p = isl_printer_print_str (p, "\n");
isl_printer_free (p); isl_printer_free (p);
} }
DEBUG_FUNCTION void DEBUG_FUNCTION void
debug_isl_set (isl_set *set) debug_isl_set (__isl_keep isl_set *set)
{ {
print_isl_set (stderr, set); print_isl_set (stderr, set);
} }
void void
print_isl_map (FILE *f, isl_map *map) print_isl_map (FILE *f, __isl_keep isl_map *map)
{ {
isl_printer *p = isl_printer_to_file (the_isl_ctx, f); isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
p = isl_printer_set_yaml_style (p, ISL_YAML_STYLE_BLOCK);
#endif
p = isl_printer_print_map (p, map); p = isl_printer_print_map (p, map);
p = isl_printer_print_str (p, "\n"); p = isl_printer_print_str (p, "\n");
isl_printer_free (p); isl_printer_free (p);
} }
DEBUG_FUNCTION void DEBUG_FUNCTION void
debug_isl_map (isl_map *map) debug_isl_map (__isl_keep isl_map *map)
{ {
print_isl_map (stderr, map); print_isl_map (stderr, map);
} }
void void
print_isl_union_map (FILE *f, isl_union_map *map) print_isl_union_map (FILE *f, __isl_keep isl_union_map *map)
{ {
isl_printer *p = isl_printer_to_file (the_isl_ctx, f); isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
p = isl_printer_set_yaml_style (p, ISL_YAML_STYLE_BLOCK);
#endif
p = isl_printer_print_union_map (p, map); p = isl_printer_print_union_map (p, map);
p = isl_printer_print_str (p, "\n"); p = isl_printer_print_str (p, "\n");
isl_printer_free (p); isl_printer_free (p);
} }
DEBUG_FUNCTION void DEBUG_FUNCTION void
debug_isl_union_map (isl_union_map *map) debug_isl_union_map (__isl_keep isl_union_map *map)
{ {
print_isl_union_map (stderr, map); print_isl_union_map (stderr, map);
} }
void void
print_isl_aff (FILE *f, isl_aff *aff) print_isl_aff (FILE *f, __isl_keep isl_aff *aff)
{ {
isl_printer *p = isl_printer_to_file (the_isl_ctx, f); isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
p = isl_printer_print_aff (p, aff); p = isl_printer_print_aff (p, aff);
...@@ -590,13 +603,13 @@ print_isl_aff (FILE *f, isl_aff *aff) ...@@ -590,13 +603,13 @@ print_isl_aff (FILE *f, isl_aff *aff)
} }
DEBUG_FUNCTION void DEBUG_FUNCTION void
debug_isl_aff (isl_aff *aff) debug_isl_aff (__isl_keep isl_aff *aff)
{ {
print_isl_aff (stderr, aff); print_isl_aff (stderr, aff);
} }
void void
print_isl_constraint (FILE *f, isl_constraint *c) print_isl_constraint (FILE *f, __isl_keep isl_constraint *c)
{ {
isl_printer *p = isl_printer_to_file (the_isl_ctx, f); isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
p = isl_printer_print_constraint (p, c); p = isl_printer_print_constraint (p, c);
...@@ -605,46 +618,49 @@ print_isl_constraint (FILE *f, isl_constraint *c) ...@@ -605,46 +618,49 @@ print_isl_constraint (FILE *f, isl_constraint *c)
} }
DEBUG_FUNCTION void DEBUG_FUNCTION void
debug_isl_constraint (isl_constraint *c) debug_isl_constraint (__isl_keep isl_constraint *c)
{ {
print_isl_constraint (stderr, c); print_isl_constraint (stderr, c);
} }
/* Returns the number of iterations RES of the loop around PBB at void
time(scattering) dimension TIME_DEPTH. */ print_isl_schedule (FILE *f, __isl_keep isl_schedule *s)
{
isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
p = isl_printer_set_yaml_style (p, ISL_YAML_STYLE_BLOCK);
#endif
p = isl_printer_print_schedule (p, s);
p = isl_printer_print_str (p, "\n");
isl_printer_free (p);
}
DEBUG_FUNCTION void
debug_isl_schedule (__isl_keep isl_schedule *s)
{
print_isl_schedule (stderr, s);
}
void void
pbb_number_of_iterations_at_time (poly_bb_p pbb, print_isl_ast (FILE *file, __isl_keep isl_ast_node *n)
graphite_dim_t time_depth, {
mpz_t res) isl_printer *prn = isl_printer_to_file (the_isl_ctx, file);
{ prn = isl_printer_set_output_format (prn, ISL_FORMAT_C);
isl_set *transdomain; prn = isl_printer_print_ast_node (prn, n);
isl_space *dc; prn = isl_printer_print_str (prn, "\n");
isl_aff *aff; isl_printer_free (prn);
isl_val *isllb, *islub; }
/* Map the iteration domain through the current scatter, and work DEBUG_FUNCTION void
on the resulting set. */ debug_isl_ast (isl_ast_node *n)
transdomain = isl_set_apply (isl_set_copy (pbb->domain), {
isl_map_copy (pbb->transformed)); print_isl_ast (stderr, n);
}
/* Select the time_depth' dimension via an affine expression. */
dc = isl_set_get_space (transdomain); DEBUG_FUNCTION void
aff = isl_aff_zero_on_domain (isl_local_space_from_space (dc)); debug_scop_pbb (scop_p scop, int i)
aff = isl_aff_set_coefficient_si (aff, isl_dim_in, time_depth, 1); {
debug_pbb (scop->pbbs[i]);
/* And find the min/max for that function. */
/* XXX isl check results? */
isllb = isl_set_min_val (transdomain, aff);
islub = isl_set_max_val (transdomain, aff);
islub = isl_val_sub (islub, isllb);
islub = isl_val_add_ui (islub, 1);
isl_val_get_num_gmp (islub, res);
isl_val_free (islub);
isl_aff_free (aff);
isl_set_free (transdomain);
} }
#endif /* HAVE_isl */ #endif /* HAVE_isl */
......
...@@ -533,21 +533,6 @@ public: ...@@ -533,21 +533,6 @@ public:
static edge get_nearest_pdom_with_single_exit (basic_block dom); static edge get_nearest_pdom_with_single_exit (basic_block dom);
/* Pretty printers. */
static void print_edge (FILE *file, const_edge e)
{
fprintf (file, "edge (bb_%d, bb_%d)", e->src->index, e->dest->index);
}
static void print_sese (FILE *file, sese_l s)
{
fprintf (file, "(entry_"); print_edge (file, s.entry);
fprintf (file, ", exit_"); print_edge (file, s.exit);
fprintf (file, ")\n");
}
/* Merge scops at same loop depth and returns the new sese. /* Merge scops at same loop depth and returns the new sese.
Returns a new SESE when merge was successful, INVALID_SESE otherwise. */ Returns a new SESE when merge was successful, INVALID_SESE otherwise. */
......
...@@ -77,6 +77,7 @@ isl_id_for_pbb (scop_p s, poly_bb_p pbb) ...@@ -77,6 +77,7 @@ isl_id_for_pbb (scop_p s, poly_bb_p pbb)
return isl_id_alloc (s->isl_context, name, pbb); return isl_id_alloc (s->isl_context, name, pbb);
} }
#ifndef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
/* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron. /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
We generate SCATTERING_DIMENSIONS scattering dimensions. We generate SCATTERING_DIMENSIONS scattering dimensions.
...@@ -221,6 +222,7 @@ build_scop_scattering (scop_p scop) ...@@ -221,6 +222,7 @@ build_scop_scattering (scop_p scop)
isl_aff_free (static_sched); isl_aff_free (static_sched);
} }
#endif
static isl_pw_aff *extract_affine (scop_p, tree, __isl_take isl_space *space); static isl_pw_aff *extract_affine (scop_p, tree, __isl_take isl_space *space);
...@@ -440,10 +442,7 @@ create_pw_aff_from_tree (poly_bb_p pbb, tree t) ...@@ -440,10 +442,7 @@ create_pw_aff_from_tree (poly_bb_p pbb, tree t)
t = scalar_evolution_in_region (scop->scop_info->region, pbb_loop (pbb), t); t = scalar_evolution_in_region (scop->scop_info->region, pbb_loop (pbb), t);
/* Bail out as we do not know the scev. */ gcc_assert (!chrec_contains_undetermined (t));
if (chrec_contains_undetermined (t))
return NULL;
gcc_assert (!automatically_generated_chrec_p (t)); gcc_assert (!automatically_generated_chrec_p (t));
return extract_affine (scop, t, isl_set_get_space (pbb->domain)); return extract_affine (scop, t, isl_set_get_space (pbb->domain));
...@@ -453,19 +452,11 @@ create_pw_aff_from_tree (poly_bb_p pbb, tree t) ...@@ -453,19 +452,11 @@ create_pw_aff_from_tree (poly_bb_p pbb, tree t)
operator. This allows us to invert the condition or to handle operator. This allows us to invert the condition or to handle
inequalities. */ inequalities. */
static bool static void
add_condition_to_pbb (poly_bb_p pbb, gcond *stmt, enum tree_code code) add_condition_to_pbb (poly_bb_p pbb, gcond *stmt, enum tree_code code)
{ {
isl_pw_aff *lhs = create_pw_aff_from_tree (pbb, gimple_cond_lhs (stmt)); isl_pw_aff *lhs = create_pw_aff_from_tree (pbb, gimple_cond_lhs (stmt));
if (!lhs)
return false;
isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt)); isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt));
if (!rhs)
{
isl_pw_aff_free (lhs);
return false;
}
isl_set *cond; isl_set *cond;
switch (code) switch (code)
...@@ -495,20 +486,17 @@ add_condition_to_pbb (poly_bb_p pbb, gcond *stmt, enum tree_code code) ...@@ -495,20 +486,17 @@ add_condition_to_pbb (poly_bb_p pbb, gcond *stmt, enum tree_code code)
break; break;
default: default:
isl_pw_aff_free (lhs); gcc_unreachable ();
isl_pw_aff_free (rhs);
return true;
} }
cond = isl_set_coalesce (cond); cond = isl_set_coalesce (cond);
cond = isl_set_set_tuple_id (cond, isl_set_get_tuple_id (pbb->domain)); cond = isl_set_set_tuple_id (cond, isl_set_get_tuple_id (pbb->domain));
pbb->domain = isl_set_coalesce (isl_set_intersect (pbb->domain, cond)); pbb->domain = isl_set_coalesce (isl_set_intersect (pbb->domain, cond));
return true;
} }
/* Add conditions to the domain of PBB. */ /* Add conditions to the domain of PBB. */
static bool static void
add_conditions_to_domain (poly_bb_p pbb) add_conditions_to_domain (poly_bb_p pbb)
{ {
unsigned int i; unsigned int i;
...@@ -516,7 +504,7 @@ add_conditions_to_domain (poly_bb_p pbb) ...@@ -516,7 +504,7 @@ add_conditions_to_domain (poly_bb_p pbb)
gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb); gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
if (GBB_CONDITIONS (gbb).is_empty ()) if (GBB_CONDITIONS (gbb).is_empty ())
return true; return;
FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt) FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
switch (gimple_code (stmt)) switch (gimple_code (stmt))
...@@ -534,36 +522,14 @@ add_conditions_to_domain (poly_bb_p pbb) ...@@ -534,36 +522,14 @@ add_conditions_to_domain (poly_bb_p pbb)
if (!GBB_CONDITION_CASES (gbb)[i]) if (!GBB_CONDITION_CASES (gbb)[i])
code = invert_tree_comparison (code, false); code = invert_tree_comparison (code, false);
if (!add_condition_to_pbb (pbb, cond_stmt, code)) add_condition_to_pbb (pbb, cond_stmt, code);
return false;
break; break;
} }
case GIMPLE_SWITCH:
/* Switch statements are not supported right now - fall through. */
default: default:
gcc_unreachable (); gcc_unreachable ();
break; break;
} }
return true;
}
/* Traverses all the GBBs of the SCOP and add their constraints to the
iteration domains. */
static bool
add_conditions_to_constraints (scop_p scop)
{
int i;
poly_bb_p pbb;
FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
if (!add_conditions_to_domain (pbb))
return false;
return true;
} }
/* Add constraints on the possible values of parameter P from the type /* Add constraints on the possible values of parameter P from the type
...@@ -898,6 +864,19 @@ build_scop_drs (scop_p scop) ...@@ -898,6 +864,19 @@ build_scop_drs (scop_p scop)
build_poly_sr (pbb); build_poly_sr (pbb);
} }
/* Add to the iteration DOMAIN one extra dimension for LOOP->num. */
static isl_set *
add_iter_domain_dimension (__isl_take isl_set *domain, loop_p loop, scop_p scop)
{
int loop_index = isl_set_dim (domain, isl_dim_set);
domain = isl_set_add_dims (domain, isl_dim_set, 1);
char name[50];
snprintf (name, sizeof(name), "i%d", loop->num);
isl_id *label = isl_id_alloc (scop->isl_context, name, NULL);
return isl_set_set_dim_id (domain, isl_dim_set, loop_index, label);
}
/* Add constraints to DOMAIN for each loop from LOOP up to CONTEXT. */ /* Add constraints to DOMAIN for each loop from LOOP up to CONTEXT. */
static isl_set * static isl_set *
...@@ -919,7 +898,7 @@ add_loop_constraints (scop_p scop, __isl_take isl_set *domain, loop_p loop, ...@@ -919,7 +898,7 @@ add_loop_constraints (scop_p scop, __isl_take isl_set *domain, loop_p loop,
if (dump_file) if (dump_file)
fprintf (dump_file, "[sese-to-poly] adding one extra dimension to the " fprintf (dump_file, "[sese-to-poly] adding one extra dimension to the "
"domain for loop_%d.\n", loop->num); "domain for loop_%d.\n", loop->num);
domain = isl_set_add_dims (domain, isl_dim_set, 1); domain = add_iter_domain_dimension (domain, loop, scop);
isl_space *space = isl_set_get_space (domain); isl_space *space = isl_set_get_space (domain);
/* 0 <= loop_i */ /* 0 <= loop_i */
...@@ -1014,8 +993,8 @@ add_loop_constraints (scop_p scop, __isl_take isl_set *domain, loop_p loop, ...@@ -1014,8 +993,8 @@ add_loop_constraints (scop_p scop, __isl_take isl_set *domain, loop_p loop,
/* Builds the original iteration domains for each pbb in the SCOP. */ /* Builds the original iteration domains for each pbb in the SCOP. */
static int static int
build_iteration_domains (scop_p scop, __isl_keep isl_set *context, int index, build_iteration_domains (scop_p scop, __isl_keep isl_set *context,
loop_p context_loop) int index, loop_p context_loop)
{ {
loop_p current = pbb_loop (scop->pbbs[index]); loop_p current = pbb_loop (scop->pbbs[index]);
isl_set *domain = isl_set_copy (context); isl_set *domain = isl_set_copy (context);
...@@ -1029,9 +1008,14 @@ build_iteration_domains (scop_p scop, __isl_keep isl_set *context, int index, ...@@ -1029,9 +1008,14 @@ build_iteration_domains (scop_p scop, __isl_keep isl_set *context, int index,
loop_p loop = pbb_loop (pbb); loop_p loop = pbb_loop (pbb);
if (current == loop) if (current == loop)
{ {
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
pbb->iterators = isl_set_copy (domain);
#endif
pbb->domain = isl_set_copy (domain); pbb->domain = isl_set_copy (domain);
pbb->domain = isl_set_set_tuple_id (pbb->domain, pbb->domain = isl_set_set_tuple_id (pbb->domain,
isl_id_for_pbb (scop, pbb)); isl_id_for_pbb (scop, pbb));
add_conditions_to_domain (pbb);
if (dump_file) if (dump_file)
{ {
fprintf (dump_file, "[sese-to-poly] set pbb_%d->domain: ", fprintf (dump_file, "[sese-to-poly] set pbb_%d->domain: ",
...@@ -1061,7 +1045,6 @@ build_iteration_domains (scop_p scop, __isl_keep isl_set *context, int index, ...@@ -1061,7 +1045,6 @@ build_iteration_domains (scop_p scop, __isl_keep isl_set *context, int index,
return i; return i;
} }
/* Assign dimension for each parameter in SCOP and add constraints for the /* Assign dimension for each parameter in SCOP and add constraints for the
parameters. */ parameters. */
...@@ -1085,6 +1068,289 @@ build_scop_context (scop_p scop) ...@@ -1085,6 +1068,289 @@ build_scop_context (scop_p scop)
add_param_constraints (scop, p); add_param_constraints (scop, p);
} }
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
/* Return true when loop A is nested in loop B. */
static bool
nested_in (loop_p a, loop_p b)
{
return b == find_common_loop (a, b);
}
/* Return the loop at a specific SCOP->pbbs[*INDEX]. */
static loop_p
loop_at (scop_p scop, int *index)
{
return pbb_loop (scop->pbbs[*index]);
}
/* Return the index of any pbb belonging to loop or a subloop of A. */
static int
index_outermost_in_loop (loop_p a, scop_p scop)
{
int i, outermost = -1;
int last_depth = -1;
poly_bb_p pbb;
FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
if (nested_in (pbb_loop (pbb), a)
&& (last_depth == -1
|| last_depth > (int) loop_depth (pbb_loop (pbb))))
{
outermost = i;
last_depth = loop_depth (pbb_loop (pbb));
}
return outermost;
}
/* Return the index of any pbb belonging to loop or a subloop of A. */
static int
index_pbb_in_loop (loop_p a, scop_p scop)
{
int i;
poly_bb_p pbb;
FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
if (pbb_loop (pbb) == a)
return i;
return -1;
}
static poly_bb_p
outermost_pbb_in (loop_p loop, scop_p scop)
{
int x = index_pbb_in_loop (loop, scop);
if (x == -1)
x = index_outermost_in_loop (loop, scop);
return scop->pbbs[x];
}
static isl_schedule *
add_in_sequence (__isl_take isl_schedule *a, __isl_take isl_schedule *b)
{
gcc_assert (a || b);
if (!a)
return b;
if (!b)
return a;
return isl_schedule_sequence (a, b);
}
struct map_to_dimension_data {
int n;
isl_union_pw_multi_aff *res;
};
/* Create a function that maps the elements of SET to its N-th dimension and add
it to USER->res. */
static isl_stat
add_outer_projection (__isl_take isl_set *set, void *user)
{
struct map_to_dimension_data *data = (struct map_to_dimension_data *) user;
int dim = isl_set_dim (set, isl_dim_set);
isl_space *space = isl_set_get_space (set);
gcc_assert (dim >= data->n);
isl_pw_multi_aff *pma
= isl_pw_multi_aff_project_out_map (space, isl_dim_set, data->n,
dim - data->n);
data->res = isl_union_pw_multi_aff_add_pw_multi_aff (data->res, pma);
isl_set_free (set);
return isl_stat_ok;
}
/* Return SET in which all inner dimensions above N are removed. */
static isl_multi_union_pw_aff *
outer_projection_mupa (__isl_take isl_union_set *set, int n)
{
gcc_assert (n >= 0);
gcc_assert (set);
gcc_assert (!isl_union_set_is_empty (set));
isl_space *space = isl_union_set_get_space (set);
isl_union_pw_multi_aff *pwaff = isl_union_pw_multi_aff_empty (space);
struct map_to_dimension_data data = {n, pwaff};
if (isl_union_set_foreach_set (set, &add_outer_projection, &data) < 0)
data.res = isl_union_pw_multi_aff_free (data.res);
isl_union_set_free (set);
return isl_multi_union_pw_aff_from_union_pw_multi_aff (data.res);
}
/* Embed SCHEDULE in the constraints of the LOOP domain. */
static isl_schedule *
add_loop_schedule (__isl_take isl_schedule *schedule, loop_p loop,
scop_p scop)
{
poly_bb_p pbb = outermost_pbb_in (loop, scop);
isl_set *iterators = pbb->iterators;
int empty = isl_set_is_empty (iterators);
if (empty < 0 || empty)
return empty < 0 ? isl_schedule_free (schedule) : schedule;
isl_space *space = isl_set_get_space (iterators);
int loop_index = isl_space_dim (space, isl_dim_set) - 1;
loop_p ploop = pbb_loop (pbb);
while (loop != ploop)
{
--loop_index;
ploop = loop_outer (ploop);
}
isl_local_space *ls = isl_local_space_from_space (space);
isl_aff *aff = isl_aff_var_on_domain (ls, isl_dim_set, loop_index);
isl_multi_aff *prefix = isl_multi_aff_from_aff (aff);
char name[50];
snprintf (name, sizeof(name), "L_%d", loop->num);
isl_id *label = isl_id_alloc (isl_schedule_get_ctx (schedule),
name, NULL);
prefix = isl_multi_aff_set_tuple_id (prefix, isl_dim_out, label);
int n = isl_multi_aff_dim (prefix, isl_dim_in);
isl_union_set *domain = isl_schedule_get_domain (schedule);
isl_multi_union_pw_aff *mupa = outer_projection_mupa (domain, n);
mupa = isl_multi_union_pw_aff_apply_multi_aff (mupa, prefix);
return isl_schedule_insert_partial_schedule (schedule, mupa);
}
/* Build schedule for the pbb at INDEX. */
static isl_schedule *
build_schedule_pbb (scop_p scop, int *index)
{
poly_bb_p pbb = scop->pbbs[*index];
++*index;
isl_set *domain = isl_set_copy (pbb->domain);
isl_union_set *ud = isl_union_set_from_set (domain);
return isl_schedule_from_domain (ud);
}
static isl_schedule *build_schedule_loop_nest (scop_p, int *, loop_p);
/* Build the schedule of the loop containing the SCOP pbb at INDEX. */
static isl_schedule *
build_schedule_loop (scop_p scop, int *index)
{
int max = scop->pbbs.length ();
gcc_assert (*index < max);
loop_p loop = loop_at (scop, index);
isl_schedule *s = NULL;
while (nested_in (loop_at (scop, index), loop))
{
if (loop == loop_at (scop, index))
s = add_in_sequence (s, build_schedule_pbb (scop, index));
else
s = add_in_sequence (s, build_schedule_loop_nest (scop, index, loop));
if (*index == max)
break;
}
return add_loop_schedule (s, loop, scop);
}
/* S is the schedule of the loop LOOP. Embed the schedule S in all outer loops.
When CONTEXT_LOOP is null, embed the schedule in all loops contained in the
SCOP surrounding LOOP. When CONTEXT_LOOP is non null, only embed S in the
maximal loop nest contained within CONTEXT_LOOP. */
static isl_schedule *
embed_in_surrounding_loops (__isl_take isl_schedule *s, scop_p scop,
loop_p loop, int *index, loop_p context_loop)
{
loop_p outer = loop_outer (loop);
sese_l region = scop->scop_info->region;
if (context_loop == outer
|| !loop_in_sese_p (outer, region))
return s;
int max = scop->pbbs.length ();
if (*index == max
|| (context_loop && !nested_in (loop_at (scop, index), context_loop))
|| (!context_loop
&& !loop_in_sese_p (find_common_loop (outer, loop_at (scop, index)),
region)))
return embed_in_surrounding_loops (add_loop_schedule (s, outer, scop),
scop, outer, index, context_loop);
bool a_pbb;
while ((a_pbb = (outer == loop_at (scop, index)))
|| nested_in (loop_at (scop, index), outer))
{
if (a_pbb)
s = add_in_sequence (s, build_schedule_pbb (scop, index));
else
s = add_in_sequence (s, build_schedule_loop (scop, index));
if (*index == max)
break;
}
/* We reached the end of the OUTER loop: embed S in OUTER. */
return embed_in_surrounding_loops (add_loop_schedule (s, outer, scop), scop,
outer, index, context_loop);
}
/* Build schedule for the full loop nest containing the pbb at INDEX. When
CONTEXT_LOOP is null, build the schedule of all loops contained in the SCOP
surrounding the pbb. When CONTEXT_LOOP is non null, only build the maximal loop
nest contained within CONTEXT_LOOP. */
static isl_schedule *
build_schedule_loop_nest (scop_p scop, int *index, loop_p context_loop)
{
gcc_assert (*index != (int) scop->pbbs.length ());
loop_p loop = loop_at (scop, index);
isl_schedule *s = build_schedule_loop (scop, index);
return embed_in_surrounding_loops (s, scop, loop, index, context_loop);
}
/* Build the schedule of the SCOP. */
static bool
build_original_schedule (scop_p scop)
{
int i = 0;
int n = scop->pbbs.length ();
while (i < n)
{
poly_bb_p pbb = scop->pbbs[i];
isl_schedule *s = NULL;
if (!loop_in_sese_p (pbb_loop (pbb), scop->scop_info->region))
s = build_schedule_pbb (scop, &i);
else
s = build_schedule_loop_nest (scop, &i, NULL);
scop->original_schedule = add_in_sequence (scop->original_schedule, s);
}
if (dump_file)
{
fprintf (dump_file, "[sese-to-poly] original schedule:\n");
print_isl_schedule (dump_file, scop->original_schedule);
}
if (!scop->original_schedule)
return false;
return true;
}
#endif
/* Builds the polyhedral representation for a SESE region. */ /* Builds the polyhedral representation for a SESE region. */
bool bool
...@@ -1097,11 +1363,12 @@ build_poly_scop (scop_p scop) ...@@ -1097,11 +1363,12 @@ build_poly_scop (scop_p scop)
while (i < n) while (i < n)
i = build_iteration_domains (scop, scop->param_context, i, NULL); i = build_iteration_domains (scop, scop->param_context, i, NULL);
if (!add_conditions_to_constraints (scop))
return false;
build_scop_drs (scop); build_scop_drs (scop);
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
build_original_schedule (scop);
#else
build_scop_scattering (scop); build_scop_scattering (scop);
#endif
return true; return true;
} }
#endif /* HAVE_isl */ #endif /* HAVE_isl */
...@@ -209,7 +209,6 @@ struct poly_dr ...@@ -209,7 +209,6 @@ struct poly_dr
void new_poly_dr (poly_bb_p, gimple *, enum poly_dr_type, void new_poly_dr (poly_bb_p, gimple *, enum poly_dr_type,
isl_map *, isl_set *); isl_map *, isl_set *);
void free_poly_dr (poly_dr_p);
void debug_pdr (poly_dr_p); void debug_pdr (poly_dr_p);
void print_pdr (FILE *, poly_dr_p); void print_pdr (FILE *, poly_dr_p);
...@@ -268,10 +267,9 @@ struct poly_bb ...@@ -268,10 +267,9 @@ struct poly_bb
The number of variables in the DOMAIN may change and is not The number of variables in the DOMAIN may change and is not
related to the number of loops in the original code. */ related to the number of loops in the original code. */
isl_set *domain; isl_set *domain;
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
/* The data references we access. */ isl_set *iterators;
vec<poly_dr_p> drs; #else
/* The original scattering. */ /* The original scattering. */
isl_map *schedule; isl_map *schedule;
...@@ -280,6 +278,10 @@ struct poly_bb ...@@ -280,6 +278,10 @@ struct poly_bb
/* A copy of the transformed scattering. */ /* A copy of the transformed scattering. */
isl_map *saved; isl_map *saved;
#endif
/* The data references we access. */
vec<poly_dr_p> drs;
/* The last basic block generated for this pbb. */ /* The last basic block generated for this pbb. */
basic_block new_bb; basic_block new_bb;
...@@ -290,8 +292,6 @@ struct poly_bb ...@@ -290,8 +292,6 @@ struct poly_bb
#define PBB_DRS(PBB) (PBB->drs) #define PBB_DRS(PBB) (PBB->drs)
extern poly_bb_p new_poly_bb (scop_p, gimple_poly_bb_p); extern poly_bb_p new_poly_bb (scop_p, gimple_poly_bb_p);
extern void free_poly_bb (poly_bb_p);
extern void debug_loop_vec (poly_bb_p);
extern void print_pbb_domain (FILE *, poly_bb_p); extern void print_pbb_domain (FILE *, poly_bb_p);
extern void print_pbb (FILE *, poly_bb_p); extern void print_pbb (FILE *, poly_bb_p);
extern void print_scop_context (FILE *, scop_p); extern void print_scop_context (FILE *, scop_p);
...@@ -313,18 +313,19 @@ extern void print_isl_map (FILE *, isl_map *); ...@@ -313,18 +313,19 @@ extern void print_isl_map (FILE *, isl_map *);
extern void print_isl_union_map (FILE *, isl_union_map *); extern void print_isl_union_map (FILE *, isl_union_map *);
extern void print_isl_aff (FILE *, isl_aff *); extern void print_isl_aff (FILE *, isl_aff *);
extern void print_isl_constraint (FILE *, isl_constraint *); extern void print_isl_constraint (FILE *, isl_constraint *);
extern void print_isl_schedule (FILE *, isl_schedule *);
extern void debug_isl_schedule (isl_schedule *);
extern void print_isl_ast (FILE *, isl_ast_node *);
extern void debug_isl_ast (isl_ast_node *);
extern void debug_isl_set (isl_set *); extern void debug_isl_set (isl_set *);
extern void debug_isl_map (isl_map *); extern void debug_isl_map (isl_map *);
extern void debug_isl_union_map (isl_union_map *); extern void debug_isl_union_map (isl_union_map *);
extern void debug_isl_aff (isl_aff *); extern void debug_isl_aff (isl_aff *);
extern void debug_isl_constraint (isl_constraint *); extern void debug_isl_constraint (isl_constraint *);
extern int scop_do_interchange (scop_p);
extern int scop_do_strip_mine (scop_p, int);
extern bool scop_do_block (scop_p);
extern bool flatten_all_loops (scop_p);
extern bool optimize_isl (scop_p);
extern void pbb_number_of_iterations_at_time (poly_bb_p, graphite_dim_t, mpz_t);
extern void debug_gmp_value (mpz_t); extern void debug_gmp_value (mpz_t);
extern void debug_scop_pbb (scop_p scop, int i);
extern void print_schedule_ast (FILE *, __isl_keep isl_schedule *, scop_p);
extern void debug_schedule_ast (__isl_keep isl_schedule *, scop_p);
/* The basic block of the PBB. */ /* The basic block of the PBB. */
...@@ -424,8 +425,16 @@ struct scop ...@@ -424,8 +425,16 @@ struct scop
/* The context used internally by isl. */ /* The context used internally by isl. */
isl_ctx *isl_context; isl_ctx *isl_context;
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
/* SCoP original schedule. */
isl_schedule *original_schedule;
/* SCoP transformed schedule. */
isl_schedule *transformed_schedule;
#else
/* SCoP final schedule. */ /* SCoP final schedule. */
isl_schedule *schedule; isl_schedule *schedule;
#endif
/* The data dependence relation among the data references in this scop. */ /* The data dependence relation among the data references in this scop. */
isl_union_map *dependence; isl_union_map *dependence;
...@@ -435,10 +444,6 @@ extern scop_p new_scop (edge, edge); ...@@ -435,10 +444,6 @@ extern scop_p new_scop (edge, edge);
extern void free_scop (scop_p); extern void free_scop (scop_p);
extern gimple_poly_bb_p new_gimple_poly_bb (basic_block, vec<data_reference_p>, extern gimple_poly_bb_p new_gimple_poly_bb (basic_block, vec<data_reference_p>,
vec<scalar_use>, vec<tree>); vec<scalar_use>, vec<tree>);
extern void free_gimple_poly_bb (gimple_poly_bb_p);
extern void print_generated_program (FILE *, scop_p);
extern void debug_generated_program (scop_p);
extern int unify_scattering_dimensions (scop_p);
extern bool apply_poly_transforms (scop_p); extern bool apply_poly_transforms (scop_p);
/* Set the region of SCOP to REGION. */ /* Set the region of SCOP to REGION. */
...@@ -465,8 +470,11 @@ scop_set_nb_params (scop_p scop, graphite_dim_t nb_params) ...@@ -465,8 +470,11 @@ scop_set_nb_params (scop_p scop, graphite_dim_t nb_params)
scop->nb_params = nb_params; scop->nb_params = nb_params;
} }
isl_union_map * #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
scop_get_dependences (scop_p scop); extern void scop_get_dependences (scop_p scop);
#else
extern isl_union_map *scop_get_dependences (scop_p scop);
#endif
bool bool
carries_deps (__isl_keep isl_union_map *schedule, carries_deps (__isl_keep isl_union_map *schedule,
...@@ -475,9 +483,9 @@ carries_deps (__isl_keep isl_union_map *schedule, ...@@ -475,9 +483,9 @@ carries_deps (__isl_keep isl_union_map *schedule,
extern bool build_poly_scop (scop_p); extern bool build_poly_scop (scop_p);
extern bool graphite_regenerate_ast_isl (scop_p); extern bool graphite_regenerate_ast_isl (scop_p);
extern void build_scops (vec<scop_p> *); extern void build_scops (vec<scop_p> *);
extern void dot_all_sese (FILE *, vec<sese_l> &); extern void dot_all_sese (FILE *, vec<sese_l> &);
extern void dot_sese (sese_l &); extern void dot_sese (sese_l &);
extern void dot_cfg (); extern void dot_cfg ();
#endif #endif
...@@ -585,3 +585,37 @@ scalar_evolution_in_region (const sese_l &region, loop_p loop, tree t) ...@@ -585,3 +585,37 @@ scalar_evolution_in_region (const sese_l &region, loop_p loop, tree t)
return instantiate_scev (before, loop, t); return instantiate_scev (before, loop, t);
} }
/* Pretty print edge E to FILE. */
void
print_edge (FILE *file, const_edge e)
{
fprintf (file, "edge (bb_%d, bb_%d)", e->src->index, e->dest->index);
}
/* Pretty print sese S to FILE. */
void
print_sese (FILE *file, const sese_l &s)
{
fprintf (file, "(entry_"); print_edge (file, s.entry);
fprintf (file, ", exit_"); print_edge (file, s.exit);
fprintf (file, ")\n");
}
/* Pretty print edge E to STDERR. */
DEBUG_FUNCTION void
debug_edge (const_edge e)
{
print_edge (stderr, e);
}
/* Pretty print sese S to STDERR. */
DEBUG_FUNCTION void
debug_sese (const sese_l &s)
{
print_sese (stderr, s);
}
...@@ -43,6 +43,11 @@ struct sese_l ...@@ -43,6 +43,11 @@ struct sese_l
edge exit; edge exit;
}; };
void print_edge (FILE *file, const_edge e);
void print_sese (FILE *file, const sese_l &s);
void dump_edge (const_edge e);
void dump_sese (const sese_l &);
/* Get the entry of an sese S. */ /* Get the entry of an sese S. */
static inline basic_block static inline basic_block
...@@ -207,7 +212,7 @@ loop_in_sese_p (struct loop *loop, const sese_l &region) ...@@ -207,7 +212,7 @@ loop_in_sese_p (struct loop *loop, const sese_l &region)
loop_2 is completely contained -> depth 1 */ loop_2 is completely contained -> depth 1 */
static inline unsigned int static inline unsigned int
sese_loop_depth (sese_l &region, loop_p loop) sese_loop_depth (const sese_l &region, loop_p loop)
{ {
unsigned int depth = 0; unsigned int depth = 0;
......
...@@ -34,4 +34,4 @@ if (n >= k + 1 && k >= 0) { ...@@ -34,4 +34,4 @@ if (n >= k + 1 && k >= 0) {
*/ */
/* { dg-final { scan-tree-dump-times "if \\\(P_9 >= P_10 \\\+ 1 && P_10 >= 0\\\) \\\{" 1 "graphite" } } */ /* { dg-final { scan-tree-dump "if \\\(P_9 >= P_10 \\\+ 1 && P_10 >= 0\\\) \\\{" "graphite" } } */
...@@ -24,4 +24,4 @@ Program FOO ...@@ -24,4 +24,4 @@ Program FOO
end Program FOO end Program FOO
! { dg-final { scan-tree-dump-times "unsuccessful, reverting back to the original code." "1" "graphite" } } ! { dg-final { scan-tree-dump-times "codegen error: reverting back to the original code." "1" "graphite" } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment