isl_schedule.c: fix types of enum isl_edge_type iterators
[platform/upstream/isl.git] / isl_schedule.c
index f944354..add0fa0 100644 (file)
@@ -127,6 +127,7 @@ struct isl_sched_edge {
 
 enum isl_edge_type {
        isl_edge_validity = 0,
+       isl_edge_first = isl_edge_validity,
        isl_edge_proximity,
        isl_edge_last = isl_edge_proximity
 };
@@ -142,6 +143,7 @@ enum isl_edge_type {
  * n is the number of nodes
  * node is the list of nodes
  * maxvar is the maximal number of variables over all nodes
+ * max_row is the allocated number of rows in the schedule
  * n_row is the current (maximal) number of linearly independent
  *     rows in the node schedules
  * n_total_row is the current number of rows in the node schedules
@@ -185,6 +187,7 @@ struct isl_sched_graph {
        struct isl_sched_node *node;
        int n;
        int maxvar;
+       int max_row;
        int n_row;
 
        int *sorted;
@@ -368,10 +371,10 @@ static int graph_has_edge(struct isl_sched_graph *graph,
 static struct isl_sched_edge *graph_find_any_edge(struct isl_sched_graph *graph,
        struct isl_sched_node *src, struct isl_sched_node *dst)
 {
-       int i;
+       enum isl_edge_type i;
        struct isl_sched_edge *edge;
 
-       for (i = 0; i <= isl_edge_last; ++i) {
+       for (i = isl_edge_first; i <= isl_edge_last; ++i) {
                edge = graph_find_edge(graph, i, src, dst);
                if (edge)
                        return edge;
@@ -386,9 +389,9 @@ static void graph_remove_edge(struct isl_sched_graph *graph,
        struct isl_sched_edge *edge)
 {
        isl_ctx *ctx = isl_map_get_ctx(edge->map);
-       int i;
+       enum isl_edge_type i;
 
-       for (i = 0; i <= isl_edge_last; ++i) {
+       for (i = isl_edge_first; i <= isl_edge_last; ++i) {
                struct isl_hash_table_entry *entry;
 
                entry = graph_find_edge_entry(graph, i, edge->src, edge->dst);
@@ -406,10 +409,10 @@ static void graph_remove_edge(struct isl_sched_graph *graph,
 static int graph_has_any_edge(struct isl_sched_graph *graph,
        struct isl_sched_node *src, struct isl_sched_node *dst)
 {
-       int i;
+       enum isl_edge_type i;
        int r;
 
-       for (i = 0; i <= isl_edge_last; ++i) {
+       for (i = isl_edge_first; i <= isl_edge_last; ++i) {
                r = graph_has_edge(graph, i, src, dst);
                if (r < 0 || r)
                        return r;
@@ -485,6 +488,43 @@ static void graph_free(isl_ctx *ctx, struct isl_sched_graph *graph)
        isl_basic_set_free(graph->lp);
 }
 
+/* For each "set" on which this function is called, increment
+ * graph->n by one and update graph->maxvar.
+ */
+static int init_n_maxvar(__isl_take isl_set *set, void *user)
+{
+       struct isl_sched_graph *graph = user;
+       int nvar = isl_set_dim(set, isl_dim_set);
+
+       graph->n++;
+       if (nvar > graph->maxvar)
+               graph->maxvar = nvar;
+
+       isl_set_free(set);
+
+       return 0;
+}
+
+/* Compute the number of rows that should be allocated for the schedule.
+ * The graph can be split at most "n - 1" times, there can be at most
+ * two rows for each dimension in the iteration domains (in particular,
+ * we usually have one row, but it may be split by split_scaled),
+ * and there can be one extra row for ordering the statements.
+ * Note that if we have actually split "n - 1" times, then no ordering
+ * is needed, so in principle we could use "graph->n + 2 * graph->maxvar - 1".
+ */
+static int compute_max_row(struct isl_sched_graph *graph,
+       __isl_keep isl_union_set *domain)
+{
+       graph->n = 0;
+       graph->maxvar = 0;
+       if (isl_union_set_foreach_set(domain, &init_n_maxvar, graph) < 0)
+               return -1;
+       graph->max_row = graph->n + 2 * graph->maxvar;
+
+       return 0;
+}
+
 /* Add a new node to the graph representing the given set.
  */
 static int extract_node(__isl_take isl_set *set, void *user)
@@ -509,11 +549,11 @@ static int extract_node(__isl_take isl_set *set, void *user)
        graph->node[graph->n].nparam = nparam;
        graph->node[graph->n].sched = sched;
        graph->node[graph->n].sched_map = NULL;
-       band = isl_alloc_array(ctx, int, graph->n_edge + nvar);
+       band = isl_alloc_array(ctx, int, graph->max_row);
        graph->node[graph->n].band = band;
-       band_id = isl_calloc_array(ctx, int, graph->n_edge + nvar);
+       band_id = isl_calloc_array(ctx, int, graph->max_row);
        graph->node[graph->n].band_id = band_id;
-       zero = isl_calloc_array(ctx, int, graph->n_edge + nvar);
+       zero = isl_calloc_array(ctx, int, graph->max_row);
        graph->node[graph->n].zero = zero;
        graph->n++;
 
@@ -1818,7 +1858,7 @@ static int copy_edges(isl_ctx *ctx, struct isl_sched_graph *dst,
        int (*edge_pred)(struct isl_sched_edge *edge, int data), int data)
 {
        int i;
-       int t;
+       enum isl_edge_type t;
 
        dst->n_edge = 0;
        for (i = 0; i < src->n_edge; ++i) {
@@ -1850,7 +1890,7 @@ static int copy_edges(isl_ctx *ctx, struct isl_sched_graph *dst,
                dst->edge[dst->n_edge].proximity = edge->proximity;
                dst->n_edge++;
 
-               for (t = 0; t <= isl_edge_last; ++t) {
+               for (t = isl_edge_first; t <= isl_edge_last; ++t) {
                        if (edge !=
                            graph_find_edge(src, t, edge->src, edge->dst))
                                continue;
@@ -2797,6 +2837,8 @@ __isl_give isl_schedule *isl_union_set_compute_schedule(
        if (graph_alloc(ctx, &graph, graph.n,
            isl_union_map_n_map(validity) + isl_union_map_n_map(proximity)) < 0)
                goto error;
+       if (compute_max_row(&graph, domain) < 0)
+               goto error;
        graph.root = 1;
        graph.n = 0;
        if (isl_union_set_foreach_set(domain, &extract_node, &graph) < 0)