From 08be2d48bc0b825f364bd0c6da05ab092517cdda Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 1 Feb 2017 17:52:08 +0100 Subject: [PATCH] isl_access_info_compute_flow: support "kill" accesses Kills have the same effect as must-sources in that they block any dependence between an earlier source and a later source, but they do not by themselves result in dependences. Kills are useful in cases where only the dependence blocking effect is required. It was already possible for the user to add the kills to the must-sources and then to remove the resulting spurious dependences from the result, but this is not very elegant. Add direct support for kills. In fact, make kills the primary interface, with must-sources considered to be both may-sources and kills since the effect of kills is actually easier to explain than that of must-sources. The initial implementation does exactly do the above treating kills as must-sources and then removing spurious dependences, but this could be improved in the future. For example, the pure kills (those that do not overlap with the actual must-sources) could be explicitly marked during the computation such that the resulting dependences would not even have to be added to the results in the first place. It would also be possible to not even compute may-dependences derived from kills. Signed-off-by: Sven Verdoolaege --- doc/user.pod | 40 ++++---- include/isl/flow.h | 4 + isl_flow.c | 153 +++++++++++++++++++++++++++++- test_inputs/flow/kill_loop-tree.ai | 11 +++ test_inputs/flow/kill_loop-tree.flow | 4 + test_inputs/flow/kill_loop.ai | 4 + test_inputs/flow/kill_loop.flow | 4 + test_inputs/flow/kill_loop2-tree.ai | 11 +++ test_inputs/flow/kill_loop2-tree.flow | 4 + test_inputs/flow/kill_loop2.ai | 4 + test_inputs/flow/kill_loop2.flow | 4 + test_inputs/flow/kill_loop3-tree.ai | 11 +++ test_inputs/flow/kill_loop3-tree.flow | 4 + test_inputs/flow/kill_loop3.ai | 4 + test_inputs/flow/kill_loop3.flow | 4 + test_inputs/flow/kill_may_loop-tree.ai | 11 +++ test_inputs/flow/kill_may_loop-tree.flow | 4 + test_inputs/flow/kill_may_loop.ai | 4 + test_inputs/flow/kill_may_loop.flow | 4 + test_inputs/flow/kill_may_loop2-tree.ai | 11 +++ test_inputs/flow/kill_may_loop2-tree.flow | 4 + test_inputs/flow/kill_may_loop2.ai | 4 + test_inputs/flow/kill_may_loop2.flow | 4 + test_inputs/flow/kill_may_loop3-tree.ai | 11 +++ test_inputs/flow/kill_may_loop3-tree.flow | 4 + test_inputs/flow/kill_may_loop3.ai | 4 + test_inputs/flow/kill_may_loop3.flow | 4 + 27 files changed, 315 insertions(+), 20 deletions(-) create mode 100644 test_inputs/flow/kill_loop-tree.ai create mode 100644 test_inputs/flow/kill_loop-tree.flow create mode 100644 test_inputs/flow/kill_loop.ai create mode 100644 test_inputs/flow/kill_loop.flow create mode 100644 test_inputs/flow/kill_loop2-tree.ai create mode 100644 test_inputs/flow/kill_loop2-tree.flow create mode 100644 test_inputs/flow/kill_loop2.ai create mode 100644 test_inputs/flow/kill_loop2.flow create mode 100644 test_inputs/flow/kill_loop3-tree.ai create mode 100644 test_inputs/flow/kill_loop3-tree.flow create mode 100644 test_inputs/flow/kill_loop3.ai create mode 100644 test_inputs/flow/kill_loop3.flow create mode 100644 test_inputs/flow/kill_may_loop-tree.ai create mode 100644 test_inputs/flow/kill_may_loop-tree.flow create mode 100644 test_inputs/flow/kill_may_loop.ai create mode 100644 test_inputs/flow/kill_may_loop.flow create mode 100644 test_inputs/flow/kill_may_loop2-tree.ai create mode 100644 test_inputs/flow/kill_may_loop2-tree.flow create mode 100644 test_inputs/flow/kill_may_loop2.ai create mode 100644 test_inputs/flow/kill_may_loop2.flow create mode 100644 test_inputs/flow/kill_may_loop3-tree.ai create mode 100644 test_inputs/flow/kill_may_loop3-tree.flow create mode 100644 test_inputs/flow/kill_may_loop3.ai create mode 100644 test_inputs/flow/kill_may_loop3.flow diff --git a/doc/user.pod b/doc/user.pod index 9e1db4f9..88cb4f77 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -8774,31 +8774,31 @@ C prints the schedule node in block format. =head2 Dependence Analysis C contains specialized functionality for performing -array dataflow analysis. That is, given a I access relation -and a collection of possible I access relations, +array dataflow analysis. That is, given a I access relation, +a collection of possible I accesses and +a collection of I accesses, C can compute relations that describe for each iteration of the sink access, which iterations -of which of the source access relations may have been the last -to access the same data element before the given iteration -of the sink access. +of which of the source access relations may have +accessed the same data element before the given iteration +of the sink access without any intermediate kill of that data element. The resulting dependence relations map source iterations to either the corresponding sink iterations or pairs of corresponding sink iterations and accessed data elements. To compute standard flow dependences, the sink should be a read, while the sources should be writes. -If any of the source accesses are marked as being I -accesses, then there will be a (may) dependence from the last -I access B from any I access that follows -or coincides with -this last I access, but still precedes the sink access. +If no kills are specified, +then memory based dependence analysis is performed. +If, on the other hand, all sources are also kills, +then value based dependence analysis is performed. +If any of the source accesses are marked as being I +accesses, then they are also treated as kills. +Furthermore, the specification of must-sources results +in the computation of must-dependences. Only dependences originating in a must access not coscheduled with any other access to the same element and without any may accesses between the must access and the sink access are considered to be must dependences. -In particular, if I sources are I accesses, -then memory based dependence analysis is performed. -If, on the other hand, all sources are I accesses, -then value based dependence analysis is performed. =head3 High-level Interface @@ -8824,14 +8824,18 @@ the following functions. isl_union_access_info_from_sink( __isl_take isl_union_map *sink); __isl_give isl_union_access_info * - isl_union_access_info_set_must_source( + isl_union_access_info_set_kill( __isl_take isl_union_access_info *access, - __isl_take isl_union_map *must_source); + __isl_take isl_union_map *kill); __isl_give isl_union_access_info * isl_union_access_info_set_may_source( __isl_take isl_union_access_info *access, __isl_take isl_union_map *may_source); __isl_give isl_union_access_info * + isl_union_access_info_set_must_source( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *must_source); + __isl_give isl_union_access_info * isl_union_access_info_set_schedule( __isl_take isl_union_access_info *access, __isl_take isl_schedule *schedule); @@ -8849,7 +8853,9 @@ the following functions. The may sources set by C do not need to include the must sources set by C as a subset. -The user is free not to call one (or both) of these functions, +The kills set by C may overlap +with the may-sources and/or must-sources. +The user is free not to call one (or more) of these functions, in which case the corresponding set is kept to its empty default. Similarly, the default schedule initialized by C is empty. diff --git a/include/isl/flow.h b/include/isl/flow.h index bc5da4ee..f606549d 100644 --- a/include/isl/flow.h +++ b/include/isl/flow.h @@ -84,6 +84,10 @@ __isl_give isl_union_access_info *isl_union_access_info_set_may_source( __isl_take isl_union_access_info *access, __isl_take isl_union_map *may_source); __isl_export +__isl_give isl_union_access_info *isl_union_access_info_set_kill( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *kill); +__isl_export __isl_give isl_union_access_info *isl_union_access_info_set_schedule( __isl_take isl_union_access_info *access, __isl_take isl_schedule *schedule); diff --git a/isl_flow.c b/isl_flow.c index b66c5148..77a87cbb 100644 --- a/isl_flow.c +++ b/isl_flow.c @@ -1373,6 +1373,7 @@ error: * "isl_access_sink" represents the sink accesses. * "isl_access_must_source" represents the definite source accesses. * "isl_access_may_source" represents the possible source accesses. + * "isl_access_kill" represents the kills. * * isl_access_sink is sometimes treated differently and * should therefore appear first. @@ -1381,6 +1382,7 @@ enum isl_access_type { isl_access_sink, isl_access_must_source, isl_access_may_source, + isl_access_kill, isl_access_end }; @@ -1543,6 +1545,61 @@ __isl_give isl_union_access_info *isl_union_access_info_set_may_source( may_source); } +/* Replace the kills of "info" by "kill". + */ +__isl_give isl_union_access_info *isl_union_access_info_set_kill( + __isl_take isl_union_access_info *info, __isl_take isl_union_map *kill) +{ + return isl_union_access_info_set(info, isl_access_kill, kill); +} + +/* Return the access relation of type "type" of "info". + */ +static __isl_give isl_union_map *isl_union_access_info_get( + __isl_keep isl_union_access_info *info, enum isl_access_type type) +{ + if (!info) + return NULL; + return isl_union_map_copy(info->access[type]); +} + +/* Return the definite source accesses of "info". + */ +__isl_give isl_union_map *isl_union_access_info_get_must_source( + __isl_keep isl_union_access_info *info) +{ + return isl_union_access_info_get(info, isl_access_must_source); +} + +/* Return the possible source accesses of "info". + */ +__isl_give isl_union_map *isl_union_access_info_get_may_source( + __isl_keep isl_union_access_info *info) +{ + return isl_union_access_info_get(info, isl_access_may_source); +} + +/* Return the kills of "info". + */ +__isl_give isl_union_map *isl_union_access_info_get_kill( + __isl_keep isl_union_access_info *info) +{ + return isl_union_access_info_get(info, isl_access_kill); +} + +/* Does "info" specify any kills? + */ +static isl_bool isl_union_access_has_kill( + __isl_keep isl_union_access_info *info) +{ + isl_bool empty; + + if (!info) + return isl_bool_error; + empty = isl_union_map_is_empty(info->access[isl_access_kill]); + return isl_bool_not(empty); +} + /* Replace the schedule of "access" by "schedule". * Also free the schedule_map in case it was set last. */ @@ -1634,6 +1691,7 @@ enum isl_ai_key { isl_ai_key_sink = isl_access_sink, isl_ai_key_must_source = isl_access_must_source, isl_ai_key_may_source = isl_access_may_source, + isl_ai_key_kill = isl_access_kill, isl_ai_key_schedule_map, isl_ai_key_schedule, isl_ai_key_end @@ -1646,6 +1704,7 @@ static char *key_str[] = { [isl_ai_key_sink] = "sink", [isl_ai_key_must_source] = "must_source", [isl_ai_key_may_source] = "may_source", + [isl_ai_key_kill] = "kill", [isl_ai_key_schedule_map] = "schedule_map", [isl_ai_key_schedule] = "schedule", }; @@ -1771,6 +1830,7 @@ __isl_give isl_union_access_info *isl_stream_read_union_access_info( sink_set = 1; case isl_ai_key_must_source: case isl_ai_key_may_source: + case isl_ai_key_kill: access = read_union_map(s); info = isl_union_access_info_set(info, key, access); if (!info) @@ -2425,6 +2485,69 @@ error: return isl_stat_error; } +/* Add the kills of "info" to the must-sources. + */ +static __isl_give isl_union_access_info * +isl_union_access_info_add_kill_to_must_source( + __isl_take isl_union_access_info *info) +{ + isl_union_map *must, *kill; + + must = isl_union_access_info_get_must_source(info); + kill = isl_union_access_info_get_kill(info); + must = isl_union_map_union(must, kill); + return isl_union_access_info_set_must_source(info, must); +} + +/* Drop dependences from "flow" that purely originate from kills. + * That is, only keep those dependences that originate from + * the original must-sources "must" and/or the original may-sources "may". + * In particular, "must" contains the must-sources from before + * the kills were added and "may" contains the may-source from before + * the kills were removed. + * + * The dependences are of the form + * + * Source -> [Sink -> Data] + * + * Only those dependences are kept where the Source -> Data part + * is a subset of the original may-sources or must-sources. + * Of those, only the must-dependences that intersect with the must-sources + * remain must-dependences. + * If there is some overlap between the may-sources and the must-sources, + * then the may-dependences and must-dependences may also overlap. + * This should be fine since the may-dependences are only kept + * disjoint from the must-dependences for the isl_union_map_compute_flow + * interface. This interface does not support kills, so it will + * not end up calling this function. + */ +static __isl_give isl_union_flow *isl_union_flow_drop_kill_source( + __isl_take isl_union_flow *flow, __isl_take isl_union_map *must, + __isl_take isl_union_map *may) +{ + isl_union_map *move; + + if (!flow) + goto error; + move = isl_union_map_copy(flow->must_dep); + move = isl_union_map_intersect_range_factor_range(move, + isl_union_map_copy(may)); + may = isl_union_map_union(may, isl_union_map_copy(must)); + flow->may_dep = isl_union_map_intersect_range_factor_range( + flow->may_dep, may); + flow->must_dep = isl_union_map_intersect_range_factor_range( + flow->must_dep, must); + flow->may_dep = isl_union_map_union(flow->may_dep, move); + if (!flow->must_dep || !flow->may_dep) + return isl_union_flow_free(flow); + + return flow; +error: + isl_union_map_free(must); + isl_union_map_free(may); + return NULL; +} + /* Remove the must accesses from the may accesses. * * A must access always trumps a may access, so there is no need @@ -2967,6 +3090,10 @@ error: * map domain elements of access->{may,must)_source to * domain elements of access->sink. * + * If any kills have been specified, then they are treated as + * must-sources internally. Any dependence that purely derives + * from an original kill is removed from the output. + * * We check whether the schedule is available as a schedule tree * or a schedule map and call the corresponding function to perform * the analysis. @@ -2974,13 +3101,33 @@ error: __isl_give isl_union_flow *isl_union_access_info_compute_flow( __isl_take isl_union_access_info *access) { + isl_bool has_kill; + isl_union_map *must = NULL, *may = NULL; + isl_union_flow *flow; + + has_kill = isl_union_access_has_kill(access); + if (has_kill < 0) + goto error; + if (has_kill) { + must = isl_union_access_info_get_must_source(access); + may = isl_union_access_info_get_may_source(access); + } + access = isl_union_access_info_add_kill_to_must_source(access); access = isl_union_access_info_normalize(access); if (!access) - return NULL; + goto error; if (access->schedule) - return compute_flow_schedule(access); + flow = compute_flow_schedule(access); else - return compute_flow_union_map(access); + flow = compute_flow_union_map(access); + if (has_kill) + flow = isl_union_flow_drop_kill_source(flow, must, may); + return flow; +error: + isl_union_access_info_free(access); + isl_union_map_free(must); + isl_union_map_free(may); + return NULL; } /* Print the information contained in "flow" to "p". diff --git a/test_inputs/flow/kill_loop-tree.ai b/test_inputs/flow/kill_loop-tree.ai new file mode 100644 index 00000000..835e1c05 --- /dev/null +++ b/test_inputs/flow/kill_loop-tree.ai @@ -0,0 +1,11 @@ +sink: "{ S[] -> a[] }" +must_source: "{ T[i] -> a[] : 0 <= i <= 9 }" +kill: "{ T[9] -> a[] }" +schedule: + domain: "{ T[i]; S[] }" + child: + sequence: + - filter: "{ T[i] }" + child: + schedule: "[{ T[i] -> [(i)] }]" + - filter: "{ S[] }" diff --git a/test_inputs/flow/kill_loop-tree.flow b/test_inputs/flow/kill_loop-tree.flow new file mode 100644 index 00000000..ef089e54 --- /dev/null +++ b/test_inputs/flow/kill_loop-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/test_inputs/flow/kill_loop.ai b/test_inputs/flow/kill_loop.ai new file mode 100644 index 00000000..619028f2 --- /dev/null +++ b/test_inputs/flow/kill_loop.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +must_source: { T[i] -> a[] : 0 <= i < 10 } +kill: { T[9] -> a[] } +schedule_map: { T[i] -> [0,i]; S[] -> [1,0] } diff --git a/test_inputs/flow/kill_loop.flow b/test_inputs/flow/kill_loop.flow new file mode 100644 index 00000000..ef089e54 --- /dev/null +++ b/test_inputs/flow/kill_loop.flow @@ -0,0 +1,4 @@ +must_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/test_inputs/flow/kill_loop2-tree.ai b/test_inputs/flow/kill_loop2-tree.ai new file mode 100644 index 00000000..19d5ff6b --- /dev/null +++ b/test_inputs/flow/kill_loop2-tree.ai @@ -0,0 +1,11 @@ +sink: "{ S[] -> a[] }" +must_source: "{ T[i] -> a[] : 0 <= i <= 9 }" +kill: "{ K[] -> a[] }" +schedule: + domain: "{ T[i]; S[]; K[] }" + child: + sequence: + - filter: "{ T[i]; K[] }" + child: + schedule: "[{ T[i] -> [(i)]; K[] -> [(10)] }]" + - filter: "{ S[] }" diff --git a/test_inputs/flow/kill_loop2-tree.flow b/test_inputs/flow/kill_loop2-tree.flow new file mode 100644 index 00000000..ec75edb7 --- /dev/null +++ b/test_inputs/flow/kill_loop2-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/test_inputs/flow/kill_loop2.ai b/test_inputs/flow/kill_loop2.ai new file mode 100644 index 00000000..622bc212 --- /dev/null +++ b/test_inputs/flow/kill_loop2.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +must_source: { T[i] -> a[] : 0 <= i < 10 } +kill: { K[] -> a[] } +schedule_map: { T[i] -> [0,i]; K[] -> [0,10]; S[] -> [1,0] } diff --git a/test_inputs/flow/kill_loop2.flow b/test_inputs/flow/kill_loop2.flow new file mode 100644 index 00000000..ec75edb7 --- /dev/null +++ b/test_inputs/flow/kill_loop2.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/test_inputs/flow/kill_loop3-tree.ai b/test_inputs/flow/kill_loop3-tree.ai new file mode 100644 index 00000000..b14325b9 --- /dev/null +++ b/test_inputs/flow/kill_loop3-tree.ai @@ -0,0 +1,11 @@ +sink: "{ S[] -> a[] }" +must_source: "{ T[i] -> a[] : 0 <= i <= 9 }" +kill: "{ K[] -> a[] }" +schedule: + domain: "{ T[i]; S[]; K[] }" + child: + sequence: + - filter: "{ T[i]; K[] }" + child: + schedule: "[{ T[i] -> [(i)]; K[] -> [(9)] }]" + - filter: "{ S[] }" diff --git a/test_inputs/flow/kill_loop3-tree.flow b/test_inputs/flow/kill_loop3-tree.flow new file mode 100644 index 00000000..51d2e2aa --- /dev/null +++ b/test_inputs/flow/kill_loop3-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/test_inputs/flow/kill_loop3.ai b/test_inputs/flow/kill_loop3.ai new file mode 100644 index 00000000..436e13c7 --- /dev/null +++ b/test_inputs/flow/kill_loop3.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +must_source: { T[i] -> a[] : 0 <= i < 10 } +kill: { K[] -> a[] } +schedule_map: { T[i] -> [0,i]; K[] -> [0,9]; S[] -> [1,0] } diff --git a/test_inputs/flow/kill_loop3.flow b/test_inputs/flow/kill_loop3.flow new file mode 100644 index 00000000..51d2e2aa --- /dev/null +++ b/test_inputs/flow/kill_loop3.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/test_inputs/flow/kill_may_loop-tree.ai b/test_inputs/flow/kill_may_loop-tree.ai new file mode 100644 index 00000000..9159e47a --- /dev/null +++ b/test_inputs/flow/kill_may_loop-tree.ai @@ -0,0 +1,11 @@ +sink: "{ S[] -> a[] }" +may_source: "{ T[i] -> a[] : 0 <= i <= 9 }" +kill: "{ T[4] -> a[] }" +schedule: + domain: "{ T[i]; S[] }" + child: + sequence: + - filter: "{ T[i] }" + child: + schedule: "[{ T[i] -> [(i)] }]" + - filter: "{ S[] }" diff --git a/test_inputs/flow/kill_may_loop-tree.flow b/test_inputs/flow/kill_may_loop-tree.flow new file mode 100644 index 00000000..7a89b0dc --- /dev/null +++ b/test_inputs/flow/kill_may_loop-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i] -> [S[] -> a[]] : 4 <= i <= 9 }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/test_inputs/flow/kill_may_loop.ai b/test_inputs/flow/kill_may_loop.ai new file mode 100644 index 00000000..5d197f6f --- /dev/null +++ b/test_inputs/flow/kill_may_loop.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +may_source: { T[i] -> a[] : 0 <= i < 10 } +kill: { T[4] -> a[] } +schedule_map: { T[i] -> [0,i]; S[] -> [1,0] } diff --git a/test_inputs/flow/kill_may_loop.flow b/test_inputs/flow/kill_may_loop.flow new file mode 100644 index 00000000..7a89b0dc --- /dev/null +++ b/test_inputs/flow/kill_may_loop.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i] -> [S[] -> a[]] : 4 <= i <= 9 }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/test_inputs/flow/kill_may_loop2-tree.ai b/test_inputs/flow/kill_may_loop2-tree.ai new file mode 100644 index 00000000..fb5d88fa --- /dev/null +++ b/test_inputs/flow/kill_may_loop2-tree.ai @@ -0,0 +1,11 @@ +sink: "{ S[] -> a[] }" +may_source: "{ T[i] -> a[] : 0 <= i <= 9 }" +kill: "{ T[9] -> a[] }" +schedule: + domain: "{ T[i]; S[] }" + child: + sequence: + - filter: "{ T[i] }" + child: + schedule: "[{ T[i] -> [(i)] }]" + - filter: "{ S[] }" diff --git a/test_inputs/flow/kill_may_loop2-tree.flow b/test_inputs/flow/kill_may_loop2-tree.flow new file mode 100644 index 00000000..51d2e2aa --- /dev/null +++ b/test_inputs/flow/kill_may_loop2-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/test_inputs/flow/kill_may_loop2.ai b/test_inputs/flow/kill_may_loop2.ai new file mode 100644 index 00000000..09aaf70a --- /dev/null +++ b/test_inputs/flow/kill_may_loop2.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +may_source: { T[i] -> a[] : 0 <= i < 10 } +kill: { T[9] -> a[] } +schedule_map: { T[i] -> [0,i]; S[] -> [1,0] } diff --git a/test_inputs/flow/kill_may_loop2.flow b/test_inputs/flow/kill_may_loop2.flow new file mode 100644 index 00000000..51d2e2aa --- /dev/null +++ b/test_inputs/flow/kill_may_loop2.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/test_inputs/flow/kill_may_loop3-tree.ai b/test_inputs/flow/kill_may_loop3-tree.ai new file mode 100644 index 00000000..80976956 --- /dev/null +++ b/test_inputs/flow/kill_may_loop3-tree.ai @@ -0,0 +1,11 @@ +sink: "{ S[] -> a[] }" +may_source: "{ T[i] -> a[] : 0 <= i <= 9 }" +kill: "{ K[] -> a[] }" +schedule: + domain: "{ T[i]; S[]; K[] }" + child: + sequence: + - filter: "{ T[i]; K[] }" + child: + schedule: "[{ T[i] -> [(i)]; K[] -> [(4)] }]" + - filter: "{ S[] }" diff --git a/test_inputs/flow/kill_may_loop3-tree.flow b/test_inputs/flow/kill_may_loop3-tree.flow new file mode 100644 index 00000000..7a89b0dc --- /dev/null +++ b/test_inputs/flow/kill_may_loop3-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i] -> [S[] -> a[]] : 4 <= i <= 9 }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/test_inputs/flow/kill_may_loop3.ai b/test_inputs/flow/kill_may_loop3.ai new file mode 100644 index 00000000..b1d2d6c3 --- /dev/null +++ b/test_inputs/flow/kill_may_loop3.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +may_source: { T[i] -> a[] : 0 <= i < 10 } +kill: { K[] -> a[] } +schedule_map: { T[i] -> [0,i]; K[] -> [0,4]; S[] -> [1,0] } diff --git a/test_inputs/flow/kill_may_loop3.flow b/test_inputs/flow/kill_may_loop3.flow new file mode 100644 index 00000000..7a89b0dc --- /dev/null +++ b/test_inputs/flow/kill_may_loop3.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i] -> [S[] -> a[]] : 4 <= i <= 9 }" +must_no_source: "{ }" +may_no_source: "{ }" -- 2.11.4.GIT