int isl_options_set_schedule_split_parallel(isl_ctx *ctx, int val);
int isl_options_get_schedule_split_parallel(isl_ctx *ctx);
+#define ISL_SCHEDULE_FUSE_MAX 0
+#define ISL_SCHEDULE_FUSE_MIN 1
+int isl_options_set_schedule_fuse(isl_ctx *ctx, int val);
+int isl_options_get_schedule_fuse(isl_ctx *ctx);
+
__isl_give isl_schedule *isl_union_set_compute_schedule(
__isl_take isl_union_set *domain,
__isl_take isl_union_map *validity,
#include <isl/ctx.h>
#include <isl_options_private.h>
+#include <isl/schedule.h>
#include <isl/version.h>
struct isl_arg_choice isl_lp_solver_choice[] = {
{0}
};
+static struct isl_arg_choice fuse[] = {
+ {"max", ISL_SCHEDULE_FUSE_MAX},
+ {"min", ISL_SCHEDULE_FUSE_MIN},
+ {0}
+};
+
static void print_version(void)
{
printf("%s", isl_version());
ISL_ARG_CHOICE(struct isl_options, schedule_algorithm, 0,
"schedule-algorithm", isl_schedule_algorithm_choice,
ISL_SCHEDULE_ALGORITHM_ISL, "scheduling algorithm to use")
+ISL_ARG_CHOICE(struct isl_options, schedule_fuse, 0, "schedule-fuse", fuse,
+ ISL_SCHEDULE_FUSE_MAX, "level of fusion during scheduling")
ISL_ARG_VERSION(print_version)
ISL_ARGS_END
schedule_algorithm)
ISL_CTX_GET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args,
schedule_algorithm)
+
+ISL_CTX_SET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args,
+ schedule_fuse)
+ISL_CTX_GET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args,
+ schedule_fuse)
return node->scc >= scc;
}
-static int edge_src_scc_exactly(struct isl_sched_edge *edge, int scc)
+static int edge_scc_exactly(struct isl_sched_edge *edge, int scc)
{
- return edge->src->scc == scc;
+ return edge->src->scc == scc && edge->dst->scc == scc;
}
static int edge_dst_scc_at_most(struct isl_sched_edge *edge, int scc)
return sort_statements(ctx, graph);
}
+/* Add a row to the schedules that separates the SCCs and move
+ * to the next band.
+ */
+static int split_on_scc(struct isl_sched_graph *graph)
+{
+ int i;
+
+ for (i = 0; i < graph->n; ++i) {
+ struct isl_sched_node *node = &graph->node[i];
+ int row = isl_mat_rows(node->sched);
+
+ isl_map_free(node->sched_map);
+ node->sched_map = NULL;
+ node->sched = isl_mat_add_zero_rows(node->sched, 1);
+ node->sched = isl_mat_set_element_si(node->sched, row, 0,
+ node->scc);
+ if (!node->sched)
+ return -1;
+ node->band[graph->n_total_row] = graph->n_band;
+ }
+
+ graph->n_total_row++;
+ next_band(graph);
+
+ return 0;
+}
+
/* Compute a schedule for each component (identified by node->scc)
* of the dependence graph separately and then combine the results.
+ * Depending on the setting of schedule_fuse, a component may be
+ * either weakly or strongly connected.
*
* The band_id is adjusted such that each component has a separate id.
* Note that the band_id may have already been set to a value different
int n_total_row, orig_total_row;
int n_band, orig_band;
+ if (ctx->opt->schedule_fuse == ISL_SCHEDULE_FUSE_MIN)
+ split_on_scc(graph);
+
n_total_row = 0;
orig_total_row = graph->n_total_row;
n_band = 0;
n++;
n_edge = 0;
for (i = 0; i < graph->n_edge; ++i)
- if (graph->edge[i].src->scc == wcc)
+ if (graph->edge[i].src->scc == wcc &&
+ graph->edge[i].dst->scc == wcc)
n_edge++;
if (compute_sub_schedule(ctx, graph, n, n_edge,
&node_scc_exactly,
- &edge_src_scc_exactly, wcc, 1) < 0)
+ &edge_scc_exactly, wcc, 1) < 0)
return -1;
if (graph->n_total_row > n_total_row)
n_total_row = graph->n_total_row;
/* Compute a schedule for the given dependence graph.
* We first check if the graph is connected (through validity dependences)
* and, if not, compute a schedule for each component separately.
+ * If schedule_fuse is set to minimal fusion, then we check for strongly
+ * connected components instead and compute a separate schedule for
+ * each such strongly connected component.
*/
static int compute_schedule(isl_ctx *ctx, struct isl_sched_graph *graph)
{
- if (detect_wccs(graph) < 0)
- return -1;
+ if (ctx->opt->schedule_fuse == ISL_SCHEDULE_FUSE_MIN) {
+ if (detect_sccs(graph) < 0)
+ return -1;
+ } else {
+ if (detect_wccs(graph) < 0)
+ return -1;
+ }
if (graph->scc > 1)
return compute_component_schedule(ctx, graph);