}
/* Given a "sink" access, a list of n "source" accesses,
- * compute for each iteration of the sink access,
+ * compute for each iteration of the sink access
+ * and for each element accessed by that iteration,
* the source access in the list that last accessed the
- * same element accessed by the sink access before this sink access.
+ * element accessed by the sink access before this sink access.
* Each access is given as a map from the loop iterators
* to the array indices.
* The result is a list of n relations between source and sink
* of dep
* add result to possible last accesses at level l of write w2
* and replace possible last accesses dep by the remainder
+ *
+ *
+ * To deal with multi-valued sink access relations, the sink iteration
+ * domain is first extended with dimensions that correspond to the data
+ * space. After the computation is finished, these extra dimensions are
+ * projected out again.
*/
__isl_give isl_flow *isl_access_info_compute_flow(__isl_take isl_access_info *acc)
{
int depth;
struct isl_map **temp_rel;
struct isl_flow *res;
+ isl_dim *dim;
+ isl_map *id;
+ unsigned n_sink;
+ unsigned n_data;
acc = isl_access_info_sort_sources(acc);
+ n_sink = isl_map_dim(acc->sink.map, isl_dim_in);
+ n_data = isl_map_dim(acc->sink.map, isl_dim_out);
+ dim = isl_dim_range(isl_map_get_dim(acc->sink.map));
+ id = isl_map_identity(dim);
+ id = isl_map_insert(id, isl_dim_in, 0, n_sink);
+ acc->sink.map = isl_map_insert(acc->sink.map, isl_dim_in,
+ n_sink, n_data);
+ acc->sink.map = isl_map_intersect(acc->sink.map, id);
+
res = isl_flow_alloc(acc);
if (!res)
goto error;
ctx = acc->sink.map->ctx;
- depth = 2 * isl_map_dim(acc->sink.map, isl_dim_in) + 1;
+ depth = 2 * n_sink + 1;
todo = isl_map_domain(isl_map_copy(acc->sink.map));
if (isl_set_fast_is_empty(todo))
goto done;
free(temp_rel);
done:
+ for (j = 0; j < res->n_source; ++j)
+ res->dep[j].map = isl_map_project_out(res->dep[j].map,
+ isl_dim_out, n_sink, n_data);
res->no_source = todo;
isl_access_info_free(acc);
return res;
#include <limits.h>
#include <isl_ctx.h>
#include <isl_set.h>
+#include <isl_flow.h>
#include <isl_constraint.h>
static char *srcdir;
isl_map_free(map);
}
+struct dep {
+ isl_map *dep;
+};
+
+static int collect_dep(__isl_take isl_map *dep, void *dep_user, void *user)
+{
+ struct dep *d = (struct dep *)user;
+
+ d->dep = isl_map_union(d->dep, dep);
+
+ return 0;
+}
+
+static int common_space(void *first, void *second)
+{
+ int depth = *(int *)first;
+ return 2 * depth;
+}
+
+int map_is_equal(__isl_keep isl_map *map, const char *str)
+{
+ isl_map *map2;
+ int equal;
+
+ map2 = isl_map_read_from_str(map->ctx, str, -1);
+ equal = isl_map_is_equal(map, map2);
+ isl_map_free(map2);
+
+ return equal;
+}
+
+void test_dep(struct isl_ctx *ctx)
+{
+ const char *str;
+ isl_dim *dim;
+ isl_map *map;
+ isl_access_info *ai;
+ isl_flow *flow;
+ int depth;
+ struct dep dep;
+
+ depth = 5;
+
+ str = "{ [1,i,0,0,0] -> [i,j] : 0 <= i <= 10 and 0 <= j <= 10 }";
+ map = isl_map_read_from_str(ctx, str, -1);
+ ai = isl_access_info_alloc(map, &depth, &common_space, 1);
+
+ str = "{ [0,i,0,j,0] -> [i,j] : 0 <= i <= 10 and 0 <= j <= 10 }";
+ map = isl_map_read_from_str(ctx, str, -1);
+ ai = isl_access_info_add_source(ai, map, &depth);
+
+ flow = isl_access_info_compute_flow(ai);
+ dim = isl_dim_alloc(ctx, 0, 5, 5);
+ dep.dep = isl_map_empty(dim);
+
+ isl_flow_foreach(flow, collect_dep, &dep);
+
+ str = "{ [0,i,0,j,0] -> [1,i,0,0,0] : 0 <= i,j <= 10 }";
+ assert(map_is_equal(dep.dep, str));
+
+ isl_map_free(dep.dep);
+ isl_flow_free(flow);
+}
+
int main()
{
struct isl_ctx *ctx;
assert(srcdir);
ctx = isl_ctx_alloc();
+ test_dep(ctx);
test_read(ctx);
test_construction(ctx);
test_dim(ctx);