File: | build/source/polly/lib/External/isl/isl_test.c |
Warning: | line 8024, column 12 The left operand of '<' is a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * Copyright 2008-2009 Katholieke Universiteit Leuven | |||
3 | * Copyright 2010 INRIA Saclay | |||
4 | * Copyright 2012-2013 Ecole Normale Superieure | |||
5 | * Copyright 2014 INRIA Rocquencourt | |||
6 | * Copyright 2022 Cerebras Systems | |||
7 | * | |||
8 | * Use of this software is governed by the MIT license | |||
9 | * | |||
10 | * Written by Sven Verdoolaege, K.U.Leuven, Departement | |||
11 | * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium | |||
12 | * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite, | |||
13 | * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France | |||
14 | * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France | |||
15 | * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, | |||
16 | * B.P. 105 - 78153 Le Chesnay, France | |||
17 | * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA | |||
18 | */ | |||
19 | ||||
20 | #include <assert.h> | |||
21 | #include <stdio.h> | |||
22 | #include <limits.h> | |||
23 | #include <isl_ctx_private.h> | |||
24 | #include <isl_map_private.h> | |||
25 | #include <isl_aff_private.h> | |||
26 | #include <isl_space_private.h> | |||
27 | #include <isl/id.h> | |||
28 | #include <isl/set.h> | |||
29 | #include <isl/flow.h> | |||
30 | #include <isl_constraint_private.h> | |||
31 | #include <isl/polynomial.h> | |||
32 | #include <isl/union_set.h> | |||
33 | #include <isl/union_map.h> | |||
34 | #include <isl_factorization.h> | |||
35 | #include <isl/schedule.h> | |||
36 | #include <isl/schedule_node.h> | |||
37 | #include <isl_options_private.h> | |||
38 | #include <isl_vertices_private.h> | |||
39 | #include <isl/ast_build.h> | |||
40 | #include <isl/val.h> | |||
41 | #include <isl/ilp.h> | |||
42 | #include <isl_ast_build_expr.h> | |||
43 | #include <isl/options.h> | |||
44 | ||||
45 | #include "isl_srcdir.c" | |||
46 | ||||
47 | #define ARRAY_SIZE(array)(sizeof(array)/sizeof(*array)) (sizeof(array)/sizeof(*array)) | |||
48 | ||||
49 | static char *get_filename(isl_ctx *ctx, const char *name, const char *suffix) { | |||
50 | char *filename; | |||
51 | int length; | |||
52 | char *pattern = "%s/test_inputs/%s.%s"; | |||
53 | ||||
54 | length = strlen(pattern) - 6 + strlen(srcdir) + strlen(name) | |||
55 | + strlen(suffix) + 1; | |||
56 | filename = isl_alloc_array(ctx, char, length)((char *)isl_malloc_or_die(ctx, (length)*sizeof(char))); | |||
57 | ||||
58 | if (!filename) | |||
59 | return NULL((void*)0); | |||
60 | ||||
61 | sprintf(filename, pattern, srcdir, name, suffix)__builtin___sprintf_chk (filename, 2 - 1, __builtin_object_size (filename, 2 > 1), pattern, srcdir, name, suffix); | |||
62 | ||||
63 | return filename; | |||
64 | } | |||
65 | ||||
66 | void test_parse_map(isl_ctx *ctx, const char *str) | |||
67 | { | |||
68 | isl_map *map; | |||
69 | ||||
70 | map = isl_map_read_from_str(ctx, str); | |||
71 | assert(map)((void) sizeof ((map) ? 1 : 0), __extension__ ({ if (map) ; else __assert_fail ("map", "polly/lib/External/isl/isl_test.c", 71 , __extension__ __PRETTY_FUNCTION__); })); | |||
72 | isl_map_free(map); | |||
73 | } | |||
74 | ||||
75 | int test_parse_map_equal(isl_ctx *ctx, const char *str, const char *str2) | |||
76 | { | |||
77 | isl_map *map, *map2; | |||
78 | int equal; | |||
79 | ||||
80 | map = isl_map_read_from_str(ctx, str); | |||
81 | map2 = isl_map_read_from_str(ctx, str2); | |||
82 | equal = isl_map_is_equal(map, map2); | |||
83 | isl_map_free(map); | |||
84 | isl_map_free(map2); | |||
85 | ||||
86 | if (equal < 0) | |||
87 | return -1; | |||
88 | if (!equal) | |||
89 | isl_die(ctx, isl_error_unknown, "maps not equal",do { isl_handle_error(ctx, isl_error_unknown, "maps not equal" , "polly/lib/External/isl/isl_test.c", 90); return -1; } while (0) | |||
90 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "maps not equal" , "polly/lib/External/isl/isl_test.c", 90); return -1; } while (0); | |||
91 | ||||
92 | return 0; | |||
93 | } | |||
94 | ||||
95 | void test_parse_pwqp(isl_ctx *ctx, const char *str) | |||
96 | { | |||
97 | isl_pw_qpolynomial *pwqp; | |||
98 | ||||
99 | pwqp = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
100 | assert(pwqp)((void) sizeof ((pwqp) ? 1 : 0), __extension__ ({ if (pwqp) ; else __assert_fail ("pwqp", "polly/lib/External/isl/isl_test.c" , 100, __extension__ __PRETTY_FUNCTION__); })); | |||
101 | isl_pw_qpolynomial_free(pwqp); | |||
102 | } | |||
103 | ||||
104 | static void test_parse_pwaff(isl_ctx *ctx, const char *str) | |||
105 | { | |||
106 | isl_pw_aff *pwaff; | |||
107 | ||||
108 | pwaff = isl_pw_aff_read_from_str(ctx, str); | |||
109 | assert(pwaff)((void) sizeof ((pwaff) ? 1 : 0), __extension__ ({ if (pwaff) ; else __assert_fail ("pwaff", "polly/lib/External/isl/isl_test.c" , 109, __extension__ __PRETTY_FUNCTION__); })); | |||
110 | isl_pw_aff_free(pwaff); | |||
111 | } | |||
112 | ||||
113 | /* Check that we can read an isl_multi_val from "str" without errors. | |||
114 | */ | |||
115 | static int test_parse_multi_val(isl_ctx *ctx, const char *str) | |||
116 | { | |||
117 | isl_multi_val *mv; | |||
118 | ||||
119 | mv = isl_multi_val_read_from_str(ctx, str); | |||
120 | isl_multi_val_free(mv); | |||
121 | ||||
122 | return mv ? 0 : -1; | |||
123 | } | |||
124 | ||||
125 | /* String descriptions of multi piecewise affine expressions | |||
126 | * that are used for testing printing and parsing. | |||
127 | */ | |||
128 | static const char *reparse_multi_pw_aff_tests[] = { | |||
129 | "{ A[x, y] -> [] : x + y >= 0 }", | |||
130 | "{ A[x, y] -> B[] : x + y >= 0 }", | |||
131 | "{ A[x, y] -> [x] : x + y >= 0 }", | |||
132 | "[N] -> { A[x, y] -> [x] : x + y <= N }", | |||
133 | "{ A[x, y] -> [x, y] : x + y >= 0 }", | |||
134 | "{ A[x, y] -> [(x : x >= 0), (y : y >= 0)] : x + y >= 0 }", | |||
135 | "[N] -> { [] : N >= 0 }", | |||
136 | "[N] -> { [] : N >= 0 }", | |||
137 | "[N] -> { [N] : N >= 0 }", | |||
138 | "[N] -> { [N, N + 1] : N >= 0 }", | |||
139 | "[N, M] -> { [(N : N >= 0), (M : M >= 0)] : N + M >= 0 }", | |||
140 | "{ [a] -> [b = a] }", | |||
141 | "{ [a] -> [b = a] : a >= 0 }", | |||
142 | }; | |||
143 | ||||
144 | #undef BASEunion_pw_qpolynomial | |||
145 | #define BASEunion_pw_qpolynomial multi_pw_aff | |||
146 | ||||
147 | #include "check_reparse_templ.c" | |||
148 | #include "check_reparse_test_templ.c" | |||
149 | ||||
150 | /* String descriptions that cannot be parsed | |||
151 | * as multi piecewise affine expressions. | |||
152 | */ | |||
153 | static const char *parse_multi_pw_aff_fail_tests[] = { | |||
154 | "{ [a] -> [b] : b = a }", | |||
155 | "{ [a] -> [b = a] : b >= 0 }", | |||
156 | }; | |||
157 | ||||
158 | #include "check_parse_fail_test_templ.c" | |||
159 | ||||
160 | /* String descriptions of piecewise multi affine expressions | |||
161 | * that are used for testing printing and parsing. | |||
162 | */ | |||
163 | static const char *reparse_pw_multi_aff_tests[] = { | |||
164 | "{ [x] -> [x] }", | |||
165 | "{ [x] -> [x % 4] }", | |||
166 | "{ [x] -> [x % 4] : x mod 3 = 1 }", | |||
167 | "{ [x, x] -> [x % 4] }", | |||
168 | "{ [x, x + 1] -> [x % 4] : x mod 3 = 1 }", | |||
169 | "{ [x, x mod 2] -> [x % 4] }", | |||
170 | "{ [a] -> [a//2] : exists (e0: 8*floor((-a + e0)/8) <= -8 - a + 8e0) }", | |||
171 | }; | |||
172 | ||||
173 | #undef BASEunion_pw_qpolynomial | |||
174 | #define BASEunion_pw_qpolynomial pw_multi_aff | |||
175 | ||||
176 | #include "check_reparse_templ.c" | |||
177 | #include "check_reparse_test_templ.c" | |||
178 | ||||
179 | /* Test parsing of piecewise multi affine expressions by printing | |||
180 | * the expressions and checking that parsing the output results | |||
181 | * in the same expression. | |||
182 | * Do this for an expression converted from a map with an output | |||
183 | * dimension name that is equal to an automatically generated name, and | |||
184 | * a set of expressions parsed from strings. | |||
185 | */ | |||
186 | static isl_stat test_parse_pma(isl_ctx *ctx) | |||
187 | { | |||
188 | isl_map *map; | |||
189 | isl_pw_multi_aff *pma; | |||
190 | ||||
191 | map = isl_map_read_from_str(ctx, "{ [a, a] -> [i1 = a + 1] }"); | |||
192 | pma = isl_pw_multi_aff_from_map(map); | |||
193 | if (check_reparse_pw_multi_aff(ctx, pma) < 0) | |||
194 | return isl_stat_error; | |||
195 | ||||
196 | if (check_reparse_pw_multi_aff_tests(ctx) < 0) | |||
197 | return isl_stat_error; | |||
198 | ||||
199 | return isl_stat_ok; | |||
200 | } | |||
201 | ||||
202 | /* String descriptions that cannot be parsed | |||
203 | * as union piecewise multi affine expressions. | |||
204 | */ | |||
205 | static const char *parse_union_pw_multi_aff_fail_tests[] = { | |||
206 | "{ [a] -> [b] : b = a }", | |||
207 | "{ [a] -> [b = a] : b >= 0 }", | |||
208 | }; | |||
209 | ||||
210 | #undef BASEunion_pw_qpolynomial | |||
211 | #define BASEunion_pw_qpolynomial union_pw_multi_aff | |||
212 | ||||
213 | #include "check_parse_fail_test_templ.c" | |||
214 | ||||
215 | /* Test parsing of union piecewise multi affine expressions. | |||
216 | * | |||
217 | * In particular, check some cases where parsing is supposed to fail. | |||
218 | */ | |||
219 | static isl_stat test_parse_upma(isl_ctx *ctx) | |||
220 | { | |||
221 | if (check_parse_union_pw_multi_aff_fail_tests(ctx) < 0) | |||
222 | return isl_stat_error; | |||
223 | ||||
224 | return isl_stat_ok; | |||
225 | } | |||
226 | ||||
227 | /* Test parsing of multi piecewise affine expressions by printing | |||
228 | * the expressions and checking that parsing the output results | |||
229 | * in the same expression. | |||
230 | * Do this for a couple of manually constructed expressions, | |||
231 | * an expression converted from a map with an output dimension name | |||
232 | * that is equal to an automatically generated name, and | |||
233 | * a set of expressions parsed from strings. | |||
234 | * | |||
235 | * Additionally, check some cases where parsing is supposed to fail. | |||
236 | */ | |||
237 | static int test_parse_mpa(isl_ctx *ctx) | |||
238 | { | |||
239 | isl_space *space; | |||
240 | isl_setisl_map *dom; | |||
241 | isl_map *map; | |||
242 | isl_pw_multi_aff *pma; | |||
243 | isl_multi_pw_aff *mpa; | |||
244 | isl_stat r; | |||
245 | ||||
246 | space = isl_space_set_alloc(ctx, 0, 0); | |||
247 | space = isl_space_set_tuple_name(space, isl_dim_set, "A"); | |||
248 | mpa = isl_multi_pw_aff_zero(space); | |||
249 | r = check_reparse_multi_pw_aff(ctx, mpa); | |||
250 | if (r < 0) | |||
251 | return -1; | |||
252 | ||||
253 | space = isl_space_set_alloc(ctx, 1, 0); | |||
254 | space = isl_space_set_dim_name(space, isl_dim_param, 0, "N"); | |||
255 | space = isl_space_set_tuple_name(space, isl_dim_set, "A"); | |||
256 | dom = isl_set_universe(isl_space_params(isl_space_copy(space))); | |||
257 | dom = isl_set_lower_bound_si(dom, isl_dim_param, 0, 5); | |||
258 | mpa = isl_multi_pw_aff_zero(space); | |||
259 | mpa = isl_multi_pw_aff_intersect_domain(mpa, dom); | |||
260 | r = check_reparse_multi_pw_aff(ctx, mpa); | |||
261 | if (r < 0) | |||
262 | return -1; | |||
263 | ||||
264 | map = isl_map_read_from_str(ctx, "{ [a, a] -> [i1 = a + 1] }"); | |||
265 | pma = isl_pw_multi_aff_from_map(map); | |||
266 | mpa = isl_multi_pw_aff_from_pw_multi_aff(pma); | |||
267 | if (check_reparse_multi_pw_aff(ctx, mpa) < 0) | |||
268 | return -1; | |||
269 | ||||
270 | if (check_reparse_multi_pw_aff_tests(ctx) < 0) | |||
271 | return -1; | |||
272 | if (check_parse_multi_pw_aff_fail_tests(ctx) < 0) | |||
273 | return -1; | |||
274 | ||||
275 | return 0; | |||
276 | } | |||
277 | ||||
278 | /* String descriptions of multi union piecewise affine expressions | |||
279 | * that are used for testing printing and parsing. | |||
280 | */ | |||
281 | static const char *reparse_multi_union_pw_aff_tests[] = { | |||
282 | "[]", | |||
283 | "A[]", | |||
284 | "A[B[] -> C[]]", | |||
285 | "(A[] : { S[x] : x > 0; T[y] : y >= 0 })", | |||
286 | "(A[] : { })", | |||
287 | "[N] -> (A[] : { })", | |||
288 | "[N] -> (A[] : { : N >= 0 })", | |||
289 | "[N] -> (A[] : { S[x] : x > N; T[y] : y >= 0 })", | |||
290 | "(A[] : [N] -> { S[x] : x > N; T[y] : y >= 0 })", | |||
291 | "A[{ S[x] -> [x + 1]; T[x] -> [x] }]", | |||
292 | "(A[{ S[x] -> [x + 1]; T[x] -> [x] }] : " | |||
293 | "{ S[x] : x > 0; T[y] : y >= 0 })", | |||
294 | }; | |||
295 | ||||
296 | #undef BASEunion_pw_qpolynomial | |||
297 | #define BASEunion_pw_qpolynomial multi_union_pw_aff | |||
298 | ||||
299 | #include "check_reparse_templ.c" | |||
300 | #include "check_reparse_test_templ.c" | |||
301 | ||||
302 | /* Test parsing of multi union piecewise affine expressions by printing | |||
303 | * the expressions and checking that parsing the output results | |||
304 | * in the same expression. | |||
305 | * Do this for a couple of manually constructed expressions and | |||
306 | * a set of expressions parsed from strings. | |||
307 | */ | |||
308 | static int test_parse_mupa(isl_ctx *ctx) | |||
309 | { | |||
310 | isl_space *space; | |||
311 | isl_multi_union_pw_aff *mupa; | |||
312 | isl_setisl_map *dom; | |||
313 | isl_union_set *uset; | |||
314 | isl_stat r; | |||
315 | ||||
316 | space = isl_space_set_alloc(ctx, 0, 0); | |||
317 | space = isl_space_set_tuple_name(space, isl_dim_set, "A"); | |||
318 | mupa = isl_multi_union_pw_aff_zero(space); | |||
319 | r = check_reparse_multi_union_pw_aff(ctx, mupa); | |||
320 | if (r < 0) | |||
321 | return -1; | |||
322 | ||||
323 | space = isl_space_set_alloc(ctx, 1, 0); | |||
324 | space = isl_space_set_dim_name(space, isl_dim_param, 0, "N"); | |||
325 | space = isl_space_set_tuple_name(space, isl_dim_set, "A"); | |||
326 | dom = isl_set_universe(space); | |||
327 | dom = isl_set_lower_bound_si(dom, isl_dim_param, 0, 5); | |||
328 | uset = isl_union_set_from_set(dom); | |||
329 | space = isl_space_set_alloc(ctx, 1, 0); | |||
330 | space = isl_space_set_dim_name(space, isl_dim_param, 0, "N"); | |||
331 | space = isl_space_set_tuple_name(space, isl_dim_set, "B"); | |||
332 | mupa = isl_multi_union_pw_aff_zero(space); | |||
333 | mupa = isl_multi_union_pw_aff_intersect_domain(mupa, uset); | |||
334 | r = check_reparse_multi_union_pw_aff(ctx, mupa); | |||
335 | if (r < 0) | |||
336 | return -1; | |||
337 | ||||
338 | if (check_reparse_multi_union_pw_aff_tests(ctx) < 0) | |||
339 | return -1; | |||
340 | ||||
341 | return 0; | |||
342 | } | |||
343 | ||||
344 | /* Test parsing of multi expressions. | |||
345 | */ | |||
346 | static int test_parse_multi(isl_ctx *ctx) | |||
347 | { | |||
348 | if (test_parse_mpa(ctx) < 0) | |||
349 | return -1; | |||
350 | if (test_parse_mupa(ctx) < 0) | |||
351 | return -1; | |||
352 | ||||
353 | return 0; | |||
354 | } | |||
355 | ||||
356 | /* Pairs of binary relation representations that should represent | |||
357 | * the same binary relations. | |||
358 | */ | |||
359 | struct { | |||
360 | const char *map1; | |||
361 | const char *map2; | |||
362 | } parse_map_equal_tests[] = { | |||
363 | { "{ [x,y] : [([x/2]+y)/3] >= 1 }", | |||
364 | "{ [x, y] : 2y >= 6 - x }" }, | |||
365 | { "{ [x,y] : x <= min(y, 2*y+3) }", | |||
366 | "{ [x,y] : x <= y, 2*y + 3 }" }, | |||
367 | { "{ [x,y] : x >= min(y, 2*y+3) }", | |||
368 | "{ [x, y] : (y <= x and y >= -3) or (2y <= -3 + x and y <= -4) }" }, | |||
369 | { "[n] -> { [c1] : c1>=0 and c1<=floord(n-4,3) }", | |||
370 | "[n] -> { [c1] : c1 >= 0 and 3c1 <= -4 + n }" }, | |||
371 | { "{ [i,j] -> [i] : i < j; [i,j] -> [j] : j <= i }", | |||
372 | "{ [i,j] -> [min(i,j)] }" }, | |||
373 | { "{ [i,j] : i != j }", | |||
374 | "{ [i,j] : i < j or i > j }" }, | |||
375 | { "{ [i,j] : (i+1)*2 >= j }", | |||
376 | "{ [i, j] : j <= 2 + 2i }" }, | |||
377 | { "{ [i] -> [i > 0 ? 4 : 5] }", | |||
378 | "{ [i] -> [5] : i <= 0; [i] -> [4] : i >= 1 }" }, | |||
379 | { "[N=2,M] -> { [i=[(M+N)/4]] }", | |||
380 | "[N, M] -> { [i] : N = 2 and 4i <= 2 + M and 4i >= -1 + M }" }, | |||
381 | { "{ [x] : x >= 0 }", | |||
382 | "{ [x] : x-0 >= 0 }" }, | |||
383 | { "{ [i] : ((i > 10)) }", | |||
384 | "{ [i] : i >= 11 }" }, | |||
385 | { "{ [i] -> [0] }", | |||
386 | "{ [i] -> [0 * i] }" }, | |||
387 | { "{ [a] -> [b] : (not false) }", | |||
388 | "{ [a] -> [b] : true }" }, | |||
389 | { "{ [i] : i/2 <= 5 }", | |||
390 | "{ [i] : i <= 10 }" }, | |||
391 | { "{Sym=[n] [i] : i <= n }", | |||
392 | "[n] -> { [i] : i <= n }" }, | |||
393 | { "{ [*] }", | |||
394 | "{ [a] }" }, | |||
395 | { "{ [i] : 2*floor(i/2) = i }", | |||
396 | "{ [i] : exists a : i = 2 a }" }, | |||
397 | { "{ [a] -> [b] : a = 5 implies b = 5 }", | |||
398 | "{ [a] -> [b] : a != 5 or b = 5 }" }, | |||
399 | { "{ [a] -> [a - 1 : a > 0] }", | |||
400 | "{ [a] -> [a - 1] : a > 0 }" }, | |||
401 | { "{ [a] -> [a - 1 : a > 0; a : a <= 0] }", | |||
402 | "{ [a] -> [a - 1] : a > 0; [a] -> [a] : a <= 0 }" }, | |||
403 | { "{ [a] -> [(a) * 2 : a >= 0; 0 : a < 0] }", | |||
404 | "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }" }, | |||
405 | { "{ [a] -> [(a * 2) : a >= 0; 0 : a < 0] }", | |||
406 | "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }" }, | |||
407 | { "{ [a] -> [(a * 2 : a >= 0); 0 : a < 0] }", | |||
408 | "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }" }, | |||
409 | { "{ [a] -> [(a * 2 : a >= 0; 0 : a < 0)] }", | |||
410 | "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }" }, | |||
411 | { "{ [a,b] -> [i,j] : a,b << i,j }", | |||
412 | "{ [a,b] -> [i,j] : a < i or (a = i and b < j) }" }, | |||
413 | { "{ [a,b] -> [i,j] : a,b <<= i,j }", | |||
414 | "{ [a,b] -> [i,j] : a < i or (a = i and b <= j) }" }, | |||
415 | { "{ [a,b] -> [i,j] : a,b >> i,j }", | |||
416 | "{ [a,b] -> [i,j] : a > i or (a = i and b > j) }" }, | |||
417 | { "{ [a,b] -> [i,j] : a,b >>= i,j }", | |||
418 | "{ [a,b] -> [i,j] : a > i or (a = i and b >= j) }" }, | |||
419 | { "{ [n] -> [i] : exists (a, b, c: 8b <= i - 32a and " | |||
420 | "8b >= -7 + i - 32 a and b >= 0 and b <= 3 and " | |||
421 | "8c < n - 32a and i < n and c >= 0 and " | |||
422 | "c <= 3 and c >= -4a) }", | |||
423 | "{ [n] -> [i] : 0 <= i < n }" }, | |||
424 | { "{ [x] -> [] : exists (a, b: 0 <= a <= 1 and 0 <= b <= 3 and " | |||
425 | "2b <= x - 8a and 2b >= -1 + x - 8a) }", | |||
426 | "{ [x] -> [] : 0 <= x <= 15 }" }, | |||
427 | { "{ [x] -> [x] : }", | |||
428 | "{ [x] -> [x] }" }, | |||
429 | { "{ [x=4:5] -> [x + 1] }", | |||
430 | "{ [x] -> [x + 1] : 4 <= x <= 5 }" }, | |||
431 | { "{ [x=4:5] -> [x + 1 : x + 1] }", | |||
432 | "{ [x=4:5] -> [x + 1] }" }, | |||
433 | { "{ [x] -> [x - 1 : x + 1] }", | |||
434 | "{ [x] -> [y] : x - 1 <= y <= x + 1 }" }, | |||
435 | { "{ [x=4:] -> [x + 1] }", | |||
436 | "{ [x] -> [x + 1] : 4 <= x }" }, | |||
437 | { "{ [x=:5] -> [x + 1] }", | |||
438 | "{ [x] -> [x + 1] : x <= 5 }" }, | |||
439 | { "{ [x=:] -> [x + 1] }", | |||
440 | "{ [x] -> [x + 1] }" }, | |||
441 | { "{ [:] -> [:] }", | |||
442 | "{ [x] -> [y] }" }, | |||
443 | { "{ [x, x//4] }", | |||
444 | "{ [x, floor(x/4)] }" }, | |||
445 | { "{ [10//4] }", | |||
446 | "{ [2] }" }, | |||
447 | { "{ [-1//4] }", | |||
448 | "{ [-1] }" }, | |||
449 | { "{ [0-1//4] }", | |||
450 | "{ [0] }" }, | |||
451 | { "{ [- 1//4] }", | |||
452 | "{ [-1] }" }, | |||
453 | { "{ [0 - 1//4] }", | |||
454 | "{ [0] }" }, | |||
455 | { "{ [0--1//4] }", | |||
456 | "{ [1] }" }, | |||
457 | { "{ [0 - -1//4] }", | |||
458 | "{ [1] }" }, | |||
459 | { "{ [-2^2:2^2-1] }", | |||
460 | "{ [-4:3] }" }, | |||
461 | { "{ [2*-2] }", | |||
462 | "{ [-4] }" }, | |||
463 | { "{ [i,i*-2] }", | |||
464 | "{ [i,-2i] }" }, | |||
465 | { "[a, b, c, d] -> { [max(a,b,c,d)] }", | |||
466 | "[a, b, c, d] -> { [a] : b < a and c < a and d < a; " | |||
467 | "[b] : b >= a and c < b and d < b; " | |||
468 | "[c] : c >= a and c >= b and d < c; " | |||
469 | "[d] : d >= a and d >= b and d >= c }" }, | |||
470 | { "[a, b, c, d] -> { [min(a,b,c,d)] }", | |||
471 | "[a, b, c, d] -> { [a] : b >= a and c >= a and d >= a; " | |||
472 | "[b] : b < a and c >= b and d >= b; " | |||
473 | "[c] : c < b and c < a and d >= c; " | |||
474 | "[d] : d < c and d < b and d < a }" }, | |||
475 | }; | |||
476 | ||||
477 | int test_parse(struct isl_ctx *ctx) | |||
478 | { | |||
479 | int i; | |||
480 | isl_map *map, *map2; | |||
481 | const char *str, *str2; | |||
482 | ||||
483 | if (test_parse_multi_val(ctx, "{ A[B[2] -> C[5, 7]] }") < 0) | |||
484 | return -1; | |||
485 | if (test_parse_multi_val(ctx, "[n] -> { [2] }") < 0) | |||
486 | return -1; | |||
487 | if (test_parse_multi_val(ctx, "{ A[4, infty, NaN, -1/2, 2/3] }") < 0) | |||
488 | return -1; | |||
489 | if (test_parse_multi(ctx) < 0) | |||
490 | return -1; | |||
491 | if (test_parse_pma(ctx) < 0) | |||
492 | return -1; | |||
493 | if (test_parse_upma(ctx) < 0) | |||
494 | return -1; | |||
495 | ||||
496 | str = "{ [i] -> [-i] }"; | |||
497 | map = isl_map_read_from_str(ctx, str); | |||
498 | assert(map)((void) sizeof ((map) ? 1 : 0), __extension__ ({ if (map) ; else __assert_fail ("map", "polly/lib/External/isl/isl_test.c", 498 , __extension__ __PRETTY_FUNCTION__); })); | |||
499 | isl_map_free(map); | |||
500 | ||||
501 | str = "{ A[i] -> L[([i/3])] }"; | |||
502 | map = isl_map_read_from_str(ctx, str); | |||
503 | assert(map)((void) sizeof ((map) ? 1 : 0), __extension__ ({ if (map) ; else __assert_fail ("map", "polly/lib/External/isl/isl_test.c", 503 , __extension__ __PRETTY_FUNCTION__); })); | |||
504 | isl_map_free(map); | |||
505 | ||||
506 | test_parse_map(ctx, "{[[s] -> A[i]] -> [[s+1] -> A[i]]}"); | |||
507 | test_parse_map(ctx, "{ [p1, y1, y2] -> [2, y1, y2] : " | |||
508 | "p1 = 1 && (y1 <= y2 || y2 = 0) }"); | |||
509 | ||||
510 | for (i = 0; i < ARRAY_SIZE(parse_map_equal_tests)(sizeof(parse_map_equal_tests)/sizeof(*parse_map_equal_tests) ); ++i) { | |||
511 | str = parse_map_equal_tests[i].map1; | |||
512 | str2 = parse_map_equal_tests[i].map2; | |||
513 | if (test_parse_map_equal(ctx, str, str2) < 0) | |||
514 | return -1; | |||
515 | } | |||
516 | ||||
517 | str = "{[new,old] -> [new+1-2*[(new+1)/2],old+1-2*[(old+1)/2]]}"; | |||
518 | map = isl_map_read_from_str(ctx, str); | |||
519 | str = "{ [new, old] -> [o0, o1] : " | |||
520 | "exists (e0 = [(-1 - new + o0)/2], e1 = [(-1 - old + o1)/2]: " | |||
521 | "2e0 = -1 - new + o0 and 2e1 = -1 - old + o1 and o0 >= 0 and " | |||
522 | "o0 <= 1 and o1 >= 0 and o1 <= 1) }"; | |||
523 | map2 = isl_map_read_from_str(ctx, str); | |||
524 | assert(isl_map_is_equal(map, map2))((void) sizeof ((isl_map_is_equal(map, map2)) ? 1 : 0), __extension__ ({ if (isl_map_is_equal(map, map2)) ; else __assert_fail ("isl_map_is_equal(map, map2)" , "polly/lib/External/isl/isl_test.c", 524, __extension__ __PRETTY_FUNCTION__ ); })); | |||
525 | isl_map_free(map); | |||
526 | isl_map_free(map2); | |||
527 | ||||
528 | str = "{[new,old] -> [new+1-2*[(new+1)/2],old+1-2*[(old+1)/2]]}"; | |||
529 | map = isl_map_read_from_str(ctx, str); | |||
530 | str = "{[new,old] -> [(new+1)%2,(old+1)%2]}"; | |||
531 | map2 = isl_map_read_from_str(ctx, str); | |||
532 | assert(isl_map_is_equal(map, map2))((void) sizeof ((isl_map_is_equal(map, map2)) ? 1 : 0), __extension__ ({ if (isl_map_is_equal(map, map2)) ; else __assert_fail ("isl_map_is_equal(map, map2)" , "polly/lib/External/isl/isl_test.c", 532, __extension__ __PRETTY_FUNCTION__ ); })); | |||
533 | isl_map_free(map); | |||
534 | isl_map_free(map2); | |||
535 | ||||
536 | test_parse_pwqp(ctx, "{ [i] -> i + [ (i + [i/3])/2 ] }"); | |||
537 | test_parse_map(ctx, "{ S1[i] -> [([i/10]),i%10] : 0 <= i <= 45 }"); | |||
538 | test_parse_pwaff(ctx, "{ [i] -> [i + 1] : i > 0; [a] -> [a] : a < 0 }"); | |||
539 | test_parse_pwqp(ctx, "{ [x] -> ([(x)/2] * [(x)/3]) }"); | |||
540 | test_parse_pwaff(ctx, "{ [] -> [(100)] }"); | |||
541 | ||||
542 | return 0; | |||
543 | } | |||
544 | ||||
545 | static int test_read(isl_ctx *ctx) | |||
546 | { | |||
547 | char *filename; | |||
548 | FILE *input; | |||
549 | isl_basic_setisl_basic_map *bset1, *bset2; | |||
550 | const char *str = "{[y]: Exists ( alpha : 2alpha = y)}"; | |||
551 | int equal; | |||
552 | ||||
553 | filename = get_filename(ctx, "set", "omega"); | |||
554 | assert(filename)((void) sizeof ((filename) ? 1 : 0), __extension__ ({ if (filename ) ; else __assert_fail ("filename", "polly/lib/External/isl/isl_test.c" , 554, __extension__ __PRETTY_FUNCTION__); })); | |||
555 | input = fopen(filename, "r"); | |||
556 | assert(input)((void) sizeof ((input) ? 1 : 0), __extension__ ({ if (input) ; else __assert_fail ("input", "polly/lib/External/isl/isl_test.c" , 556, __extension__ __PRETTY_FUNCTION__); })); | |||
557 | ||||
558 | bset1 = isl_basic_set_read_from_file(ctx, input); | |||
559 | bset2 = isl_basic_set_read_from_str(ctx, str); | |||
560 | ||||
561 | equal = isl_basic_set_is_equal(bset1, bset2); | |||
562 | ||||
563 | isl_basic_set_free(bset1); | |||
564 | isl_basic_set_free(bset2); | |||
565 | free(filename); | |||
566 | ||||
567 | fclose(input); | |||
568 | ||||
569 | if (equal < 0) | |||
570 | return -1; | |||
571 | if (!equal) | |||
572 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "read sets not equal" , "polly/lib/External/isl/isl_test.c", 573); return -1; } while (0) | |||
573 | "read sets not equal", return -1)do { isl_handle_error(ctx, isl_error_unknown, "read sets not equal" , "polly/lib/External/isl/isl_test.c", 573); return -1; } while (0); | |||
574 | ||||
575 | return 0; | |||
576 | } | |||
577 | ||||
578 | static int test_bounded(isl_ctx *ctx) | |||
579 | { | |||
580 | isl_setisl_map *set; | |||
581 | isl_bool bounded; | |||
582 | ||||
583 | set = isl_set_read_from_str(ctx, "[n] -> {[i] : 0 <= i <= n }"); | |||
584 | bounded = isl_set_is_bounded(set); | |||
585 | isl_set_free(set); | |||
586 | ||||
587 | if (bounded < 0) | |||
588 | return -1; | |||
589 | if (!bounded) | |||
590 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "set not considered bounded" , "polly/lib/External/isl/isl_test.c", 591); return -1; } while (0) | |||
591 | "set not considered bounded", return -1)do { isl_handle_error(ctx, isl_error_unknown, "set not considered bounded" , "polly/lib/External/isl/isl_test.c", 591); return -1; } while (0); | |||
592 | ||||
593 | set = isl_set_read_from_str(ctx, "{[n, i] : 0 <= i <= n }"); | |||
594 | bounded = isl_set_is_bounded(set); | |||
595 | assert(!bounded)((void) sizeof ((!bounded) ? 1 : 0), __extension__ ({ if (!bounded ) ; else __assert_fail ("!bounded", "polly/lib/External/isl/isl_test.c" , 595, __extension__ __PRETTY_FUNCTION__); })); | |||
596 | isl_set_free(set); | |||
597 | ||||
598 | if (bounded < 0) | |||
599 | return -1; | |||
600 | if (bounded) | |||
601 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "set considered bounded" , "polly/lib/External/isl/isl_test.c", 602); return -1; } while (0) | |||
602 | "set considered bounded", return -1)do { isl_handle_error(ctx, isl_error_unknown, "set considered bounded" , "polly/lib/External/isl/isl_test.c", 602); return -1; } while (0); | |||
603 | ||||
604 | set = isl_set_read_from_str(ctx, "[n] -> {[i] : i <= n }"); | |||
605 | bounded = isl_set_is_bounded(set); | |||
606 | isl_set_free(set); | |||
607 | ||||
608 | if (bounded < 0) | |||
609 | return -1; | |||
610 | if (bounded) | |||
611 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "set considered bounded" , "polly/lib/External/isl/isl_test.c", 612); return -1; } while (0) | |||
612 | "set considered bounded", return -1)do { isl_handle_error(ctx, isl_error_unknown, "set considered bounded" , "polly/lib/External/isl/isl_test.c", 612); return -1; } while (0); | |||
613 | ||||
614 | return 0; | |||
615 | } | |||
616 | ||||
617 | /* Construct the basic set { [i] : 5 <= i <= N } */ | |||
618 | static int test_construction_1(isl_ctx *ctx) | |||
619 | { | |||
620 | isl_space *space; | |||
621 | isl_local_space *ls; | |||
622 | isl_basic_setisl_basic_map *bset; | |||
623 | isl_constraint *c; | |||
624 | ||||
625 | space = isl_space_set_alloc(ctx, 1, 1); | |||
626 | bset = isl_basic_set_universe(isl_space_copy(space)); | |||
627 | ls = isl_local_space_from_space(space); | |||
628 | ||||
629 | c = isl_constraint_alloc_inequality(isl_local_space_copy(ls)); | |||
630 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); | |||
631 | c = isl_constraint_set_coefficient_si(c, isl_dim_param, 0, 1); | |||
632 | bset = isl_basic_set_add_constraint(bset, c); | |||
633 | ||||
634 | c = isl_constraint_alloc_inequality(isl_local_space_copy(ls)); | |||
635 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); | |||
636 | c = isl_constraint_set_constant_si(c, -5); | |||
637 | bset = isl_basic_set_add_constraint(bset, c); | |||
638 | ||||
639 | isl_local_space_free(ls); | |||
640 | isl_basic_set_free(bset); | |||
641 | ||||
642 | return 0; | |||
643 | } | |||
644 | ||||
645 | /* Construct the basic set { [x] : -100 <= x <= 100 } | |||
646 | * using isl_basic_set_{lower,upper}_bound_val and | |||
647 | * check that it is equal the same basic set parsed from a string. | |||
648 | */ | |||
649 | static int test_construction_2(isl_ctx *ctx) | |||
650 | { | |||
651 | isl_bool equal; | |||
652 | isl_val *v; | |||
653 | isl_space *space; | |||
654 | isl_basic_setisl_basic_map *bset1, *bset2; | |||
655 | ||||
656 | v = isl_val_int_from_si(ctx, 100); | |||
657 | space = isl_space_set_alloc(ctx, 0, 1); | |||
658 | bset1 = isl_basic_set_universe(space); | |||
659 | bset1 = isl_basic_set_upper_bound_val(bset1, isl_dim_set, 0, | |||
660 | isl_val_copy(v)); | |||
661 | bset1 = isl_basic_set_lower_bound_val(bset1, isl_dim_set, 0, | |||
662 | isl_val_neg(v)); | |||
663 | bset2 = isl_basic_set_read_from_str(ctx, "{ [x] : -100 <= x <= 100 }"); | |||
664 | equal = isl_basic_set_is_equal(bset1, bset2); | |||
665 | isl_basic_set_free(bset1); | |||
666 | isl_basic_set_free(bset2); | |||
667 | ||||
668 | if (equal < 0) | |||
669 | return -1; | |||
670 | if (!equal) | |||
671 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "failed construction" , "polly/lib/External/isl/isl_test.c", 672); return -1; } while (0) | |||
672 | "failed construction", return -1)do { isl_handle_error(ctx, isl_error_unknown, "failed construction" , "polly/lib/External/isl/isl_test.c", 672); return -1; } while (0); | |||
673 | ||||
674 | return 0; | |||
675 | } | |||
676 | ||||
677 | /* Basic tests for constructing basic sets. | |||
678 | */ | |||
679 | static int test_construction(isl_ctx *ctx) | |||
680 | { | |||
681 | if (test_construction_1(ctx) < 0) | |||
682 | return -1; | |||
683 | if (test_construction_2(ctx) < 0) | |||
684 | return -1; | |||
685 | return 0; | |||
686 | } | |||
687 | ||||
688 | static int test_dim(isl_ctx *ctx) | |||
689 | { | |||
690 | const char *str; | |||
691 | isl_map *map1, *map2; | |||
692 | int equal; | |||
693 | ||||
694 | map1 = isl_map_read_from_str(ctx, | |||
695 | "[n] -> { [i] -> [j] : exists (a = [i/10] : i - 10a <= n ) }"); | |||
696 | map1 = isl_map_add_dims(map1, isl_dim_in, 1); | |||
697 | map2 = isl_map_read_from_str(ctx, | |||
698 | "[n] -> { [i,k] -> [j] : exists (a = [i/10] : i - 10a <= n ) }"); | |||
699 | equal = isl_map_is_equal(map1, map2); | |||
700 | isl_map_free(map2); | |||
701 | ||||
702 | map1 = isl_map_project_out(map1, isl_dim_in, 0, 1); | |||
703 | map2 = isl_map_read_from_str(ctx, "[n] -> { [i] -> [j] : n >= 0 }"); | |||
704 | if (equal >= 0 && equal) | |||
705 | equal = isl_map_is_equal(map1, map2); | |||
706 | ||||
707 | isl_map_free(map1); | |||
708 | isl_map_free(map2); | |||
709 | ||||
710 | if (equal < 0) | |||
711 | return -1; | |||
712 | if (!equal) | |||
713 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 714); return -1; } while (0) | |||
714 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 714); return -1; } while (0); | |||
715 | ||||
716 | str = "[n] -> { [i] -> [] : exists a : 0 <= i <= n and i = 2 a }"; | |||
717 | map1 = isl_map_read_from_str(ctx, str); | |||
718 | str = "{ [i] -> [j] : exists a : 0 <= i <= j and i = 2 a }"; | |||
719 | map2 = isl_map_read_from_str(ctx, str); | |||
720 | map1 = isl_map_move_dims(map1, isl_dim_out, 0, isl_dim_param, 0, 1); | |||
721 | equal = isl_map_is_equal(map1, map2); | |||
722 | isl_map_free(map1); | |||
723 | isl_map_free(map2); | |||
724 | ||||
725 | if (equal < 0) | |||
726 | return -1; | |||
727 | if (!equal) | |||
728 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 729); return -1; } while (0) | |||
729 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 729); return -1; } while (0); | |||
730 | ||||
731 | return 0; | |||
732 | } | |||
733 | ||||
734 | #undef BASEunion_pw_qpolynomial | |||
735 | #define BASEunion_pw_qpolynomial multi_val | |||
736 | #include "isl_test_plain_equal_templ.c" | |||
737 | ||||
738 | #undef BASEunion_pw_qpolynomial | |||
739 | #define BASEunion_pw_qpolynomial multi_aff | |||
740 | #include "isl_test_plain_equal_templ.c" | |||
741 | ||||
742 | /* Check that "val" is equal to the value described by "str". | |||
743 | * If "str" is "NaN", then check for a NaN value explicitly. | |||
744 | */ | |||
745 | static isl_stat val_check_equal(__isl_keep isl_val *val, const char *str) | |||
746 | { | |||
747 | isl_bool ok, is_nan; | |||
748 | isl_ctx *ctx; | |||
749 | isl_val *res; | |||
750 | ||||
751 | if (!val) | |||
752 | return isl_stat_error; | |||
753 | ||||
754 | ctx = isl_val_get_ctx(val); | |||
755 | res = isl_val_read_from_str(ctx, str); | |||
756 | is_nan = isl_val_is_nan(res); | |||
757 | if (is_nan < 0) | |||
758 | ok = isl_bool_error; | |||
759 | else if (is_nan) | |||
760 | ok = isl_val_is_nan(val); | |||
761 | else | |||
762 | ok = isl_val_eq(val, res); | |||
763 | isl_val_free(res); | |||
764 | if (ok < 0) | |||
765 | return isl_stat_error; | |||
766 | if (!ok) | |||
767 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 768); return isl_stat_error ; } while (0) | |||
768 | "unexpected result", return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 768); return isl_stat_error ; } while (0); | |||
769 | return isl_stat_ok; | |||
770 | } | |||
771 | ||||
772 | struct { | |||
773 | __isl_give isl_val *(*op)(__isl_take isl_val *v); | |||
774 | const char *arg; | |||
775 | const char *res; | |||
776 | } val_un_tests[] = { | |||
777 | { &isl_val_neg, "0", "0" }, | |||
778 | { &isl_val_abs, "0", "0" }, | |||
779 | { &isl_val_pow2, "0", "1" }, | |||
780 | { &isl_val_floor, "0", "0" }, | |||
781 | { &isl_val_ceil, "0", "0" }, | |||
782 | { &isl_val_neg, "1", "-1" }, | |||
783 | { &isl_val_neg, "-1", "1" }, | |||
784 | { &isl_val_neg, "1/2", "-1/2" }, | |||
785 | { &isl_val_neg, "-1/2", "1/2" }, | |||
786 | { &isl_val_neg, "infty", "-infty" }, | |||
787 | { &isl_val_neg, "-infty", "infty" }, | |||
788 | { &isl_val_neg, "NaN", "NaN" }, | |||
789 | { &isl_val_abs, "1", "1" }, | |||
790 | { &isl_val_abs, "-1", "1" }, | |||
791 | { &isl_val_abs, "1/2", "1/2" }, | |||
792 | { &isl_val_abs, "-1/2", "1/2" }, | |||
793 | { &isl_val_abs, "infty", "infty" }, | |||
794 | { &isl_val_abs, "-infty", "infty" }, | |||
795 | { &isl_val_abs, "NaN", "NaN" }, | |||
796 | { &isl_val_floor, "1", "1" }, | |||
797 | { &isl_val_floor, "-1", "-1" }, | |||
798 | { &isl_val_floor, "1/2", "0" }, | |||
799 | { &isl_val_floor, "-1/2", "-1" }, | |||
800 | { &isl_val_floor, "infty", "infty" }, | |||
801 | { &isl_val_floor, "-infty", "-infty" }, | |||
802 | { &isl_val_floor, "NaN", "NaN" }, | |||
803 | { &isl_val_ceil, "1", "1" }, | |||
804 | { &isl_val_ceil, "-1", "-1" }, | |||
805 | { &isl_val_ceil, "1/2", "1" }, | |||
806 | { &isl_val_ceil, "-1/2", "0" }, | |||
807 | { &isl_val_ceil, "infty", "infty" }, | |||
808 | { &isl_val_ceil, "-infty", "-infty" }, | |||
809 | { &isl_val_ceil, "NaN", "NaN" }, | |||
810 | { &isl_val_pow2, "-3", "1/8" }, | |||
811 | { &isl_val_pow2, "-1", "1/2" }, | |||
812 | { &isl_val_pow2, "1", "2" }, | |||
813 | { &isl_val_pow2, "2", "4" }, | |||
814 | { &isl_val_pow2, "3", "8" }, | |||
815 | { &isl_val_inv, "1", "1" }, | |||
816 | { &isl_val_inv, "2", "1/2" }, | |||
817 | { &isl_val_inv, "1/2", "2" }, | |||
818 | { &isl_val_inv, "-2", "-1/2" }, | |||
819 | { &isl_val_inv, "-1/2", "-2" }, | |||
820 | { &isl_val_inv, "0", "NaN" }, | |||
821 | { &isl_val_inv, "NaN", "NaN" }, | |||
822 | { &isl_val_inv, "infty", "0" }, | |||
823 | { &isl_val_inv, "-infty", "0" }, | |||
824 | }; | |||
825 | ||||
826 | /* Perform some basic tests of unary operations on isl_val objects. | |||
827 | */ | |||
828 | static int test_un_val(isl_ctx *ctx) | |||
829 | { | |||
830 | int i; | |||
831 | isl_val *v; | |||
832 | __isl_give isl_val *(*fn)(__isl_take isl_val *v); | |||
833 | ||||
834 | for (i = 0; i < ARRAY_SIZE(val_un_tests)(sizeof(val_un_tests)/sizeof(*val_un_tests)); ++i) { | |||
835 | isl_stat r; | |||
836 | ||||
837 | v = isl_val_read_from_str(ctx, val_un_tests[i].arg); | |||
838 | fn = val_un_tests[i].op; | |||
839 | v = fn(v); | |||
840 | r = val_check_equal(v, val_un_tests[i].res); | |||
841 | isl_val_free(v); | |||
842 | if (r < 0) | |||
843 | return -1; | |||
844 | } | |||
845 | ||||
846 | return 0; | |||
847 | } | |||
848 | ||||
849 | struct { | |||
850 | __isl_give isl_val *(*fn)(__isl_take isl_val *v1, | |||
851 | __isl_take isl_val *v2); | |||
852 | } val_bin_op[] = { | |||
853 | ['+'] = { &isl_val_add }, | |||
854 | ['-'] = { &isl_val_sub }, | |||
855 | ['*'] = { &isl_val_mul }, | |||
856 | ['/'] = { &isl_val_div }, | |||
857 | ['g'] = { &isl_val_gcd }, | |||
858 | ['m'] = { &isl_val_min }, | |||
859 | ['M'] = { &isl_val_max }, | |||
860 | }; | |||
861 | ||||
862 | struct { | |||
863 | const char *arg1; | |||
864 | unsigned char op; | |||
865 | const char *arg2; | |||
866 | const char *res; | |||
867 | } val_bin_tests[] = { | |||
868 | { "0", '+', "0", "0" }, | |||
869 | { "1", '+', "0", "1" }, | |||
870 | { "1", '+', "1", "2" }, | |||
871 | { "1", '-', "1", "0" }, | |||
872 | { "1", '*', "1", "1" }, | |||
873 | { "1", '/', "1", "1" }, | |||
874 | { "2", '*', "3", "6" }, | |||
875 | { "2", '*', "1/2", "1" }, | |||
876 | { "2", '*', "1/3", "2/3" }, | |||
877 | { "2/3", '*', "3/5", "2/5" }, | |||
878 | { "2/3", '*', "7/5", "14/15" }, | |||
879 | { "2", '/', "1/2", "4" }, | |||
880 | { "-2", '/', "-1/2", "4" }, | |||
881 | { "-2", '/', "1/2", "-4" }, | |||
882 | { "2", '/', "-1/2", "-4" }, | |||
883 | { "2", '/', "2", "1" }, | |||
884 | { "2", '/', "3", "2/3" }, | |||
885 | { "2/3", '/', "5/3", "2/5" }, | |||
886 | { "2/3", '/', "5/7", "14/15" }, | |||
887 | { "0", '/', "0", "NaN" }, | |||
888 | { "42", '/', "0", "NaN" }, | |||
889 | { "-42", '/', "0", "NaN" }, | |||
890 | { "infty", '/', "0", "NaN" }, | |||
891 | { "-infty", '/', "0", "NaN" }, | |||
892 | { "NaN", '/', "0", "NaN" }, | |||
893 | { "0", '/', "NaN", "NaN" }, | |||
894 | { "42", '/', "NaN", "NaN" }, | |||
895 | { "-42", '/', "NaN", "NaN" }, | |||
896 | { "infty", '/', "NaN", "NaN" }, | |||
897 | { "-infty", '/', "NaN", "NaN" }, | |||
898 | { "NaN", '/', "NaN", "NaN" }, | |||
899 | { "0", '/', "infty", "0" }, | |||
900 | { "42", '/', "infty", "0" }, | |||
901 | { "-42", '/', "infty", "0" }, | |||
902 | { "infty", '/', "infty", "NaN" }, | |||
903 | { "-infty", '/', "infty", "NaN" }, | |||
904 | { "NaN", '/', "infty", "NaN" }, | |||
905 | { "0", '/', "-infty", "0" }, | |||
906 | { "42", '/', "-infty", "0" }, | |||
907 | { "-42", '/', "-infty", "0" }, | |||
908 | { "infty", '/', "-infty", "NaN" }, | |||
909 | { "-infty", '/', "-infty", "NaN" }, | |||
910 | { "NaN", '/', "-infty", "NaN" }, | |||
911 | { "1", '-', "1/3", "2/3" }, | |||
912 | { "1/3", '+', "1/2", "5/6" }, | |||
913 | { "1/2", '+', "1/2", "1" }, | |||
914 | { "3/4", '-', "1/4", "1/2" }, | |||
915 | { "1/2", '-', "1/3", "1/6" }, | |||
916 | { "infty", '+', "42", "infty" }, | |||
917 | { "infty", '+', "infty", "infty" }, | |||
918 | { "42", '+', "infty", "infty" }, | |||
919 | { "infty", '-', "infty", "NaN" }, | |||
920 | { "infty", '*', "infty", "infty" }, | |||
921 | { "infty", '*', "-infty", "-infty" }, | |||
922 | { "-infty", '*', "infty", "-infty" }, | |||
923 | { "-infty", '*', "-infty", "infty" }, | |||
924 | { "0", '*', "infty", "NaN" }, | |||
925 | { "1", '*', "infty", "infty" }, | |||
926 | { "infty", '*', "0", "NaN" }, | |||
927 | { "infty", '*', "42", "infty" }, | |||
928 | { "42", '-', "infty", "-infty" }, | |||
929 | { "infty", '+', "-infty", "NaN" }, | |||
930 | { "4", 'g', "6", "2" }, | |||
931 | { "5", 'g', "6", "1" }, | |||
932 | { "42", 'm', "3", "3" }, | |||
933 | { "42", 'M', "3", "42" }, | |||
934 | { "3", 'm', "42", "3" }, | |||
935 | { "3", 'M', "42", "42" }, | |||
936 | { "42", 'm', "infty", "42" }, | |||
937 | { "42", 'M', "infty", "infty" }, | |||
938 | { "42", 'm', "-infty", "-infty" }, | |||
939 | { "42", 'M', "-infty", "42" }, | |||
940 | { "42", 'm', "NaN", "NaN" }, | |||
941 | { "42", 'M', "NaN", "NaN" }, | |||
942 | { "infty", 'm', "-infty", "-infty" }, | |||
943 | { "infty", 'M', "-infty", "infty" }, | |||
944 | }; | |||
945 | ||||
946 | /* Perform some basic tests of binary operations on isl_val objects. | |||
947 | */ | |||
948 | static int test_bin_val(isl_ctx *ctx) | |||
949 | { | |||
950 | int i; | |||
951 | isl_val *v1, *v2, *res; | |||
952 | __isl_give isl_val *(*fn)(__isl_take isl_val *v1, | |||
953 | __isl_take isl_val *v2); | |||
954 | int ok; | |||
955 | ||||
956 | for (i = 0; i < ARRAY_SIZE(val_bin_tests)(sizeof(val_bin_tests)/sizeof(*val_bin_tests)); ++i) { | |||
957 | v1 = isl_val_read_from_str(ctx, val_bin_tests[i].arg1); | |||
958 | v2 = isl_val_read_from_str(ctx, val_bin_tests[i].arg2); | |||
959 | res = isl_val_read_from_str(ctx, val_bin_tests[i].res); | |||
960 | fn = val_bin_op[val_bin_tests[i].op].fn; | |||
961 | v1 = fn(v1, v2); | |||
962 | if (isl_val_is_nan(res)) | |||
963 | ok = isl_val_is_nan(v1); | |||
964 | else | |||
965 | ok = isl_val_eq(v1, res); | |||
966 | isl_val_free(v1); | |||
967 | isl_val_free(res); | |||
968 | if (ok < 0) | |||
969 | return -1; | |||
970 | if (!ok) | |||
971 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 972); return -1; } while (0) | |||
972 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 972); return -1; } while (0); | |||
973 | } | |||
974 | ||||
975 | return 0; | |||
976 | } | |||
977 | ||||
978 | /* Perform some basic tests on isl_val objects. | |||
979 | */ | |||
980 | static int test_val(isl_ctx *ctx) | |||
981 | { | |||
982 | if (test_un_val(ctx) < 0) | |||
983 | return -1; | |||
984 | if (test_bin_val(ctx) < 0) | |||
985 | return -1; | |||
986 | return 0; | |||
987 | } | |||
988 | ||||
989 | /* Sets described using existentially quantified variables that | |||
990 | * can also be described without. | |||
991 | */ | |||
992 | static const char *elimination_tests[] = { | |||
993 | "{ [i,j] : 2 * [i/2] + 3 * [j/4] <= 10 and 2 i = j }", | |||
994 | "{ [m, w] : exists a : w - 2m - 5 <= 3a <= m - 2w }", | |||
995 | "{ [m, w] : exists a : w >= 0 and a < m and -1 + w <= a <= 2m - w }", | |||
996 | }; | |||
997 | ||||
998 | /* Check that redundant existentially quantified variables are | |||
999 | * getting removed. | |||
1000 | */ | |||
1001 | static int test_elimination(isl_ctx *ctx) | |||
1002 | { | |||
1003 | int i; | |||
1004 | isl_size n; | |||
1005 | isl_basic_setisl_basic_map *bset; | |||
1006 | ||||
1007 | for (i = 0; i < ARRAY_SIZE(elimination_tests)(sizeof(elimination_tests)/sizeof(*elimination_tests)); ++i) { | |||
1008 | bset = isl_basic_set_read_from_str(ctx, elimination_tests[i]); | |||
1009 | n = isl_basic_set_dim(bset, isl_dim_div); | |||
1010 | isl_basic_set_free(bset); | |||
1011 | if (n < 0) | |||
1012 | return -1; | |||
1013 | if (n != 0) | |||
1014 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "expecting no existentials" , "polly/lib/External/isl/isl_test.c", 1015); return -1; } while (0) | |||
1015 | "expecting no existentials", return -1)do { isl_handle_error(ctx, isl_error_unknown, "expecting no existentials" , "polly/lib/External/isl/isl_test.c", 1015); return -1; } while (0); | |||
1016 | } | |||
1017 | ||||
1018 | return 0; | |||
1019 | } | |||
1020 | ||||
1021 | static int test_div(isl_ctx *ctx) | |||
1022 | { | |||
1023 | const char *str; | |||
1024 | int empty; | |||
1025 | isl_space *space; | |||
1026 | isl_setisl_map *set; | |||
1027 | isl_local_space *ls; | |||
1028 | struct isl_basic_setisl_basic_map *bset; | |||
1029 | struct isl_constraint *c; | |||
1030 | ||||
1031 | /* test 1 */ | |||
1032 | space = isl_space_set_alloc(ctx, 0, 3); | |||
1033 | bset = isl_basic_set_universe(isl_space_copy(space)); | |||
1034 | ls = isl_local_space_from_space(space); | |||
1035 | ||||
1036 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1037 | c = isl_constraint_set_constant_si(c, -1); | |||
1038 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); | |||
1039 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, 3); | |||
1040 | bset = isl_basic_set_add_constraint(bset, c); | |||
1041 | ||||
1042 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1043 | c = isl_constraint_set_constant_si(c, 1); | |||
1044 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); | |||
1045 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, 3); | |||
1046 | bset = isl_basic_set_add_constraint(bset, c); | |||
1047 | ||||
1048 | bset = isl_basic_set_project_out(bset, isl_dim_set, 1, 2); | |||
1049 | ||||
1050 | assert(bset && bset->n_div == 1)((void) sizeof ((bset && bset->n_div == 1) ? 1 : 0 ), __extension__ ({ if (bset && bset->n_div == 1) ; else __assert_fail ("bset && bset->n_div == 1", "polly/lib/External/isl/isl_test.c" , 1050, __extension__ __PRETTY_FUNCTION__); })); | |||
1051 | isl_local_space_free(ls); | |||
1052 | isl_basic_set_free(bset); | |||
1053 | ||||
1054 | /* test 2 */ | |||
1055 | space = isl_space_set_alloc(ctx, 0, 3); | |||
1056 | bset = isl_basic_set_universe(isl_space_copy(space)); | |||
1057 | ls = isl_local_space_from_space(space); | |||
1058 | ||||
1059 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1060 | c = isl_constraint_set_constant_si(c, 1); | |||
1061 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); | |||
1062 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, 3); | |||
1063 | bset = isl_basic_set_add_constraint(bset, c); | |||
1064 | ||||
1065 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1066 | c = isl_constraint_set_constant_si(c, -1); | |||
1067 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); | |||
1068 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, 3); | |||
1069 | bset = isl_basic_set_add_constraint(bset, c); | |||
1070 | ||||
1071 | bset = isl_basic_set_project_out(bset, isl_dim_set, 1, 2); | |||
1072 | ||||
1073 | assert(bset && bset->n_div == 1)((void) sizeof ((bset && bset->n_div == 1) ? 1 : 0 ), __extension__ ({ if (bset && bset->n_div == 1) ; else __assert_fail ("bset && bset->n_div == 1", "polly/lib/External/isl/isl_test.c" , 1073, __extension__ __PRETTY_FUNCTION__); })); | |||
1074 | isl_local_space_free(ls); | |||
1075 | isl_basic_set_free(bset); | |||
1076 | ||||
1077 | /* test 3 */ | |||
1078 | space = isl_space_set_alloc(ctx, 0, 3); | |||
1079 | bset = isl_basic_set_universe(isl_space_copy(space)); | |||
1080 | ls = isl_local_space_from_space(space); | |||
1081 | ||||
1082 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1083 | c = isl_constraint_set_constant_si(c, 1); | |||
1084 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); | |||
1085 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, 3); | |||
1086 | bset = isl_basic_set_add_constraint(bset, c); | |||
1087 | ||||
1088 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1089 | c = isl_constraint_set_constant_si(c, -3); | |||
1090 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); | |||
1091 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, 4); | |||
1092 | bset = isl_basic_set_add_constraint(bset, c); | |||
1093 | ||||
1094 | bset = isl_basic_set_project_out(bset, isl_dim_set, 1, 2); | |||
1095 | ||||
1096 | assert(bset && bset->n_div == 1)((void) sizeof ((bset && bset->n_div == 1) ? 1 : 0 ), __extension__ ({ if (bset && bset->n_div == 1) ; else __assert_fail ("bset && bset->n_div == 1", "polly/lib/External/isl/isl_test.c" , 1096, __extension__ __PRETTY_FUNCTION__); })); | |||
1097 | isl_local_space_free(ls); | |||
1098 | isl_basic_set_free(bset); | |||
1099 | ||||
1100 | /* test 4 */ | |||
1101 | space = isl_space_set_alloc(ctx, 0, 3); | |||
1102 | bset = isl_basic_set_universe(isl_space_copy(space)); | |||
1103 | ls = isl_local_space_from_space(space); | |||
1104 | ||||
1105 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1106 | c = isl_constraint_set_constant_si(c, 2); | |||
1107 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); | |||
1108 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, 3); | |||
1109 | bset = isl_basic_set_add_constraint(bset, c); | |||
1110 | ||||
1111 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1112 | c = isl_constraint_set_constant_si(c, -1); | |||
1113 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); | |||
1114 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, 6); | |||
1115 | bset = isl_basic_set_add_constraint(bset, c); | |||
1116 | ||||
1117 | bset = isl_basic_set_project_out(bset, isl_dim_set, 1, 2); | |||
1118 | ||||
1119 | assert(isl_basic_set_is_empty(bset))((void) sizeof ((isl_basic_set_is_empty(bset)) ? 1 : 0), __extension__ ({ if (isl_basic_set_is_empty(bset)) ; else __assert_fail ("isl_basic_set_is_empty(bset)" , "polly/lib/External/isl/isl_test.c", 1119, __extension__ __PRETTY_FUNCTION__ ); })); | |||
1120 | isl_local_space_free(ls); | |||
1121 | isl_basic_set_free(bset); | |||
1122 | ||||
1123 | /* test 5 */ | |||
1124 | space = isl_space_set_alloc(ctx, 0, 3); | |||
1125 | bset = isl_basic_set_universe(isl_space_copy(space)); | |||
1126 | ls = isl_local_space_from_space(space); | |||
1127 | ||||
1128 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1129 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); | |||
1130 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, 3); | |||
1131 | bset = isl_basic_set_add_constraint(bset, c); | |||
1132 | ||||
1133 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1134 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); | |||
1135 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, -3); | |||
1136 | bset = isl_basic_set_add_constraint(bset, c); | |||
1137 | ||||
1138 | bset = isl_basic_set_project_out(bset, isl_dim_set, 2, 1); | |||
1139 | ||||
1140 | assert(bset && bset->n_div == 0)((void) sizeof ((bset && bset->n_div == 0) ? 1 : 0 ), __extension__ ({ if (bset && bset->n_div == 0) ; else __assert_fail ("bset && bset->n_div == 0", "polly/lib/External/isl/isl_test.c" , 1140, __extension__ __PRETTY_FUNCTION__); })); | |||
1141 | isl_basic_set_free(bset); | |||
1142 | isl_local_space_free(ls); | |||
1143 | ||||
1144 | /* test 6 */ | |||
1145 | space = isl_space_set_alloc(ctx, 0, 3); | |||
1146 | bset = isl_basic_set_universe(isl_space_copy(space)); | |||
1147 | ls = isl_local_space_from_space(space); | |||
1148 | ||||
1149 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1150 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); | |||
1151 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, 6); | |||
1152 | bset = isl_basic_set_add_constraint(bset, c); | |||
1153 | ||||
1154 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1155 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); | |||
1156 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, -3); | |||
1157 | bset = isl_basic_set_add_constraint(bset, c); | |||
1158 | ||||
1159 | bset = isl_basic_set_project_out(bset, isl_dim_set, 2, 1); | |||
1160 | ||||
1161 | assert(bset && bset->n_div == 1)((void) sizeof ((bset && bset->n_div == 1) ? 1 : 0 ), __extension__ ({ if (bset && bset->n_div == 1) ; else __assert_fail ("bset && bset->n_div == 1", "polly/lib/External/isl/isl_test.c" , 1161, __extension__ __PRETTY_FUNCTION__); })); | |||
1162 | isl_basic_set_free(bset); | |||
1163 | isl_local_space_free(ls); | |||
1164 | ||||
1165 | /* test 7 */ | |||
1166 | /* This test is a bit tricky. We set up an equality | |||
1167 | * a + 3b + 3c = 6 e0 | |||
1168 | * Normalization of divs creates _two_ divs | |||
1169 | * a = 3 e0 | |||
1170 | * c - b - e0 = 2 e1 | |||
1171 | * Afterwards e0 is removed again because it has coefficient -1 | |||
1172 | * and we end up with the original equality and div again. | |||
1173 | * Perhaps we can avoid the introduction of this temporary div. | |||
1174 | */ | |||
1175 | space = isl_space_set_alloc(ctx, 0, 4); | |||
1176 | bset = isl_basic_set_universe(isl_space_copy(space)); | |||
1177 | ls = isl_local_space_from_space(space); | |||
1178 | ||||
1179 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1180 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); | |||
1181 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, -3); | |||
1182 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, -3); | |||
1183 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 3, 6); | |||
1184 | bset = isl_basic_set_add_constraint(bset, c); | |||
1185 | ||||
1186 | bset = isl_basic_set_project_out(bset, isl_dim_set, 3, 1); | |||
1187 | ||||
1188 | /* Test disabled for now */ | |||
1189 | /* | |||
1190 | assert(bset && bset->n_div == 1); | |||
1191 | */ | |||
1192 | isl_local_space_free(ls); | |||
1193 | isl_basic_set_free(bset); | |||
1194 | ||||
1195 | /* test 8 */ | |||
1196 | space = isl_space_set_alloc(ctx, 0, 5); | |||
1197 | bset = isl_basic_set_universe(isl_space_copy(space)); | |||
1198 | ls = isl_local_space_from_space(space); | |||
1199 | ||||
1200 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1201 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); | |||
1202 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, -3); | |||
1203 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 3, -3); | |||
1204 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 4, 6); | |||
1205 | bset = isl_basic_set_add_constraint(bset, c); | |||
1206 | ||||
1207 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1208 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); | |||
1209 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, 1); | |||
1210 | c = isl_constraint_set_constant_si(c, 1); | |||
1211 | bset = isl_basic_set_add_constraint(bset, c); | |||
1212 | ||||
1213 | bset = isl_basic_set_project_out(bset, isl_dim_set, 4, 1); | |||
1214 | ||||
1215 | /* Test disabled for now */ | |||
1216 | /* | |||
1217 | assert(bset && bset->n_div == 1); | |||
1218 | */ | |||
1219 | isl_local_space_free(ls); | |||
1220 | isl_basic_set_free(bset); | |||
1221 | ||||
1222 | /* test 9 */ | |||
1223 | space = isl_space_set_alloc(ctx, 0, 4); | |||
1224 | bset = isl_basic_set_universe(isl_space_copy(space)); | |||
1225 | ls = isl_local_space_from_space(space); | |||
1226 | ||||
1227 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1228 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); | |||
1229 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, -1); | |||
1230 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, -2); | |||
1231 | bset = isl_basic_set_add_constraint(bset, c); | |||
1232 | ||||
1233 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1234 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); | |||
1235 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 3, 3); | |||
1236 | c = isl_constraint_set_constant_si(c, 2); | |||
1237 | bset = isl_basic_set_add_constraint(bset, c); | |||
1238 | ||||
1239 | bset = isl_basic_set_project_out(bset, isl_dim_set, 2, 2); | |||
1240 | ||||
1241 | bset = isl_basic_set_fix_si(bset, isl_dim_set, 0, 2); | |||
1242 | ||||
1243 | assert(!isl_basic_set_is_empty(bset))((void) sizeof ((!isl_basic_set_is_empty(bset)) ? 1 : 0), __extension__ ({ if (!isl_basic_set_is_empty(bset)) ; else __assert_fail ( "!isl_basic_set_is_empty(bset)", "polly/lib/External/isl/isl_test.c" , 1243, __extension__ __PRETTY_FUNCTION__); })); | |||
1244 | ||||
1245 | isl_local_space_free(ls); | |||
1246 | isl_basic_set_free(bset); | |||
1247 | ||||
1248 | /* test 10 */ | |||
1249 | space = isl_space_set_alloc(ctx, 0, 3); | |||
1250 | bset = isl_basic_set_universe(isl_space_copy(space)); | |||
1251 | ls = isl_local_space_from_space(space); | |||
1252 | ||||
1253 | c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); | |||
1254 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); | |||
1255 | c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, -2); | |||
1256 | bset = isl_basic_set_add_constraint(bset, c); | |||
1257 | ||||
1258 | bset = isl_basic_set_project_out(bset, isl_dim_set, 2, 1); | |||
1259 | ||||
1260 | bset = isl_basic_set_fix_si(bset, isl_dim_set, 0, 2); | |||
1261 | ||||
1262 | isl_local_space_free(ls); | |||
1263 | isl_basic_set_free(bset); | |||
1264 | ||||
1265 | str = "{ [i] : exists (e0, e1: 3e1 >= 1 + 2e0 and " | |||
1266 | "8e1 <= -1 + 5i - 5e0 and 2e1 >= 1 + 2i - 5e0) }"; | |||
1267 | set = isl_set_read_from_str(ctx, str); | |||
1268 | set = isl_set_compute_divs(set); | |||
1269 | isl_set_free(set); | |||
1270 | if (!set) | |||
1271 | return -1; | |||
1272 | ||||
1273 | if (test_elimination(ctx) < 0) | |||
1274 | return -1; | |||
1275 | ||||
1276 | str = "{ [i,j,k] : 3 + i + 2j >= 0 and 2 * [(i+2j)/4] <= k }"; | |||
1277 | set = isl_set_read_from_str(ctx, str); | |||
1278 | set = isl_set_remove_divs_involving_dims(set, isl_dim_set, 0, 2); | |||
1279 | set = isl_set_fix_si(set, isl_dim_set, 2, -3); | |||
1280 | empty = isl_set_is_empty(set); | |||
1281 | isl_set_free(set); | |||
1282 | if (empty < 0) | |||
1283 | return -1; | |||
1284 | if (!empty) | |||
1285 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "result not as accurate as expected" , "polly/lib/External/isl/isl_test.c", 1286); return -1; } while (0) | |||
1286 | "result not as accurate as expected", return -1)do { isl_handle_error(ctx, isl_error_unknown, "result not as accurate as expected" , "polly/lib/External/isl/isl_test.c", 1286); return -1; } while (0); | |||
1287 | ||||
1288 | return 0; | |||
1289 | } | |||
1290 | ||||
1291 | void test_application_case(struct isl_ctx *ctx, const char *name) | |||
1292 | { | |||
1293 | char *filename; | |||
1294 | FILE *input; | |||
1295 | struct isl_basic_setisl_basic_map *bset1, *bset2; | |||
1296 | struct isl_basic_map *bmap; | |||
1297 | ||||
1298 | filename = get_filename(ctx, name, "omega"); | |||
1299 | assert(filename)((void) sizeof ((filename) ? 1 : 0), __extension__ ({ if (filename ) ; else __assert_fail ("filename", "polly/lib/External/isl/isl_test.c" , 1299, __extension__ __PRETTY_FUNCTION__); })); | |||
1300 | input = fopen(filename, "r"); | |||
1301 | assert(input)((void) sizeof ((input) ? 1 : 0), __extension__ ({ if (input) ; else __assert_fail ("input", "polly/lib/External/isl/isl_test.c" , 1301, __extension__ __PRETTY_FUNCTION__); })); | |||
1302 | ||||
1303 | bset1 = isl_basic_set_read_from_file(ctx, input); | |||
1304 | bmap = isl_basic_map_read_from_file(ctx, input); | |||
1305 | ||||
1306 | bset1 = isl_basic_set_apply(bset1, bmap); | |||
1307 | ||||
1308 | bset2 = isl_basic_set_read_from_file(ctx, input); | |||
1309 | ||||
1310 | assert(isl_basic_set_is_equal(bset1, bset2) == 1)((void) sizeof ((isl_basic_set_is_equal(bset1, bset2) == 1) ? 1 : 0), __extension__ ({ if (isl_basic_set_is_equal(bset1, bset2 ) == 1) ; else __assert_fail ("isl_basic_set_is_equal(bset1, bset2) == 1" , "polly/lib/External/isl/isl_test.c", 1310, __extension__ __PRETTY_FUNCTION__ ); })); | |||
1311 | ||||
1312 | isl_basic_set_free(bset1); | |||
1313 | isl_basic_set_free(bset2); | |||
1314 | free(filename); | |||
1315 | ||||
1316 | fclose(input); | |||
1317 | } | |||
1318 | ||||
1319 | static int test_application(isl_ctx *ctx) | |||
1320 | { | |||
1321 | test_application_case(ctx, "application"); | |||
1322 | test_application_case(ctx, "application2"); | |||
1323 | ||||
1324 | return 0; | |||
1325 | } | |||
1326 | ||||
1327 | void test_affine_hull_case(struct isl_ctx *ctx, const char *name) | |||
1328 | { | |||
1329 | char *filename; | |||
1330 | FILE *input; | |||
1331 | struct isl_basic_setisl_basic_map *bset1, *bset2; | |||
1332 | ||||
1333 | filename = get_filename(ctx, name, "polylib"); | |||
1334 | assert(filename)((void) sizeof ((filename) ? 1 : 0), __extension__ ({ if (filename ) ; else __assert_fail ("filename", "polly/lib/External/isl/isl_test.c" , 1334, __extension__ __PRETTY_FUNCTION__); })); | |||
1335 | input = fopen(filename, "r"); | |||
1336 | assert(input)((void) sizeof ((input) ? 1 : 0), __extension__ ({ if (input) ; else __assert_fail ("input", "polly/lib/External/isl/isl_test.c" , 1336, __extension__ __PRETTY_FUNCTION__); })); | |||
1337 | ||||
1338 | bset1 = isl_basic_set_read_from_file(ctx, input); | |||
1339 | bset2 = isl_basic_set_read_from_file(ctx, input); | |||
1340 | ||||
1341 | bset1 = isl_basic_set_affine_hull(bset1); | |||
1342 | ||||
1343 | assert(isl_basic_set_is_equal(bset1, bset2) == 1)((void) sizeof ((isl_basic_set_is_equal(bset1, bset2) == 1) ? 1 : 0), __extension__ ({ if (isl_basic_set_is_equal(bset1, bset2 ) == 1) ; else __assert_fail ("isl_basic_set_is_equal(bset1, bset2) == 1" , "polly/lib/External/isl/isl_test.c", 1343, __extension__ __PRETTY_FUNCTION__ ); })); | |||
1344 | ||||
1345 | isl_basic_set_free(bset1); | |||
1346 | isl_basic_set_free(bset2); | |||
1347 | free(filename); | |||
1348 | ||||
1349 | fclose(input); | |||
1350 | } | |||
1351 | ||||
1352 | /* Pairs of sets and the corresponding expected results of | |||
1353 | * isl_basic_set_recession_cone. | |||
1354 | */ | |||
1355 | struct { | |||
1356 | const char *set; | |||
1357 | const char *cone; | |||
1358 | } recession_cone_tests[] = { | |||
1359 | { "{ [i] : 0 <= i <= 10 }", "{ [0] }" }, | |||
1360 | { "{ [i] : 0 <= i }", "{ [i] : 0 <= i }" }, | |||
1361 | { "{ [i] : i <= 10 }", "{ [i] : i <= 0 }" }, | |||
1362 | { "{ [i] : false }", "{ [i] : false }" }, | |||
1363 | }; | |||
1364 | ||||
1365 | /* Perform some basic isl_basic_set_recession_cone tests. | |||
1366 | */ | |||
1367 | static int test_recession_cone(struct isl_ctx *ctx) | |||
1368 | { | |||
1369 | int i; | |||
1370 | ||||
1371 | for (i = 0; i < ARRAY_SIZE(recession_cone_tests)(sizeof(recession_cone_tests)/sizeof(*recession_cone_tests)); ++i) { | |||
1372 | const char *str; | |||
1373 | isl_basic_setisl_basic_map *bset; | |||
1374 | isl_basic_setisl_basic_map *cone, *expected; | |||
1375 | isl_bool equal; | |||
1376 | ||||
1377 | str = recession_cone_tests[i].set; | |||
1378 | bset = isl_basic_set_read_from_str(ctx, str); | |||
1379 | str = recession_cone_tests[i].cone; | |||
1380 | expected = isl_basic_set_read_from_str(ctx, str); | |||
1381 | cone = isl_basic_set_recession_cone(bset); | |||
1382 | equal = isl_basic_set_is_equal(cone, expected); | |||
1383 | isl_basic_set_free(cone); | |||
1384 | isl_basic_set_free(expected); | |||
1385 | if (equal < 0) | |||
1386 | return -1; | |||
1387 | if (!equal) | |||
1388 | isl_die(ctx, isl_error_unknown, "unexpected cone",do { isl_handle_error(ctx, isl_error_unknown, "unexpected cone" , "polly/lib/External/isl/isl_test.c", 1389); return -1; } while (0) | |||
1389 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected cone" , "polly/lib/External/isl/isl_test.c", 1389); return -1; } while (0); | |||
1390 | } | |||
1391 | ||||
1392 | return 0; | |||
1393 | } | |||
1394 | ||||
1395 | int test_affine_hull(struct isl_ctx *ctx) | |||
1396 | { | |||
1397 | const char *str; | |||
1398 | isl_setisl_map *set; | |||
1399 | isl_basic_setisl_basic_map *bset, *bset2; | |||
1400 | isl_size n; | |||
1401 | isl_bool subset; | |||
1402 | ||||
1403 | test_affine_hull_case(ctx, "affine2"); | |||
1404 | test_affine_hull_case(ctx, "affine"); | |||
1405 | test_affine_hull_case(ctx, "affine3"); | |||
1406 | ||||
1407 | str = "[m] -> { [i0] : exists (e0, e1: e1 <= 1 + i0 and " | |||
1408 | "m >= 3 and 4i0 <= 2 + m and e1 >= i0 and " | |||
1409 | "e1 >= 0 and e1 <= 2 and e1 >= 1 + 2e0 and " | |||
1410 | "2e1 <= 1 + m + 4e0 and 2e1 >= 2 - m + 4i0 - 4e0) }"; | |||
1411 | set = isl_set_read_from_str(ctx, str); | |||
1412 | bset = isl_set_affine_hull(set); | |||
1413 | n = isl_basic_set_dim(bset, isl_dim_div); | |||
1414 | isl_basic_set_free(bset); | |||
1415 | if (n < 0) | |||
1416 | return -1; | |||
1417 | if (n != 0) | |||
1418 | isl_die(ctx, isl_error_unknown, "not expecting any divs",do { isl_handle_error(ctx, isl_error_unknown, "not expecting any divs" , "polly/lib/External/isl/isl_test.c", 1419); return -1; } while (0) | |||
1419 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "not expecting any divs" , "polly/lib/External/isl/isl_test.c", 1419); return -1; } while (0); | |||
1420 | ||||
1421 | /* Check that isl_map_affine_hull is not confused by | |||
1422 | * the reordering of divs in isl_map_align_divs. | |||
1423 | */ | |||
1424 | str = "{ [a, b, c, 0] : exists (e0 = [(b)/32], e1 = [(c)/32]: " | |||
1425 | "32e0 = b and 32e1 = c); " | |||
1426 | "[a, 0, c, 0] : exists (e0 = [(c)/32]: 32e0 = c) }"; | |||
1427 | set = isl_set_read_from_str(ctx, str); | |||
1428 | bset = isl_set_affine_hull(set); | |||
1429 | isl_basic_set_free(bset); | |||
1430 | if (!bset) | |||
1431 | return -1; | |||
1432 | ||||
1433 | str = "{ [a] : exists e0, e1, e2: 32e1 = 31 + 31a + 31e0 and " | |||
1434 | "32e2 = 31 + 31e0 }"; | |||
1435 | set = isl_set_read_from_str(ctx, str); | |||
1436 | bset = isl_set_affine_hull(set); | |||
1437 | str = "{ [a] : exists e : a = 32 e }"; | |||
1438 | bset2 = isl_basic_set_read_from_str(ctx, str); | |||
1439 | subset = isl_basic_set_is_subset(bset, bset2); | |||
1440 | isl_basic_set_free(bset); | |||
1441 | isl_basic_set_free(bset2); | |||
1442 | if (subset < 0) | |||
1443 | return -1; | |||
1444 | if (!subset) | |||
1445 | isl_die(ctx, isl_error_unknown, "not as accurate as expected",do { isl_handle_error(ctx, isl_error_unknown, "not as accurate as expected" , "polly/lib/External/isl/isl_test.c", 1446); return -1; } while (0) | |||
1446 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "not as accurate as expected" , "polly/lib/External/isl/isl_test.c", 1446); return -1; } while (0); | |||
1447 | ||||
1448 | return 0; | |||
1449 | } | |||
1450 | ||||
1451 | /* Test a special case of isl_set_plain_unshifted_simple_hull | |||
1452 | * where older versions of isl would include a redundant constraint | |||
1453 | * in the result. | |||
1454 | * Check that the result does not have any constraints. | |||
1455 | */ | |||
1456 | static isl_stat test_plain_unshifted_simple_hull_special(isl_ctx *ctx) | |||
1457 | { | |||
1458 | const char *str; | |||
1459 | isl_bool is_universe; | |||
1460 | isl_setisl_map *set; | |||
1461 | isl_basic_setisl_basic_map *bset; | |||
1462 | ||||
1463 | str = "{[x, y] : x = 0 or 2*((x+y)//2) <= y + 2 }"; | |||
1464 | set = isl_set_read_from_str(ctx, str); | |||
1465 | bset = isl_set_plain_unshifted_simple_hull(set); | |||
1466 | is_universe = isl_basic_set_plain_is_universe(bset); | |||
1467 | isl_basic_set_free(bset); | |||
1468 | ||||
1469 | if (is_universe < 0) | |||
1470 | return isl_stat_error; | |||
1471 | if (!is_universe) | |||
1472 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "hull should not have any constraints" , "polly/lib/External/isl/isl_test.c", 1474); return isl_stat_error ; } while (0) | |||
1473 | "hull should not have any constraints",do { isl_handle_error(ctx, isl_error_unknown, "hull should not have any constraints" , "polly/lib/External/isl/isl_test.c", 1474); return isl_stat_error ; } while (0) | |||
1474 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "hull should not have any constraints" , "polly/lib/External/isl/isl_test.c", 1474); return isl_stat_error ; } while (0); | |||
1475 | ||||
1476 | return isl_stat_ok; | |||
1477 | } | |||
1478 | ||||
1479 | /* Inputs for simple hull tests, consisting of | |||
1480 | * the specific simple hull function, the input set and the expected result. | |||
1481 | */ | |||
1482 | struct { | |||
1483 | __isl_give isl_basic_setisl_basic_map *(*fn)(__isl_take isl_setisl_map *set); | |||
1484 | const char *set; | |||
1485 | const char *hull; | |||
1486 | } simple_hull_tests[] = { | |||
1487 | { &isl_set_plain_unshifted_simple_hull, | |||
1488 | "{ [i,j] : i >= 1 and j >= 1 or i >= 2 and j <= 10 }", | |||
1489 | "{ [i,j] : i >= 1 }" }, | |||
1490 | { &isl_set_plain_unshifted_simple_hull, | |||
1491 | "{ [n,i,j,k] : (i mod 3 = 2 and j mod 4 = 2) or " | |||
1492 | "(j mod 4 = 2 and k mod 6 = n) }", | |||
1493 | "{ [n,i,j,k] : j mod 4 = 2 }" }, | |||
1494 | { &isl_set_unshifted_simple_hull, | |||
1495 | "{ [0,x,y] : x <= -1; [1,x,y] : x <= y <= -x; [2,x,y] : x <= 1 }", | |||
1496 | "{ [t,x,y] : 0 <= t <= 2 and x <= 1 }" }, | |||
1497 | { &isl_set_simple_hull, | |||
1498 | "{ [a, b] : b <= 0 and " | |||
1499 | "2*floor((-2*floor((b)/2))/5) >= a - floor((b)/2); " | |||
1500 | "[a, b] : a mod 2 = 0 }", | |||
1501 | "{ [a, b] }" }, | |||
1502 | }; | |||
1503 | ||||
1504 | /* Basic tests for various simple hull functions. | |||
1505 | */ | |||
1506 | static int test_various_simple_hull(isl_ctx *ctx) | |||
1507 | { | |||
1508 | int i; | |||
1509 | isl_setisl_map *set; | |||
1510 | isl_basic_setisl_basic_map *hull, *expected; | |||
1511 | isl_bool equal; | |||
1512 | ||||
1513 | for (i = 0; i < ARRAY_SIZE(simple_hull_tests)(sizeof(simple_hull_tests)/sizeof(*simple_hull_tests)); ++i) { | |||
1514 | const char *str; | |||
1515 | str = simple_hull_tests[i].set; | |||
1516 | set = isl_set_read_from_str(ctx, str); | |||
1517 | str = simple_hull_tests[i].hull; | |||
1518 | expected = isl_basic_set_read_from_str(ctx, str); | |||
1519 | hull = simple_hull_tests[i].fn(set); | |||
1520 | equal = isl_basic_set_is_equal(hull, expected); | |||
1521 | isl_basic_set_free(hull); | |||
1522 | isl_basic_set_free(expected); | |||
1523 | if (equal < 0) | |||
1524 | return -1; | |||
1525 | if (!equal) | |||
1526 | isl_die(ctx, isl_error_unknown, "unexpected hull",do { isl_handle_error(ctx, isl_error_unknown, "unexpected hull" , "polly/lib/External/isl/isl_test.c", 1527); return -1; } while (0) | |||
1527 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected hull" , "polly/lib/External/isl/isl_test.c", 1527); return -1; } while (0); | |||
1528 | } | |||
1529 | ||||
1530 | return 0; | |||
1531 | } | |||
1532 | ||||
1533 | static int test_simple_hull(struct isl_ctx *ctx) | |||
1534 | { | |||
1535 | const char *str; | |||
1536 | isl_setisl_map *set; | |||
1537 | isl_basic_setisl_basic_map *bset; | |||
1538 | isl_bool is_empty; | |||
1539 | ||||
1540 | str = "{ [x, y] : 3y <= 2x and y >= -2 + 2x and 2y >= 2 - x;" | |||
1541 | "[y, x] : 3y <= 2x and y >= -2 + 2x and 2y >= 2 - x }"; | |||
1542 | set = isl_set_read_from_str(ctx, str); | |||
1543 | bset = isl_set_simple_hull(set); | |||
1544 | is_empty = isl_basic_set_is_empty(bset); | |||
1545 | isl_basic_set_free(bset); | |||
1546 | ||||
1547 | if (is_empty == isl_bool_error) | |||
1548 | return -1; | |||
1549 | ||||
1550 | if (is_empty == isl_bool_false) | |||
1551 | isl_die(ctx, isl_error_unknown, "Empty set should be detected",do { isl_handle_error(ctx, isl_error_unknown, "Empty set should be detected" , "polly/lib/External/isl/isl_test.c", 1552); return -1; } while (0) | |||
1552 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "Empty set should be detected" , "polly/lib/External/isl/isl_test.c", 1552); return -1; } while (0); | |||
1553 | ||||
1554 | if (test_plain_unshifted_simple_hull_special(ctx) < 0) | |||
1555 | return -1; | |||
1556 | if (test_various_simple_hull(ctx) < 0) | |||
1557 | return -1; | |||
1558 | ||||
1559 | return 0; | |||
1560 | } | |||
1561 | ||||
1562 | /* Inputs for isl_set_get_simple_fixed_box_hull tests. | |||
1563 | * "set" is the input set. | |||
1564 | * "offset" is the expected box offset. | |||
1565 | * "size" is the expected box size. | |||
1566 | */ | |||
1567 | static struct { | |||
1568 | const char *set; | |||
1569 | const char *offset; | |||
1570 | const char *size; | |||
1571 | } box_hull_tests[] = { | |||
1572 | { "{ S[x, y] : 0 <= x, y < 10 }", "{ S[0, 0] }", "{ S[10, 10] }" }, | |||
1573 | { "[N] -> { S[x, y] : N <= x, y < N + 10 }", | |||
1574 | "[N] -> { S[N, N] }", "{ S[10, 10] }" }, | |||
1575 | { "{ S[x, y] : 0 <= x + y, x - y < 10 }", | |||
1576 | "{ S[0, -4] }", "{ S[10, 9] }" }, | |||
1577 | { "{ [i=0:10] : exists (e0, e1: 3e1 >= 1 + 2e0 and " | |||
1578 | "8e1 <= -1 + 5i - 5e0 and 2e1 >= 1 + 2i - 5e0) }", | |||
1579 | "{ [3] }", "{ [8] }" }, | |||
1580 | { "[N] -> { [w = 0:17] : exists (e0: w < 2N and " | |||
1581 | "-1 + w <= e0 <= w and 2e0 >= N + w and w <= 2e0 <= 15 + w) }", | |||
1582 | "[N] -> { [N] }", "{ [9] }" }, | |||
1583 | }; | |||
1584 | ||||
1585 | /* Perform basic isl_set_get_simple_fixed_box_hull tests. | |||
1586 | */ | |||
1587 | static int test_box_hull(struct isl_ctx *ctx) | |||
1588 | { | |||
1589 | int i; | |||
1590 | ||||
1591 | for (i = 0; i < ARRAY_SIZE(box_hull_tests)(sizeof(box_hull_tests)/sizeof(*box_hull_tests)); ++i) { | |||
1592 | const char *str; | |||
1593 | isl_stat r; | |||
1594 | isl_setisl_map *set; | |||
1595 | isl_multi_aff *offset; | |||
1596 | isl_multi_val *size; | |||
1597 | isl_fixed_box *box; | |||
1598 | ||||
1599 | set = isl_set_read_from_str(ctx, box_hull_tests[i].set); | |||
1600 | box = isl_set_get_simple_fixed_box_hull(set); | |||
1601 | offset = isl_fixed_box_get_offset(box); | |||
1602 | size = isl_fixed_box_get_size(box); | |||
1603 | str = box_hull_tests[i].offset; | |||
1604 | r = multi_aff_check_plain_equal(offset, str); | |||
1605 | str = box_hull_tests[i].size; | |||
1606 | if (r >= 0) | |||
1607 | r = multi_val_check_plain_equal(size, str); | |||
1608 | isl_multi_aff_free(offset); | |||
1609 | isl_multi_val_free(size); | |||
1610 | isl_fixed_box_free(box); | |||
1611 | isl_set_free(set); | |||
1612 | if (r < 0) | |||
1613 | return -1; | |||
1614 | } | |||
1615 | ||||
1616 | return 0; | |||
1617 | } | |||
1618 | ||||
1619 | void test_convex_hull_case(struct isl_ctx *ctx, const char *name) | |||
1620 | { | |||
1621 | char *filename; | |||
1622 | FILE *input; | |||
1623 | struct isl_basic_setisl_basic_map *bset1, *bset2; | |||
1624 | struct isl_setisl_map *set; | |||
1625 | ||||
1626 | filename = get_filename(ctx, name, "polylib"); | |||
1627 | assert(filename)((void) sizeof ((filename) ? 1 : 0), __extension__ ({ if (filename ) ; else __assert_fail ("filename", "polly/lib/External/isl/isl_test.c" , 1627, __extension__ __PRETTY_FUNCTION__); })); | |||
1628 | input = fopen(filename, "r"); | |||
1629 | assert(input)((void) sizeof ((input) ? 1 : 0), __extension__ ({ if (input) ; else __assert_fail ("input", "polly/lib/External/isl/isl_test.c" , 1629, __extension__ __PRETTY_FUNCTION__); })); | |||
1630 | ||||
1631 | bset1 = isl_basic_set_read_from_file(ctx, input); | |||
1632 | bset2 = isl_basic_set_read_from_file(ctx, input); | |||
1633 | ||||
1634 | set = isl_basic_set_union(bset1, bset2); | |||
1635 | bset1 = isl_set_convex_hull(set); | |||
1636 | ||||
1637 | bset2 = isl_basic_set_read_from_file(ctx, input); | |||
1638 | ||||
1639 | assert(isl_basic_set_is_equal(bset1, bset2) == 1)((void) sizeof ((isl_basic_set_is_equal(bset1, bset2) == 1) ? 1 : 0), __extension__ ({ if (isl_basic_set_is_equal(bset1, bset2 ) == 1) ; else __assert_fail ("isl_basic_set_is_equal(bset1, bset2) == 1" , "polly/lib/External/isl/isl_test.c", 1639, __extension__ __PRETTY_FUNCTION__ ); })); | |||
1640 | ||||
1641 | isl_basic_set_free(bset1); | |||
1642 | isl_basic_set_free(bset2); | |||
1643 | free(filename); | |||
1644 | ||||
1645 | fclose(input); | |||
1646 | } | |||
1647 | ||||
1648 | struct { | |||
1649 | const char *set; | |||
1650 | const char *hull; | |||
1651 | } convex_hull_tests[] = { | |||
1652 | { "{ [i0, i1, i2] : (i2 = 1 and i0 = 0 and i1 >= 0) or " | |||
1653 | "(i0 = 1 and i1 = 0 and i2 = 1) or " | |||
1654 | "(i0 = 0 and i1 = 0 and i2 = 0) }", | |||
1655 | "{ [i0, i1, i2] : i0 >= 0 and i2 >= i0 and i2 <= 1 and i1 >= 0 }" }, | |||
1656 | { "[n] -> { [i0, i1, i0] : i0 <= -4 + n; " | |||
1657 | "[i0, i0, i2] : n = 6 and i0 >= 0 and i2 <= 7 - i0 and " | |||
1658 | "i2 <= 5 and i2 >= 4; " | |||
1659 | "[3, i1, 3] : n = 5 and i1 <= 2 and i1 >= 0 }", | |||
1660 | "[n] -> { [i0, i1, i2] : i2 <= -1 + n and 2i2 <= -6 + 3n - i0 and " | |||
1661 | "i2 <= 5 + i0 and i2 >= i0 }" }, | |||
1662 | { "{ [x, y] : 3y <= 2x and y >= -2 + 2x and 2y >= 2 - x }", | |||
1663 | "{ [x, y] : 1 = 0 }" }, | |||
1664 | { "{ [x, y, z] : 0 <= x, y, z <= 10; [x, y, 0] : x >= 0 and y > 0; " | |||
1665 | "[x, y, 0] : x >= 0 and y < 0 }", | |||
1666 | "{ [x, y, z] : x >= 0 and 0 <= z <= 10 }" }, | |||
1667 | { "{ [a, b, c] : a <= 1 and -a < b <= 1 and 0 <= c <= 2 - a - b and " | |||
1668 | "c <= a; " | |||
1669 | "[0, 2, 0]; [3, 1, 0] }", | |||
1670 | "{ [a, b, c] : b > -a and 2b >= -1 + a and 0 <= c <= a and " | |||
1671 | "5c <= 6 - a - 3b }" }, | |||
1672 | }; | |||
1673 | ||||
1674 | static int test_convex_hull_algo(isl_ctx *ctx, int convex) | |||
1675 | { | |||
1676 | int i; | |||
1677 | int orig_convex = ctx->opt->convex; | |||
1678 | ctx->opt->convex = convex; | |||
1679 | ||||
1680 | test_convex_hull_case(ctx, "convex0"); | |||
1681 | test_convex_hull_case(ctx, "convex1"); | |||
1682 | test_convex_hull_case(ctx, "convex2"); | |||
1683 | test_convex_hull_case(ctx, "convex3"); | |||
1684 | test_convex_hull_case(ctx, "convex4"); | |||
1685 | test_convex_hull_case(ctx, "convex5"); | |||
1686 | test_convex_hull_case(ctx, "convex6"); | |||
1687 | test_convex_hull_case(ctx, "convex7"); | |||
1688 | test_convex_hull_case(ctx, "convex8"); | |||
1689 | test_convex_hull_case(ctx, "convex9"); | |||
1690 | test_convex_hull_case(ctx, "convex10"); | |||
1691 | test_convex_hull_case(ctx, "convex11"); | |||
1692 | test_convex_hull_case(ctx, "convex12"); | |||
1693 | test_convex_hull_case(ctx, "convex13"); | |||
1694 | test_convex_hull_case(ctx, "convex14"); | |||
1695 | test_convex_hull_case(ctx, "convex15"); | |||
1696 | ||||
1697 | for (i = 0; i < ARRAY_SIZE(convex_hull_tests)(sizeof(convex_hull_tests)/sizeof(*convex_hull_tests)); ++i) { | |||
1698 | isl_setisl_map *set1, *set2; | |||
1699 | int equal; | |||
1700 | ||||
1701 | set1 = isl_set_read_from_str(ctx, convex_hull_tests[i].set); | |||
1702 | set2 = isl_set_read_from_str(ctx, convex_hull_tests[i].hull); | |||
1703 | set1 = isl_set_from_basic_set(isl_set_convex_hull(set1)); | |||
1704 | equal = isl_set_is_equal(set1, set2); | |||
1705 | isl_set_free(set1); | |||
1706 | isl_set_free(set2); | |||
1707 | ||||
1708 | if (equal < 0) | |||
1709 | return -1; | |||
1710 | if (!equal) | |||
1711 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected convex hull" , "polly/lib/External/isl/isl_test.c", 1712); return -1; } while (0) | |||
1712 | "unexpected convex hull", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected convex hull" , "polly/lib/External/isl/isl_test.c", 1712); return -1; } while (0); | |||
1713 | } | |||
1714 | ||||
1715 | ctx->opt->convex = orig_convex; | |||
1716 | ||||
1717 | return 0; | |||
1718 | } | |||
1719 | ||||
1720 | static int test_convex_hull(isl_ctx *ctx) | |||
1721 | { | |||
1722 | if (test_convex_hull_algo(ctx, ISL_CONVEX_HULL_FM1) < 0) | |||
1723 | return -1; | |||
1724 | if (test_convex_hull_algo(ctx, ISL_CONVEX_HULL_WRAP0) < 0) | |||
1725 | return -1; | |||
1726 | return 0; | |||
1727 | } | |||
1728 | ||||
1729 | /* Check that computing the gist of "map" with respect to "context" | |||
1730 | * does not make any copy of "map" get marked empty. | |||
1731 | * Earlier versions of isl would end up doing that. | |||
1732 | */ | |||
1733 | static isl_stat test_gist_empty_pair(isl_ctx *ctx, const char *map, | |||
1734 | const char *context) | |||
1735 | { | |||
1736 | isl_map *m1, *m2, *m3; | |||
1737 | isl_bool empty_before, empty_after; | |||
1738 | ||||
1739 | m1 = isl_map_read_from_str(ctx, map); | |||
1740 | m2 = isl_map_read_from_str(ctx, context); | |||
1741 | m3 = isl_map_copy(m1); | |||
1742 | empty_before = isl_map_is_empty(m3); | |||
1743 | m1 = isl_map_gist(m1, m2); | |||
1744 | empty_after = isl_map_is_empty(m3); | |||
1745 | isl_map_free(m1); | |||
1746 | isl_map_free(m3); | |||
1747 | ||||
1748 | if (empty_before < 0 || empty_after < 0) | |||
1749 | return isl_stat_error; | |||
1750 | if (empty_before) | |||
1751 | isl_die(ctx, isl_error_unknown, "map should not be empty",do { isl_handle_error(ctx, isl_error_unknown, "map should not be empty" , "polly/lib/External/isl/isl_test.c", 1752); return isl_stat_error ; } while (0) | |||
1752 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "map should not be empty" , "polly/lib/External/isl/isl_test.c", 1752); return isl_stat_error ; } while (0); | |||
1753 | if (empty_after) | |||
1754 | isl_die(ctx, isl_error_unknown, "map should still not be empty",do { isl_handle_error(ctx, isl_error_unknown, "map should still not be empty" , "polly/lib/External/isl/isl_test.c", 1755); return isl_stat_error ; } while (0) | |||
1755 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "map should still not be empty" , "polly/lib/External/isl/isl_test.c", 1755); return isl_stat_error ; } while (0); | |||
1756 | ||||
1757 | return isl_stat_ok; | |||
1758 | } | |||
1759 | ||||
1760 | /* Check that computing a gist does not make any copy of the input | |||
1761 | * get marked empty. | |||
1762 | * Earlier versions of isl would end up doing that on some pairs of inputs. | |||
1763 | */ | |||
1764 | static isl_stat test_gist_empty(isl_ctx *ctx) | |||
1765 | { | |||
1766 | const char *map, *context; | |||
1767 | ||||
1768 | map = "{ [] -> [a, b, c] : 2b = 1 + a }"; | |||
1769 | context = "{ [] -> [a, b, c] : 2c = 2 + a }"; | |||
1770 | if (test_gist_empty_pair(ctx, map, context) < 0) | |||
1771 | return isl_stat_error; | |||
1772 | map = "{ [] -> [0, 0] }"; | |||
1773 | context = "{ [] -> [a, b] : a > b }"; | |||
1774 | if (test_gist_empty_pair(ctx, map, context) < 0) | |||
1775 | return isl_stat_error; | |||
1776 | ||||
1777 | return isl_stat_ok; | |||
1778 | } | |||
1779 | ||||
1780 | /* Inputs to isl_map_plain_gist_basic_map, along with the expected output. | |||
1781 | */ | |||
1782 | struct { | |||
1783 | const char *map; | |||
1784 | const char *context; | |||
1785 | const char *gist; | |||
1786 | } plain_gist_tests[] = { | |||
1787 | { "{ [i] -> [j] : i >= 1 and j >= 1 or i >= 2 and j <= 10 }", | |||
1788 | "{ [i] -> [j] : i >= 1 }", | |||
1789 | "{ [i] -> [j] : j >= 1 or i >= 2 and j <= 10 }" }, | |||
1790 | { "{ [n] -> [i,j,k] : (i mod 3 = 2 and j mod 4 = 2) or " | |||
1791 | "(j mod 4 = 2 and k mod 6 = n) }", | |||
1792 | "{ [n] -> [i,j,k] : j mod 4 = 2 }", | |||
1793 | "{ [n] -> [i,j,k] : (i mod 3 = 2) or (k mod 6 = n) }" }, | |||
1794 | { "{ [i] -> [j] : i > j and (exists a,b : i <= 2a + 5b <= 2) }", | |||
1795 | "{ [i] -> [j] : i > j }", | |||
1796 | "{ [i] -> [j] : exists a,b : i <= 2a + 5b <= 2 }" }, | |||
1797 | }; | |||
1798 | ||||
1799 | /* Basic tests for isl_map_plain_gist_basic_map. | |||
1800 | */ | |||
1801 | static int test_plain_gist(isl_ctx *ctx) | |||
1802 | { | |||
1803 | int i; | |||
1804 | ||||
1805 | for (i = 0; i < ARRAY_SIZE(plain_gist_tests)(sizeof(plain_gist_tests)/sizeof(*plain_gist_tests)); ++i) { | |||
1806 | const char *str; | |||
1807 | int equal; | |||
1808 | isl_map *map, *gist; | |||
1809 | isl_basic_map *context; | |||
1810 | ||||
1811 | map = isl_map_read_from_str(ctx, plain_gist_tests[i].map); | |||
1812 | str = plain_gist_tests[i].context; | |||
1813 | context = isl_basic_map_read_from_str(ctx, str); | |||
1814 | map = isl_map_plain_gist_basic_map(map, context); | |||
1815 | gist = isl_map_read_from_str(ctx, plain_gist_tests[i].gist); | |||
1816 | equal = isl_map_is_equal(map, gist); | |||
1817 | isl_map_free(map); | |||
1818 | isl_map_free(gist); | |||
1819 | if (equal < 0) | |||
1820 | return -1; | |||
1821 | if (!equal) | |||
1822 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "incorrect gist result" , "polly/lib/External/isl/isl_test.c", 1823); return -1; } while (0) | |||
1823 | "incorrect gist result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "incorrect gist result" , "polly/lib/External/isl/isl_test.c", 1823); return -1; } while (0); | |||
1824 | } | |||
1825 | ||||
1826 | return 0; | |||
1827 | } | |||
1828 | ||||
1829 | /* Inputs for isl_basic_set_gist tests that are expected to fail. | |||
1830 | */ | |||
1831 | struct { | |||
1832 | const char *set; | |||
1833 | const char *context; | |||
1834 | } gist_fail_tests[] = { | |||
1835 | { "{ [i] : exists (e0, e1: 3e1 >= 1 + 2e0 and " | |||
1836 | "8e1 <= -1 + 5i - 5e0 and 2e1 >= 1 + 2i - 5e0) }", | |||
1837 | "{ [i] : i >= 0 }" }, | |||
1838 | }; | |||
1839 | ||||
1840 | /* Check that isl_basic_set_gist fails (gracefully) when expected. | |||
1841 | * In particular, the user should be able to recover from the failure. | |||
1842 | */ | |||
1843 | static isl_stat test_gist_fail(struct isl_ctx *ctx) | |||
1844 | { | |||
1845 | int i, n; | |||
1846 | int on_error; | |||
1847 | ||||
1848 | on_error = isl_options_get_on_error(ctx); | |||
1849 | isl_options_set_on_error(ctx, ISL_ON_ERROR_CONTINUE1); | |||
1850 | n = ARRAY_SIZE(gist_fail_tests)(sizeof(gist_fail_tests)/sizeof(*gist_fail_tests)); | |||
1851 | for (i = 0; i < n; ++i) { | |||
1852 | const char *str; | |||
1853 | isl_basic_setisl_basic_map *bset, *context; | |||
1854 | ||||
1855 | bset = isl_basic_set_read_from_str(ctx, gist_fail_tests[i].set); | |||
1856 | str = gist_fail_tests[i].context; | |||
1857 | context = isl_basic_set_read_from_str(ctx, str); | |||
1858 | bset = isl_basic_set_gist(bset, context); | |||
1859 | isl_basic_set_free(bset); | |||
1860 | if (bset) | |||
1861 | break; | |||
1862 | } | |||
1863 | isl_options_set_on_error(ctx, on_error); | |||
1864 | if (i < n) | |||
1865 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "operation not expected to succeed" , "polly/lib/External/isl/isl_test.c", 1867); return isl_stat_error ; } while (0) | |||
1866 | "operation not expected to succeed",do { isl_handle_error(ctx, isl_error_unknown, "operation not expected to succeed" , "polly/lib/External/isl/isl_test.c", 1867); return isl_stat_error ; } while (0) | |||
1867 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "operation not expected to succeed" , "polly/lib/External/isl/isl_test.c", 1867); return isl_stat_error ; } while (0); | |||
1868 | ||||
1869 | return isl_stat_ok; | |||
1870 | } | |||
1871 | ||||
1872 | struct { | |||
1873 | const char *set; | |||
1874 | const char *context; | |||
1875 | const char *gist; | |||
1876 | } gist_tests[] = { | |||
1877 | { "{ [1, -1, 3] }", | |||
1878 | "{ [1, b, 2 - b] : -1 <= b <= 2 }", | |||
1879 | "{ [a, -1, c] }" }, | |||
1880 | { "{ [a, b, c] : a <= 15 and a >= 1 }", | |||
1881 | "{ [a, b, c] : exists (e0 = floor((-1 + a)/16): a >= 1 and " | |||
1882 | "c <= 30 and 32e0 >= -62 + 2a + 2b - c and b >= 0) }", | |||
1883 | "{ [a, b, c] : a <= 15 }" }, | |||
1884 | { "{ : }", "{ : 1 = 0 }", "{ : }" }, | |||
1885 | { "{ : 1 = 0 }", "{ : 1 = 0 }", "{ : }" }, | |||
1886 | { "[M] -> { [x] : exists (e0 = floor((-2 + x)/3): 3e0 = -2 + x) }", | |||
1887 | "[M] -> { [3M] }" , "[M] -> { [x] : 1 = 0 }" }, | |||
1888 | { "{ [m, n, a, b] : a <= 2147 + n }", | |||
1889 | "{ [m, n, a, b] : (m >= 1 and n >= 1 and a <= 2148 - m and " | |||
1890 | "b <= 2148 - n and b >= 0 and b >= 2149 - n - a) or " | |||
1891 | "(n >= 1 and a >= 0 and b <= 2148 - n - a and " | |||
1892 | "b >= 0) }", | |||
1893 | "{ [m, n, ku, kl] }" }, | |||
1894 | { "{ [a, a, b] : a >= 10 }", | |||
1895 | "{ [a, b, c] : c >= a and c <= b and c >= 2 }", | |||
1896 | "{ [a, a, b] : a >= 10 }" }, | |||
1897 | { "{ [i, j] : i >= 0 and i + j >= 0 }", "{ [i, j] : i <= 0 }", | |||
1898 | "{ [0, j] : j >= 0 }" }, | |||
1899 | /* Check that no constraints on i6 are introduced in the gist */ | |||
1900 | { "[t1] -> { [i4, i6] : exists (e0 = floor((1530 - 4t1 - 5i4)/20): " | |||
1901 | "20e0 <= 1530 - 4t1 - 5i4 and 20e0 >= 1511 - 4t1 - 5i4 and " | |||
1902 | "5e0 <= 381 - t1 and i4 <= 1) }", | |||
1903 | "[t1] -> { [i4, i6] : exists (e0 = floor((-t1 + i6)/5): " | |||
1904 | "5e0 = -t1 + i6 and i6 <= 6 and i6 >= 3) }", | |||
1905 | "[t1] -> { [i4, i6] : exists (e0 = floor((1530 - 4t1 - 5i4)/20): " | |||
1906 | "i4 <= 1 and 5e0 <= 381 - t1 and 20e0 <= 1530 - 4t1 - 5i4 and " | |||
1907 | "20e0 >= 1511 - 4t1 - 5i4) }" }, | |||
1908 | /* Check that no constraints on i6 are introduced in the gist */ | |||
1909 | { "[t1, t2] -> { [i4, i5, i6] : exists (e0 = floor((1 + i4)/2), " | |||
1910 | "e1 = floor((1530 - 4t1 - 5i4)/20), " | |||
1911 | "e2 = floor((-4t1 - 5i4 + 10*floor((1 + i4)/2))/20), " | |||
1912 | "e3 = floor((-1 + i4)/2): t2 = 0 and 2e3 = -1 + i4 and " | |||
1913 | "20e2 >= -19 - 4t1 - 5i4 + 10e0 and 5e2 <= 1 - t1 and " | |||
1914 | "2e0 <= 1 + i4 and 2e0 >= i4 and " | |||
1915 | "20e1 <= 1530 - 4t1 - 5i4 and " | |||
1916 | "20e1 >= 1511 - 4t1 - 5i4 and i4 <= 1 and " | |||
1917 | "5e1 <= 381 - t1 and 20e2 <= -4t1 - 5i4 + 10e0) }", | |||
1918 | "[t1, t2] -> { [i4, i5, i6] : exists (e0 = floor((-17 + i4)/2), " | |||
1919 | "e1 = floor((-t1 + i6)/5): 5e1 = -t1 + i6 and " | |||
1920 | "2e0 <= -17 + i4 and 2e0 >= -18 + i4 and " | |||
1921 | "10e0 <= -91 + 5i4 + 4i6 and " | |||
1922 | "10e0 >= -105 + 5i4 + 4i6) }", | |||
1923 | "[t1, t2] -> { [i4, i5, i6] : exists (e0 = floor((381 - t1)/5), " | |||
1924 | "e1 = floor((-1 + i4)/2): t2 = 0 and 2e1 = -1 + i4 and " | |||
1925 | "i4 <= 1 and 5e0 <= 381 - t1 and 20e0 >= 1511 - 4t1 - 5i4) }" }, | |||
1926 | { "{ [0, 0, q, p] : -5 <= q <= 5 and p >= 0 }", | |||
1927 | "{ [a, b, q, p] : b >= 1 + a }", | |||
1928 | "{ [a, b, q, p] : false }" }, | |||
1929 | { "[n] -> { [x] : x = n && x mod 32 = 0 }", | |||
1930 | "[n] -> { [x] : x mod 32 = 0 }", | |||
1931 | "[n] -> { [x = n] }" }, | |||
1932 | { "{ [x] : x mod 6 = 0 }", "{ [x] : x mod 3 = 0 }", | |||
1933 | "{ [x] : x mod 2 = 0 }" }, | |||
1934 | { "{ [x] : x mod 3200 = 0 }", "{ [x] : x mod 10000 = 0 }", | |||
1935 | "{ [x] : x mod 128 = 0 }" }, | |||
1936 | { "{ [x] : x mod 3200 = 0 }", "{ [x] : x mod 10 = 0 }", | |||
1937 | "{ [x] : x mod 3200 = 0 }" }, | |||
1938 | { "{ [a, b, c] : a mod 2 = 0 and a = c }", | |||
1939 | "{ [a, b, c] : b mod 2 = 0 and b = c }", | |||
1940 | "{ [a, b, c = a] }" }, | |||
1941 | { "{ [a, b, c] : a mod 6 = 0 and a = c }", | |||
1942 | "{ [a, b, c] : b mod 2 = 0 and b = c }", | |||
1943 | "{ [a, b, c = a] : a mod 3 = 0 }" }, | |||
1944 | { "{ [x] : 0 <= x <= 4 or 6 <= x <= 9 }", | |||
1945 | "{ [x] : 1 <= x <= 3 or 7 <= x <= 8 }", | |||
1946 | "{ [x] }" }, | |||
1947 | { "{ [x,y] : x < 0 and 0 <= y <= 4 or x >= -2 and -x <= y <= 10 + x }", | |||
1948 | "{ [x,y] : 1 <= y <= 3 }", | |||
1949 | "{ [x,y] }" }, | |||
1950 | }; | |||
1951 | ||||
1952 | /* Check that isl_set_gist behaves as expected. | |||
1953 | * | |||
1954 | * For the test cases in gist_tests, besides checking that the result | |||
1955 | * is as expected, also check that applying the gist operation does | |||
1956 | * not modify the input set (an earlier version of isl would do that) and | |||
1957 | * that the test case is consistent, i.e., that the gist has the same | |||
1958 | * intersection with the context as the input set. | |||
1959 | */ | |||
1960 | static int test_gist(struct isl_ctx *ctx) | |||
1961 | { | |||
1962 | int i; | |||
1963 | const char *str; | |||
1964 | isl_basic_setisl_basic_map *bset1, *bset2; | |||
1965 | isl_map *map1, *map2; | |||
1966 | isl_bool equal; | |||
1967 | isl_size n_div; | |||
1968 | ||||
1969 | for (i = 0; i < ARRAY_SIZE(gist_tests)(sizeof(gist_tests)/sizeof(*gist_tests)); ++i) { | |||
1970 | isl_bool equal_input, equal_intersection; | |||
1971 | isl_setisl_map *set1, *set2, *copy, *context; | |||
1972 | ||||
1973 | set1 = isl_set_read_from_str(ctx, gist_tests[i].set); | |||
1974 | context = isl_set_read_from_str(ctx, gist_tests[i].context); | |||
1975 | copy = isl_set_copy(set1); | |||
1976 | set1 = isl_set_gist(set1, isl_set_copy(context)); | |||
1977 | set2 = isl_set_read_from_str(ctx, gist_tests[i].gist); | |||
1978 | equal = isl_set_is_equal(set1, set2); | |||
1979 | isl_set_free(set1); | |||
1980 | set1 = isl_set_read_from_str(ctx, gist_tests[i].set); | |||
1981 | equal_input = isl_set_is_equal(set1, copy); | |||
1982 | isl_set_free(copy); | |||
1983 | set1 = isl_set_intersect(set1, isl_set_copy(context)); | |||
1984 | set2 = isl_set_intersect(set2, context); | |||
1985 | equal_intersection = isl_set_is_equal(set1, set2); | |||
1986 | isl_set_free(set2); | |||
1987 | isl_set_free(set1); | |||
1988 | if (equal < 0 || equal_input < 0 || equal_intersection < 0) | |||
1989 | return -1; | |||
1990 | if (!equal) | |||
1991 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "incorrect gist result" , "polly/lib/External/isl/isl_test.c", 1992); return -1; } while (0) | |||
1992 | "incorrect gist result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "incorrect gist result" , "polly/lib/External/isl/isl_test.c", 1992); return -1; } while (0); | |||
1993 | if (!equal_input) | |||
1994 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "gist modified input" , "polly/lib/External/isl/isl_test.c", 1995); return -1; } while (0) | |||
1995 | "gist modified input", return -1)do { isl_handle_error(ctx, isl_error_unknown, "gist modified input" , "polly/lib/External/isl/isl_test.c", 1995); return -1; } while (0); | |||
1996 | if (!equal_input) | |||
1997 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "inconsistent gist test case" , "polly/lib/External/isl/isl_test.c", 1998); return -1; } while (0) | |||
1998 | "inconsistent gist test case", return -1)do { isl_handle_error(ctx, isl_error_unknown, "inconsistent gist test case" , "polly/lib/External/isl/isl_test.c", 1998); return -1; } while (0); | |||
1999 | } | |||
2000 | ||||
2001 | if (test_gist_fail(ctx) < 0) | |||
2002 | return -1; | |||
2003 | ||||
2004 | str = "[p0, p2, p3, p5, p6, p10] -> { [] : " | |||
2005 | "exists (e0 = [(15 + p0 + 15p6 + 15p10)/16], e1 = [(p5)/8], " | |||
2006 | "e2 = [(p6)/128], e3 = [(8p2 - p5)/128], " | |||
2007 | "e4 = [(128p3 - p6)/4096]: 8e1 = p5 and 128e2 = p6 and " | |||
2008 | "128e3 = 8p2 - p5 and 4096e4 = 128p3 - p6 and p2 >= 0 and " | |||
2009 | "16e0 >= 16 + 16p6 + 15p10 and p2 <= 15 and p3 >= 0 and " | |||
2010 | "p3 <= 31 and p6 >= 128p3 and p5 >= 8p2 and p10 >= 0 and " | |||
2011 | "16e0 <= 15 + p0 + 15p6 + 15p10 and 16e0 >= p0 + 15p6 + 15p10 and " | |||
2012 | "p10 <= 15 and p10 <= -1 + p0 - p6) }"; | |||
2013 | bset1 = isl_basic_set_read_from_str(ctx, str); | |||
2014 | str = "[p0, p2, p3, p5, p6, p10] -> { [] : exists (e0 = [(p5)/8], " | |||
2015 | "e1 = [(p6)/128], e2 = [(8p2 - p5)/128], " | |||
2016 | "e3 = [(128p3 - p6)/4096]: 8e0 = p5 and 128e1 = p6 and " | |||
2017 | "128e2 = 8p2 - p5 and 4096e3 = 128p3 - p6 and p5 >= -7 and " | |||
2018 | "p2 >= 0 and 8p2 <= -1 + p0 and p2 <= 15 and p3 >= 0 and " | |||
2019 | "p3 <= 31 and 128p3 <= -1 + p0 and p6 >= -127 and " | |||
2020 | "p5 <= -1 + p0 and p6 <= -1 + p0 and p6 >= 128p3 and " | |||
2021 | "p0 >= 1 and p5 >= 8p2 and p10 >= 0 and p10 <= 15 ) }"; | |||
2022 | bset2 = isl_basic_set_read_from_str(ctx, str); | |||
2023 | bset1 = isl_basic_set_gist(bset1, bset2); | |||
2024 | assert(bset1 && bset1->n_div == 0)((void) sizeof ((bset1 && bset1->n_div == 0) ? 1 : 0), __extension__ ({ if (bset1 && bset1->n_div == 0) ; else __assert_fail ("bset1 && bset1->n_div == 0" , "polly/lib/External/isl/isl_test.c", 2024, __extension__ __PRETTY_FUNCTION__ ); })); | |||
2025 | isl_basic_set_free(bset1); | |||
2026 | ||||
2027 | /* Check that the integer divisions of the second disjunct | |||
2028 | * do not spread to the first disjunct. | |||
2029 | */ | |||
2030 | str = "[t1] -> { S_0[] -> A[o0] : (exists (e0 = [(-t1 + o0)/16]: " | |||
2031 | "16e0 = -t1 + o0 and o0 >= 0 and o0 <= 15 and t1 >= 0)) or " | |||
2032 | "(exists (e0 = [(-1 + t1)/16], " | |||
2033 | "e1 = [(-16 + t1 - 16e0)/4294967296]: " | |||
2034 | "4294967296e1 = -16 + t1 - o0 - 16e0 and " | |||
2035 | "16e0 <= -1 + t1 and 16e0 >= -16 + t1 and o0 >= 0 and " | |||
2036 | "o0 <= 4294967295 and t1 <= -1)) }"; | |||
2037 | map1 = isl_map_read_from_str(ctx, str); | |||
2038 | str = "[t1] -> { S_0[] -> A[o0] : t1 >= 0 and t1 <= 4294967295 }"; | |||
2039 | map2 = isl_map_read_from_str(ctx, str); | |||
2040 | map1 = isl_map_gist(map1, map2); | |||
2041 | if (!map1) | |||
2042 | return -1; | |||
2043 | if (map1->n != 1) | |||
2044 | isl_die(ctx, isl_error_unknown, "expecting single disjunct",do { isl_handle_error(ctx, isl_error_unknown, "expecting single disjunct" , "polly/lib/External/isl/isl_test.c", 2045); isl_map_free(map1 ); return -1; } while (0) | |||
2045 | isl_map_free(map1); return -1)do { isl_handle_error(ctx, isl_error_unknown, "expecting single disjunct" , "polly/lib/External/isl/isl_test.c", 2045); isl_map_free(map1 ); return -1; } while (0); | |||
2046 | n_div = isl_basic_map_dim(map1->p[0], isl_dim_div); | |||
2047 | isl_map_free(map1); | |||
2048 | if (n_div < 0) | |||
2049 | return -1; | |||
2050 | if (n_div != 1) | |||
2051 | isl_die(ctx, isl_error_unknown, "expecting single div",do { isl_handle_error(ctx, isl_error_unknown, "expecting single div" , "polly/lib/External/isl/isl_test.c", 2052); return -1; } while (0) | |||
2052 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "expecting single div" , "polly/lib/External/isl/isl_test.c", 2052); return -1; } while (0); | |||
2053 | ||||
2054 | if (test_gist_empty(ctx) < 0) | |||
2055 | return -1; | |||
2056 | if (test_plain_gist(ctx) < 0) | |||
2057 | return -1; | |||
2058 | ||||
2059 | return 0; | |||
2060 | } | |||
2061 | ||||
2062 | int test_coalesce_set(isl_ctx *ctx, const char *str, int check_one) | |||
2063 | { | |||
2064 | isl_setisl_map *set, *set2; | |||
2065 | int equal; | |||
2066 | int one; | |||
2067 | ||||
2068 | set = isl_set_read_from_str(ctx, str); | |||
2069 | set = isl_set_coalesce(set); | |||
2070 | set2 = isl_set_read_from_str(ctx, str); | |||
2071 | equal = isl_set_is_equal(set, set2); | |||
2072 | one = set && set->n == 1; | |||
2073 | isl_set_free(set); | |||
2074 | isl_set_free(set2); | |||
2075 | ||||
2076 | if (equal < 0) | |||
2077 | return -1; | |||
2078 | if (!equal) | |||
2079 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "coalesced set not equal to input" , "polly/lib/External/isl/isl_test.c", 2080); return -1; } while (0) | |||
2080 | "coalesced set not equal to input", return -1)do { isl_handle_error(ctx, isl_error_unknown, "coalesced set not equal to input" , "polly/lib/External/isl/isl_test.c", 2080); return -1; } while (0); | |||
2081 | if (check_one && !one) | |||
2082 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "coalesced set should not be a union" , "polly/lib/External/isl/isl_test.c", 2083); return -1; } while (0) | |||
2083 | "coalesced set should not be a union", return -1)do { isl_handle_error(ctx, isl_error_unknown, "coalesced set should not be a union" , "polly/lib/External/isl/isl_test.c", 2083); return -1; } while (0); | |||
2084 | ||||
2085 | return 0; | |||
2086 | } | |||
2087 | ||||
2088 | /* Inputs for coalescing tests with unbounded wrapping. | |||
2089 | * "str" is a string representation of the input set. | |||
2090 | * "single_disjunct" is set if we expect the result to consist of | |||
2091 | * a single disjunct. | |||
2092 | */ | |||
2093 | struct { | |||
2094 | int single_disjunct; | |||
2095 | const char *str; | |||
2096 | } coalesce_unbounded_tests[] = { | |||
2097 | { 1, "{ [x,y,z] : y + 2 >= 0 and x - y + 1 >= 0 and " | |||
2098 | "-x - y + 1 >= 0 and -3 <= z <= 3;" | |||
2099 | "[x,y,z] : -x+z + 20 >= 0 and -x-z + 20 >= 0 and " | |||
2100 | "x-z + 20 >= 0 and x+z + 20 >= 0 and " | |||
2101 | "-10 <= y <= 0}" }, | |||
2102 | { 1, "{ [x,y] : 0 <= x,y <= 10; [5,y]: 4 <= y <= 11 }" }, | |||
2103 | { 1, "{ [x,0,0] : -5 <= x <= 5; [0,y,1] : -5 <= y <= 5 }" }, | |||
2104 | { 1, "{ [x,y] : 0 <= x <= 10 and 0 >= y >= -1 and x+y >= 0; [0,1] }" }, | |||
2105 | { 1, "{ [x,y] : (0 <= x,y <= 4) or (2 <= x,y <= 5 and x + y <= 9) }" }, | |||
2106 | { 0, "{ [x, y, z] : 0 <= x,y,z <= 100 and 0 < z <= 2 + 2x + 2y; " | |||
2107 | "[x, y, 0] : x,y <= 100 and y <= 9 + 11x and x <= 9 + 11y }" }, | |||
2108 | { 1, "{ [0:1, 0:1]; [0, 2:3] }" }, | |||
2109 | { 1, "{ [0:1, 0:1]; [0, 2:3]; [1, -2:-1] }" }, | |||
2110 | { 1, "{ [0:3, 0:1]; [1:2, 2:5] }" }, | |||
2111 | { 1, "{ [0:3, 0:1]; [0:2, 2:5] }" }, | |||
2112 | { 1, "{ [0:3, 0:1]; [1:3, 2:5] }" }, | |||
2113 | { 0, "{ [0:3, 0:1]; [1:4, 2:5] }" }, | |||
2114 | { 0, "{ [0:3, 0:1]; [1:5, 2:5] }" }, | |||
2115 | }; | |||
2116 | ||||
2117 | /* Test the functionality of isl_set_coalesce with the bounded wrapping | |||
2118 | * option turned off. | |||
2119 | */ | |||
2120 | int test_coalesce_unbounded_wrapping(isl_ctx *ctx) | |||
2121 | { | |||
2122 | int i; | |||
2123 | int r = 0; | |||
2124 | int bounded; | |||
2125 | ||||
2126 | bounded = isl_options_get_coalesce_bounded_wrapping(ctx); | |||
2127 | isl_options_set_coalesce_bounded_wrapping(ctx, 0); | |||
2128 | ||||
2129 | for (i = 0; i < ARRAY_SIZE(coalesce_unbounded_tests)(sizeof(coalesce_unbounded_tests)/sizeof(*coalesce_unbounded_tests )); ++i) { | |||
2130 | const char *str = coalesce_unbounded_tests[i].str; | |||
2131 | int check_one = coalesce_unbounded_tests[i].single_disjunct; | |||
2132 | if (test_coalesce_set(ctx, str, check_one) >= 0) | |||
2133 | continue; | |||
2134 | r = -1; | |||
2135 | break; | |||
2136 | } | |||
2137 | ||||
2138 | isl_options_set_coalesce_bounded_wrapping(ctx, bounded); | |||
2139 | ||||
2140 | return r; | |||
2141 | } | |||
2142 | ||||
2143 | /* Inputs for coalescing tests. | |||
2144 | * "str" is a string representation of the input set. | |||
2145 | * "single_disjunct" is set if we expect the result to consist of | |||
2146 | * a single disjunct. | |||
2147 | */ | |||
2148 | struct { | |||
2149 | int single_disjunct; | |||
2150 | const char *str; | |||
2151 | } coalesce_tests[] = { | |||
2152 | { 1, "{[x,y]: x >= 0 & x <= 10 & y >= 0 & y <= 10 or " | |||
2153 | "y >= x & x >= 2 & 5 >= y }" }, | |||
2154 | { 1, "{[x,y]: y >= 0 & 2x + y <= 30 & y <= 10 & x >= 0 or " | |||
2155 | "x + y >= 10 & y <= x & x + y <= 20 & y >= 0}" }, | |||
2156 | { 0, "{[x,y]: y >= 0 & 2x + y <= 30 & y <= 10 & x >= 0 or " | |||
2157 | "x + y >= 10 & y <= x & x + y <= 19 & y >= 0}" }, | |||
2158 | { 1, "{[x,y]: y >= 0 & x <= 5 & y <= x or " | |||
2159 | "y >= 0 & x >= 6 & x <= 10 & y <= x}" }, | |||
2160 | { 0, "{[x,y]: y >= 0 & x <= 5 & y <= x or " | |||
2161 | "y >= 0 & x >= 7 & x <= 10 & y <= x}" }, | |||
2162 | { 0, "{[x,y]: y >= 0 & x <= 5 & y <= x or " | |||
2163 | "y >= 0 & x >= 6 & x <= 10 & y + 1 <= x}" }, | |||
2164 | { 1, "{[x,y]: y >= 0 & x <= 5 & y <= x or y >= 0 & x = 6 & y <= 6}" }, | |||
2165 | { 0, "{[x,y]: y >= 0 & x <= 5 & y <= x or y >= 0 & x = 7 & y <= 6}" }, | |||
2166 | { 1, "{[x,y]: y >= 0 & x <= 5 & y <= x or y >= 0 & x = 6 & y <= 5}" }, | |||
2167 | { 0, "{[x,y]: y >= 0 & x <= 5 & y <= x or y >= 0 & x = 6 & y <= 7}" }, | |||
2168 | { 1, "[n] -> { [i] : i = 1 and n >= 2 or 2 <= i and i <= n }" }, | |||
2169 | { 0, "{[x,y] : x >= 0 and y >= 0 or 0 <= y and y <= 5 and x = -1}" }, | |||
2170 | { 1, "[n] -> { [i] : 1 <= i and i <= n - 1 or 2 <= i and i <= n }" }, | |||
2171 | { 0, "[n] -> { [[i0] -> [o0]] : exists (e0 = [(i0)/4], e1 = [(o0)/4], " | |||
2172 | "e2 = [(n)/2], e3 = [(-2 + i0)/4], e4 = [(-2 + o0)/4], " | |||
2173 | "e5 = [(-2n + i0)/4]: 2e2 = n and 4e3 = -2 + i0 and " | |||
2174 | "4e4 = -2 + o0 and i0 >= 8 + 2n and o0 >= 2 + i0 and " | |||
2175 | "o0 <= 56 + 2n and o0 <= -12 + 4n and i0 <= 57 + 2n and " | |||
2176 | "i0 <= -11 + 4n and o0 >= 6 + 2n and 4e0 <= i0 and " | |||
2177 | "4e0 >= -3 + i0 and 4e1 <= o0 and 4e1 >= -3 + o0 and " | |||
2178 | "4e5 <= -2n + i0 and 4e5 >= -3 - 2n + i0);" | |||
2179 | "[[i0] -> [o0]] : exists (e0 = [(i0)/4], e1 = [(o0)/4], " | |||
2180 | "e2 = [(n)/2], e3 = [(-2 + i0)/4], e4 = [(-2 + o0)/4], " | |||
2181 | "e5 = [(-2n + i0)/4]: 2e2 = n and 4e3 = -2 + i0 and " | |||
2182 | "4e4 = -2 + o0 and 2e0 >= 3 + n and e0 <= -4 + n and " | |||
2183 | "2e0 <= 27 + n and e1 <= -4 + n and 2e1 <= 27 + n and " | |||
2184 | "2e1 >= 2 + n and e1 >= 1 + e0 and i0 >= 7 + 2n and " | |||
2185 | "i0 <= -11 + 4n and i0 <= 57 + 2n and 4e0 <= -2 + i0 and " | |||
2186 | "4e0 >= -3 + i0 and o0 >= 6 + 2n and o0 <= -11 + 4n and " | |||
2187 | "o0 <= 57 + 2n and 4e1 <= -2 + o0 and 4e1 >= -3 + o0 and " | |||
2188 | "4e5 <= -2n + i0 and 4e5 >= -3 - 2n + i0 ) }" }, | |||
2189 | { 0, "[n, m] -> { [o0, o2, o3] : (o3 = 1 and o0 >= 1 + m and " | |||
2190 | "o0 <= n + m and o2 <= m and o0 >= 2 + n and o2 >= 3) or " | |||
2191 | "(o0 >= 2 + n and o0 >= 1 + m and o0 <= n + m and n >= 1 and " | |||
2192 | "o3 <= -1 + o2 and o3 >= 1 - m + o2 and o3 >= 2 and o3 <= n) }" }, | |||
2193 | { 0, "[M, N] -> { [[i0, i1, i2, i3, i4, i5, i6] -> " | |||
2194 | "[o0, o1, o2, o3, o4, o5, o6]] : " | |||
2195 | "(o6 <= -4 + 2M - 2N + i0 + i1 - i2 + i6 - o0 - o1 + o2 and " | |||
2196 | "o3 <= -2 + i3 and o6 >= 2 + i0 + i3 + i6 - o0 - o3 and " | |||
2197 | "o6 >= 2 - M + N + i3 + i4 + i6 - o3 - o4 and o0 <= -1 + i0 and " | |||
2198 | "o4 >= 4 - 3M + 3N - i0 - i1 + i2 + 2i3 + i4 + o0 + o1 - o2 - 2o3 " | |||
2199 | "and o6 <= -3 + 2M - 2N + i3 + i4 - i5 + i6 - o3 - o4 + o5 and " | |||
2200 | "2o6 <= -5 + 5M - 5N + 2i0 + i1 - i2 - i5 + 2i6 - 2o0 - o1 + o2 + o5 " | |||
2201 | "and o6 >= 2i0 + i1 + i6 - 2o0 - o1 and " | |||
2202 | "3o6 <= -5 + 4M - 4N + 2i0 + i1 - i2 + 2i3 + i4 - i5 + 3i6 " | |||
2203 | "- 2o0 - o1 + o2 - 2o3 - o4 + o5) or " | |||
2204 | "(N >= 2 and o3 <= -1 + i3 and o0 <= -1 + i0 and " | |||
2205 | "o6 >= i3 + i6 - o3 and M >= 0 and " | |||
2206 | "2o6 >= 1 + i0 + i3 + 2i6 - o0 - o3 and " | |||
2207 | "o6 >= 1 - M + i0 + i6 - o0 and N >= 2M and o6 >= i0 + i6 - o0) }" }, | |||
2208 | { 0, "[M, N] -> { [o0] : (o0 = 0 and M >= 1 and N >= 2) or " | |||
2209 | "(o0 = 0 and M >= 1 and N >= 2M and N >= 2 + M) or " | |||
2210 | "(o0 = 0 and M >= 2 and N >= 3) or " | |||
2211 | "(M = 0 and o0 = 0 and N >= 3) }" }, | |||
2212 | { 0, "{ [i0, i1, i2, i3] : (i1 = 10i0 and i0 >= 1 and 10i0 <= 100 and " | |||
2213 | "i3 <= 9 + 10 i2 and i3 >= 1 + 10i2 and i3 >= 0) or " | |||
2214 | "(i1 <= 9 + 10i0 and i1 >= 1 + 10i0 and i2 >= 0 and " | |||
2215 | "i0 >= 0 and i1 <= 100 and i3 <= 9 + 10i2 and i3 >= 1 + 10i2) }" }, | |||
2216 | { 0, "[M] -> { [i1] : (i1 >= 2 and i1 <= M) or (i1 = M and M >= 1) }" }, | |||
2217 | { 0, "{[x,y] : x,y >= 0; [x,y] : 10 <= x <= 20 and y >= -1 }" }, | |||
2218 | { 1, "{ [x, y] : (x >= 1 and y >= 1 and x <= 2 and y <= 2) or " | |||
2219 | "(y = 3 and x = 1) }" }, | |||
2220 | { 1, "[M] -> { [i0, i1, i2, i3, i4] : (i1 >= 3 and i4 >= 2 + i2 and " | |||
2221 | "i2 >= 2 and i0 >= 2 and i3 >= 1 + i2 and i0 <= M and " | |||
2222 | "i1 <= M and i3 <= M and i4 <= M) or " | |||
2223 | "(i1 >= 2 and i4 >= 1 + i2 and i2 >= 2 and i0 >= 2 and " | |||
2224 | "i3 >= 1 + i2 and i0 <= M and i1 <= -1 + M and i3 <= M and " | |||
2225 | "i4 <= -1 + M) }" }, | |||
2226 | { 1, "{ [x, y] : (x >= 0 and y >= 0 and x <= 10 and y <= 10) or " | |||
2227 | "(x >= 1 and y >= 1 and x <= 11 and y <= 11) }" }, | |||
2228 | { 0, "{[x,0] : x >= 0; [x,1] : x <= 20}" }, | |||
2229 | { 1, "{ [x, 1 - x] : 0 <= x <= 1; [0,0] }" }, | |||
2230 | { 1, "{ [0,0]; [i,i] : 1 <= i <= 10 }" }, | |||
2231 | { 0, "{ [0,0]; [i,j] : 1 <= i,j <= 10 }" }, | |||
2232 | { 1, "{ [0,0]; [i,2i] : 1 <= i <= 10 }" }, | |||
2233 | { 0, "{ [0,0]; [i,2i] : 2 <= i <= 10 }" }, | |||
2234 | { 0, "{ [1,0]; [i,2i] : 1 <= i <= 10 }" }, | |||
2235 | { 0, "{ [0,1]; [i,2i] : 1 <= i <= 10 }" }, | |||
2236 | { 0, "{ [a, b] : exists e : 2e = a and " | |||
2237 | "a >= 0 and (a <= 3 or (b <= 0 and b >= -4 + a)) }" }, | |||
2238 | { 0, "{ [i, j, i', j'] : i <= 2 and j <= 2 and " | |||
2239 | "j' >= -1 + 2i + j - 2i' and i' <= -1 + i and " | |||
2240 | "j >= 1 and j' <= i + j - i' and i >= 1; " | |||
2241 | "[1, 1, 1, 1] }" }, | |||
2242 | { 1, "{ [i,j] : exists a,b : i = 2a and j = 3b; " | |||
2243 | "[i,j] : exists a : j = 3a }" }, | |||
2244 | { 1, "{ [a, b, c] : (c <= 7 - b and b <= 1 and b >= 0 and " | |||
2245 | "c >= 3 + b and b <= 3 + 8a and b >= -26 + 8a and " | |||
2246 | "a >= 3) or " | |||
2247 | "(b <= 1 and c <= 7 and b >= 0 and c >= 4 + b and " | |||
2248 | "b <= 3 + 8a and b >= -26 + 8a and a >= 3) }" }, | |||
2249 | { 1, "{ [a, 0, c] : c >= 1 and c <= 29 and c >= -1 + 8a and " | |||
2250 | "c <= 6 + 8a and a >= 3; " | |||
2251 | "[a, -1, c] : c >= 1 and c <= 30 and c >= 8a and " | |||
2252 | "c <= 7 + 8a and a >= 3 and a <= 4 }" }, | |||
2253 | { 1, "{ [x,y] : 0 <= x <= 2 and y >= 0 and x + 2y <= 4; " | |||
2254 | "[x,0] : 3 <= x <= 4 }" }, | |||
2255 | { 1, "{ [x,y] : 0 <= x <= 3 and y >= 0 and x + 3y <= 6; " | |||
2256 | "[x,0] : 4 <= x <= 5 }" }, | |||
2257 | { 0, "{ [x,y] : 0 <= x <= 2 and y >= 0 and x + 2y <= 4; " | |||
2258 | "[x,0] : 3 <= x <= 5 }" }, | |||
2259 | { 0, "{ [x,y] : 0 <= x <= 2 and y >= 0 and x + y <= 4; " | |||
2260 | "[x,0] : 3 <= x <= 4 }" }, | |||
2261 | { 1, "{ [i0, i1] : i0 <= 122 and i0 >= 1 and 128i1 >= -249 + i0 and " | |||
2262 | "i1 <= 0; " | |||
2263 | "[i0, 0] : i0 >= 123 and i0 <= 124 }" }, | |||
2264 | { 1, "{ [0,0]; [1,1] }" }, | |||
2265 | { 1, "[n] -> { [k] : 16k <= -1 + n and k >= 1; [0] : n >= 2 }" }, | |||
2266 | { 1, "{ [k, ii, k - ii] : ii >= -6 + k and ii <= 6 and ii >= 1 and " | |||
2267 | "ii <= k;" | |||
2268 | "[k, 0, k] : k <= 6 and k >= 1 }" }, | |||
2269 | { 1, "{ [i,j] : i = 4 j and 0 <= i <= 100;" | |||
2270 | "[i,j] : 1 <= i <= 100 and i >= 4j + 1 and i <= 4j + 2 }" }, | |||
2271 | { 1, "{ [x,y] : x % 2 = 0 and y % 2 = 0; [x,x] : x % 2 = 0 }" }, | |||
2272 | { 1, "[n] -> { [1] : n >= 0;" | |||
2273 | "[x] : exists (e0 = floor((x)/2): x >= 2 and " | |||
2274 | "2e0 >= -1 + x and 2e0 <= x and 2e0 <= n) }" }, | |||
2275 | { 1, "[n] -> { [x, y] : exists (e0 = floor((x)/2), e1 = floor((y)/3): " | |||
2276 | "3e1 = y and x >= 2 and 2e0 >= -1 + x and " | |||
2277 | "2e0 <= x and 2e0 <= n);" | |||
2278 | "[1, y] : exists (e0 = floor((y)/3): 3e0 = y and " | |||
2279 | "n >= 0) }" }, | |||
2280 | { 1, "[t1] -> { [i0] : (exists (e0 = floor((63t1)/64): " | |||
2281 | "128e0 >= -134 + 127t1 and t1 >= 2 and " | |||
2282 | "64e0 <= 63t1 and 64e0 >= -63 + 63t1)) or " | |||
2283 | "t1 = 1 }" }, | |||
2284 | { 1, "{ [i, i] : exists (e0 = floor((1 + 2i)/3): 3e0 <= 2i and " | |||
2285 | "3e0 >= -1 + 2i and i <= 9 and i >= 1);" | |||
2286 | "[0, 0] }" }, | |||
2287 | { 1, "{ [t1] : exists (e0 = floor((-11 + t1)/2): 2e0 = -11 + t1 and " | |||
2288 | "t1 >= 13 and t1 <= 16);" | |||
2289 | "[t1] : t1 <= 15 and t1 >= 12 }" }, | |||
2290 | { 1, "{ [x,y] : x = 3y and 0 <= y <= 2; [-3,-1] }" }, | |||
2291 | { 1, "{ [x,y] : 2x = 3y and 0 <= y <= 4; [-3,-2] }" }, | |||
2292 | { 0, "{ [x,y] : 2x = 3y and 0 <= y <= 4; [-2,-2] }" }, | |||
2293 | { 0, "{ [x,y] : 2x = 3y and 0 <= y <= 4; [-3,-1] }" }, | |||
2294 | { 1, "{ [i] : exists j : i = 4 j and 0 <= i <= 100;" | |||
2295 | "[i] : exists j : 1 <= i <= 100 and i >= 4j + 1 and " | |||
2296 | "i <= 4j + 2 }" }, | |||
2297 | { 1, "{ [c0] : (exists (e0 : c0 - 1 <= 3e0 <= c0)) or " | |||
2298 | "(exists (e0 : 3e0 = -2 + c0)) }" }, | |||
2299 | { 0, "[n, b0, t0] -> " | |||
2300 | "{ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12] : " | |||
2301 | "(exists (e0 = floor((-32b0 + i4)/1048576), " | |||
2302 | "e1 = floor((i8)/32): 1048576e0 = -32b0 + i4 and 32e1 = i8 and " | |||
2303 | "n <= 2147483647 and b0 <= 32767 and b0 >= 0 and " | |||
2304 | "32b0 <= -2 + n and t0 <= 31 and t0 >= 0 and i0 >= 8 + n and " | |||
2305 | "3i4 <= -96 + 3t0 + i0 and 3i4 >= -95 - n + 3t0 + i0 and " | |||
2306 | "i8 >= -157 + i0 - 4i4 and i8 >= 0 and " | |||
2307 | "i8 <= -33 + i0 - 4i4 and 3i8 <= -91 + 4n - i0)) or " | |||
2308 | "(exists (e0 = floor((-32b0 + i4)/1048576), " | |||
2309 | "e1 = floor((i8)/32): 1048576e0 = -32b0 + i4 and 32e1 = i8 and " | |||
2310 | "n <= 2147483647 and b0 <= 32767 and b0 >= 0 and " | |||
2311 | "32b0 <= -2 + n and t0 <= 31 and t0 >= 0 and i0 <= 7 + n and " | |||
2312 | "4i4 <= -3 + i0 and 3i4 <= -96 + 3t0 + i0 and " | |||
2313 | "3i4 >= -95 - n + 3t0 + i0 and i8 >= -157 + i0 - 4i4 and " | |||
2314 | "i8 >= 0 and i8 <= -4 + i0 - 3i4 and i8 <= -41 + i0));" | |||
2315 | "[i0, i1, i2, i3, 0, i5, i6, i7, i8, i9, i10, i11, i12] : " | |||
2316 | "(exists (e0 = floor((i8)/32): b0 = 0 and 32e0 = i8 and " | |||
2317 | "n <= 2147483647 and t0 <= 31 and t0 >= 0 and i0 >= 11 and " | |||
2318 | "i0 >= 96 - 3t0 and i0 <= 95 + n - 3t0 and i0 <= 7 + n and " | |||
2319 | "i8 >= -40 + i0 and i8 <= -10 + i0)) }" }, | |||
2320 | { 0, "{ [i0, i1, i2] : " | |||
2321 | "(exists (e0, e1 = floor((i0)/32), e2 = floor((i1)/32): " | |||
2322 | "32e1 = i0 and 32e2 = i1 and i1 >= -31 + i0 and " | |||
2323 | "i1 <= 31 + i0 and i2 >= -30 + i0 and i2 >= -30 + i1 and " | |||
2324 | "32e0 >= -30 + i0 and 32e0 >= -30 + i1 and " | |||
2325 | "32e0 >= -31 + i2 and 32e0 <= 30 + i2 and 32e0 <= 31 + i1 and " | |||
2326 | "32e0 <= 31 + i0)) or " | |||
2327 | "i0 >= 0 }" }, | |||
2328 | { 1, "{ [a, b, c] : 2b = 1 + a and 2c = 2 + a; [0, 0, 0] }" }, | |||
2329 | { 1, "{ [a, a, b, c] : 32*floor((a)/32) = a and 2*floor((b)/2) = b and " | |||
2330 | "2*floor((c)/2) = c and 0 <= a <= 192;" | |||
2331 | "[224, 224, b, c] : 2*floor((b)/2) = b and 2*floor((c)/2) = c }" | |||
2332 | }, | |||
2333 | { 1, "[n] -> { [a,b] : (exists e : 1 <= a <= 7e and 9e <= b <= n) or " | |||
2334 | "(0 <= a <= b <= n) }" }, | |||
2335 | { 1, "{ [a, b] : 0 <= a <= 2 and b >= 0 and " | |||
2336 | "((0 < b <= 13) or (2*floor((a + b)/2) >= -5 + a + 2b)) }" }, | |||
2337 | { 1, "{ [a] : (2 <= a <= 5) or (a mod 2 = 1 and 1 <= a <= 5) }" }, | |||
2338 | { 1, "{ [a, b, c] : (b = -1 + a and 0 < a <= 3 and " | |||
2339 | "9*floor((-4a + 2c)/9) <= -3 - 4a + 2c) or " | |||
2340 | "(exists (e0 = floor((-16 + 2c)/9): a = 4 and " | |||
2341 | "b = 3 and 9e0 <= -19 + 2c)) }" }, | |||
2342 | { 1, "{ [a, b, c] : (b = -1 + a and 0 < a <= 3 and " | |||
2343 | "9*floor((-4a + 2c)/9) <= -3 - 4a + 2c) or " | |||
2344 | "(a = 4 and b = 3 and " | |||
2345 | "9*floor((-16 + 2c)/9) <= -19 + 2c) }" }, | |||
2346 | { 0, "{ [a, b, c] : (b <= 2 and b <= -2 + a) or " | |||
2347 | "(b = -1 + a and 0 < a <= 3 and " | |||
2348 | "9*floor((-4a + 2c)/9) <= -3 - 4a + 2c) or " | |||
2349 | "(exists (e0 = floor((-16 + 2c)/9): a = 4 and " | |||
2350 | "b = 3 and 9e0 <= -19 + 2c)) }" }, | |||
2351 | { 1, "{ [y, x] : (x - y) mod 3 = 2 and 2 <= y <= 200 and 0 <= x <= 2;" | |||
2352 | "[1, 0] }" }, | |||
2353 | { 1, "{ [x, y] : (x - y) mod 3 = 2 and 2 <= y <= 200 and 0 <= x <= 2;" | |||
2354 | "[0, 1] }" }, | |||
2355 | { 1, "{ [1, y] : -1 <= y <= 1; [x, -x] : 0 <= x <= 1 }" }, | |||
2356 | { 1, "{ [1, y] : 0 <= y <= 1; [x, -x] : 0 <= x <= 1 }" }, | |||
2357 | { 1, "{ [x, y] : 0 <= x <= 10 and x - 4*floor(x/4) <= 1 and y <= 0; " | |||
2358 | "[x, y] : 0 <= x <= 10 and x - 4*floor(x/4) > 1 and y <= 0; " | |||
2359 | "[x, y] : 0 <= x <= 10 and x - 5*floor(x/5) <= 1 and 0 < y; " | |||
2360 | "[x, y] : 0 <= x <= 10 and x - 5*floor(x/5) > 1 and 0 < y }" }, | |||
2361 | { 1, "{ [x, 0] : 0 <= x <= 10 and x mod 2 = 0; " | |||
2362 | "[x, 0] : 0 <= x <= 10 and x mod 2 = 1; " | |||
2363 | "[x, y] : 0 <= x <= 10 and 1 <= y <= 10 }" }, | |||
2364 | { 1, "{ [a] : a <= 8 and " | |||
2365 | "(a mod 10 = 7 or a mod 10 = 8 or a mod 10 = 9) }" }, | |||
2366 | { 1, "{ [x, y] : 2y = -x and x <= 0 or " | |||
2367 | "x <= -1 and 2y <= -x - 1 and 2y >= x - 1 }" }, | |||
2368 | { 0, "{ [x, y] : 2y = -x and x <= 0 or " | |||
2369 | "x <= -2 and 2y <= -x - 1 and 2y >= x - 1 }" }, | |||
2370 | { 1, "{ [a] : (a <= 0 and 3*floor((a)/3) = a) or " | |||
2371 | "(a < 0 and 3*floor((a)/3) < a) }" }, | |||
2372 | { 1, "{ [a] : (a <= 0 and 3*floor((a)/3) = a) or " | |||
2373 | "(a < -1 and 3*floor((a)/3) < a) }" }, | |||
2374 | { 1, "{ [a, b] : a <= 1024 and b >= 0 and " | |||
2375 | "((-31 - a + b <= 32*floor((-1 - a)/32) <= -33 + b and " | |||
2376 | "32*floor((-1 - a)/32) <= -16 + b + 16*floor((-1 - a)/16))" | |||
2377 | "or (2 <= a <= 15 and b < a)) }" }, | |||
2378 | { 1, "{ [a] : a > 0 and ((16*floor((a)/16) < a and " | |||
2379 | "32*floor((a)/32) < a) or a <= 15) }" }, | |||
2380 | { 1, "{ [a, b, c, d] : (-a + d) mod 64 = 0 and a <= 8 and b <= 1 and " | |||
2381 | "10 - a <= c <= 3 and d >= 5 and 9 - 64b <= d <= 70;" | |||
2382 | "[a, b = 1, c, d] : (-a + d) mod 64 = 0 and a <= 8 and c >= 4 and " | |||
2383 | "10 - a <= c <= 5 and 5 <= d <= 73 - c }" }, | |||
2384 | { 1, "[n, m] -> { S_0[i] : (-n + i) mod 3 = 0 and m >= 3 + n and " | |||
2385 | "i >= n and 3*floor((2 + n + 2m)/3) <= n + 3m - i; " | |||
2386 | "S_0[n] : n <= m <= 2 + n }" }, | |||
2387 | { 1, "{ [a, b] : exists (e0: 0 <= a <= 1 and b >= 0 and " | |||
2388 | "2e0 >= -5 + a + 2b and 2e0 >= -1 + a + b and " | |||
2389 | "2e0 <= a + b); " | |||
2390 | "[a, b] : exists (e0: 0 <= a <= 1 and 2e0 >= -5 + a + 2b and " | |||
2391 | "2e0 >= -1 - a + b and 2e0 <= -a + b and " | |||
2392 | "2e0 < -a + 2b) }" }, | |||
2393 | { 1, "{ [i, j, i - 8j] : 8 <= i <= 63 and -7 + i <= 8j <= i; " | |||
2394 | "[i, 0, i] : 0 <= i <= 7 }" }, | |||
2395 | { 1, "{ [a, b] : a >= 0 and 0 <= b <= 1 - a; [1, 1] }" }, | |||
2396 | { 0, "{ [a, b] : a >= 0 and 0 <= b <= 1 - a; [0, 2] }" }, | |||
2397 | { 0, "{ [a, b] : a >= 0 and 0 <= b <= 1 - a; [-1, 3] }" }, | |||
2398 | { 1, "{ [a, b] : a, b >= 0 and a + 2b <= 2; [1, 1] }" }, | |||
2399 | { 0, "{ [a, b] : a, b >= 0 and a + 2b <= 2; [2, 1] }" }, | |||
2400 | { 0, "{ [a, c] : (2 + a) mod 4 = 0 or " | |||
2401 | "(c = 4 + a and 4 * floor((a)/4) = a and a >= 0 and a <= 4) or " | |||
2402 | "(c = 3 + a and 4 * floor((-1 + a)/4) = -1 + a and " | |||
2403 | "a > 0 and a <= 5) }" }, | |||
2404 | { 1, "{ [1, 0, 0]; [a, b, c] : -1 <= -a < b <= 0 and 2c > b }" }, | |||
2405 | { 0, "{ [j, a, l] : a mod 2 = 0 and j <= 29 and a >= 2 and " | |||
2406 | "2a <= -5 + j and 32j + 2a + 2 <= 4l < 33j; " | |||
2407 | "[j, 0, l] : 4 <= j <= 29 and -3 + 33j <= 4l <= 33j }" }, | |||
2408 | { 0, "{ [0:1, 0:1]; [0, 2:3] }" }, | |||
2409 | { 1, "{ [a] : (a = 0 or ((1 + a) mod 2 = 0 and 0 < a <= 15) or " | |||
2410 | "((a) mod 2 = 0 and 0 < a <= 15)) }" }, | |||
2411 | { 1, "{ rat: [0:2]; rat: [1:3] }" }, | |||
2412 | }; | |||
2413 | ||||
2414 | /* A specialized coalescing test case that would result | |||
2415 | * in a segmentation fault or a failed assertion in earlier versions of isl. | |||
2416 | */ | |||
2417 | static int test_coalesce_special(struct isl_ctx *ctx) | |||
2418 | { | |||
2419 | const char *str; | |||
2420 | isl_map *map1, *map2; | |||
2421 | ||||
2422 | str = "[y] -> { [S_L220_OUT[] -> T7[]] -> " | |||
2423 | "[[S_L309_IN[] -> T11[]] -> ce_imag2[1, o1]] : " | |||
2424 | "(y = 201 and o1 <= 239 and o1 >= 212) or " | |||
2425 | "(exists (e0 = [(y)/3]: 3e0 = y and y <= 198 and y >= 3 and " | |||
2426 | "o1 <= 239 and o1 >= 212)) or " | |||
2427 | "(exists (e0 = [(y)/3]: 3e0 = y and y <= 201 and y >= 3 and " | |||
2428 | "o1 <= 241 and o1 >= 240));" | |||
2429 | "[S_L220_OUT[] -> T7[]] -> " | |||
2430 | "[[S_L309_IN[] -> T11[]] -> ce_imag2[0, o1]] : " | |||
2431 | "(y = 2 and o1 <= 241 and o1 >= 212) or " | |||
2432 | "(exists (e0 = [(-2 + y)/3]: 3e0 = -2 + y and y <= 200 and " | |||
2433 | "y >= 5 and o1 <= 241 and o1 >= 212)) }"; | |||
2434 | map1 = isl_map_read_from_str(ctx, str); | |||
2435 | map1 = isl_map_align_divs_internal(map1); | |||
2436 | map1 = isl_map_coalesce(map1); | |||
2437 | str = "[y] -> { [S_L220_OUT[] -> T7[]] -> " | |||
2438 | "[[S_L309_IN[] -> T11[]] -> ce_imag2[o0, o1]] : " | |||
2439 | "exists (e0 = [(-1 - y + o0)/3]: 3e0 = -1 - y + o0 and " | |||
2440 | "y <= 201 and o0 <= 2 and o1 >= 212 and o1 <= 241 and " | |||
2441 | "o0 >= 3 - y and o0 <= -2 + y and o0 >= 0) }"; | |||
2442 | map2 = isl_map_read_from_str(ctx, str); | |||
2443 | map2 = isl_map_union(map2, map1); | |||
2444 | map2 = isl_map_align_divs_internal(map2); | |||
2445 | map2 = isl_map_coalesce(map2); | |||
2446 | isl_map_free(map2); | |||
2447 | if (!map2) | |||
2448 | return -1; | |||
2449 | ||||
2450 | return 0; | |||
2451 | } | |||
2452 | ||||
2453 | /* Check that the union of the basic sets described by "str1" and "str2" | |||
2454 | * can be coalesced and that the result is equal to the union. | |||
2455 | * The explicit call to isl_basic_set_union prevents the implicit | |||
2456 | * equality constraints in the basic maps from being detected prior | |||
2457 | * to the call to isl_set_coalesce, at least at the point | |||
2458 | * where this function was introduced. | |||
2459 | */ | |||
2460 | static isl_stat test_coalesce_union(isl_ctx *ctx, const char *str1, | |||
2461 | const char *str2) | |||
2462 | { | |||
2463 | isl_basic_setisl_basic_map *bset1, *bset2; | |||
2464 | isl_setisl_map *set, *set2; | |||
2465 | isl_bool equal; | |||
2466 | ||||
2467 | bset1 = isl_basic_set_read_from_str(ctx, str1); | |||
2468 | bset2 = isl_basic_set_read_from_str(ctx, str2); | |||
2469 | set = isl_basic_set_union(bset1, bset2); | |||
2470 | set = isl_set_coalesce(set); | |||
2471 | ||||
2472 | bset1 = isl_basic_set_read_from_str(ctx, str1); | |||
2473 | bset2 = isl_basic_set_read_from_str(ctx, str2); | |||
2474 | set2 = isl_basic_set_union(bset1, bset2); | |||
2475 | ||||
2476 | equal = isl_set_is_equal(set, set2); | |||
2477 | isl_set_free(set); | |||
2478 | isl_set_free(set2); | |||
2479 | ||||
2480 | if (equal < 0) | |||
2481 | return isl_stat_error; | |||
2482 | if (!equal) | |||
2483 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "coalesced set not equal to input" , "polly/lib/External/isl/isl_test.c", 2485); return isl_stat_error ; } while (0) | |||
2484 | "coalesced set not equal to input",do { isl_handle_error(ctx, isl_error_unknown, "coalesced set not equal to input" , "polly/lib/External/isl/isl_test.c", 2485); return isl_stat_error ; } while (0) | |||
2485 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "coalesced set not equal to input" , "polly/lib/External/isl/isl_test.c", 2485); return isl_stat_error ; } while (0); | |||
2486 | ||||
2487 | return isl_stat_non_null(set); | |||
2488 | } | |||
2489 | ||||
2490 | /* A specialized coalescing test case that would result in an assertion | |||
2491 | * in an earlier version of isl. Use test_coalesce_union with | |||
2492 | * an explicit call to isl_basic_set_union to prevent the implicit | |||
2493 | * equality constraints in the first basic map from being detected prior | |||
2494 | * to the call to isl_set_coalesce, at least at the point | |||
2495 | * where this test case was introduced. | |||
2496 | */ | |||
2497 | static isl_stat test_coalesce_special2(struct isl_ctx *ctx) | |||
2498 | { | |||
2499 | const char *str1; | |||
2500 | const char *str2; | |||
2501 | ||||
2502 | str1 = "{ [x, y] : x, y >= 0 and x + 2y <= 1 and 2x + y <= 1 }"; | |||
2503 | str2 = "{ [x,0] : -1 <= x <= 1 and x mod 2 = 1 }"; | |||
2504 | return test_coalesce_union(ctx, str1, str2); | |||
2505 | } | |||
2506 | ||||
2507 | /* Check that calling isl_set_coalesce does not leave other sets | |||
2508 | * that may share some information with the input to isl_set_coalesce | |||
2509 | * in an inconsistent state. | |||
2510 | * In particular, older versions of isl would modify all copies | |||
2511 | * of the basic sets in the isl_set_coalesce input in a way | |||
2512 | * that could leave them in an inconsistent state. | |||
2513 | * The result of printing any other set containing one of these | |||
2514 | * basic sets would then result in an invalid set description. | |||
2515 | */ | |||
2516 | static int test_coalesce_special3(isl_ctx *ctx) | |||
2517 | { | |||
2518 | const char *str; | |||
2519 | char *s; | |||
2520 | isl_setisl_map *set1, *set2; | |||
2521 | isl_printer *p; | |||
2522 | ||||
2523 | set1 = isl_set_read_from_str(ctx, "{ [0, 0, 0] }"); | |||
2524 | str = "{ [a, b, a + b] : a >= 0 and b >= 0 and 0 < a + b }"; | |||
2525 | set2 = isl_set_read_from_str(ctx, str); | |||
2526 | set1 = isl_set_union(set1, isl_set_copy(set2)); | |||
2527 | set1 = isl_set_coalesce(set1); | |||
2528 | isl_set_free(set1); | |||
2529 | ||||
2530 | p = isl_printer_to_str(ctx); | |||
2531 | p = isl_printer_print_set(p, set2); | |||
2532 | isl_set_free(set2); | |||
2533 | s = isl_printer_get_str(p); | |||
2534 | isl_printer_free(p); | |||
2535 | set1 = isl_set_read_from_str(ctx, s); | |||
2536 | free(s); | |||
2537 | isl_set_free(set1); | |||
2538 | ||||
2539 | if (!set1) | |||
2540 | return -1; | |||
2541 | ||||
2542 | return 0; | |||
2543 | } | |||
2544 | ||||
2545 | /* Check that calling isl_set_coalesce on the intersection of | |||
2546 | * the sets described by "s1" and "s2" does not leave other sets | |||
2547 | * that may share some information with the input to isl_set_coalesce | |||
2548 | * in an inconsistent state. | |||
2549 | * In particular, when isl_set_coalesce detects equality constraints, | |||
2550 | * it does not immediately perform Gaussian elimination on them, | |||
2551 | * but then it needs to ensure that it is performed at some point. | |||
2552 | * The input set has implicit equality constraints in the first disjunct. | |||
2553 | * It is constructed as an intersection, because otherwise | |||
2554 | * those equality constraints would already be detected during parsing. | |||
2555 | */ | |||
2556 | static isl_stat test_coalesce_intersection(isl_ctx *ctx, | |||
2557 | const char *s1, const char *s2) | |||
2558 | { | |||
2559 | isl_setisl_map *set1, *set2; | |||
2560 | ||||
2561 | set1 = isl_set_read_from_str(ctx, s1); | |||
2562 | set2 = isl_set_read_from_str(ctx, s2); | |||
2563 | set1 = isl_set_intersect(set1, set2); | |||
2564 | isl_set_free(isl_set_coalesce(isl_set_copy(set1))); | |||
2565 | set1 = isl_set_coalesce(set1); | |||
2566 | isl_set_free(set1); | |||
2567 | ||||
2568 | if (!set1) | |||
2569 | return isl_stat_error; | |||
2570 | ||||
2571 | return isl_stat_ok; | |||
2572 | } | |||
2573 | ||||
2574 | /* Check that calling isl_set_coalesce does not leave other sets | |||
2575 | * that may share some information with the input to isl_set_coalesce | |||
2576 | * in an inconsistent state, for the case where one disjunct | |||
2577 | * is a subset of the other. | |||
2578 | */ | |||
2579 | static isl_stat test_coalesce_special4(isl_ctx *ctx) | |||
2580 | { | |||
2581 | const char *s1, *s2; | |||
2582 | ||||
2583 | s1 = "{ [a, b] : b <= 0 or a <= 1 }"; | |||
2584 | s2 = "{ [a, b] : -1 <= -a < b }"; | |||
2585 | return test_coalesce_intersection(ctx, s1, s2); | |||
2586 | } | |||
2587 | ||||
2588 | /* Check that calling isl_set_coalesce does not leave other sets | |||
2589 | * that may share some information with the input to isl_set_coalesce | |||
2590 | * in an inconsistent state, for the case where two disjuncts | |||
2591 | * can be fused. | |||
2592 | */ | |||
2593 | static isl_stat test_coalesce_special5(isl_ctx *ctx) | |||
2594 | { | |||
2595 | const char *s1, *s2; | |||
2596 | ||||
2597 | s1 = "{ [a, b, c] : b <= 0 }"; | |||
2598 | s2 = "{ [a, b, c] : -1 <= -a < b and (c >= 0 or c < 0) }"; | |||
2599 | return test_coalesce_intersection(ctx, s1, s2); | |||
2600 | } | |||
2601 | ||||
2602 | /* Check that calling isl_set_coalesce does not leave other sets | |||
2603 | * that may share some information with the input to isl_set_coalesce | |||
2604 | * in an inconsistent state, for the case where two disjuncts | |||
2605 | * can be fused and where both disjuncts have implicit equality constraints. | |||
2606 | */ | |||
2607 | static isl_stat test_coalesce_special6(isl_ctx *ctx) | |||
2608 | { | |||
2609 | const char *s1, *s2; | |||
2610 | ||||
2611 | s1 = "{ [a, b, c] : c <= 0 }"; | |||
2612 | s2 = "{ [a, b, c] : 0 <= a <= b <= c or (0 <= b <= c and a > 0) }"; | |||
2613 | return test_coalesce_intersection(ctx, s1, s2); | |||
2614 | } | |||
2615 | ||||
2616 | /* A specialized coalescing test case that would result in an assertion failure | |||
2617 | * in an earlier version of isl. Use test_coalesce_union with | |||
2618 | * an explicit call to isl_basic_set_union to prevent the implicit | |||
2619 | * equality constraints in the basic maps from being detected prior | |||
2620 | * to the call to isl_set_coalesce, at least at the point | |||
2621 | * where this test case was introduced. | |||
2622 | */ | |||
2623 | static isl_stat test_coalesce_special7(isl_ctx *ctx) | |||
2624 | { | |||
2625 | const char *str1; | |||
2626 | const char *str2; | |||
2627 | ||||
2628 | str1 = "{ [a, b, c=0:17] : a <= 7 and 2b <= 11 - a and " | |||
2629 | "c <= -7 + 2a and 2c >= - 3 + 3a - 2b }"; | |||
2630 | str2 = "{ [a, b, c] : c > -15a and c >= -7 + 2a and c < 0 and " | |||
2631 | "3c <= -5 + 5a - 3b and 2b >= 11 - a }"; | |||
2632 | return test_coalesce_union(ctx, str1, str2); | |||
2633 | } | |||
2634 | ||||
2635 | /* A specialized coalescing test case that would result in a disjunct | |||
2636 | * getting dropped in an earlier version of isl. Use test_coalesce_union with | |||
2637 | * an explicit call to isl_basic_set_union to prevent the implicit | |||
2638 | * equality constraints in the basic maps from being detected prior | |||
2639 | * to the call to isl_set_coalesce, at least at the point | |||
2640 | * where this test case was introduced. | |||
2641 | */ | |||
2642 | static isl_stat test_coalesce_special8(isl_ctx *ctx) | |||
2643 | { | |||
2644 | const char *str1; | |||
2645 | const char *str2; | |||
2646 | ||||
2647 | str1 = "{ [a, b, c] : 2c <= -a and b >= -a and b <= 5 and " | |||
2648 | "6c > -7a and 11c >= -5a - b and a <= 3 }"; | |||
2649 | str2 = "{ [a, b, c] : 6c > -7a and b >= -a and b <= 5 and " | |||
2650 | "11c >= -5a - b and a >= 4 and 2b <= a and 2c <= -a }"; | |||
2651 | return test_coalesce_union(ctx, str1, str2); | |||
2652 | } | |||
2653 | ||||
2654 | /* Test the functionality of isl_set_coalesce. | |||
2655 | * That is, check that the output is always equal to the input | |||
2656 | * and in some cases that the result consists of a single disjunct. | |||
2657 | */ | |||
2658 | static int test_coalesce(struct isl_ctx *ctx) | |||
2659 | { | |||
2660 | int i; | |||
2661 | ||||
2662 | for (i = 0; i < ARRAY_SIZE(coalesce_tests)(sizeof(coalesce_tests)/sizeof(*coalesce_tests)); ++i) { | |||
2663 | const char *str = coalesce_tests[i].str; | |||
2664 | int check_one = coalesce_tests[i].single_disjunct; | |||
2665 | if (test_coalesce_set(ctx, str, check_one) < 0) | |||
2666 | return -1; | |||
2667 | } | |||
2668 | ||||
2669 | if (test_coalesce_unbounded_wrapping(ctx) < 0) | |||
2670 | return -1; | |||
2671 | if (test_coalesce_special(ctx) < 0) | |||
2672 | return -1; | |||
2673 | if (test_coalesce_special2(ctx) < 0) | |||
2674 | return -1; | |||
2675 | if (test_coalesce_special3(ctx) < 0) | |||
2676 | return -1; | |||
2677 | if (test_coalesce_special4(ctx) < 0) | |||
2678 | return -1; | |||
2679 | if (test_coalesce_special5(ctx) < 0) | |||
2680 | return -1; | |||
2681 | if (test_coalesce_special6(ctx) < 0) | |||
2682 | return -1; | |||
2683 | if (test_coalesce_special7(ctx) < 0) | |||
2684 | return -1; | |||
2685 | if (test_coalesce_special8(ctx) < 0) | |||
2686 | return -1; | |||
2687 | ||||
2688 | return 0; | |||
2689 | } | |||
2690 | ||||
2691 | /* Construct a representation of the graph on the right of Figure 1 | |||
2692 | * in "Computing the Transitive Closure of a Union of | |||
2693 | * Affine Integer Tuple Relations". | |||
2694 | */ | |||
2695 | static __isl_give isl_map *cocoa_fig_1_right_graph(isl_ctx *ctx) | |||
2696 | { | |||
2697 | isl_setisl_map *dom; | |||
2698 | isl_map *up, *right; | |||
2699 | ||||
2700 | dom = isl_set_read_from_str(ctx, | |||
2701 | "{ [x,y] : x >= 0 and -2 x + 3 y >= 0 and x <= 3 and " | |||
2702 | "2 x - 3 y + 3 >= 0 }"); | |||
2703 | right = isl_map_read_from_str(ctx, | |||
2704 | "{ [x,y] -> [x2,y2] : x2 = x + 1 and y2 = y }"); | |||
2705 | up = isl_map_read_from_str(ctx, | |||
2706 | "{ [x,y] -> [x2,y2] : x2 = x and y2 = y + 1 }"); | |||
2707 | right = isl_map_intersect_domain(right, isl_set_copy(dom)); | |||
2708 | right = isl_map_intersect_range(right, isl_set_copy(dom)); | |||
2709 | up = isl_map_intersect_domain(up, isl_set_copy(dom)); | |||
2710 | up = isl_map_intersect_range(up, dom); | |||
2711 | return isl_map_union(up, right); | |||
2712 | } | |||
2713 | ||||
2714 | /* Construct a representation of the power of the graph | |||
2715 | * on the right of Figure 1 in "Computing the Transitive Closure of | |||
2716 | * a Union of Affine Integer Tuple Relations". | |||
2717 | */ | |||
2718 | static __isl_give isl_map *cocoa_fig_1_right_power(isl_ctx *ctx) | |||
2719 | { | |||
2720 | return isl_map_read_from_str(ctx, | |||
2721 | "{ [1] -> [[0,0] -> [0,1]]; [2] -> [[0,0] -> [1,1]]; " | |||
2722 | " [1] -> [[0,1] -> [1,1]]; [1] -> [[2,2] -> [3,2]]; " | |||
2723 | " [2] -> [[2,2] -> [3,3]]; [1] -> [[3,2] -> [3,3]] }"); | |||
2724 | } | |||
2725 | ||||
2726 | /* Construct a representation of the transitive closure of the graph | |||
2727 | * on the right of Figure 1 in "Computing the Transitive Closure of | |||
2728 | * a Union of Affine Integer Tuple Relations". | |||
2729 | */ | |||
2730 | static __isl_give isl_map *cocoa_fig_1_right_tc(isl_ctx *ctx) | |||
2731 | { | |||
2732 | return isl_set_unwrap(isl_map_range(cocoa_fig_1_right_power(ctx))); | |||
2733 | } | |||
2734 | ||||
2735 | static int test_closure(isl_ctx *ctx) | |||
2736 | { | |||
2737 | const char *str; | |||
2738 | isl_map *map, *map2; | |||
2739 | isl_bool exact, equal; | |||
2740 | ||||
2741 | /* COCOA example 1 */ | |||
2742 | map = isl_map_read_from_str(ctx, | |||
2743 | "[n] -> { [i,j] -> [i2,j2] : i2 = i + 1 and j2 = j + 1 and " | |||
2744 | "1 <= i and i < n and 1 <= j and j < n or " | |||
2745 | "i2 = i + 1 and j2 = j - 1 and " | |||
2746 | "1 <= i and i < n and 2 <= j and j <= n }"); | |||
2747 | map = isl_map_power(map, &exact); | |||
2748 | assert(exact)((void) sizeof ((exact) ? 1 : 0), __extension__ ({ if (exact) ; else __assert_fail ("exact", "polly/lib/External/isl/isl_test.c" , 2748, __extension__ __PRETTY_FUNCTION__); })); | |||
2749 | isl_map_free(map); | |||
2750 | ||||
2751 | /* COCOA example 1 */ | |||
2752 | map = isl_map_read_from_str(ctx, | |||
2753 | "[n] -> { [i,j] -> [i2,j2] : i2 = i + 1 and j2 = j + 1 and " | |||
2754 | "1 <= i and i < n and 1 <= j and j < n or " | |||
2755 | "i2 = i + 1 and j2 = j - 1 and " | |||
2756 | "1 <= i and i < n and 2 <= j and j <= n }"); | |||
2757 | map = isl_map_transitive_closure(map, &exact); | |||
2758 | assert(exact)((void) sizeof ((exact) ? 1 : 0), __extension__ ({ if (exact) ; else __assert_fail ("exact", "polly/lib/External/isl/isl_test.c" , 2758, __extension__ __PRETTY_FUNCTION__); })); | |||
2759 | map2 = isl_map_read_from_str(ctx, | |||
2760 | "[n] -> { [i,j] -> [i2,j2] : exists (k1,k2,k : " | |||
2761 | "1 <= i and i < n and 1 <= j and j <= n and " | |||
2762 | "2 <= i2 and i2 <= n and 1 <= j2 and j2 <= n and " | |||
2763 | "i2 = i + k1 + k2 and j2 = j + k1 - k2 and " | |||
2764 | "k1 >= 0 and k2 >= 0 and k1 + k2 = k and k >= 1 )}"); | |||
2765 | assert(isl_map_is_equal(map, map2))((void) sizeof ((isl_map_is_equal(map, map2)) ? 1 : 0), __extension__ ({ if (isl_map_is_equal(map, map2)) ; else __assert_fail ("isl_map_is_equal(map, map2)" , "polly/lib/External/isl/isl_test.c", 2765, __extension__ __PRETTY_FUNCTION__ ); })); | |||
2766 | isl_map_free(map2); | |||
2767 | isl_map_free(map); | |||
2768 | ||||
2769 | map = isl_map_read_from_str(ctx, | |||
2770 | "[n] -> { [x] -> [y] : y = x + 1 and 0 <= x and x <= n and " | |||
2771 | " 0 <= y and y <= n }"); | |||
2772 | map = isl_map_transitive_closure(map, &exact); | |||
2773 | map2 = isl_map_read_from_str(ctx, | |||
2774 | "[n] -> { [x] -> [y] : y > x and 0 <= x and x <= n and " | |||
2775 | " 0 <= y and y <= n }"); | |||
2776 | assert(isl_map_is_equal(map, map2))((void) sizeof ((isl_map_is_equal(map, map2)) ? 1 : 0), __extension__ ({ if (isl_map_is_equal(map, map2)) ; else __assert_fail ("isl_map_is_equal(map, map2)" , "polly/lib/External/isl/isl_test.c", 2776, __extension__ __PRETTY_FUNCTION__ ); })); | |||
2777 | isl_map_free(map2); | |||
2778 | isl_map_free(map); | |||
2779 | ||||
2780 | /* COCOA example 2 */ | |||
2781 | map = isl_map_read_from_str(ctx, | |||
2782 | "[n] -> { [i,j] -> [i2,j2] : i2 = i + 2 and j2 = j + 2 and " | |||
2783 | "1 <= i and i < n - 1 and 1 <= j and j < n - 1 or " | |||
2784 | "i2 = i + 2 and j2 = j - 2 and " | |||
2785 | "1 <= i and i < n - 1 and 3 <= j and j <= n }"); | |||
2786 | map = isl_map_transitive_closure(map, &exact); | |||
2787 | assert(exact)((void) sizeof ((exact) ? 1 : 0), __extension__ ({ if (exact) ; else __assert_fail ("exact", "polly/lib/External/isl/isl_test.c" , 2787, __extension__ __PRETTY_FUNCTION__); })); | |||
2788 | map2 = isl_map_read_from_str(ctx, | |||
2789 | "[n] -> { [i,j] -> [i2,j2] : exists (k1,k2,k : " | |||
2790 | "1 <= i and i < n - 1 and 1 <= j and j <= n and " | |||
2791 | "3 <= i2 and i2 <= n and 1 <= j2 and j2 <= n and " | |||
2792 | "i2 = i + 2 k1 + 2 k2 and j2 = j + 2 k1 - 2 k2 and " | |||
2793 | "k1 >= 0 and k2 >= 0 and k1 + k2 = k and k >= 1) }"); | |||
2794 | assert(isl_map_is_equal(map, map2))((void) sizeof ((isl_map_is_equal(map, map2)) ? 1 : 0), __extension__ ({ if (isl_map_is_equal(map, map2)) ; else __assert_fail ("isl_map_is_equal(map, map2)" , "polly/lib/External/isl/isl_test.c", 2794, __extension__ __PRETTY_FUNCTION__ ); })); | |||
2795 | isl_map_free(map); | |||
2796 | isl_map_free(map2); | |||
2797 | ||||
2798 | /* COCOA Fig.2 left */ | |||
2799 | map = isl_map_read_from_str(ctx, | |||
2800 | "[n] -> { [i,j] -> [i2,j2] : i2 = i + 2 and j2 = j and " | |||
2801 | "i <= 2 j - 3 and i <= n - 2 and j <= 2 i - 1 and " | |||
2802 | "j <= n or " | |||
2803 | "i2 = i and j2 = j + 2 and i <= 2 j - 1 and i <= n and " | |||
2804 | "j <= 2 i - 3 and j <= n - 2 or " | |||
2805 | "i2 = i + 1 and j2 = j + 1 and i <= 2 j - 1 and " | |||
2806 | "i <= n - 1 and j <= 2 i - 1 and j <= n - 1 }"); | |||
2807 | map = isl_map_transitive_closure(map, &exact); | |||
2808 | assert(exact)((void) sizeof ((exact) ? 1 : 0), __extension__ ({ if (exact) ; else __assert_fail ("exact", "polly/lib/External/isl/isl_test.c" , 2808, __extension__ __PRETTY_FUNCTION__); })); | |||
2809 | isl_map_free(map); | |||
2810 | ||||
2811 | /* COCOA Fig.2 right */ | |||
2812 | map = isl_map_read_from_str(ctx, | |||
2813 | "[n] -> { [i,j] -> [i2,j2] : i2 = i + 3 and j2 = j and " | |||
2814 | "i <= 2 j - 4 and i <= n - 3 and j <= 2 i - 1 and " | |||
2815 | "j <= n or " | |||
2816 | "i2 = i and j2 = j + 3 and i <= 2 j - 1 and i <= n and " | |||
2817 | "j <= 2 i - 4 and j <= n - 3 or " | |||
2818 | "i2 = i + 1 and j2 = j + 1 and i <= 2 j - 1 and " | |||
2819 | "i <= n - 1 and j <= 2 i - 1 and j <= n - 1 }"); | |||
2820 | map = isl_map_power(map, &exact); | |||
2821 | assert(exact)((void) sizeof ((exact) ? 1 : 0), __extension__ ({ if (exact) ; else __assert_fail ("exact", "polly/lib/External/isl/isl_test.c" , 2821, __extension__ __PRETTY_FUNCTION__); })); | |||
2822 | isl_map_free(map); | |||
2823 | ||||
2824 | /* COCOA Fig.2 right */ | |||
2825 | map = isl_map_read_from_str(ctx, | |||
2826 | "[n] -> { [i,j] -> [i2,j2] : i2 = i + 3 and j2 = j and " | |||
2827 | "i <= 2 j - 4 and i <= n - 3 and j <= 2 i - 1 and " | |||
2828 | "j <= n or " | |||
2829 | "i2 = i and j2 = j + 3 and i <= 2 j - 1 and i <= n and " | |||
2830 | "j <= 2 i - 4 and j <= n - 3 or " | |||
2831 | "i2 = i + 1 and j2 = j + 1 and i <= 2 j - 1 and " | |||
2832 | "i <= n - 1 and j <= 2 i - 1 and j <= n - 1 }"); | |||
2833 | map = isl_map_transitive_closure(map, &exact); | |||
2834 | assert(exact)((void) sizeof ((exact) ? 1 : 0), __extension__ ({ if (exact) ; else __assert_fail ("exact", "polly/lib/External/isl/isl_test.c" , 2834, __extension__ __PRETTY_FUNCTION__); })); | |||
2835 | map2 = isl_map_read_from_str(ctx, | |||
2836 | "[n] -> { [i,j] -> [i2,j2] : exists (k1,k2,k3,k : " | |||
2837 | "i <= 2 j - 1 and i <= n and j <= 2 i - 1 and " | |||
2838 | "j <= n and 3 + i + 2 j <= 3 n and " | |||
2839 | "3 + 2 i + j <= 3n and i2 <= 2 j2 -1 and i2 <= n and " | |||
2840 | "i2 <= 3 j2 - 4 and j2 <= 2 i2 -1 and j2 <= n and " | |||
2841 | "13 + 4 j2 <= 11 i2 and i2 = i + 3 k1 + k3 and " | |||
2842 | "j2 = j + 3 k2 + k3 and k1 >= 0 and k2 >= 0 and " | |||
2843 | "k3 >= 0 and k1 + k2 + k3 = k and k > 0) }"); | |||
2844 | assert(isl_map_is_equal(map, map2))((void) sizeof ((isl_map_is_equal(map, map2)) ? 1 : 0), __extension__ ({ if (isl_map_is_equal(map, map2)) ; else __assert_fail ("isl_map_is_equal(map, map2)" , "polly/lib/External/isl/isl_test.c", 2844, __extension__ __PRETTY_FUNCTION__ ); })); | |||
2845 | isl_map_free(map2); | |||
2846 | isl_map_free(map); | |||
2847 | ||||
2848 | map = cocoa_fig_1_right_graph(ctx); | |||
2849 | map = isl_map_transitive_closure(map, &exact); | |||
2850 | assert(exact)((void) sizeof ((exact) ? 1 : 0), __extension__ ({ if (exact) ; else __assert_fail ("exact", "polly/lib/External/isl/isl_test.c" , 2850, __extension__ __PRETTY_FUNCTION__); })); | |||
2851 | map2 = cocoa_fig_1_right_tc(ctx); | |||
2852 | assert(isl_map_is_equal(map, map2))((void) sizeof ((isl_map_is_equal(map, map2)) ? 1 : 0), __extension__ ({ if (isl_map_is_equal(map, map2)) ; else __assert_fail ("isl_map_is_equal(map, map2)" , "polly/lib/External/isl/isl_test.c", 2852, __extension__ __PRETTY_FUNCTION__ ); })); | |||
2853 | isl_map_free(map2); | |||
2854 | isl_map_free(map); | |||
2855 | ||||
2856 | map = cocoa_fig_1_right_graph(ctx); | |||
2857 | map = isl_map_power(map, &exact); | |||
2858 | map2 = cocoa_fig_1_right_power(ctx); | |||
2859 | equal = isl_map_is_equal(map, map2); | |||
2860 | isl_map_free(map2); | |||
2861 | isl_map_free(map); | |||
2862 | if (equal < 0) | |||
2863 | return -1; | |||
2864 | if (!exact) | |||
2865 | isl_die(ctx, isl_error_unknown, "power not exact", return -1)do { isl_handle_error(ctx, isl_error_unknown, "power not exact" , "polly/lib/External/isl/isl_test.c", 2865); return -1; } while (0); | |||
2866 | if (!equal) | |||
2867 | isl_die(ctx, isl_error_unknown, "unexpected power", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected power" , "polly/lib/External/isl/isl_test.c", 2867); return -1; } while (0); | |||
2868 | ||||
2869 | /* COCOA Theorem 1 counter example */ | |||
2870 | map = isl_map_read_from_str(ctx, | |||
2871 | "{ [i,j] -> [i2,j2] : i = 0 and 0 <= j and j <= 1 and " | |||
2872 | "i2 = 1 and j2 = j or " | |||
2873 | "i = 0 and j = 0 and i2 = 0 and j2 = 1 }"); | |||
2874 | map = isl_map_transitive_closure(map, &exact); | |||
2875 | assert(exact)((void) sizeof ((exact) ? 1 : 0), __extension__ ({ if (exact) ; else __assert_fail ("exact", "polly/lib/External/isl/isl_test.c" , 2875, __extension__ __PRETTY_FUNCTION__); })); | |||
2876 | isl_map_free(map); | |||
2877 | ||||
2878 | map = isl_map_read_from_str(ctx, | |||
2879 | "[m,n] -> { [i,j] -> [i2,j2] : i2 = i and j2 = j + 2 and " | |||
2880 | "1 <= i,i2 <= n and 1 <= j,j2 <= m or " | |||
2881 | "i2 = i + 1 and 3 <= j2 - j <= 4 and " | |||
2882 | "1 <= i,i2 <= n and 1 <= j,j2 <= m }"); | |||
2883 | map = isl_map_transitive_closure(map, &exact); | |||
2884 | assert(exact)((void) sizeof ((exact) ? 1 : 0), __extension__ ({ if (exact) ; else __assert_fail ("exact", "polly/lib/External/isl/isl_test.c" , 2884, __extension__ __PRETTY_FUNCTION__); })); | |||
2885 | isl_map_free(map); | |||
2886 | ||||
2887 | /* Kelly et al 1996, fig 12 */ | |||
2888 | map = isl_map_read_from_str(ctx, | |||
2889 | "[n] -> { [i,j] -> [i2,j2] : i2 = i and j2 = j + 1 and " | |||
2890 | "1 <= i,j,j+1 <= n or " | |||
2891 | "j = n and j2 = 1 and i2 = i + 1 and " | |||
2892 | "1 <= i,i+1 <= n }"); | |||
2893 | map = isl_map_transitive_closure(map, &exact); | |||
2894 | assert(exact)((void) sizeof ((exact) ? 1 : 0), __extension__ ({ if (exact) ; else __assert_fail ("exact", "polly/lib/External/isl/isl_test.c" , 2894, __extension__ __PRETTY_FUNCTION__); })); | |||
2895 | map2 = isl_map_read_from_str(ctx, | |||
2896 | "[n] -> { [i,j] -> [i2,j2] : 1 <= j < j2 <= n and " | |||
2897 | "1 <= i <= n and i = i2 or " | |||
2898 | "1 <= i < i2 <= n and 1 <= j <= n and " | |||
2899 | "1 <= j2 <= n }"); | |||
2900 | assert(isl_map_is_equal(map, map2))((void) sizeof ((isl_map_is_equal(map, map2)) ? 1 : 0), __extension__ ({ if (isl_map_is_equal(map, map2)) ; else __assert_fail ("isl_map_is_equal(map, map2)" , "polly/lib/External/isl/isl_test.c", 2900, __extension__ __PRETTY_FUNCTION__ ); })); | |||
2901 | isl_map_free(map2); | |||
2902 | isl_map_free(map); | |||
2903 | ||||
2904 | /* Omega's closure4 */ | |||
2905 | map = isl_map_read_from_str(ctx, | |||
2906 | "[m,n] -> { [x,y] -> [x2,y2] : x2 = x and y2 = y + 1 and " | |||
2907 | "1 <= x,y <= 10 or " | |||
2908 | "x2 = x + 1 and y2 = y and " | |||
2909 | "1 <= x <= 20 && 5 <= y <= 15 }"); | |||
2910 | map = isl_map_transitive_closure(map, &exact); | |||
2911 | assert(exact)((void) sizeof ((exact) ? 1 : 0), __extension__ ({ if (exact) ; else __assert_fail ("exact", "polly/lib/External/isl/isl_test.c" , 2911, __extension__ __PRETTY_FUNCTION__); })); | |||
2912 | isl_map_free(map); | |||
2913 | ||||
2914 | map = isl_map_read_from_str(ctx, | |||
2915 | "[n] -> { [x] -> [y]: 1 <= n <= y - x <= 10 }"); | |||
2916 | map = isl_map_transitive_closure(map, &exact); | |||
2917 | assert(!exact)((void) sizeof ((!exact) ? 1 : 0), __extension__ ({ if (!exact ) ; else __assert_fail ("!exact", "polly/lib/External/isl/isl_test.c" , 2917, __extension__ __PRETTY_FUNCTION__); })); | |||
2918 | map2 = isl_map_read_from_str(ctx, | |||
2919 | "[n] -> { [x] -> [y] : 1 <= n <= 10 and y >= n + x }"); | |||
2920 | assert(isl_map_is_equal(map, map2))((void) sizeof ((isl_map_is_equal(map, map2)) ? 1 : 0), __extension__ ({ if (isl_map_is_equal(map, map2)) ; else __assert_fail ("isl_map_is_equal(map, map2)" , "polly/lib/External/isl/isl_test.c", 2920, __extension__ __PRETTY_FUNCTION__ ); })); | |||
2921 | isl_map_free(map); | |||
2922 | isl_map_free(map2); | |||
2923 | ||||
2924 | str = "[n, m] -> { [i0, i1, i2, i3] -> [o0, o1, o2, o3] : " | |||
2925 | "i3 = 1 and o0 = i0 and o1 = -1 + i1 and o2 = -1 + i2 and " | |||
2926 | "o3 = -2 + i2 and i1 <= -1 + i0 and i1 >= 1 - m + i0 and " | |||
2927 | "i1 >= 2 and i1 <= n and i2 >= 3 and i2 <= 1 + n and i2 <= m }"; | |||
2928 | map = isl_map_read_from_str(ctx, str); | |||
2929 | map = isl_map_transitive_closure(map, &exact); | |||
2930 | assert(exact)((void) sizeof ((exact) ? 1 : 0), __extension__ ({ if (exact) ; else __assert_fail ("exact", "polly/lib/External/isl/isl_test.c" , 2930, __extension__ __PRETTY_FUNCTION__); })); | |||
2931 | map2 = isl_map_read_from_str(ctx, str); | |||
2932 | assert(isl_map_is_equal(map, map2))((void) sizeof ((isl_map_is_equal(map, map2)) ? 1 : 0), __extension__ ({ if (isl_map_is_equal(map, map2)) ; else __assert_fail ("isl_map_is_equal(map, map2)" , "polly/lib/External/isl/isl_test.c", 2932, __extension__ __PRETTY_FUNCTION__ ); })); | |||
2933 | isl_map_free(map); | |||
2934 | isl_map_free(map2); | |||
2935 | ||||
2936 | str = "{[0] -> [1]; [2] -> [3]}"; | |||
2937 | map = isl_map_read_from_str(ctx, str); | |||
2938 | map = isl_map_transitive_closure(map, &exact); | |||
2939 | assert(exact)((void) sizeof ((exact) ? 1 : 0), __extension__ ({ if (exact) ; else __assert_fail ("exact", "polly/lib/External/isl/isl_test.c" , 2939, __extension__ __PRETTY_FUNCTION__); })); | |||
2940 | map2 = isl_map_read_from_str(ctx, str); | |||
2941 | assert(isl_map_is_equal(map, map2))((void) sizeof ((isl_map_is_equal(map, map2)) ? 1 : 0), __extension__ ({ if (isl_map_is_equal(map, map2)) ; else __assert_fail ("isl_map_is_equal(map, map2)" , "polly/lib/External/isl/isl_test.c", 2941, __extension__ __PRETTY_FUNCTION__ ); })); | |||
2942 | isl_map_free(map); | |||
2943 | isl_map_free(map2); | |||
2944 | ||||
2945 | str = "[n] -> { [[i0, i1, 1, 0, i0] -> [i5, 1]] -> " | |||
2946 | "[[i0, -1 + i1, 2, 0, i0] -> [-1 + i5, 2]] : " | |||
2947 | "exists (e0 = [(3 - n)/3]: i5 >= 2 and i1 >= 2 and " | |||
2948 | "3i0 <= -1 + n and i1 <= -1 + n and i5 <= -1 + n and " | |||
2949 | "3e0 >= 1 - n and 3e0 <= 2 - n and 3i0 >= -2 + n); " | |||
2950 | "[[i0, i1, 2, 0, i0] -> [i5, 1]] -> " | |||
2951 | "[[i0, i1, 1, 0, i0] -> [-1 + i5, 2]] : " | |||
2952 | "exists (e0 = [(3 - n)/3]: i5 >= 2 and i1 >= 1 and " | |||
2953 | "3i0 <= -1 + n and i1 <= -1 + n and i5 <= -1 + n and " | |||
2954 | "3e0 >= 1 - n and 3e0 <= 2 - n and 3i0 >= -2 + n); " | |||
2955 | "[[i0, i1, 1, 0, i0] -> [i5, 2]] -> " | |||
2956 | "[[i0, -1 + i1, 2, 0, i0] -> [i5, 1]] : " | |||
2957 | "exists (e0 = [(3 - n)/3]: i1 >= 2 and i5 >= 1 and " | |||
2958 | "3i0 <= -1 + n and i1 <= -1 + n and i5 <= -1 + n and " | |||
2959 | "3e0 >= 1 - n and 3e0 <= 2 - n and 3i0 >= -2 + n); " | |||
2960 | "[[i0, i1, 2, 0, i0] -> [i5, 2]] -> " | |||
2961 | "[[i0, i1, 1, 0, i0] -> [i5, 1]] : " | |||
2962 | "exists (e0 = [(3 - n)/3]: i5 >= 1 and i1 >= 1 and " | |||
2963 | "3i0 <= -1 + n and i1 <= -1 + n and i5 <= -1 + n and " | |||
2964 | "3e0 >= 1 - n and 3e0 <= 2 - n and 3i0 >= -2 + n) }"; | |||
2965 | map = isl_map_read_from_str(ctx, str); | |||
2966 | map = isl_map_transitive_closure(map, NULL((void*)0)); | |||
2967 | assert(map)((void) sizeof ((map) ? 1 : 0), __extension__ ({ if (map) ; else __assert_fail ("map", "polly/lib/External/isl/isl_test.c", 2967 , __extension__ __PRETTY_FUNCTION__); })); | |||
2968 | isl_map_free(map); | |||
2969 | ||||
2970 | return 0; | |||
2971 | } | |||
2972 | ||||
2973 | /* Check that the actual result of a boolean operation is equal | |||
2974 | * to the expected result. | |||
2975 | */ | |||
2976 | static isl_stat check_bool(isl_ctx *ctx, isl_bool actual, isl_bool expected) | |||
2977 | { | |||
2978 | if (actual != expected) | |||
2979 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "incorrect boolean operation" , "polly/lib/External/isl/isl_test.c", 2980); return isl_stat_error ; } while (0) | |||
2980 | "incorrect boolean operation", return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "incorrect boolean operation" , "polly/lib/External/isl/isl_test.c", 2980); return isl_stat_error ; } while (0); | |||
2981 | return isl_stat_ok; | |||
2982 | } | |||
2983 | ||||
2984 | /* Test operations on isl_bool values. | |||
2985 | * | |||
2986 | * This tests: | |||
2987 | * | |||
2988 | * isl_bool_not | |||
2989 | * isl_bool_ok | |||
2990 | */ | |||
2991 | static int test_isl_bool(isl_ctx *ctx) | |||
2992 | { | |||
2993 | if (check_bool(ctx, isl_bool_not(isl_bool_true), isl_bool_false) < 0) | |||
2994 | return -1; | |||
2995 | if (check_bool(ctx, isl_bool_not(isl_bool_false), isl_bool_true) < 0) | |||
2996 | return -1; | |||
2997 | if (check_bool(ctx, isl_bool_not(isl_bool_error), isl_bool_error) < 0) | |||
2998 | return -1; | |||
2999 | if (check_bool(ctx, isl_bool_ok(0), isl_bool_false) < 0) | |||
3000 | return -1; | |||
3001 | if (check_bool(ctx, isl_bool_ok(1), isl_bool_true) < 0) | |||
3002 | return -1; | |||
3003 | if (check_bool(ctx, isl_bool_ok(-1), isl_bool_true) < 0) | |||
3004 | return -1; | |||
3005 | if (check_bool(ctx, isl_bool_ok(2), isl_bool_true) < 0) | |||
3006 | return -1; | |||
3007 | if (check_bool(ctx, isl_bool_ok(-2), isl_bool_true) < 0) | |||
3008 | return -1; | |||
3009 | ||||
3010 | return 0; | |||
3011 | } | |||
3012 | ||||
3013 | static int test_lex(struct isl_ctx *ctx) | |||
3014 | { | |||
3015 | isl_space *space; | |||
3016 | isl_map *map; | |||
3017 | int empty; | |||
3018 | ||||
3019 | space = isl_space_set_alloc(ctx, 0, 0); | |||
3020 | map = isl_map_lex_le(space); | |||
3021 | empty = isl_map_is_empty(map); | |||
3022 | isl_map_free(map); | |||
3023 | ||||
3024 | if (empty < 0) | |||
3025 | return -1; | |||
3026 | if (empty) | |||
3027 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "expecting non-empty result" , "polly/lib/External/isl/isl_test.c", 3028); return -1; } while (0) | |||
3028 | "expecting non-empty result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "expecting non-empty result" , "polly/lib/External/isl/isl_test.c", 3028); return -1; } while (0); | |||
3029 | ||||
3030 | return 0; | |||
3031 | } | |||
3032 | ||||
3033 | /* Inputs for isl_map_lexmin tests. | |||
3034 | * "map" is the input and "lexmin" is the expected result. | |||
3035 | */ | |||
3036 | struct { | |||
3037 | const char *map; | |||
3038 | const char *lexmin; | |||
3039 | } lexmin_tests [] = { | |||
3040 | { "{ [x] -> [y] : x <= y <= 10; [x] -> [5] : -8 <= x <= 8 }", | |||
3041 | "{ [x] -> [5] : 6 <= x <= 8; " | |||
3042 | "[x] -> [x] : x <= 5 or (9 <= x <= 10) }" }, | |||
3043 | { "{ [x] -> [y] : 4y = x or 4y = -1 + x or 4y = -2 + x }", | |||
3044 | "{ [x] -> [y] : 4y = x or 4y = -1 + x or 4y = -2 + x }" }, | |||
3045 | { "{ [x] -> [y] : x = 4y; [x] -> [y] : x = 2y }", | |||
3046 | "{ [x] -> [y] : (4y = x and x >= 0) or " | |||
3047 | "(exists (e0 = [(x)/4], e1 = [(-2 + x)/4]: 2y = x and " | |||
3048 | "4e1 = -2 + x and 4e0 <= -1 + x and 4e0 >= -3 + x)) or " | |||
3049 | "(exists (e0 = [(x)/4]: 2y = x and 4e0 = x and x <= -4)) }" }, | |||
3050 | { "{ T[a] -> S[b, c] : a = 4b-2c and c >= b }", | |||
3051 | "{ T[a] -> S[b, c] : 2b = a and 2c = a }" }, | |||
3052 | /* Check that empty pieces are properly combined. */ | |||
3053 | { "[K, N] -> { [x, y] -> [a, b] : K+2<=N<=K+4 and x>=4 and " | |||
3054 | "2N-6<=x<K+N and N-1<=a<=K+N-1 and N+b-6<=a<=2N-4 and " | |||
3055 | "b<=2N-3K+a and 3b<=4N-K+1 and b>=N and a>=x+1 }", | |||
3056 | "[K, N] -> { [x, y] -> [1 + x, N] : x >= -6 + 2N and " | |||
3057 | "x <= -5 + 2N and x >= -1 + 3K - N and x <= -2 + K + N and " | |||
3058 | "x >= 4 }" }, | |||
3059 | { "{ [i, k, j] -> [a, b, c, d] : 8*floor((b)/8) = b and k <= 255 and " | |||
3060 | "a <= 255 and c <= 255 and d <= 255 - j and " | |||
3061 | "255 - j <= 7d <= 7 - i and 240d <= 239 + a and " | |||
3062 | "247d <= 247 + k - j and 247d <= 247 + k - b and " | |||
3063 | "247d <= 247 + i and 248 - b <= 248d <= c and " | |||
3064 | "254d >= i - a + b and 254d >= -a + b and " | |||
3065 | "255d >= -i + a - b and 1792d >= -63736 + 257b }", | |||
3066 | "{ [i, k, j] -> " | |||
3067 | "[-127762 + i + 502j, -62992 + 248j, 63240 - 248j, 255 - j] : " | |||
3068 | "k <= 255 and 7j >= 1778 + i and 246j >= 62738 - k and " | |||
3069 | "247j >= 62738 - i and 509j <= 129795 + i and " | |||
3070 | "742j >= 188724 - i; " | |||
3071 | "[0, k, j] -> [1, 0, 248, 1] : k <= 255 and 248 <= j <= 254, k }" }, | |||
3072 | { "{ [a] -> [b] : 0 <= b <= 255 and -509 + a <= 512b < a and " | |||
3073 | "16*floor((8 + b)/16) <= 7 + b; " | |||
3074 | "[a] -> [1] }", | |||
3075 | "{ [a] -> [b = 1] : a >= 510 or a <= 0; " | |||
3076 | "[a] -> [b = 0] : 0 < a <= 509 }" }, | |||
3077 | { "{ rat: [i] : 1 <= 2i <= 9 }", "{ rat: [i] : 2i = 1 }" }, | |||
3078 | { "{ rat: [i] : 1 <= 2i <= 9 or i >= 10 }", "{ rat: [i] : 2i = 1 }" }, | |||
3079 | { "{ rat: [i] : 21 <= 2i <= 29 or i = 5 }", "{ rat: [5] }" }, | |||
3080 | }; | |||
3081 | ||||
3082 | static int test_lexmin(struct isl_ctx *ctx) | |||
3083 | { | |||
3084 | int i; | |||
3085 | int equal; | |||
3086 | const char *str; | |||
3087 | isl_basic_map *bmap; | |||
3088 | isl_map *map, *map2; | |||
3089 | isl_setisl_map *set; | |||
3090 | isl_setisl_map *set2; | |||
3091 | isl_pw_multi_aff *pma; | |||
3092 | ||||
3093 | str = "[p0, p1] -> { [] -> [] : " | |||
3094 | "exists (e0 = [(2p1)/3], e1, e2, e3 = [(3 - p1 + 3e0)/3], " | |||
3095 | "e4 = [(p1)/3], e5 = [(p1 + 3e4)/3]: " | |||
3096 | "3e0 >= -2 + 2p1 and 3e0 >= p1 and 3e3 >= 1 - p1 + 3e0 and " | |||
3097 | "3e0 <= 2p1 and 3e3 >= -2 + p1 and 3e3 <= -1 + p1 and p1 >= 3 and " | |||
3098 | "3e5 >= -2 + 2p1 and 3e5 >= p1 and 3e5 <= -1 + p1 + 3e4 and " | |||
3099 | "3e4 <= p1 and 3e4 >= -2 + p1 and e3 <= -1 + e0 and " | |||
3100 | "3e4 >= 6 - p1 + 3e1 and 3e1 >= p1 and 3e5 >= -2 + p1 + 3e4 and " | |||
3101 | "2e4 >= 3 - p1 + 2e1 and e4 <= e1 and 3e3 <= 2 - p1 + 3e0 and " | |||
3102 | "e5 >= 1 + e1 and 3e4 >= 6 - 2p1 + 3e1 and " | |||
3103 | "p0 >= 2 and p1 >= p0 and 3e2 >= p1 and 3e4 >= 6 - p1 + 3e2 and " | |||
3104 | "e2 <= e1 and e3 >= 1 and e4 <= e2) }"; | |||
3105 | map = isl_map_read_from_str(ctx, str); | |||
3106 | map = isl_map_lexmin(map); | |||
3107 | isl_map_free(map); | |||
3108 | if (!map) | |||
3109 | return -1; | |||
3110 | ||||
3111 | str = "[C] -> { [obj,a,b,c] : obj <= 38 a + 7 b + 10 c and " | |||
3112 | "a + b <= 1 and c <= 10 b and c <= C and a,b,c,C >= 0 }"; | |||
3113 | set = isl_set_read_from_str(ctx, str); | |||
3114 | set = isl_set_lexmax(set); | |||
3115 | str = "[C] -> { [obj,a,b,c] : C = 8 }"; | |||
3116 | set2 = isl_set_read_from_str(ctx, str); | |||
3117 | set = isl_set_intersect(set, set2); | |||
3118 | assert(!isl_set_is_empty(set))((void) sizeof ((!isl_set_is_empty(set)) ? 1 : 0), __extension__ ({ if (!isl_set_is_empty(set)) ; else __assert_fail ("!isl_set_is_empty(set)" , "polly/lib/External/isl/isl_test.c", 3118, __extension__ __PRETTY_FUNCTION__ ); })); | |||
3119 | isl_set_free(set); | |||
3120 | ||||
3121 | for (i = 0; i < ARRAY_SIZE(lexmin_tests)(sizeof(lexmin_tests)/sizeof(*lexmin_tests)); ++i) { | |||
3122 | map = isl_map_read_from_str(ctx, lexmin_tests[i].map); | |||
3123 | map = isl_map_lexmin(map); | |||
3124 | map2 = isl_map_read_from_str(ctx, lexmin_tests[i].lexmin); | |||
3125 | equal = isl_map_is_equal(map, map2); | |||
3126 | isl_map_free(map); | |||
3127 | isl_map_free(map2); | |||
3128 | ||||
3129 | if (equal < 0) | |||
3130 | return -1; | |||
3131 | if (!equal) | |||
3132 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 3133); return -1; } while (0) | |||
3133 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 3133); return -1; } while (0); | |||
3134 | } | |||
3135 | ||||
3136 | str = "{ [i] -> [i', j] : j = i - 8i' and i' >= 0 and i' <= 7 and " | |||
3137 | " 8i' <= i and 8i' >= -7 + i }"; | |||
3138 | bmap = isl_basic_map_read_from_str(ctx, str); | |||
3139 | pma = isl_basic_map_lexmin_pw_multi_aff(isl_basic_map_copy(bmap)); | |||
3140 | map2 = isl_map_from_pw_multi_aff(pma); | |||
3141 | map = isl_map_from_basic_map(bmap); | |||
3142 | assert(isl_map_is_equal(map, map2))((void) sizeof ((isl_map_is_equal(map, map2)) ? 1 : 0), __extension__ ({ if (isl_map_is_equal(map, map2)) ; else __assert_fail ("isl_map_is_equal(map, map2)" , "polly/lib/External/isl/isl_test.c", 3142, __extension__ __PRETTY_FUNCTION__ ); })); | |||
3143 | isl_map_free(map); | |||
3144 | isl_map_free(map2); | |||
3145 | ||||
3146 | str = "[i] -> { [i', j] : j = i - 8i' and i' >= 0 and i' <= 7 and " | |||
3147 | " 8i' <= i and 8i' >= -7 + i }"; | |||
3148 | set = isl_set_read_from_str(ctx, str); | |||
3149 | pma = isl_set_lexmin_pw_multi_aff(isl_set_copy(set)); | |||
3150 | set2 = isl_set_from_pw_multi_aff(pma); | |||
3151 | equal = isl_set_is_equal(set, set2); | |||
3152 | isl_set_free(set); | |||
3153 | isl_set_free(set2); | |||
3154 | if (equal < 0) | |||
3155 | return -1; | |||
3156 | if (!equal) | |||
3157 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected difference between set and " "piecewise affine expression", "polly/lib/External/isl/isl_test.c" , 3159); return -1; } while (0) | |||
3158 | "unexpected difference between set and "do { isl_handle_error(ctx, isl_error_unknown, "unexpected difference between set and " "piecewise affine expression", "polly/lib/External/isl/isl_test.c" , 3159); return -1; } while (0) | |||
3159 | "piecewise affine expression", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected difference between set and " "piecewise affine expression", "polly/lib/External/isl/isl_test.c" , 3159); return -1; } while (0); | |||
3160 | ||||
3161 | return 0; | |||
3162 | } | |||
3163 | ||||
3164 | /* Inputs for isl_pw_multi_aff_max_multi_val tests. | |||
3165 | * "pma" is the input. | |||
3166 | * "res" is the expected result. | |||
3167 | */ | |||
3168 | static struct { | |||
3169 | const char *pma; | |||
3170 | const char *res; | |||
3171 | } opt_pw_tests[] = { | |||
3172 | { "{ [-1] -> [-1]; [1] -> [1] }", "{ [1] }" }, | |||
3173 | { "{ [a, b] -> [floor((b - 2*floor((-a)/4))/5)] : " | |||
3174 | "0 <= a, b <= 100 and b mod 2 = 0}", "{ [30] }" }, | |||
3175 | { "[N] -> { [i,j] -> A[i, -i, i + j] : 0 <= i,j <= N <= 10 }", | |||
3176 | "{ A[10, 0, 20] }" }, | |||
3177 | { "[N] -> {A[N, -N, 2N] : 0 <= N }", "{ A[infty, 0, infty] }" }, | |||
3178 | }; | |||
3179 | ||||
3180 | /* Perform basic isl_pw_multi_aff_max_multi_val tests. | |||
3181 | */ | |||
3182 | static isl_stat test_pw_max(struct isl_ctx *ctx) | |||
3183 | { | |||
3184 | int i; | |||
3185 | isl_pw_multi_aff *pma; | |||
3186 | isl_multi_val *mv; | |||
3187 | isl_stat r; | |||
3188 | ||||
3189 | for (i = 0; i < ARRAY_SIZE(opt_pw_tests)(sizeof(opt_pw_tests)/sizeof(*opt_pw_tests)); ++i) { | |||
3190 | pma = isl_pw_multi_aff_read_from_str(ctx, opt_pw_tests[i].pma); | |||
3191 | mv = isl_pw_multi_aff_max_multi_val(pma); | |||
3192 | r = multi_val_check_plain_equal(mv, opt_pw_tests[i].res); | |||
3193 | isl_multi_val_free(mv); | |||
3194 | ||||
3195 | if (r < 0) | |||
3196 | return isl_stat_error; | |||
3197 | } | |||
3198 | ||||
3199 | return isl_stat_ok; | |||
3200 | } | |||
3201 | ||||
3202 | /* A specialized isl_set_min_val test case that would return the wrong result | |||
3203 | * in earlier versions of isl. | |||
3204 | * The explicit call to isl_basic_set_union prevents the second basic set | |||
3205 | * from being determined to be empty prior to the call to isl_set_min_val, | |||
3206 | * at least at the point where this test case was introduced. | |||
3207 | */ | |||
3208 | static int test_min_special(isl_ctx *ctx) | |||
3209 | { | |||
3210 | const char *str; | |||
3211 | isl_basic_setisl_basic_map *bset1, *bset2; | |||
3212 | isl_setisl_map *set; | |||
3213 | isl_aff *obj; | |||
3214 | isl_val *res; | |||
3215 | int ok; | |||
3216 | ||||
3217 | str = "{ [a, b] : a >= 2 and b >= 0 and 14 - a <= b <= 9 }"; | |||
3218 | bset1 = isl_basic_set_read_from_str(ctx, str); | |||
3219 | str = "{ [a, b] : 1 <= a, b and a + b <= 1 }"; | |||
3220 | bset2 = isl_basic_set_read_from_str(ctx, str); | |||
3221 | set = isl_basic_set_union(bset1, bset2); | |||
3222 | obj = isl_aff_read_from_str(ctx, "{ [a, b] -> [a] }"); | |||
3223 | ||||
3224 | res = isl_set_min_val(set, obj); | |||
3225 | ok = isl_val_cmp_si(res, 5) == 0; | |||
3226 | ||||
3227 | isl_aff_free(obj); | |||
3228 | isl_set_free(set); | |||
3229 | isl_val_free(res); | |||
3230 | ||||
3231 | if (!res) | |||
3232 | return -1; | |||
3233 | if (!ok) | |||
3234 | isl_die(ctx, isl_error_unknown, "unexpected minimum",do { isl_handle_error(ctx, isl_error_unknown, "unexpected minimum" , "polly/lib/External/isl/isl_test.c", 3235); return -1; } while (0) | |||
3235 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected minimum" , "polly/lib/External/isl/isl_test.c", 3235); return -1; } while (0); | |||
3236 | ||||
3237 | return 0; | |||
3238 | } | |||
3239 | ||||
3240 | /* A specialized isl_set_min_val test case that would return an error | |||
3241 | * in earlier versions of isl. | |||
3242 | */ | |||
3243 | static int test_min_special2(isl_ctx *ctx) | |||
3244 | { | |||
3245 | const char *str; | |||
3246 | isl_basic_setisl_basic_map *bset; | |||
3247 | isl_aff *obj; | |||
3248 | isl_val *res; | |||
3249 | ||||
3250 | str = "{ [i, j, k] : 2j = i and 2k = i + 1 and i >= 2 }"; | |||
3251 | bset = isl_basic_set_read_from_str(ctx, str); | |||
3252 | ||||
3253 | obj = isl_aff_read_from_str(ctx, "{ [i, j, k] -> [i] }"); | |||
3254 | ||||
3255 | res = isl_basic_set_max_val(bset, obj); | |||
3256 | ||||
3257 | isl_basic_set_free(bset); | |||
3258 | isl_aff_free(obj); | |||
3259 | isl_val_free(res); | |||
3260 | ||||
3261 | if (!res) | |||
3262 | return -1; | |||
3263 | ||||
3264 | return 0; | |||
3265 | } | |||
3266 | ||||
3267 | /* Check that the result of isl_set_min_multi_pw_aff | |||
3268 | * on the union of the sets with string descriptions "s1" and "s2" | |||
3269 | * consists of a single expression (on a single cell). | |||
3270 | */ | |||
3271 | static isl_stat check_single_expr_min(isl_ctx *ctx, const char *s1, | |||
3272 | const char *s2) | |||
3273 | { | |||
3274 | isl_size n; | |||
3275 | isl_setisl_map *set1, *set2; | |||
3276 | isl_multi_pw_aff *mpa; | |||
3277 | isl_pw_multi_aff *pma; | |||
3278 | ||||
3279 | set1 = isl_set_read_from_str(ctx, s1); | |||
3280 | set2 = isl_set_read_from_str(ctx, s2); | |||
3281 | set1 = isl_set_union(set1, set2); | |||
3282 | mpa = isl_set_min_multi_pw_aff(set1); | |||
3283 | pma = isl_pw_multi_aff_from_multi_pw_aff(mpa); | |||
3284 | n = isl_pw_multi_aff_n_piece(pma); | |||
3285 | isl_pw_multi_aff_free(pma); | |||
3286 | ||||
3287 | if (n < 0) | |||
3288 | return isl_stat_error; | |||
3289 | if (n != 1) | |||
3290 | isl_die(ctx, isl_error_unknown, "expecting single expression",do { isl_handle_error(ctx, isl_error_unknown, "expecting single expression" , "polly/lib/External/isl/isl_test.c", 3291); return isl_stat_error ; } while (0) | |||
3291 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "expecting single expression" , "polly/lib/External/isl/isl_test.c", 3291); return isl_stat_error ; } while (0); | |||
3292 | return isl_stat_ok; | |||
3293 | } | |||
3294 | ||||
3295 | /* A specialized isl_set_min_multi_pw_aff test that checks | |||
3296 | * that the minimum of 2N and 3N for N >= 0 is represented | |||
3297 | * by a single expression, without splitting off the special case N = 0. | |||
3298 | * Do this for both orderings. | |||
3299 | */ | |||
3300 | static int test_min_mpa(isl_ctx *ctx) | |||
3301 | { | |||
3302 | const char *s1, *s2; | |||
3303 | ||||
3304 | s1 = "[N=0:] -> { [1, 3N:] }"; | |||
3305 | s2 = "[N=0:] -> { [10, 2N:] }"; | |||
3306 | if (check_single_expr_min(ctx, s1, s2) < 0) | |||
3307 | return -1; | |||
3308 | if (check_single_expr_min(ctx, s2, s1) < 0) | |||
3309 | return -1; | |||
3310 | ||||
3311 | return 0; | |||
3312 | } | |||
3313 | ||||
3314 | struct { | |||
3315 | const char *set; | |||
3316 | const char *obj; | |||
3317 | __isl_give isl_val *(*fn)(__isl_keep isl_setisl_map *set, | |||
3318 | __isl_keep isl_aff *obj); | |||
3319 | const char *res; | |||
3320 | } opt_tests[] = { | |||
3321 | { "{ [-1]; [1] }", "{ [x] -> [x] }", &isl_set_min_val, "-1" }, | |||
3322 | { "{ [-1]; [1] }", "{ [x] -> [x] }", &isl_set_max_val, "1" }, | |||
3323 | { "{ [a, b] : 0 <= a, b <= 100 and b mod 2 = 0}", | |||
3324 | "{ [a, b] -> [floor((b - 2*floor((-a)/4))/5)] }", | |||
3325 | &isl_set_max_val, "30" }, | |||
3326 | ||||
3327 | }; | |||
3328 | ||||
3329 | /* Perform basic isl_set_min_val and isl_set_max_val tests. | |||
3330 | * In particular, check the results on non-convex inputs. | |||
3331 | */ | |||
3332 | static int test_min(struct isl_ctx *ctx) | |||
3333 | { | |||
3334 | int i; | |||
3335 | isl_setisl_map *set; | |||
3336 | isl_aff *obj; | |||
3337 | isl_val *val, *res; | |||
3338 | isl_bool ok; | |||
3339 | ||||
3340 | for (i = 0; i < ARRAY_SIZE(opt_tests)(sizeof(opt_tests)/sizeof(*opt_tests)); ++i) { | |||
3341 | set = isl_set_read_from_str(ctx, opt_tests[i].set); | |||
3342 | obj = isl_aff_read_from_str(ctx, opt_tests[i].obj); | |||
3343 | res = isl_val_read_from_str(ctx, opt_tests[i].res); | |||
3344 | val = opt_tests[i].fn(set, obj); | |||
3345 | ok = isl_val_eq(res, val); | |||
3346 | isl_val_free(res); | |||
3347 | isl_val_free(val); | |||
3348 | isl_aff_free(obj); | |||
3349 | isl_set_free(set); | |||
3350 | ||||
3351 | if (ok < 0) | |||
3352 | return -1; | |||
3353 | if (!ok) | |||
3354 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected optimum" , "polly/lib/External/isl/isl_test.c", 3355); return -1; } while (0) | |||
3355 | "unexpected optimum", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected optimum" , "polly/lib/External/isl/isl_test.c", 3355); return -1; } while (0); | |||
3356 | } | |||
3357 | ||||
3358 | if (test_pw_max(ctx) < 0) | |||
3359 | return -1; | |||
3360 | if (test_min_special(ctx) < 0) | |||
3361 | return -1; | |||
3362 | if (test_min_special2(ctx) < 0) | |||
3363 | return -1; | |||
3364 | ||||
3365 | return 0; | |||
3366 | } | |||
3367 | ||||
3368 | struct must_may { | |||
3369 | isl_map *must; | |||
3370 | isl_map *may; | |||
3371 | }; | |||
3372 | ||||
3373 | static isl_stat collect_must_may(__isl_take isl_map *dep, int must, | |||
3374 | void *dep_user, void *user) | |||
3375 | { | |||
3376 | struct must_may *mm = (struct must_may *)user; | |||
3377 | ||||
3378 | if (must) | |||
3379 | mm->must = isl_map_union(mm->must, dep); | |||
3380 | else | |||
3381 | mm->may = isl_map_union(mm->may, dep); | |||
3382 | ||||
3383 | return isl_stat_ok; | |||
3384 | } | |||
3385 | ||||
3386 | static int common_space(void *first, void *second) | |||
3387 | { | |||
3388 | int depth = *(int *)first; | |||
3389 | return 2 * depth; | |||
3390 | } | |||
3391 | ||||
3392 | static int map_is_equal(__isl_keep isl_map *map, const char *str) | |||
3393 | { | |||
3394 | isl_map *map2; | |||
3395 | int equal; | |||
3396 | ||||
3397 | if (!map) | |||
3398 | return -1; | |||
3399 | ||||
3400 | map2 = isl_map_read_from_str(map->ctx, str); | |||
3401 | equal = isl_map_is_equal(map, map2); | |||
3402 | isl_map_free(map2); | |||
3403 | ||||
3404 | return equal; | |||
3405 | } | |||
3406 | ||||
3407 | static int map_check_equal(__isl_keep isl_map *map, const char *str) | |||
3408 | { | |||
3409 | int equal; | |||
3410 | ||||
3411 | equal = map_is_equal(map, str); | |||
3412 | if (equal < 0) | |||
3413 | return -1; | |||
3414 | if (!equal) | |||
3415 | isl_die(isl_map_get_ctx(map), isl_error_unknown,do { isl_handle_error(isl_map_get_ctx(map), isl_error_unknown , "result not as expected", "polly/lib/External/isl/isl_test.c" , 3416); return -1; } while (0) | |||
3416 | "result not as expected", return -1)do { isl_handle_error(isl_map_get_ctx(map), isl_error_unknown , "result not as expected", "polly/lib/External/isl/isl_test.c" , 3416); return -1; } while (0); | |||
3417 | return 0; | |||
3418 | } | |||
3419 | ||||
3420 | /* Is "set" equal to the set described by "str"? | |||
3421 | */ | |||
3422 | static isl_bool set_is_equal(__isl_keep isl_setisl_map *set, const char *str) | |||
3423 | { | |||
3424 | isl_setisl_map *set2; | |||
3425 | isl_bool equal; | |||
3426 | ||||
3427 | if (!set) | |||
3428 | return isl_bool_error; | |||
3429 | ||||
3430 | set2 = isl_set_read_from_str(isl_set_get_ctx(set), str); | |||
3431 | equal = isl_set_is_equal(set, set2); | |||
3432 | isl_set_free(set2); | |||
3433 | ||||
3434 | return equal; | |||
3435 | } | |||
3436 | ||||
3437 | /* Check that "set" is equal to the set described by "str". | |||
3438 | */ | |||
3439 | static isl_stat set_check_equal(__isl_keep isl_setisl_map *set, const char *str) | |||
3440 | { | |||
3441 | isl_bool equal; | |||
3442 | ||||
3443 | equal = set_is_equal(set, str); | |||
3444 | if (equal < 0) | |||
3445 | return isl_stat_error; | |||
3446 | if (!equal) | |||
3447 | isl_die(isl_set_get_ctx(set), isl_error_unknown,do { isl_handle_error(isl_set_get_ctx(set), isl_error_unknown , "result not as expected", "polly/lib/External/isl/isl_test.c" , 3448); return isl_stat_error; } while (0) | |||
3448 | "result not as expected", return isl_stat_error)do { isl_handle_error(isl_set_get_ctx(set), isl_error_unknown , "result not as expected", "polly/lib/External/isl/isl_test.c" , 3448); return isl_stat_error; } while (0); | |||
3449 | return isl_stat_ok; | |||
3450 | } | |||
3451 | ||||
3452 | /* Is "uset" equal to the union set described by "str"? | |||
3453 | */ | |||
3454 | static isl_bool uset_is_equal(__isl_keep isl_union_set *uset, const char *str) | |||
3455 | { | |||
3456 | isl_union_set *uset2; | |||
3457 | isl_bool equal; | |||
3458 | ||||
3459 | if (!uset) | |||
3460 | return isl_bool_error; | |||
3461 | ||||
3462 | uset2 = isl_union_set_read_from_str(isl_union_set_get_ctx(uset), str); | |||
3463 | equal = isl_union_set_is_equal(uset, uset2); | |||
3464 | isl_union_set_free(uset2); | |||
3465 | ||||
3466 | return equal; | |||
3467 | } | |||
3468 | ||||
3469 | /* Check that "uset" is equal to the union set described by "str". | |||
3470 | */ | |||
3471 | static isl_stat uset_check_equal(__isl_keep isl_union_set *uset, | |||
3472 | const char *str) | |||
3473 | { | |||
3474 | isl_bool equal; | |||
3475 | ||||
3476 | equal = uset_is_equal(uset, str); | |||
3477 | if (equal < 0) | |||
3478 | return isl_stat_error; | |||
3479 | if (!equal) | |||
3480 | isl_die(isl_union_set_get_ctx(uset), isl_error_unknown,do { isl_handle_error(isl_union_set_get_ctx(uset), isl_error_unknown , "result not as expected", "polly/lib/External/isl/isl_test.c" , 3481); return isl_stat_error; } while (0) | |||
3481 | "result not as expected", return isl_stat_error)do { isl_handle_error(isl_union_set_get_ctx(uset), isl_error_unknown , "result not as expected", "polly/lib/External/isl/isl_test.c" , 3481); return isl_stat_error; } while (0); | |||
3482 | return isl_stat_ok; | |||
3483 | } | |||
3484 | ||||
3485 | static int test_dep(struct isl_ctx *ctx) | |||
3486 | { | |||
3487 | const char *str; | |||
3488 | isl_space *space; | |||
3489 | isl_map *map; | |||
3490 | isl_access_info *ai; | |||
3491 | isl_flow *flow; | |||
3492 | int depth; | |||
3493 | struct must_may mm; | |||
3494 | ||||
3495 | depth = 3; | |||
3496 | ||||
3497 | str = "{ [2,i,0] -> [i] : 0 <= i <= 10 }"; | |||
3498 | map = isl_map_read_from_str(ctx, str); | |||
3499 | ai = isl_access_info_alloc(map, &depth, &common_space, 2); | |||
3500 | ||||
3501 | str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }"; | |||
3502 | map = isl_map_read_from_str(ctx, str); | |||
3503 | ai = isl_access_info_add_source(ai, map, 1, &depth); | |||
3504 | ||||
3505 | str = "{ [1,i,0] -> [5] : 0 <= i <= 10 }"; | |||
3506 | map = isl_map_read_from_str(ctx, str); | |||
3507 | ai = isl_access_info_add_source(ai, map, 1, &depth); | |||
3508 | ||||
3509 | flow = isl_access_info_compute_flow(ai); | |||
3510 | space = isl_space_alloc(ctx, 0, 3, 3); | |||
3511 | mm.must = isl_map_empty(isl_space_copy(space)); | |||
3512 | mm.may = isl_map_empty(space); | |||
3513 | ||||
3514 | isl_flow_foreach(flow, collect_must_may, &mm); | |||
3515 | ||||
3516 | str = "{ [0,i,0] -> [2,i,0] : (0 <= i <= 4) or (6 <= i <= 10); " | |||
3517 | " [1,10,0] -> [2,5,0] }"; | |||
3518 | assert(map_is_equal(mm.must, str))((void) sizeof ((map_is_equal(mm.must, str)) ? 1 : 0), __extension__ ({ if (map_is_equal(mm.must, str)) ; else __assert_fail ("map_is_equal(mm.must, str)" , "polly/lib/External/isl/isl_test.c", 3518, __extension__ __PRETTY_FUNCTION__ ); })); | |||
3519 | str = "{ [i,j,k] -> [l,m,n] : 1 = 0 }"; | |||
3520 | assert(map_is_equal(mm.may, str))((void) sizeof ((map_is_equal(mm.may, str)) ? 1 : 0), __extension__ ({ if (map_is_equal(mm.may, str)) ; else __assert_fail ("map_is_equal(mm.may, str)" , "polly/lib/External/isl/isl_test.c", 3520, __extension__ __PRETTY_FUNCTION__ ); })); | |||
3521 | ||||
3522 | isl_map_free(mm.must); | |||
3523 | isl_map_free(mm.may); | |||
3524 | isl_flow_free(flow); | |||
3525 | ||||
3526 | ||||
3527 | str = "{ [2,i,0] -> [i] : 0 <= i <= 10 }"; | |||
3528 | map = isl_map_read_from_str(ctx, str); | |||
3529 | ai = isl_access_info_alloc(map, &depth, &common_space, 2); | |||
3530 | ||||
3531 | str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }"; | |||
3532 | map = isl_map_read_from_str(ctx, str); | |||
3533 | ai = isl_access_info_add_source(ai, map, 1, &depth); | |||
3534 | ||||
3535 | str = "{ [1,i,0] -> [5] : 0 <= i <= 10 }"; | |||
3536 | map = isl_map_read_from_str(ctx, str); | |||
3537 | ai = isl_access_info_add_source(ai, map, 0, &depth); | |||
3538 | ||||
3539 | flow = isl_access_info_compute_flow(ai); | |||
3540 | space = isl_space_alloc(ctx, 0, 3, 3); | |||
3541 | mm.must = isl_map_empty(isl_space_copy(space)); | |||
3542 | mm.may = isl_map_empty(space); | |||
3543 | ||||
3544 | isl_flow_foreach(flow, collect_must_may, &mm); | |||
3545 | ||||
3546 | str = "{ [0,i,0] -> [2,i,0] : (0 <= i <= 4) or (6 <= i <= 10) }"; | |||
3547 | assert(map_is_equal(mm.must, str))((void) sizeof ((map_is_equal(mm.must, str)) ? 1 : 0), __extension__ ({ if (map_is_equal(mm.must, str)) ; else __assert_fail ("map_is_equal(mm.must, str)" , "polly/lib/External/isl/isl_test.c", 3547, __extension__ __PRETTY_FUNCTION__ ); })); | |||
3548 | str = "{ [0,5,0] -> [2,5,0]; [1,i,0] -> [2,5,0] : 0 <= i <= 10 }"; | |||
3549 | assert(map_is_equal(mm.may, str))((void) sizeof ((map_is_equal(mm.may, str)) ? 1 : 0), __extension__ ({ if (map_is_equal(mm.may, str)) ; else __assert_fail ("map_is_equal(mm.may, str)" , "polly/lib/External/isl/isl_test.c", 3549, __extension__ __PRETTY_FUNCTION__ ); })); | |||
3550 | ||||
3551 | isl_map_free(mm.must); | |||
3552 | isl_map_free(mm.may); | |||
3553 | isl_flow_free(flow); | |||
3554 | ||||
3555 | ||||
3556 | str = "{ [2,i,0] -> [i] : 0 <= i <= 10 }"; | |||
3557 | map = isl_map_read_from_str(ctx, str); | |||
3558 | ai = isl_access_info_alloc(map, &depth, &common_space, 2); | |||
3559 | ||||
3560 | str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }"; | |||
3561 | map = isl_map_read_from_str(ctx, str); | |||
3562 | ai = isl_access_info_add_source(ai, map, 0, &depth); | |||
3563 | ||||
3564 | str = "{ [1,i,0] -> [5] : 0 <= i <= 10 }"; | |||
3565 | map = isl_map_read_from_str(ctx, str); | |||
3566 | ai = isl_access_info_add_source(ai, map, 0, &depth); | |||
3567 | ||||
3568 | flow = isl_access_info_compute_flow(ai); | |||
3569 | space = isl_space_alloc(ctx, 0, 3, 3); | |||
3570 | mm.must = isl_map_empty(isl_space_copy(space)); | |||
3571 | mm.may = isl_map_empty(space); | |||
3572 | ||||
3573 | isl_flow_foreach(flow, collect_must_may, &mm); | |||
3574 | ||||
3575 | str = "{ [0,i,0] -> [2,i,0] : 0 <= i <= 10; " | |||
3576 | " [1,i,0] -> [2,5,0] : 0 <= i <= 10 }"; | |||
3577 | assert(map_is_equal(mm.may, str))((void) sizeof ((map_is_equal(mm.may, str)) ? 1 : 0), __extension__ ({ if (map_is_equal(mm.may, str)) ; else __assert_fail ("map_is_equal(mm.may, str)" , "polly/lib/External/isl/isl_test.c", 3577, __extension__ __PRETTY_FUNCTION__ ); })); | |||
3578 | str = "{ [i,j,k] -> [l,m,n] : 1 = 0 }"; | |||
3579 | assert(map_is_equal(mm.must, str))((void) sizeof ((map_is_equal(mm.must, str)) ? 1 : 0), __extension__ ({ if (map_is_equal(mm.must, str)) ; else __assert_fail ("map_is_equal(mm.must, str)" , "polly/lib/External/isl/isl_test.c", 3579, __extension__ __PRETTY_FUNCTION__ ); })); | |||
3580 | ||||
3581 | isl_map_free(mm.must); | |||
3582 | isl_map_free(mm.may); | |||
3583 | isl_flow_free(flow); | |||
3584 | ||||
3585 | ||||
3586 | str = "{ [0,i,2] -> [i] : 0 <= i <= 10 }"; | |||
3587 | map = isl_map_read_from_str(ctx, str); | |||
3588 | ai = isl_access_info_alloc(map, &depth, &common_space, 2); | |||
3589 | ||||
3590 | str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }"; | |||
3591 | map = isl_map_read_from_str(ctx, str); | |||
3592 | ai = isl_access_info_add_source(ai, map, 0, &depth); | |||
3593 | ||||
3594 | str = "{ [0,i,1] -> [5] : 0 <= i <= 10 }"; | |||
3595 | map = isl_map_read_from_str(ctx, str); | |||
3596 | ai = isl_access_info_add_source(ai, map, 0, &depth); | |||
3597 | ||||
3598 | flow = isl_access_info_compute_flow(ai); | |||
3599 | space = isl_space_alloc(ctx, 0, 3, 3); | |||
3600 | mm.must = isl_map_empty(isl_space_copy(space)); | |||
3601 | mm.may = isl_map_empty(space); | |||
3602 | ||||
3603 | isl_flow_foreach(flow, collect_must_may, &mm); | |||
3604 | ||||
3605 | str = "{ [0,i,0] -> [0,i,2] : 0 <= i <= 10; " | |||
3606 | " [0,i,1] -> [0,5,2] : 0 <= i <= 5 }"; | |||
3607 | assert(map_is_equal(mm.may, str))((void) sizeof ((map_is_equal(mm.may, str)) ? 1 : 0), __extension__ ({ if (map_is_equal(mm.may, str)) ; else __assert_fail ("map_is_equal(mm.may, str)" , "polly/lib/External/isl/isl_test.c", 3607, __extension__ __PRETTY_FUNCTION__ ); })); | |||
3608 | str = "{ [i,j,k] -> [l,m,n] : 1 = 0 }"; | |||
3609 | assert(map_is_equal(mm.must, str))((void) sizeof ((map_is_equal(mm.must, str)) ? 1 : 0), __extension__ ({ if (map_is_equal(mm.must, str)) ; else __assert_fail ("map_is_equal(mm.must, str)" , "polly/lib/External/isl/isl_test.c", 3609, __extension__ __PRETTY_FUNCTION__ ); })); | |||
3610 | ||||
3611 | isl_map_free(mm.must); | |||
3612 | isl_map_free(mm.may); | |||
3613 | isl_flow_free(flow); | |||
3614 | ||||
3615 | ||||
3616 | str = "{ [0,i,1] -> [i] : 0 <= i <= 10 }"; | |||
3617 | map = isl_map_read_from_str(ctx, str); | |||
3618 | ai = isl_access_info_alloc(map, &depth, &common_space, 2); | |||
3619 | ||||
3620 | str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }"; | |||
3621 | map = isl_map_read_from_str(ctx, str); | |||
3622 | ai = isl_access_info_add_source(ai, map, 0, &depth); | |||
3623 | ||||
3624 | str = "{ [0,i,2] -> [5] : 0 <= i <= 10 }"; | |||
3625 | map = isl_map_read_from_str(ctx, str); | |||
3626 | ai = isl_access_info_add_source(ai, map, 0, &depth); | |||
3627 | ||||
3628 | flow = isl_access_info_compute_flow(ai); | |||
3629 | space = isl_space_alloc(ctx, 0, 3, 3); | |||
3630 | mm.must = isl_map_empty(isl_space_copy(space)); | |||
3631 | mm.may = isl_map_empty(space); | |||
3632 | ||||
3633 | isl_flow_foreach(flow, collect_must_may, &mm); | |||
3634 | ||||
3635 | str = "{ [0,i,0] -> [0,i,1] : 0 <= i <= 10; " | |||
3636 | " [0,i,2] -> [0,5,1] : 0 <= i <= 4 }"; | |||
3637 | assert(map_is_equal(mm.may, str))((void) sizeof ((map_is_equal(mm.may, str)) ? 1 : 0), __extension__ ({ if (map_is_equal(mm.may, str)) ; else __assert_fail ("map_is_equal(mm.may, str)" , "polly/lib/External/isl/isl_test.c", 3637, __extension__ __PRETTY_FUNCTION__ ); })); | |||
3638 | str = "{ [i,j,k] -> [l,m,n] : 1 = 0 }"; | |||
3639 | assert(map_is_equal(mm.must, str))((void) sizeof ((map_is_equal(mm.must, str)) ? 1 : 0), __extension__ ({ if (map_is_equal(mm.must, str)) ; else __assert_fail ("map_is_equal(mm.must, str)" , "polly/lib/External/isl/isl_test.c", 3639, __extension__ __PRETTY_FUNCTION__ ); })); | |||
3640 | ||||
3641 | isl_map_free(mm.must); | |||
3642 | isl_map_free(mm.may); | |||
3643 | isl_flow_free(flow); | |||
3644 | ||||
3645 | ||||
3646 | depth = 5; | |||
3647 | ||||
3648 | str = "{ [1,i,0,0,0] -> [i,j] : 0 <= i <= 10 and 0 <= j <= 10 }"; | |||
3649 | map = isl_map_read_from_str(ctx, str); | |||
3650 | ai = isl_access_info_alloc(map, &depth, &common_space, 1); | |||
3651 | ||||
3652 | str = "{ [0,i,0,j,0] -> [i,j] : 0 <= i <= 10 and 0 <= j <= 10 }"; | |||
3653 | map = isl_map_read_from_str(ctx, str); | |||
3654 | ai = isl_access_info_add_source(ai, map, 1, &depth); | |||
3655 | ||||
3656 | flow = isl_access_info_compute_flow(ai); | |||
3657 | space = isl_space_alloc(ctx, 0, 5, 5); | |||
3658 | mm.must = isl_map_empty(isl_space_copy(space)); | |||
3659 | mm.may = isl_map_empty(space); | |||
3660 | ||||
3661 | isl_flow_foreach(flow, collect_must_may, &mm); | |||
3662 | ||||
3663 | str = "{ [0,i,0,j,0] -> [1,i,0,0,0] : 0 <= i,j <= 10 }"; | |||
3664 | assert(map_is_equal(mm.must, str))((void) sizeof ((map_is_equal(mm.must, str)) ? 1 : 0), __extension__ ({ if (map_is_equal(mm.must, str)) ; else __assert_fail ("map_is_equal(mm.must, str)" , "polly/lib/External/isl/isl_test.c", 3664, __extension__ __PRETTY_FUNCTION__ ); })); | |||
3665 | str = "{ [0,0,0,0,0] -> [0,0,0,0,0] : 1 = 0 }"; | |||
3666 | assert(map_is_equal(mm.may, str))((void) sizeof ((map_is_equal(mm.may, str)) ? 1 : 0), __extension__ ({ if (map_is_equal(mm.may, str)) ; else __assert_fail ("map_is_equal(mm.may, str)" , "polly/lib/External/isl/isl_test.c", 3666, __extension__ __PRETTY_FUNCTION__ ); })); | |||
3667 | ||||
3668 | isl_map_free(mm.must); | |||
3669 | isl_map_free(mm.may); | |||
3670 | isl_flow_free(flow); | |||
3671 | ||||
3672 | return 0; | |||
3673 | } | |||
3674 | ||||
3675 | /* Check that the dependence analysis proceeds without errors. | |||
3676 | * Earlier versions of isl would break down during the analysis | |||
3677 | * due to the use of the wrong spaces. | |||
3678 | */ | |||
3679 | static int test_flow(isl_ctx *ctx) | |||
3680 | { | |||
3681 | const char *str; | |||
3682 | isl_union_map *access, *schedule; | |||
3683 | isl_union_map *must_dep, *may_dep; | |||
3684 | int r; | |||
3685 | ||||
3686 | str = "{ S0[j] -> i[]; S1[j,i] -> i[]; S2[] -> i[]; S3[] -> i[] }"; | |||
3687 | access = isl_union_map_read_from_str(ctx, str); | |||
3688 | str = "{ S0[j] -> [0,j,0,0] : 0 <= j < 10; " | |||
3689 | "S1[j,i] -> [0,j,1,i] : 0 <= j < i < 10; " | |||
3690 | "S2[] -> [1,0,0,0]; " | |||
3691 | "S3[] -> [-1,0,0,0] }"; | |||
3692 | schedule = isl_union_map_read_from_str(ctx, str); | |||
3693 | r = isl_union_map_compute_flow(access, isl_union_map_copy(access), | |||
3694 | isl_union_map_copy(access), schedule, | |||
3695 | &must_dep, &may_dep, NULL((void*)0), NULL((void*)0)); | |||
3696 | isl_union_map_free(may_dep); | |||
3697 | isl_union_map_free(must_dep); | |||
3698 | ||||
3699 | return r; | |||
3700 | } | |||
3701 | ||||
3702 | struct { | |||
3703 | const char *map; | |||
3704 | int sv; | |||
3705 | } sv_tests[] = { | |||
3706 | { "[N] -> { [i] -> [f] : 0 <= i <= N and 0 <= i - 10 f <= 9 }", 1 }, | |||
3707 | { "[N] -> { [i] -> [f] : 0 <= i <= N and 0 <= i - 10 f <= 10 }", 0 }, | |||
3708 | { "{ [i] -> [3*floor(i/2) + 5*floor(i/3)] }", 1 }, | |||
3709 | { "{ S1[i] -> [i] : 0 <= i <= 9; S2[i] -> [i] : 0 <= i <= 9 }", 1 }, | |||
3710 | { "{ [i] -> S1[i] : 0 <= i <= 9; [i] -> S2[i] : 0 <= i <= 9 }", 0 }, | |||
3711 | { "{ A[i] -> [i]; B[i] -> [i]; B[i] -> [i + 1] }", 0 }, | |||
3712 | { "{ A[i] -> [i]; B[i] -> [i] : i < 0; B[i] -> [i + 1] : i > 0 }", 1 }, | |||
3713 | { "{ A[i] -> [i]; B[i] -> A[i] : i < 0; B[i] -> [i + 1] : i > 0 }", 1 }, | |||
3714 | { "{ A[i] -> [i]; B[i] -> [j] : i - 1 <= j <= i }", 0 }, | |||
3715 | }; | |||
3716 | ||||
3717 | int test_sv(isl_ctx *ctx) | |||
3718 | { | |||
3719 | isl_union_map *umap; | |||
3720 | int i; | |||
3721 | int sv; | |||
3722 | ||||
3723 | for (i = 0; i < ARRAY_SIZE(sv_tests)(sizeof(sv_tests)/sizeof(*sv_tests)); ++i) { | |||
3724 | umap = isl_union_map_read_from_str(ctx, sv_tests[i].map); | |||
3725 | sv = isl_union_map_is_single_valued(umap); | |||
3726 | isl_union_map_free(umap); | |||
3727 | if (sv < 0) | |||
3728 | return -1; | |||
3729 | if (sv_tests[i].sv && !sv) | |||
3730 | isl_die(ctx, isl_error_internal,do { isl_handle_error(ctx, isl_error_internal, "map not detected as single valued" , "polly/lib/External/isl/isl_test.c", 3731); return -1; } while (0) | |||
3731 | "map not detected as single valued", return -1)do { isl_handle_error(ctx, isl_error_internal, "map not detected as single valued" , "polly/lib/External/isl/isl_test.c", 3731); return -1; } while (0); | |||
3732 | if (!sv_tests[i].sv && sv) | |||
3733 | isl_die(ctx, isl_error_internal,do { isl_handle_error(ctx, isl_error_internal, "map detected as single valued" , "polly/lib/External/isl/isl_test.c", 3734); return -1; } while (0) | |||
3734 | "map detected as single valued", return -1)do { isl_handle_error(ctx, isl_error_internal, "map detected as single valued" , "polly/lib/External/isl/isl_test.c", 3734); return -1; } while (0); | |||
3735 | } | |||
3736 | ||||
3737 | return 0; | |||
3738 | } | |||
3739 | ||||
3740 | struct { | |||
3741 | const char *str; | |||
3742 | int bijective; | |||
3743 | } bijective_tests[] = { | |||
3744 | { "[N,M]->{[i,j] -> [i]}", 0 }, | |||
3745 | { "[N,M]->{[i,j] -> [i] : j=i}", 1 }, | |||
3746 | { "[N,M]->{[i,j] -> [i] : j=0}", 1 }, | |||
3747 | { "[N,M]->{[i,j] -> [i] : j=N}", 1 }, | |||
3748 | { "[N,M]->{[i,j] -> [j,i]}", 1 }, | |||
3749 | { "[N,M]->{[i,j] -> [i+j]}", 0 }, | |||
3750 | { "[N,M]->{[i,j] -> []}", 0 }, | |||
3751 | { "[N,M]->{[i,j] -> [i,j,N]}", 1 }, | |||
3752 | { "[N,M]->{[i,j] -> [2i]}", 0 }, | |||
3753 | { "[N,M]->{[i,j] -> [i,i]}", 0 }, | |||
3754 | { "[N,M]->{[i,j] -> [2i,i]}", 0 }, | |||
3755 | { "[N,M]->{[i,j] -> [2i,j]}", 1 }, | |||
3756 | { "[N,M]->{[i,j] -> [x,y] : 2x=i & y =j}", 1 }, | |||
3757 | }; | |||
3758 | ||||
3759 | static int test_bijective(struct isl_ctx *ctx) | |||
3760 | { | |||
3761 | isl_map *map; | |||
3762 | int i; | |||
3763 | int bijective; | |||
3764 | ||||
3765 | for (i = 0; i < ARRAY_SIZE(bijective_tests)(sizeof(bijective_tests)/sizeof(*bijective_tests)); ++i) { | |||
3766 | map = isl_map_read_from_str(ctx, bijective_tests[i].str); | |||
3767 | bijective = isl_map_is_bijective(map); | |||
3768 | isl_map_free(map); | |||
3769 | if (bijective < 0) | |||
3770 | return -1; | |||
3771 | if (bijective_tests[i].bijective && !bijective) | |||
3772 | isl_die(ctx, isl_error_internal,do { isl_handle_error(ctx, isl_error_internal, "map not detected as bijective" , "polly/lib/External/isl/isl_test.c", 3773); return -1; } while (0) | |||
3773 | "map not detected as bijective", return -1)do { isl_handle_error(ctx, isl_error_internal, "map not detected as bijective" , "polly/lib/External/isl/isl_test.c", 3773); return -1; } while (0); | |||
3774 | if (!bijective_tests[i].bijective && bijective) | |||
3775 | isl_die(ctx, isl_error_internal,do { isl_handle_error(ctx, isl_error_internal, "map detected as bijective" , "polly/lib/External/isl/isl_test.c", 3776); return -1; } while (0) | |||
3776 | "map detected as bijective", return -1)do { isl_handle_error(ctx, isl_error_internal, "map detected as bijective" , "polly/lib/External/isl/isl_test.c", 3776); return -1; } while (0); | |||
3777 | } | |||
3778 | ||||
3779 | return 0; | |||
3780 | } | |||
3781 | ||||
3782 | /* Inputs for isl_pw_qpolynomial_gist tests. | |||
3783 | * "pwqp" is the input, "set" is the context and "gist" is the expected result. | |||
3784 | */ | |||
3785 | struct { | |||
3786 | const char *pwqp; | |||
3787 | const char *set; | |||
3788 | const char *gist; | |||
3789 | } pwqp_gist_tests[] = { | |||
3790 | { "{ [i] -> i }", "{ [k] : exists a : k = 2a }", "{ [i] -> i }" }, | |||
3791 | { "{ [i] -> i + [ (i + [i/3])/2 ] }", "{ [10] }", "{ [i] -> 16 }" }, | |||
3792 | { "{ [i] -> ([(i)/2]) }", "{ [k] : exists a : k = 2a+1 }", | |||
3793 | "{ [i] -> -1/2 + 1/2 * i }" }, | |||
3794 | { "{ [i] -> i^2 : i != 0 }", "{ [i] : i != 0 }", "{ [i] -> i^2 }" }, | |||
3795 | { "{ [i] -> i^2 : i > 0; [i] -> i^2 : i < 0 }", "{ [i] : i != 0 }", | |||
3796 | "{ [i] -> i^2 }" }, | |||
3797 | }; | |||
3798 | ||||
3799 | /* Perform some basic isl_pw_qpolynomial_gist tests. | |||
3800 | */ | |||
3801 | static isl_stat test_pwqp_gist(isl_ctx *ctx) | |||
3802 | { | |||
3803 | int i; | |||
3804 | const char *str; | |||
3805 | isl_setisl_map *set; | |||
3806 | isl_pw_qpolynomial *pwqp1, *pwqp2; | |||
3807 | isl_bool equal; | |||
3808 | ||||
3809 | for (i = 0; i < ARRAY_SIZE(pwqp_gist_tests)(sizeof(pwqp_gist_tests)/sizeof(*pwqp_gist_tests)); ++i) { | |||
3810 | str = pwqp_gist_tests[i].pwqp; | |||
3811 | pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3812 | str = pwqp_gist_tests[i].set; | |||
3813 | set = isl_set_read_from_str(ctx, str); | |||
3814 | pwqp1 = isl_pw_qpolynomial_gist(pwqp1, set); | |||
3815 | str = pwqp_gist_tests[i].gist; | |||
3816 | pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3817 | pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); | |||
3818 | equal = isl_pw_qpolynomial_is_zero(pwqp1); | |||
3819 | isl_pw_qpolynomial_free(pwqp1); | |||
3820 | ||||
3821 | if (equal < 0) | |||
3822 | return isl_stat_error; | |||
3823 | if (!equal) | |||
3824 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 3825); return isl_stat_error ; } while (0) | |||
3825 | "unexpected result", return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 3825); return isl_stat_error ; } while (0); | |||
3826 | } | |||
3827 | ||||
3828 | return isl_stat_ok; | |||
3829 | } | |||
3830 | ||||
3831 | /* Perform a basic isl_pw_qpolynomial_max test. | |||
3832 | */ | |||
3833 | static isl_stat test_pwqp_max(isl_ctx *ctx) | |||
3834 | { | |||
3835 | const char *str; | |||
3836 | isl_pw_qpolynomial *pwqp; | |||
3837 | isl_val *v; | |||
3838 | int ok; | |||
3839 | ||||
3840 | str = "{ [x=2:9, y] -> floor((x + 1)/4)^3 - floor((2x)/3)^2 }"; | |||
3841 | pwqp = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3842 | v = isl_pw_qpolynomial_max(pwqp); | |||
3843 | ok = isl_val_cmp_si(v, -1) == 0; | |||
3844 | isl_val_free(v); | |||
3845 | ||||
3846 | if (!v) | |||
3847 | return isl_stat_error; | |||
3848 | if (!ok) | |||
3849 | isl_die(ctx, isl_error_unknown, "unexpected maximum",do { isl_handle_error(ctx, isl_error_unknown, "unexpected maximum" , "polly/lib/External/isl/isl_test.c", 3850); return isl_stat_error ; } while (0) | |||
3850 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "unexpected maximum" , "polly/lib/External/isl/isl_test.c", 3850); return isl_stat_error ; } while (0); | |||
3851 | ||||
3852 | return isl_stat_ok; | |||
3853 | } | |||
3854 | ||||
3855 | static int test_pwqp(struct isl_ctx *ctx) | |||
3856 | { | |||
3857 | const char *str; | |||
3858 | isl_setisl_map *set; | |||
3859 | isl_pw_qpolynomial *pwqp1, *pwqp2; | |||
3860 | int equal; | |||
3861 | ||||
3862 | str = "{ [i,j,k] -> 1 + 9 * [i/5] + 7 * [j/11] + 4 * [k/13] }"; | |||
3863 | pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3864 | ||||
3865 | pwqp1 = isl_pw_qpolynomial_move_dims(pwqp1, isl_dim_param, 0, | |||
3866 | isl_dim_in, 1, 1); | |||
3867 | ||||
3868 | str = "[j] -> { [i,k] -> 1 + 9 * [i/5] + 7 * [j/11] + 4 * [k/13] }"; | |||
3869 | pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3870 | ||||
3871 | pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); | |||
3872 | ||||
3873 | assert(isl_pw_qpolynomial_is_zero(pwqp1))((void) sizeof ((isl_pw_qpolynomial_is_zero(pwqp1)) ? 1 : 0), __extension__ ({ if (isl_pw_qpolynomial_is_zero(pwqp1)) ; else __assert_fail ("isl_pw_qpolynomial_is_zero(pwqp1)", "polly/lib/External/isl/isl_test.c" , 3873, __extension__ __PRETTY_FUNCTION__); })); | |||
3874 | ||||
3875 | isl_pw_qpolynomial_free(pwqp1); | |||
3876 | ||||
3877 | if (test_pwqp_gist(ctx) < 0) | |||
3878 | return -1; | |||
3879 | ||||
3880 | str = "{ [i] -> ([([i/2] + [i/2])/5]) }"; | |||
3881 | pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3882 | str = "{ [i] -> ([(2 * [i/2])/5]) }"; | |||
3883 | pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3884 | ||||
3885 | pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); | |||
3886 | ||||
3887 | assert(isl_pw_qpolynomial_is_zero(pwqp1))((void) sizeof ((isl_pw_qpolynomial_is_zero(pwqp1)) ? 1 : 0), __extension__ ({ if (isl_pw_qpolynomial_is_zero(pwqp1)) ; else __assert_fail ("isl_pw_qpolynomial_is_zero(pwqp1)", "polly/lib/External/isl/isl_test.c" , 3887, __extension__ __PRETTY_FUNCTION__); })); | |||
3888 | ||||
3889 | isl_pw_qpolynomial_free(pwqp1); | |||
3890 | ||||
3891 | str = "{ [x] -> ([x/2] + [(x+1)/2]) }"; | |||
3892 | pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3893 | str = "{ [x] -> x }"; | |||
3894 | pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3895 | ||||
3896 | pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); | |||
3897 | ||||
3898 | assert(isl_pw_qpolynomial_is_zero(pwqp1))((void) sizeof ((isl_pw_qpolynomial_is_zero(pwqp1)) ? 1 : 0), __extension__ ({ if (isl_pw_qpolynomial_is_zero(pwqp1)) ; else __assert_fail ("isl_pw_qpolynomial_is_zero(pwqp1)", "polly/lib/External/isl/isl_test.c" , 3898, __extension__ __PRETTY_FUNCTION__); })); | |||
3899 | ||||
3900 | isl_pw_qpolynomial_free(pwqp1); | |||
3901 | ||||
3902 | str = "{ [i] -> ([i/2]) : i >= 0; [i] -> ([i/3]) : i < 0 }"; | |||
3903 | pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3904 | pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3905 | pwqp1 = isl_pw_qpolynomial_coalesce(pwqp1); | |||
3906 | pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); | |||
3907 | assert(isl_pw_qpolynomial_is_zero(pwqp1))((void) sizeof ((isl_pw_qpolynomial_is_zero(pwqp1)) ? 1 : 0), __extension__ ({ if (isl_pw_qpolynomial_is_zero(pwqp1)) ; else __assert_fail ("isl_pw_qpolynomial_is_zero(pwqp1)", "polly/lib/External/isl/isl_test.c" , 3907, __extension__ __PRETTY_FUNCTION__); })); | |||
3908 | isl_pw_qpolynomial_free(pwqp1); | |||
3909 | ||||
3910 | str = "{ [a,b,a] -> (([(2*[a/3]+b)/5]) * ([(2*[a/3]+b)/5])) }"; | |||
3911 | pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3912 | str = "{ [a,b,c] -> (([(2*[a/3]+b)/5]) * ([(2*[c/3]+b)/5])) }"; | |||
3913 | pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3914 | set = isl_set_read_from_str(ctx, "{ [a,b,a] }"); | |||
3915 | pwqp1 = isl_pw_qpolynomial_intersect_domain(pwqp1, set); | |||
3916 | equal = isl_pw_qpolynomial_plain_is_equal(pwqp1, pwqp2); | |||
3917 | isl_pw_qpolynomial_free(pwqp1); | |||
3918 | isl_pw_qpolynomial_free(pwqp2); | |||
3919 | if (equal < 0) | |||
3920 | return -1; | |||
3921 | if (!equal) | |||
3922 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 3922); return -1; } while (0); | |||
3923 | ||||
3924 | str = "{ [a,b,c] -> (([(2*[a/3]+1)/5]) * ([(2*[c/3]+1)/5])) : b = 1 }"; | |||
3925 | pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3926 | str = "{ [a,b,c] -> (([(2*[a/3]+b)/5]) * ([(2*[c/3]+b)/5])) }"; | |||
3927 | pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3928 | pwqp1 = isl_pw_qpolynomial_fix_val(pwqp1, isl_dim_set, 1, | |||
3929 | isl_val_one(ctx)); | |||
3930 | equal = isl_pw_qpolynomial_plain_is_equal(pwqp1, pwqp2); | |||
3931 | isl_pw_qpolynomial_free(pwqp1); | |||
3932 | isl_pw_qpolynomial_free(pwqp2); | |||
3933 | if (equal < 0) | |||
3934 | return -1; | |||
3935 | if (!equal) | |||
3936 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 3936); return -1; } while (0); | |||
3937 | ||||
3938 | if (test_pwqp_max(ctx) < 0) | |||
3939 | return -1; | |||
3940 | ||||
3941 | return 0; | |||
3942 | } | |||
3943 | ||||
3944 | static int test_split_periods(isl_ctx *ctx) | |||
3945 | { | |||
3946 | const char *str; | |||
3947 | isl_pw_qpolynomial *pwqp; | |||
3948 | ||||
3949 | str = "{ [U,V] -> 1/3 * U + 2/3 * V - [(U + 2V)/3] + [U/2] : " | |||
3950 | "U + 2V + 3 >= 0 and - U -2V >= 0 and - U + 10 >= 0 and " | |||
3951 | "U >= 0; [U,V] -> U^2 : U >= 100 }"; | |||
3952 | pwqp = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
3953 | ||||
3954 | pwqp = isl_pw_qpolynomial_split_periods(pwqp, 2); | |||
3955 | ||||
3956 | isl_pw_qpolynomial_free(pwqp); | |||
3957 | ||||
3958 | if (!pwqp) | |||
3959 | return -1; | |||
3960 | ||||
3961 | return 0; | |||
3962 | } | |||
3963 | ||||
3964 | static int test_union(isl_ctx *ctx) | |||
3965 | { | |||
3966 | const char *str; | |||
3967 | isl_union_set *uset1, *uset2; | |||
3968 | isl_union_map *umap1, *umap2; | |||
3969 | int equal; | |||
3970 | ||||
3971 | str = "{ [i] : 0 <= i <= 1 }"; | |||
3972 | uset1 = isl_union_set_read_from_str(ctx, str); | |||
3973 | str = "{ [1] -> [0] }"; | |||
3974 | umap1 = isl_union_map_read_from_str(ctx, str); | |||
3975 | ||||
3976 | umap2 = isl_union_set_lex_gt_union_set(isl_union_set_copy(uset1), uset1); | |||
3977 | equal = isl_union_map_is_equal(umap1, umap2); | |||
3978 | ||||
3979 | isl_union_map_free(umap1); | |||
3980 | isl_union_map_free(umap2); | |||
3981 | ||||
3982 | if (equal < 0) | |||
3983 | return -1; | |||
3984 | if (!equal) | |||
3985 | isl_die(ctx, isl_error_unknown, "union maps not equal",do { isl_handle_error(ctx, isl_error_unknown, "union maps not equal" , "polly/lib/External/isl/isl_test.c", 3986); return -1; } while (0) | |||
3986 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "union maps not equal" , "polly/lib/External/isl/isl_test.c", 3986); return -1; } while (0); | |||
3987 | ||||
3988 | str = "{ A[i] -> B[i]; B[i] -> C[i]; A[0] -> C[1] }"; | |||
3989 | umap1 = isl_union_map_read_from_str(ctx, str); | |||
3990 | str = "{ A[i]; B[i] }"; | |||
3991 | uset1 = isl_union_set_read_from_str(ctx, str); | |||
3992 | ||||
3993 | uset2 = isl_union_map_domain(umap1); | |||
3994 | ||||
3995 | equal = isl_union_set_is_equal(uset1, uset2); | |||
3996 | ||||
3997 | isl_union_set_free(uset1); | |||
3998 | isl_union_set_free(uset2); | |||
3999 | ||||
4000 | if (equal < 0) | |||
4001 | return -1; | |||
4002 | if (!equal) | |||
4003 | isl_die(ctx, isl_error_unknown, "union sets not equal",do { isl_handle_error(ctx, isl_error_unknown, "union sets not equal" , "polly/lib/External/isl/isl_test.c", 4004); return -1; } while (0) | |||
4004 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "union sets not equal" , "polly/lib/External/isl/isl_test.c", 4004); return -1; } while (0); | |||
4005 | ||||
4006 | return 0; | |||
4007 | } | |||
4008 | ||||
4009 | /* Inputs for basic isl_pw_qpolynomial_bound tests. | |||
4010 | * "type" is the type of bound that should be computed. | |||
4011 | * "poly" is a string representation of the input. | |||
4012 | * "bound" is a string representation of the expected result. | |||
4013 | * "tight" is set if the result is expected to be tight. | |||
4014 | */ | |||
4015 | static struct { | |||
4016 | int tight; | |||
4017 | enum isl_fold type; | |||
4018 | const char *poly; | |||
4019 | const char *bound; | |||
4020 | } bound_tests[] = { | |||
4021 | /* Check that computing a bound of a non-zero polynomial | |||
4022 | * over an unbounded domain does not produce a rational value. | |||
4023 | * In particular, check that the upper bound is infinity. | |||
4024 | */ | |||
4025 | { 0, isl_fold_max, "{ [m, n] -> -m * n }", "{ max(infty) }" }, | |||
4026 | { 1, isl_fold_max, "{ [[a, b, c, d] -> [e]] -> 0 }", | |||
4027 | "{ [a, b, c, d] -> max(0) }" }, | |||
4028 | { 1, isl_fold_max, "{ [[x] -> [x]] -> 1 : exists a : x = 2 a }", | |||
4029 | "{ [x] -> max(1) : x mod 2 = 0 }" }, | |||
4030 | { 1, isl_fold_min, "{ [x=5:10] -> (x + 2)^2 }", "{ min(49) }" }, | |||
4031 | { 1, isl_fold_max, "{ [0:10] -> 1 }", "{ max(1) }" }, | |||
4032 | { 1, isl_fold_max, "{ [[m] -> [0:m]] -> m^2 }", | |||
4033 | "{ [m] -> max(m^2) : m >= 0 }" }, | |||
4034 | }; | |||
4035 | ||||
4036 | /* Check that the bound computation can handle differences | |||
4037 | * in domain dimension names of the input polynomial and its domain. | |||
4038 | */ | |||
4039 | static isl_stat test_bound_space(isl_ctx *ctx) | |||
4040 | { | |||
4041 | const char *str; | |||
4042 | isl_setisl_map *set; | |||
4043 | isl_pw_qpolynomial *pwqp; | |||
4044 | isl_pw_qpolynomial_fold *pwf; | |||
4045 | ||||
4046 | str = "{ [[c] -> [c]] }"; | |||
4047 | set = isl_set_read_from_str(ctx, str); | |||
4048 | str = "{ [[a] -> [b]] -> 1 }"; | |||
4049 | pwqp = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
4050 | pwqp = isl_pw_qpolynomial_intersect_domain(pwqp, set); | |||
4051 | pwf = isl_pw_qpolynomial_bound(pwqp, isl_fold_max, NULL((void*)0)); | |||
4052 | isl_pw_qpolynomial_fold_free(pwf); | |||
4053 | ||||
4054 | return isl_stat_non_null(pwf); | |||
4055 | } | |||
4056 | ||||
4057 | /* Perform basic isl_pw_qpolynomial_bound tests. | |||
4058 | */ | |||
4059 | static int test_bound(isl_ctx *ctx) | |||
4060 | { | |||
4061 | int i; | |||
4062 | ||||
4063 | if (test_bound_space(ctx) < 0) | |||
4064 | return -1; | |||
4065 | ||||
4066 | for (i = 0; i < ARRAY_SIZE(bound_tests)(sizeof(bound_tests)/sizeof(*bound_tests)); ++i) { | |||
4067 | const char *str; | |||
4068 | enum isl_fold type; | |||
4069 | isl_bool equal, tight; | |||
4070 | isl_pw_qpolynomial *pwqp; | |||
4071 | isl_pw_qpolynomial_fold *pwf1, *pwf2; | |||
4072 | ||||
4073 | str = bound_tests[i].poly; | |||
4074 | pwqp = isl_pw_qpolynomial_read_from_str(ctx, str); | |||
4075 | type = bound_tests[i].type; | |||
4076 | pwf1 = isl_pw_qpolynomial_bound(pwqp, type, &tight); | |||
4077 | str = bound_tests[i].bound; | |||
4078 | pwf2 = isl_pw_qpolynomial_fold_read_from_str(ctx, str); | |||
4079 | equal = isl_pw_qpolynomial_fold_plain_is_equal(pwf1, pwf2); | |||
4080 | isl_pw_qpolynomial_fold_free(pwf2); | |||
4081 | isl_pw_qpolynomial_fold_free(pwf1); | |||
4082 | if (equal < 0) | |||
4083 | return -1; | |||
4084 | if (!equal) | |||
4085 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "incorrect bound result" , "polly/lib/External/isl/isl_test.c", 4086); return -1; } while (0) | |||
4086 | "incorrect bound result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "incorrect bound result" , "polly/lib/External/isl/isl_test.c", 4086); return -1; } while (0); | |||
4087 | if (bound_tests[i].tight && !tight) | |||
4088 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "bound unexpectedly not tight" , "polly/lib/External/isl/isl_test.c", 4089); return -1; } while (0) | |||
4089 | "bound unexpectedly not tight", return -1)do { isl_handle_error(ctx, isl_error_unknown, "bound unexpectedly not tight" , "polly/lib/External/isl/isl_test.c", 4089); return -1; } while (0); | |||
4090 | } | |||
4091 | ||||
4092 | return 0; | |||
4093 | } | |||
4094 | ||||
4095 | /* isl_set is defined to isl_map internally, so the corresponding elements | |||
4096 | * are isl_basic_map objects. | |||
4097 | */ | |||
4098 | #undef EL_BASEmap | |||
4099 | #undef SET_BASEunion_map | |||
4100 | #define EL_BASEmap basic_map | |||
4101 | #define SET_BASEunion_map set | |||
4102 | #include "isl_test_list_templ.c" | |||
4103 | ||||
4104 | #undef EL_BASEmap | |||
4105 | #undef SET_BASEunion_map | |||
4106 | #define EL_BASEmap basic_set | |||
4107 | #define SET_BASEunion_map union_set | |||
4108 | #include "isl_test_list_templ.c" | |||
4109 | ||||
4110 | #undef EL_BASEmap | |||
4111 | #undef SET_BASEunion_map | |||
4112 | #define EL_BASEmap set | |||
4113 | #define SET_BASEunion_map union_set | |||
4114 | #include "isl_test_list_templ.c" | |||
4115 | ||||
4116 | #undef EL_BASEmap | |||
4117 | #undef SET_BASEunion_map | |||
4118 | #define EL_BASEmap basic_map | |||
4119 | #define SET_BASEunion_map map | |||
4120 | #include "isl_test_list_templ.c" | |||
4121 | ||||
4122 | #undef EL_BASEmap | |||
4123 | #undef SET_BASEunion_map | |||
4124 | #define EL_BASEmap map | |||
4125 | #define SET_BASEunion_map union_map | |||
4126 | #include "isl_test_list_templ.c" | |||
4127 | ||||
4128 | /* Check that the conversion from isl objects to lists works as expected. | |||
4129 | */ | |||
4130 | static int test_get_list(isl_ctx *ctx) | |||
4131 | { | |||
4132 | if (test_get_list_basic_map_from_set(ctx, "{ [0]; [2]; [3] }")) | |||
4133 | return -1; | |||
4134 | if (test_get_list_basic_set_from_union_set(ctx, "{ A[0]; B[2]; B[3] }")) | |||
4135 | return -1; | |||
4136 | if (test_get_list_set_from_union_set(ctx, "{ A[0]; A[2]; B[3] }")) | |||
4137 | return -1; | |||
4138 | if (test_get_list_basic_map_from_map(ctx, | |||
4139 | "{ [0] -> [0]; [2] -> [0]; [3] -> [0] }")) | |||
4140 | return -1; | |||
4141 | if (test_get_list_map_from_union_map(ctx, | |||
4142 | "{ A[0] -> [0]; A[2] -> [0]; B[3] -> [0] }")) | |||
4143 | return -1; | |||
4144 | ||||
4145 | return 0; | |||
4146 | } | |||
4147 | ||||
4148 | static int test_lift(isl_ctx *ctx) | |||
4149 | { | |||
4150 | const char *str; | |||
4151 | isl_basic_map *bmap; | |||
4152 | isl_basic_setisl_basic_map *bset; | |||
4153 | ||||
4154 | str = "{ [i0] : exists e0 : i0 = 4e0 }"; | |||
4155 | bset = isl_basic_set_read_from_str(ctx, str); | |||
4156 | bset = isl_basic_set_lift(bset); | |||
4157 | bmap = isl_basic_map_from_range(bset); | |||
4158 | bset = isl_basic_map_domain(bmap); | |||
4159 | isl_basic_set_free(bset); | |||
4160 | ||||
4161 | return 0; | |||
4162 | } | |||
4163 | ||||
4164 | /* Check that isl_set_is_subset is not confused by identical | |||
4165 | * integer divisions. | |||
4166 | * The call to isl_set_normalize ensures that the equality constraints | |||
4167 | * a = b = 0 are discovered, turning e0 and e1 into identical | |||
4168 | * integer divisions. Any further simplification would remove | |||
4169 | * the duplicate integer divisions. | |||
4170 | */ | |||
4171 | static isl_stat test_subset_duplicate_integer_divisions(isl_ctx *ctx) | |||
4172 | { | |||
4173 | const char *str; | |||
4174 | isl_bool is_subset; | |||
4175 | isl_setisl_map *set1, *set2; | |||
4176 | ||||
4177 | str = "{ [a, b, c, d] : " | |||
4178 | "exists (e0 = floor((a + d)/4), e1 = floor((d)/4), " | |||
4179 | "e2 = floor((-a - d + 4 *floor((a + d)/4))/10), " | |||
4180 | "e3 = floor((-d + 4*floor((d)/4))/10): " | |||
4181 | "10e2 = -a - 2c - d + 4e0 and 10e3 = -2c - d + 4e1 and " | |||
4182 | "b >= 0 and a <= 0 and b <= a) }"; | |||
4183 | set1 = isl_set_read_from_str(ctx, str); | |||
4184 | set2 = isl_set_read_from_str(ctx, str); | |||
4185 | set2 = isl_set_normalize(set2); | |||
4186 | ||||
4187 | is_subset = isl_set_is_subset(set1, set2); | |||
4188 | ||||
4189 | isl_set_free(set1); | |||
4190 | isl_set_free(set2); | |||
4191 | ||||
4192 | if (is_subset < 0) | |||
4193 | return isl_stat_error; | |||
4194 | if (!is_subset) | |||
4195 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "set is not considered to be a subset of itself" , "polly/lib/External/isl/isl_test.c", 4197); return isl_stat_error ; } while (0) | |||
4196 | "set is not considered to be a subset of itself",do { isl_handle_error(ctx, isl_error_unknown, "set is not considered to be a subset of itself" , "polly/lib/External/isl/isl_test.c", 4197); return isl_stat_error ; } while (0) | |||
4197 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "set is not considered to be a subset of itself" , "polly/lib/External/isl/isl_test.c", 4197); return isl_stat_error ; } while (0); | |||
4198 | ||||
4199 | return isl_stat_ok; | |||
4200 | } | |||
4201 | ||||
4202 | struct { | |||
4203 | const char *set1; | |||
4204 | const char *set2; | |||
4205 | int subset; | |||
4206 | } subset_tests[] = { | |||
4207 | { "{ [112, 0] }", | |||
4208 | "{ [i0, i1] : exists (e0 = [(i0 - i1)/16], e1: " | |||
4209 | "16e0 <= i0 - i1 and 16e0 >= -15 + i0 - i1 and " | |||
4210 | "16e1 <= i1 and 16e0 >= -i1 and 16e1 >= -i0 + i1) }", 1 }, | |||
4211 | { "{ [65] }", | |||
4212 | "{ [i] : exists (e0 = [(255i)/256], e1 = [(127i + 65e0)/191], " | |||
4213 | "e2 = [(3i + 61e1)/65], e3 = [(52i + 12e2)/61], " | |||
4214 | "e4 = [(2i + e3)/3], e5 = [(4i + e3)/4], e6 = [(8i + e3)/12]: " | |||
4215 | "3e4 = 2i + e3 and 4e5 = 4i + e3 and 12e6 = 8i + e3 and " | |||
4216 | "i <= 255 and 64e3 >= -45 + 67i and i >= 0 and " | |||
4217 | "256e0 <= 255i and 256e0 >= -255 + 255i and " | |||
4218 | "191e1 <= 127i + 65e0 and 191e1 >= -190 + 127i + 65e0 and " | |||
4219 | "65e2 <= 3i + 61e1 and 65e2 >= -64 + 3i + 61e1 and " | |||
4220 | "61e3 <= 52i + 12e2 and 61e3 >= -60 + 52i + 12e2) }", 1 }, | |||
4221 | { "{ [i] : 0 <= i <= 10 }", "{ rat: [i] : 0 <= i <= 10 }", 1 }, | |||
4222 | { "{ rat: [i] : 0 <= i <= 10 }", "{ [i] : 0 <= i <= 10 }", 0 }, | |||
4223 | { "{ rat: [0] }", "{ [i] : 0 <= i <= 10 }", 1 }, | |||
4224 | { "{ rat: [(1)/2] }", "{ [i] : 0 <= i <= 10 }", 0 }, | |||
4225 | { "{ [t, i] : (exists (e0 = [(2 + t)/4]: 4e0 <= 2 + t and " | |||
4226 | "4e0 >= -1 + t and i >= 57 and i <= 62 and " | |||
4227 | "4e0 <= 62 + t - i and 4e0 >= -61 + t + i and " | |||
4228 | "t >= 0 and t <= 511 and 4e0 <= -57 + t + i and " | |||
4229 | "4e0 >= 58 + t - i and i >= 58 + t and i >= 62 - t)) }", | |||
4230 | "{ [i0, i1] : (exists (e0 = [(4 + i0)/4]: 4e0 <= 62 + i0 - i1 and " | |||
4231 | "4e0 >= 1 + i0 and i0 >= 0 and i0 <= 511 and " | |||
4232 | "4e0 <= -57 + i0 + i1)) or " | |||
4233 | "(exists (e0 = [(2 + i0)/4]: 4e0 <= i0 and " | |||
4234 | "4e0 >= 58 + i0 - i1 and i0 >= 2 and i0 <= 511 and " | |||
4235 | "4e0 >= -61 + i0 + i1)) or " | |||
4236 | "(i1 <= 66 - i0 and i0 >= 2 and i1 >= 59 + i0) }", 1 }, | |||
4237 | { "[a, b] -> { : a = 0 and b = -1 }", "[b, a] -> { : b >= -10 }", 1 }, | |||
4238 | }; | |||
4239 | ||||
4240 | static int test_subset(isl_ctx *ctx) | |||
4241 | { | |||
4242 | int i; | |||
4243 | isl_setisl_map *set1, *set2; | |||
4244 | int subset; | |||
4245 | ||||
4246 | if (test_subset_duplicate_integer_divisions(ctx) < 0) | |||
4247 | return -1; | |||
4248 | ||||
4249 | for (i = 0; i < ARRAY_SIZE(subset_tests)(sizeof(subset_tests)/sizeof(*subset_tests)); ++i) { | |||
4250 | set1 = isl_set_read_from_str(ctx, subset_tests[i].set1); | |||
4251 | set2 = isl_set_read_from_str(ctx, subset_tests[i].set2); | |||
4252 | subset = isl_set_is_subset(set1, set2); | |||
4253 | isl_set_free(set1); | |||
4254 | isl_set_free(set2); | |||
4255 | if (subset < 0) | |||
4256 | return -1; | |||
4257 | if (subset != subset_tests[i].subset) | |||
4258 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "incorrect subset result" , "polly/lib/External/isl/isl_test.c", 4259); return -1; } while (0) | |||
4259 | "incorrect subset result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "incorrect subset result" , "polly/lib/External/isl/isl_test.c", 4259); return -1; } while (0); | |||
4260 | } | |||
4261 | ||||
4262 | return 0; | |||
4263 | } | |||
4264 | ||||
4265 | /* Perform a set subtraction with a set that has a non-obviously empty disjunct. | |||
4266 | * Older versions of isl would fail on such cases. | |||
4267 | */ | |||
4268 | static isl_stat test_subtract_empty(isl_ctx *ctx) | |||
4269 | { | |||
4270 | const char *str; | |||
4271 | isl_setisl_map *s1, *s2; | |||
4272 | ||||
4273 | s1 = isl_set_read_from_str(ctx, "{ [0] }"); | |||
4274 | str = "{ [a] : (exists (e0, e1, e2: 1056e1 <= 32 + a - 33e0 and " | |||
4275 | "1089e1 >= a - 33e0 and 1089e1 <= 1 + a - 33e0 and " | |||
4276 | "33e2 >= -a + 33e0 + 1056e1 and " | |||
4277 | "33e2 < -2a + 66e0 + 2112e1)) or a = 0 }"; | |||
4278 | s2 = isl_set_read_from_str(ctx, str); | |||
4279 | s1 = isl_set_subtract(s1, s2); | |||
4280 | isl_set_free(s1); | |||
4281 | ||||
4282 | return isl_stat_non_null(s1); | |||
4283 | } | |||
4284 | ||||
4285 | struct { | |||
4286 | const char *minuend; | |||
4287 | const char *subtrahend; | |||
4288 | const char *difference; | |||
4289 | } subtract_domain_tests[] = { | |||
4290 | { "{ A[i] -> B[i] }", "{ A[i] }", "{ }" }, | |||
4291 | { "{ A[i] -> B[i] }", "{ B[i] }", "{ A[i] -> B[i] }" }, | |||
4292 | { "{ A[i] -> B[i] }", "{ A[i] : i > 0 }", "{ A[i] -> B[i] : i <= 0 }" }, | |||
4293 | }; | |||
4294 | ||||
4295 | static int test_subtract(isl_ctx *ctx) | |||
4296 | { | |||
4297 | int i; | |||
4298 | isl_union_map *umap1, *umap2; | |||
4299 | isl_union_pw_multi_aff *upma1, *upma2; | |||
4300 | isl_union_set *uset; | |||
4301 | int equal; | |||
4302 | ||||
4303 | if (test_subtract_empty(ctx) < 0) | |||
4304 | return -1; | |||
4305 | ||||
4306 | for (i = 0; i < ARRAY_SIZE(subtract_domain_tests)(sizeof(subtract_domain_tests)/sizeof(*subtract_domain_tests) ); ++i) { | |||
4307 | umap1 = isl_union_map_read_from_str(ctx, | |||
4308 | subtract_domain_tests[i].minuend); | |||
4309 | uset = isl_union_set_read_from_str(ctx, | |||
4310 | subtract_domain_tests[i].subtrahend); | |||
4311 | umap2 = isl_union_map_read_from_str(ctx, | |||
4312 | subtract_domain_tests[i].difference); | |||
4313 | umap1 = isl_union_map_subtract_domain(umap1, uset); | |||
4314 | equal = isl_union_map_is_equal(umap1, umap2); | |||
4315 | isl_union_map_free(umap1); | |||
4316 | isl_union_map_free(umap2); | |||
4317 | if (equal < 0) | |||
4318 | return -1; | |||
4319 | if (!equal) | |||
4320 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "incorrect subtract domain result" , "polly/lib/External/isl/isl_test.c", 4321); return -1; } while (0) | |||
4321 | "incorrect subtract domain result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "incorrect subtract domain result" , "polly/lib/External/isl/isl_test.c", 4321); return -1; } while (0); | |||
4322 | } | |||
4323 | ||||
4324 | for (i = 0; i < ARRAY_SIZE(subtract_domain_tests)(sizeof(subtract_domain_tests)/sizeof(*subtract_domain_tests) ); ++i) { | |||
4325 | upma1 = isl_union_pw_multi_aff_read_from_str(ctx, | |||
4326 | subtract_domain_tests[i].minuend); | |||
4327 | uset = isl_union_set_read_from_str(ctx, | |||
4328 | subtract_domain_tests[i].subtrahend); | |||
4329 | upma2 = isl_union_pw_multi_aff_read_from_str(ctx, | |||
4330 | subtract_domain_tests[i].difference); | |||
4331 | upma1 = isl_union_pw_multi_aff_subtract_domain(upma1, uset); | |||
4332 | equal = isl_union_pw_multi_aff_plain_is_equal(upma1, upma2); | |||
4333 | isl_union_pw_multi_aff_free(upma1); | |||
4334 | isl_union_pw_multi_aff_free(upma2); | |||
4335 | if (equal < 0) | |||
4336 | return -1; | |||
4337 | if (!equal) | |||
4338 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "incorrect subtract domain result" , "polly/lib/External/isl/isl_test.c", 4339); return -1; } while (0) | |||
4339 | "incorrect subtract domain result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "incorrect subtract domain result" , "polly/lib/External/isl/isl_test.c", 4339); return -1; } while (0); | |||
4340 | } | |||
4341 | ||||
4342 | return 0; | |||
4343 | } | |||
4344 | ||||
4345 | /* Check that intersecting the empty basic set with another basic set | |||
4346 | * does not increase the number of constraints. In particular, | |||
4347 | * the empty basic set should maintain its canonical representation. | |||
4348 | */ | |||
4349 | static int test_intersect_1(isl_ctx *ctx) | |||
4350 | { | |||
4351 | isl_size n1, n2; | |||
4352 | isl_basic_setisl_basic_map *bset1, *bset2; | |||
4353 | ||||
4354 | bset1 = isl_basic_set_read_from_str(ctx, "{ [a,b,c] : 1 = 0 }"); | |||
4355 | bset2 = isl_basic_set_read_from_str(ctx, "{ [1,2,3] }"); | |||
4356 | n1 = isl_basic_set_n_constraint(bset1); | |||
4357 | bset1 = isl_basic_set_intersect(bset1, bset2); | |||
4358 | n2 = isl_basic_set_n_constraint(bset1); | |||
4359 | isl_basic_set_free(bset1); | |||
4360 | if (n1 < 0 || n2 < 0) | |||
4361 | return -1; | |||
4362 | if (n1 != n2) | |||
4363 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "number of constraints of empty set changed" , "polly/lib/External/isl/isl_test.c", 4365); return -1; } while (0) | |||
4364 | "number of constraints of empty set changed",do { isl_handle_error(ctx, isl_error_unknown, "number of constraints of empty set changed" , "polly/lib/External/isl/isl_test.c", 4365); return -1; } while (0) | |||
4365 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "number of constraints of empty set changed" , "polly/lib/External/isl/isl_test.c", 4365); return -1; } while (0); | |||
4366 | ||||
4367 | return 0; | |||
4368 | } | |||
4369 | ||||
4370 | /* Check that intersecting a set with itself does not cause | |||
4371 | * an explosion in the number of disjuncts. | |||
4372 | */ | |||
4373 | static isl_stat test_intersect_2(isl_ctx *ctx) | |||
4374 | { | |||
4375 | int i; | |||
4376 | isl_setisl_map *set; | |||
4377 | ||||
4378 | set = isl_set_read_from_str(ctx, "{ [x,y] : x >= 0 or y >= 0 }"); | |||
4379 | for (i = 0; i < 100; ++i) | |||
4380 | set = isl_set_intersect(set, isl_set_copy(set)); | |||
4381 | isl_set_free(set); | |||
4382 | if (!set) | |||
4383 | return isl_stat_error; | |||
4384 | return isl_stat_ok; | |||
4385 | } | |||
4386 | ||||
4387 | /* Perform some intersection tests. | |||
4388 | */ | |||
4389 | static int test_intersect(isl_ctx *ctx) | |||
4390 | { | |||
4391 | if (test_intersect_1(ctx) < 0) | |||
4392 | return -1; | |||
4393 | if (test_intersect_2(ctx) < 0) | |||
4394 | return -1; | |||
4395 | ||||
4396 | return 0; | |||
4397 | } | |||
4398 | ||||
4399 | int test_factorize(isl_ctx *ctx) | |||
4400 | { | |||
4401 | const char *str; | |||
4402 | isl_basic_setisl_basic_map *bset; | |||
4403 | isl_factorizer *f; | |||
4404 | ||||
4405 | str = "{ [i0, i1, i2, i3, i4, i5, i6, i7] : 3i5 <= 2 - 2i0 and " | |||
4406 | "i0 >= -2 and i6 >= 1 + i3 and i7 >= 0 and 3i5 >= -2i0 and " | |||
4407 | "2i4 <= i2 and i6 >= 1 + 2i0 + 3i1 and i4 <= -1 and " | |||
4408 | "i6 >= 1 + 2i0 + 3i5 and i6 <= 2 + 2i0 + 3i5 and " | |||
4409 | "3i5 <= 2 - 2i0 - i2 + 3i4 and i6 <= 2 + 2i0 + 3i1 and " | |||
4410 | "i0 <= -1 and i7 <= i2 + i3 - 3i4 - i6 and " | |||
4411 | "3i5 >= -2i0 - i2 + 3i4 }"; | |||
4412 | bset = isl_basic_set_read_from_str(ctx, str); | |||
4413 | f = isl_basic_set_factorizer(bset); | |||
4414 | isl_basic_set_free(bset); | |||
4415 | isl_factorizer_free(f); | |||
4416 | if (!f) | |||
4417 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "failed to construct factorizer" , "polly/lib/External/isl/isl_test.c", 4418); return -1; } while (0) | |||
4418 | "failed to construct factorizer", return -1)do { isl_handle_error(ctx, isl_error_unknown, "failed to construct factorizer" , "polly/lib/External/isl/isl_test.c", 4418); return -1; } while (0); | |||
4419 | ||||
4420 | str = "{ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12] : " | |||
4421 | "i12 <= 2 + i0 - i11 and 2i8 >= -i4 and i11 >= i1 and " | |||
4422 | "3i5 <= -i2 and 2i11 >= -i4 - 2i7 and i11 <= 3 + i0 + 3i9 and " | |||
4423 | "i11 <= -i4 - 2i7 and i12 >= -i10 and i2 >= -2 and " | |||
4424 | "i11 >= i1 + 3i10 and i11 >= 1 + i0 + 3i9 and " | |||
4425 | "i11 <= 1 - i4 - 2i8 and 6i6 <= 6 - i2 and 3i6 >= 1 - i2 and " | |||
4426 | "i11 <= 2 + i1 and i12 <= i4 + i11 and i12 >= i0 - i11 and " | |||
4427 | "3i5 >= -2 - i2 and i12 >= -1 + i4 + i11 and 3i3 <= 3 - i2 and " | |||
4428 | "9i6 <= 11 - i2 + 6i5 and 3i3 >= 1 - i2 and " | |||
4429 | "9i6 <= 5 - i2 + 6i3 and i12 <= -1 and i2 <= 0 }"; | |||
4430 | bset = isl_basic_set_read_from_str(ctx, str); | |||
4431 | f = isl_basic_set_factorizer(bset); | |||
4432 | isl_basic_set_free(bset); | |||
4433 | isl_factorizer_free(f); | |||
4434 | if (!f) | |||
4435 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "failed to construct factorizer" , "polly/lib/External/isl/isl_test.c", 4436); return -1; } while (0) | |||
4436 | "failed to construct factorizer", return -1)do { isl_handle_error(ctx, isl_error_unknown, "failed to construct factorizer" , "polly/lib/External/isl/isl_test.c", 4436); return -1; } while (0); | |||
4437 | ||||
4438 | return 0; | |||
4439 | } | |||
4440 | ||||
4441 | static isl_stat check_injective(__isl_take isl_map *map, void *user) | |||
4442 | { | |||
4443 | int *injective = user; | |||
4444 | ||||
4445 | *injective = isl_map_is_injective(map); | |||
4446 | isl_map_free(map); | |||
4447 | ||||
4448 | if (*injective < 0 || !*injective) | |||
4449 | return isl_stat_error; | |||
4450 | ||||
4451 | return isl_stat_ok; | |||
4452 | } | |||
4453 | ||||
4454 | int test_one_schedule(isl_ctx *ctx, const char *d, const char *w, | |||
4455 | const char *r, const char *s, int tilable, int parallel) | |||
4456 | { | |||
4457 | int i; | |||
4458 | isl_union_set *D; | |||
4459 | isl_union_map *W, *R, *S; | |||
4460 | isl_union_map *empty; | |||
4461 | isl_union_map *dep_raw, *dep_war, *dep_waw, *dep; | |||
4462 | isl_union_map *validity, *proximity, *coincidence; | |||
4463 | isl_union_map *schedule; | |||
4464 | isl_union_map *test; | |||
4465 | isl_union_set *delta; | |||
4466 | isl_union_set *domain; | |||
4467 | isl_setisl_map *delta_set; | |||
4468 | isl_setisl_map *slice; | |||
4469 | isl_setisl_map *origin; | |||
4470 | isl_schedule_constraints *sc; | |||
4471 | isl_schedule *sched; | |||
4472 | int is_nonneg, is_parallel, is_tilable, is_injection, is_complete; | |||
4473 | isl_size n; | |||
4474 | ||||
4475 | D = isl_union_set_read_from_str(ctx, d); | |||
4476 | W = isl_union_map_read_from_str(ctx, w); | |||
4477 | R = isl_union_map_read_from_str(ctx, r); | |||
4478 | S = isl_union_map_read_from_str(ctx, s); | |||
4479 | ||||
4480 | W = isl_union_map_intersect_domain(W, isl_union_set_copy(D)); | |||
4481 | R = isl_union_map_intersect_domain(R, isl_union_set_copy(D)); | |||
4482 | ||||
4483 | empty = isl_union_map_empty(isl_union_map_get_space(S)); | |||
4484 | isl_union_map_compute_flow(isl_union_map_copy(R), | |||
4485 | isl_union_map_copy(W), empty, | |||
4486 | isl_union_map_copy(S), | |||
4487 | &dep_raw, NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
4488 | isl_union_map_compute_flow(isl_union_map_copy(W), | |||
4489 | isl_union_map_copy(W), | |||
4490 | isl_union_map_copy(R), | |||
4491 | isl_union_map_copy(S), | |||
4492 | &dep_waw, &dep_war, NULL((void*)0), NULL((void*)0)); | |||
4493 | ||||
4494 | dep = isl_union_map_union(dep_waw, dep_war); | |||
4495 | dep = isl_union_map_union(dep, dep_raw); | |||
4496 | validity = isl_union_map_copy(dep); | |||
4497 | coincidence = isl_union_map_copy(dep); | |||
4498 | proximity = isl_union_map_copy(dep); | |||
4499 | ||||
4500 | sc = isl_schedule_constraints_on_domain(isl_union_set_copy(D)); | |||
4501 | sc = isl_schedule_constraints_set_validity(sc, validity); | |||
4502 | sc = isl_schedule_constraints_set_coincidence(sc, coincidence); | |||
4503 | sc = isl_schedule_constraints_set_proximity(sc, proximity); | |||
4504 | sched = isl_schedule_constraints_compute_schedule(sc); | |||
4505 | schedule = isl_schedule_get_map(sched); | |||
4506 | isl_schedule_free(sched); | |||
4507 | isl_union_map_free(W); | |||
4508 | isl_union_map_free(R); | |||
4509 | isl_union_map_free(S); | |||
4510 | ||||
4511 | is_injection = 1; | |||
4512 | isl_union_map_foreach_map(schedule, &check_injective, &is_injection); | |||
4513 | ||||
4514 | domain = isl_union_map_domain(isl_union_map_copy(schedule)); | |||
4515 | is_complete = isl_union_set_is_subset(D, domain); | |||
4516 | isl_union_set_free(D); | |||
4517 | isl_union_set_free(domain); | |||
4518 | ||||
4519 | test = isl_union_map_reverse(isl_union_map_copy(schedule)); | |||
4520 | test = isl_union_map_apply_range(test, dep); | |||
4521 | test = isl_union_map_apply_range(test, schedule); | |||
4522 | ||||
4523 | delta = isl_union_map_deltas(test); | |||
4524 | n = isl_union_set_n_set(delta); | |||
4525 | if (n < 0) { | |||
4526 | isl_union_set_free(delta); | |||
4527 | return -1; | |||
4528 | } | |||
4529 | if (n == 0) { | |||
4530 | is_tilable = 1; | |||
4531 | is_parallel = 1; | |||
4532 | is_nonneg = 1; | |||
4533 | isl_union_set_free(delta); | |||
4534 | } else { | |||
4535 | isl_size dim; | |||
4536 | ||||
4537 | delta_set = isl_set_from_union_set(delta); | |||
4538 | ||||
4539 | slice = isl_set_universe(isl_set_get_space(delta_set)); | |||
4540 | for (i = 0; i < tilable; ++i) | |||
4541 | slice = isl_set_lower_bound_si(slice, isl_dim_set, i, 0); | |||
4542 | is_tilable = isl_set_is_subset(delta_set, slice); | |||
4543 | isl_set_free(slice); | |||
4544 | ||||
4545 | slice = isl_set_universe(isl_set_get_space(delta_set)); | |||
4546 | for (i = 0; i < parallel; ++i) | |||
4547 | slice = isl_set_fix_si(slice, isl_dim_set, i, 0); | |||
4548 | is_parallel = isl_set_is_subset(delta_set, slice); | |||
4549 | isl_set_free(slice); | |||
4550 | ||||
4551 | origin = isl_set_universe(isl_set_get_space(delta_set)); | |||
4552 | dim = isl_set_dim(origin, isl_dim_set); | |||
4553 | if (dim < 0) | |||
4554 | origin = isl_set_free(origin); | |||
4555 | for (i = 0; i < dim; ++i) | |||
4556 | origin = isl_set_fix_si(origin, isl_dim_set, i, 0); | |||
4557 | ||||
4558 | delta_set = isl_set_union(delta_set, isl_set_copy(origin)); | |||
4559 | delta_set = isl_set_lexmin(delta_set); | |||
4560 | ||||
4561 | is_nonneg = isl_set_is_equal(delta_set, origin); | |||
4562 | ||||
4563 | isl_set_free(origin); | |||
4564 | isl_set_free(delta_set); | |||
4565 | } | |||
4566 | ||||
4567 | if (is_nonneg < 0 || is_parallel < 0 || is_tilable < 0 || | |||
4568 | is_injection < 0 || is_complete < 0) | |||
4569 | return -1; | |||
4570 | if (!is_complete) | |||
4571 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "generated schedule incomplete" , "polly/lib/External/isl/isl_test.c", 4572); return -1; } while (0) | |||
4572 | "generated schedule incomplete", return -1)do { isl_handle_error(ctx, isl_error_unknown, "generated schedule incomplete" , "polly/lib/External/isl/isl_test.c", 4572); return -1; } while (0); | |||
4573 | if (!is_injection) | |||
4574 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "generated schedule not injective on each statement" , "polly/lib/External/isl/isl_test.c", 4576); return -1; } while (0) | |||
4575 | "generated schedule not injective on each statement",do { isl_handle_error(ctx, isl_error_unknown, "generated schedule not injective on each statement" , "polly/lib/External/isl/isl_test.c", 4576); return -1; } while (0) | |||
4576 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "generated schedule not injective on each statement" , "polly/lib/External/isl/isl_test.c", 4576); return -1; } while (0); | |||
4577 | if (!is_nonneg) | |||
4578 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "negative dependences in generated schedule" , "polly/lib/External/isl/isl_test.c", 4580); return -1; } while (0) | |||
4579 | "negative dependences in generated schedule",do { isl_handle_error(ctx, isl_error_unknown, "negative dependences in generated schedule" , "polly/lib/External/isl/isl_test.c", 4580); return -1; } while (0) | |||
4580 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "negative dependences in generated schedule" , "polly/lib/External/isl/isl_test.c", 4580); return -1; } while (0); | |||
4581 | if (!is_tilable) | |||
4582 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "generated schedule not as tilable as expected" , "polly/lib/External/isl/isl_test.c", 4584); return -1; } while (0) | |||
4583 | "generated schedule not as tilable as expected",do { isl_handle_error(ctx, isl_error_unknown, "generated schedule not as tilable as expected" , "polly/lib/External/isl/isl_test.c", 4584); return -1; } while (0) | |||
4584 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "generated schedule not as tilable as expected" , "polly/lib/External/isl/isl_test.c", 4584); return -1; } while (0); | |||
4585 | if (!is_parallel) | |||
4586 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "generated schedule not as parallel as expected" , "polly/lib/External/isl/isl_test.c", 4588); return -1; } while (0) | |||
4587 | "generated schedule not as parallel as expected",do { isl_handle_error(ctx, isl_error_unknown, "generated schedule not as parallel as expected" , "polly/lib/External/isl/isl_test.c", 4588); return -1; } while (0) | |||
4588 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "generated schedule not as parallel as expected" , "polly/lib/External/isl/isl_test.c", 4588); return -1; } while (0); | |||
4589 | ||||
4590 | return 0; | |||
4591 | } | |||
4592 | ||||
4593 | /* Compute a schedule for the given instance set, validity constraints, | |||
4594 | * proximity constraints and context and return a corresponding union map | |||
4595 | * representation. | |||
4596 | */ | |||
4597 | static __isl_give isl_union_map *compute_schedule_with_context(isl_ctx *ctx, | |||
4598 | const char *domain, const char *validity, const char *proximity, | |||
4599 | const char *context) | |||
4600 | { | |||
4601 | isl_setisl_map *con; | |||
4602 | isl_union_set *dom; | |||
4603 | isl_union_map *dep; | |||
4604 | isl_union_map *prox; | |||
4605 | isl_schedule_constraints *sc; | |||
4606 | isl_schedule *schedule; | |||
4607 | isl_union_map *sched; | |||
4608 | ||||
4609 | con = isl_set_read_from_str(ctx, context); | |||
4610 | dom = isl_union_set_read_from_str(ctx, domain); | |||
4611 | dep = isl_union_map_read_from_str(ctx, validity); | |||
4612 | prox = isl_union_map_read_from_str(ctx, proximity); | |||
4613 | sc = isl_schedule_constraints_on_domain(dom); | |||
4614 | sc = isl_schedule_constraints_set_context(sc, con); | |||
4615 | sc = isl_schedule_constraints_set_validity(sc, dep); | |||
4616 | sc = isl_schedule_constraints_set_proximity(sc, prox); | |||
4617 | schedule = isl_schedule_constraints_compute_schedule(sc); | |||
4618 | sched = isl_schedule_get_map(schedule); | |||
4619 | isl_schedule_free(schedule); | |||
4620 | ||||
4621 | return sched; | |||
4622 | } | |||
4623 | ||||
4624 | /* Compute a schedule for the given instance set, validity constraints and | |||
4625 | * proximity constraints and return a corresponding union map representation. | |||
4626 | */ | |||
4627 | static __isl_give isl_union_map *compute_schedule(isl_ctx *ctx, | |||
4628 | const char *domain, const char *validity, const char *proximity) | |||
4629 | { | |||
4630 | return compute_schedule_with_context(ctx, domain, validity, proximity, | |||
4631 | "{ : }"); | |||
4632 | } | |||
4633 | ||||
4634 | /* Check that a schedule can be constructed on the given domain | |||
4635 | * with the given validity and proximity constraints. | |||
4636 | */ | |||
4637 | static int test_has_schedule(isl_ctx *ctx, const char *domain, | |||
4638 | const char *validity, const char *proximity) | |||
4639 | { | |||
4640 | isl_union_map *sched; | |||
4641 | ||||
4642 | sched = compute_schedule(ctx, domain, validity, proximity); | |||
4643 | if (!sched) | |||
4644 | return -1; | |||
4645 | ||||
4646 | isl_union_map_free(sched); | |||
4647 | return 0; | |||
4648 | } | |||
4649 | ||||
4650 | int test_special_schedule(isl_ctx *ctx, const char *domain, | |||
4651 | const char *validity, const char *proximity, const char *expected_sched) | |||
4652 | { | |||
4653 | isl_union_map *sched1, *sched2; | |||
4654 | int equal; | |||
4655 | ||||
4656 | sched1 = compute_schedule(ctx, domain, validity, proximity); | |||
4657 | sched2 = isl_union_map_read_from_str(ctx, expected_sched); | |||
4658 | ||||
4659 | equal = isl_union_map_is_equal(sched1, sched2); | |||
4660 | isl_union_map_free(sched1); | |||
4661 | isl_union_map_free(sched2); | |||
4662 | ||||
4663 | if (equal < 0) | |||
4664 | return -1; | |||
4665 | if (!equal) | |||
4666 | isl_die(ctx, isl_error_unknown, "unexpected schedule",do { isl_handle_error(ctx, isl_error_unknown, "unexpected schedule" , "polly/lib/External/isl/isl_test.c", 4667); return -1; } while (0) | |||
4667 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected schedule" , "polly/lib/External/isl/isl_test.c", 4667); return -1; } while (0); | |||
4668 | ||||
4669 | return 0; | |||
4670 | } | |||
4671 | ||||
4672 | /* Check that the schedule map is properly padded, i.e., that the range | |||
4673 | * lives in a single space. | |||
4674 | */ | |||
4675 | static int test_padded_schedule(isl_ctx *ctx) | |||
4676 | { | |||
4677 | const char *str; | |||
4678 | isl_union_set *D; | |||
4679 | isl_union_map *validity, *proximity; | |||
4680 | isl_schedule_constraints *sc; | |||
4681 | isl_schedule *sched; | |||
4682 | isl_union_map *umap; | |||
4683 | isl_union_set *range; | |||
4684 | isl_setisl_map *set; | |||
4685 | ||||
4686 | str = "[N] -> { S0[i] : 0 <= i <= N; S1[i, j] : 0 <= i, j <= N }"; | |||
4687 | D = isl_union_set_read_from_str(ctx, str); | |||
4688 | validity = isl_union_map_empty(isl_union_set_get_space(D)); | |||
4689 | proximity = isl_union_map_copy(validity); | |||
4690 | sc = isl_schedule_constraints_on_domain(D); | |||
4691 | sc = isl_schedule_constraints_set_validity(sc, validity); | |||
4692 | sc = isl_schedule_constraints_set_proximity(sc, proximity); | |||
4693 | sched = isl_schedule_constraints_compute_schedule(sc); | |||
4694 | umap = isl_schedule_get_map(sched); | |||
4695 | isl_schedule_free(sched); | |||
4696 | range = isl_union_map_range(umap); | |||
4697 | set = isl_set_from_union_set(range); | |||
4698 | isl_set_free(set); | |||
4699 | ||||
4700 | if (!set) | |||
4701 | return -1; | |||
4702 | ||||
4703 | return 0; | |||
4704 | } | |||
4705 | ||||
4706 | /* Check that conditional validity constraints are also taken into | |||
4707 | * account across bands. | |||
4708 | * In particular, try to make sure that live ranges D[1,0]->C[2,1] and | |||
4709 | * D[2,0]->C[3,0] are not local in the outer band of the generated schedule | |||
4710 | * and then check that the adjacent order constraint C[2,1]->D[2,0] | |||
4711 | * is enforced by the rest of the schedule. | |||
4712 | */ | |||
4713 | static int test_special_conditional_schedule_constraints(isl_ctx *ctx) | |||
4714 | { | |||
4715 | const char *str; | |||
4716 | isl_union_set *domain; | |||
4717 | isl_union_map *validity, *proximity, *condition; | |||
4718 | isl_union_map *sink, *source, *dep; | |||
4719 | isl_schedule_constraints *sc; | |||
4720 | isl_schedule *schedule; | |||
4721 | isl_union_access_info *access; | |||
4722 | isl_union_flow *flow; | |||
4723 | int empty; | |||
4724 | ||||
4725 | str = "[n] -> { C[k, i] : k <= -1 + n and i >= 0 and i <= -1 + k; " | |||
4726 | "A[k] : k >= 1 and k <= -1 + n; " | |||
4727 | "B[k, i] : k <= -1 + n and i >= 0 and i <= -1 + k; " | |||
4728 | "D[k, i] : k <= -1 + n and i >= 0 and i <= -1 + k }"; | |||
4729 | domain = isl_union_set_read_from_str(ctx, str); | |||
4730 | sc = isl_schedule_constraints_on_domain(domain); | |||
4731 | str = "[n] -> { D[k, i] -> C[1 + k, k - i] : " | |||
4732 | "k <= -2 + n and i >= 1 and i <= -1 + k; " | |||
4733 | "D[k, i] -> C[1 + k, i] : " | |||
4734 | "k <= -2 + n and i >= 1 and i <= -1 + k; " | |||
4735 | "D[k, 0] -> C[1 + k, k] : k >= 1 and k <= -2 + n; " | |||
4736 | "D[k, 0] -> C[1 + k, 0] : k >= 1 and k <= -2 + n }"; | |||
4737 | validity = isl_union_map_read_from_str(ctx, str); | |||
4738 | sc = isl_schedule_constraints_set_validity(sc, validity); | |||
4739 | str = "[n] -> { C[k, i] -> D[k, i] : " | |||
4740 | "0 <= i <= -1 + k and k <= -1 + n }"; | |||
4741 | proximity = isl_union_map_read_from_str(ctx, str); | |||
4742 | sc = isl_schedule_constraints_set_proximity(sc, proximity); | |||
4743 | str = "[n] -> { [D[k, i] -> a[]] -> [C[1 + k, k - i] -> b[]] : " | |||
4744 | "i <= -1 + k and i >= 1 and k <= -2 + n; " | |||
4745 | "[B[k, i] -> c[]] -> [B[k, 1 + i] -> c[]] : " | |||
4746 | "k <= -1 + n and i >= 0 and i <= -2 + k }"; | |||
4747 | condition = isl_union_map_read_from_str(ctx, str); | |||
4748 | str = "[n] -> { [B[k, i] -> e[]] -> [D[k, i] -> a[]] : " | |||
4749 | "i >= 0 and i <= -1 + k and k <= -1 + n; " | |||
4750 | "[C[k, i] -> b[]] -> [D[k', -1 + k - i] -> a[]] : " | |||
4751 | "i >= 0 and i <= -1 + k and k <= -1 + n and " | |||
4752 | "k' <= -1 + n and k' >= k - i and k' >= 1 + k; " | |||
4753 | "[C[k, i] -> b[]] -> [D[k, -1 + k - i] -> a[]] : " | |||
4754 | "i >= 0 and i <= -1 + k and k <= -1 + n; " | |||
4755 | "[B[k, i] -> c[]] -> [A[k'] -> d[]] : " | |||
4756 | "k <= -1 + n and i >= 0 and i <= -1 + k and " | |||
4757 | "k' >= 1 and k' <= -1 + n and k' >= 1 + k }"; | |||
4758 | validity = isl_union_map_read_from_str(ctx, str); | |||
4759 | sc = isl_schedule_constraints_set_conditional_validity(sc, condition, | |||
4760 | validity); | |||
4761 | schedule = isl_schedule_constraints_compute_schedule(sc); | |||
4762 | str = "{ D[2,0] -> [] }"; | |||
4763 | sink = isl_union_map_read_from_str(ctx, str); | |||
4764 | access = isl_union_access_info_from_sink(sink); | |||
4765 | str = "{ C[2,1] -> [] }"; | |||
4766 | source = isl_union_map_read_from_str(ctx, str); | |||
4767 | access = isl_union_access_info_set_must_source(access, source); | |||
4768 | access = isl_union_access_info_set_schedule(access, schedule); | |||
4769 | flow = isl_union_access_info_compute_flow(access); | |||
4770 | dep = isl_union_flow_get_must_dependence(flow); | |||
4771 | isl_union_flow_free(flow); | |||
4772 | empty = isl_union_map_is_empty(dep); | |||
4773 | isl_union_map_free(dep); | |||
4774 | ||||
4775 | if (empty < 0) | |||
4776 | return -1; | |||
4777 | if (empty) | |||
4778 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "conditional validity not respected" , "polly/lib/External/isl/isl_test.c", 4779); return -1; } while (0) | |||
4779 | "conditional validity not respected", return -1)do { isl_handle_error(ctx, isl_error_unknown, "conditional validity not respected" , "polly/lib/External/isl/isl_test.c", 4779); return -1; } while (0); | |||
4780 | ||||
4781 | return 0; | |||
4782 | } | |||
4783 | ||||
4784 | /* Check that the test for violated conditional validity constraints | |||
4785 | * is not confused by domain compression. | |||
4786 | * In particular, earlier versions of isl would apply | |||
4787 | * a schedule on the compressed domains to the original domains, | |||
4788 | * resulting in a failure to detect that the default schedule | |||
4789 | * violates the conditional validity constraints. | |||
4790 | */ | |||
4791 | static int test_special_conditional_schedule_constraints_2(isl_ctx *ctx) | |||
4792 | { | |||
4793 | const char *str; | |||
4794 | isl_bool empty; | |||
4795 | isl_union_set *domain; | |||
4796 | isl_union_map *validity, *condition; | |||
4797 | isl_schedule_constraints *sc; | |||
4798 | isl_schedule *schedule; | |||
4799 | isl_union_map *umap; | |||
4800 | isl_map *map, *ge; | |||
4801 | ||||
4802 | str = "{ A[0, i] : 0 <= i <= 10; B[1, i] : 0 <= i <= 10 }"; | |||
4803 | domain = isl_union_set_read_from_str(ctx, str); | |||
4804 | sc = isl_schedule_constraints_on_domain(domain); | |||
4805 | str = "{ B[1, i] -> A[0, i + 1] }"; | |||
4806 | condition = isl_union_map_read_from_str(ctx, str); | |||
4807 | str = "{ A[0, i] -> B[1, i - 1] }"; | |||
4808 | validity = isl_union_map_read_from_str(ctx, str); | |||
4809 | sc = isl_schedule_constraints_set_conditional_validity(sc, condition, | |||
4810 | isl_union_map_copy(validity)); | |||
4811 | schedule = isl_schedule_constraints_compute_schedule(sc); | |||
4812 | umap = isl_schedule_get_map(schedule); | |||
4813 | isl_schedule_free(schedule); | |||
4814 | validity = isl_union_map_apply_domain(validity, | |||
4815 | isl_union_map_copy(umap)); | |||
4816 | validity = isl_union_map_apply_range(validity, umap); | |||
4817 | map = isl_map_from_union_map(validity); | |||
4818 | ge = isl_map_lex_ge(isl_space_domain(isl_map_get_space(map))); | |||
4819 | map = isl_map_intersect(map, ge); | |||
4820 | empty = isl_map_is_empty(map); | |||
4821 | isl_map_free(map); | |||
4822 | ||||
4823 | if (empty < 0) | |||
4824 | return -1; | |||
4825 | if (!empty) | |||
4826 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "conditional validity constraints not satisfied" , "polly/lib/External/isl/isl_test.c", 4828); return -1; } while (0) | |||
4827 | "conditional validity constraints not satisfied",do { isl_handle_error(ctx, isl_error_unknown, "conditional validity constraints not satisfied" , "polly/lib/External/isl/isl_test.c", 4828); return -1; } while (0) | |||
4828 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "conditional validity constraints not satisfied" , "polly/lib/External/isl/isl_test.c", 4828); return -1; } while (0); | |||
4829 | ||||
4830 | return 0; | |||
4831 | } | |||
4832 | ||||
4833 | /* Input for testing of schedule construction based on | |||
4834 | * conditional constraints. | |||
4835 | * | |||
4836 | * domain is the iteration domain | |||
4837 | * flow are the flow dependences, which determine the validity and | |||
4838 | * proximity constraints | |||
4839 | * condition are the conditions on the conditional validity constraints | |||
4840 | * conditional_validity are the conditional validity constraints | |||
4841 | * outer_band_n is the expected number of members in the outer band | |||
4842 | */ | |||
4843 | struct { | |||
4844 | const char *domain; | |||
4845 | const char *flow; | |||
4846 | const char *condition; | |||
4847 | const char *conditional_validity; | |||
4848 | int outer_band_n; | |||
4849 | } live_range_tests[] = { | |||
4850 | /* Contrived example that illustrates that we need to keep | |||
4851 | * track of tagged condition dependences and | |||
4852 | * tagged conditional validity dependences | |||
4853 | * in isl_sched_edge separately. | |||
4854 | * In particular, the conditional validity constraints on A | |||
4855 | * cannot be satisfied, | |||
4856 | * but they can be ignored because there are no corresponding | |||
4857 | * condition constraints. However, we do have an additional | |||
4858 | * conditional validity constraint that maps to the same | |||
4859 | * dependence relation | |||
4860 | * as the condition constraint on B. If we did not make a distinction | |||
4861 | * between tagged condition and tagged conditional validity | |||
4862 | * dependences, then we | |||
4863 | * could end up treating this shared dependence as an condition | |||
4864 | * constraint on A, forcing a localization of the conditions, | |||
4865 | * which is impossible. | |||
4866 | */ | |||
4867 | { "{ S[i] : 0 <= 1 < 100; T[i] : 0 <= 1 < 100 }", | |||
4868 | "{ S[i] -> S[i+1] : 0 <= i < 99 }", | |||
4869 | "{ [S[i] -> B[]] -> [S[i+1] -> B[]] : 0 <= i < 99 }", | |||
4870 | "{ [S[i] -> A[]] -> [T[i'] -> A[]] : 0 <= i', i < 100 and i != i';" | |||
4871 | "[T[i] -> A[]] -> [S[i'] -> A[]] : 0 <= i', i < 100 and i != i';" | |||
4872 | "[S[i] -> A[]] -> [S[i+1] -> A[]] : 0 <= i < 99 }", | |||
4873 | 1 | |||
4874 | }, | |||
4875 | /* TACO 2013 Fig. 7 */ | |||
4876 | { "[n] -> { S1[i,j] : 0 <= i,j < n; S2[i,j] : 0 <= i,j < n }", | |||
4877 | "[n] -> { S1[i,j] -> S2[i,j] : 0 <= i,j < n;" | |||
4878 | "S2[i,j] -> S2[i,j+1] : 0 <= i < n and 0 <= j < n - 1 }", | |||
4879 | "[n] -> { [S1[i,j] -> t[]] -> [S2[i,j] -> t[]] : 0 <= i,j < n;" | |||
4880 | "[S2[i,j] -> x1[]] -> [S2[i,j+1] -> x1[]] : " | |||
4881 | "0 <= i < n and 0 <= j < n - 1 }", | |||
4882 | "[n] -> { [S2[i,j] -> t[]] -> [S1[i,j'] -> t[]] : " | |||
4883 | "0 <= i < n and 0 <= j < j' < n;" | |||
4884 | "[S2[i,j] -> t[]] -> [S1[i',j'] -> t[]] : " | |||
4885 | "0 <= i < i' < n and 0 <= j,j' < n;" | |||
4886 | "[S2[i,j] -> x1[]] -> [S2[i,j'] -> x1[]] : " | |||
4887 | "0 <= i,j,j' < n and j < j' }", | |||
4888 | 2 | |||
4889 | }, | |||
4890 | /* TACO 2013 Fig. 7, without tags */ | |||
4891 | { "[n] -> { S1[i,j] : 0 <= i,j < n; S2[i,j] : 0 <= i,j < n }", | |||
4892 | "[n] -> { S1[i,j] -> S2[i,j] : 0 <= i,j < n;" | |||
4893 | "S2[i,j] -> S2[i,j+1] : 0 <= i < n and 0 <= j < n - 1 }", | |||
4894 | "[n] -> { S1[i,j] -> S2[i,j] : 0 <= i,j < n;" | |||
4895 | "S2[i,j] -> S2[i,j+1] : 0 <= i < n and 0 <= j < n - 1 }", | |||
4896 | "[n] -> { S2[i,j] -> S1[i,j'] : 0 <= i < n and 0 <= j < j' < n;" | |||
4897 | "S2[i,j] -> S1[i',j'] : 0 <= i < i' < n and 0 <= j,j' < n;" | |||
4898 | "S2[i,j] -> S2[i,j'] : 0 <= i,j,j' < n and j < j' }", | |||
4899 | 1 | |||
4900 | }, | |||
4901 | /* TACO 2013 Fig. 12 */ | |||
4902 | { "{ S1[i,0] : 0 <= i <= 1; S2[i,j] : 0 <= i <= 1 and 1 <= j <= 2;" | |||
4903 | "S3[i,3] : 0 <= i <= 1 }", | |||
4904 | "{ S1[i,0] -> S2[i,1] : 0 <= i <= 1;" | |||
4905 | "S2[i,1] -> S2[i,2] : 0 <= i <= 1;" | |||
4906 | "S2[i,2] -> S3[i,3] : 0 <= i <= 1 }", | |||
4907 | "{ [S1[i,0]->t[]] -> [S2[i,1]->t[]] : 0 <= i <= 1;" | |||
4908 | "[S2[i,1]->t[]] -> [S2[i,2]->t[]] : 0 <= i <= 1;" | |||
4909 | "[S2[i,2]->t[]] -> [S3[i,3]->t[]] : 0 <= i <= 1 }", | |||
4910 | "{ [S2[i,1]->t[]] -> [S2[i,2]->t[]] : 0 <= i <= 1;" | |||
4911 | "[S2[0,j]->t[]] -> [S2[1,j']->t[]] : 1 <= j,j' <= 2;" | |||
4912 | "[S2[0,j]->t[]] -> [S1[1,0]->t[]] : 1 <= j <= 2;" | |||
4913 | "[S3[0,3]->t[]] -> [S2[1,j]->t[]] : 1 <= j <= 2;" | |||
4914 | "[S3[0,3]->t[]] -> [S1[1,0]->t[]] }", | |||
4915 | 1 | |||
4916 | } | |||
4917 | }; | |||
4918 | ||||
4919 | /* Test schedule construction based on conditional constraints. | |||
4920 | * In particular, check the number of members in the outer band node | |||
4921 | * as an indication of whether tiling is possible or not. | |||
4922 | */ | |||
4923 | static int test_conditional_schedule_constraints(isl_ctx *ctx) | |||
4924 | { | |||
4925 | int i; | |||
4926 | isl_union_set *domain; | |||
4927 | isl_union_map *condition; | |||
4928 | isl_union_map *flow; | |||
4929 | isl_union_map *validity; | |||
4930 | isl_schedule_constraints *sc; | |||
4931 | isl_schedule *schedule; | |||
4932 | isl_schedule_node *node; | |||
4933 | isl_size n_member; | |||
4934 | ||||
4935 | if (test_special_conditional_schedule_constraints(ctx) < 0) | |||
4936 | return -1; | |||
4937 | if (test_special_conditional_schedule_constraints_2(ctx) < 0) | |||
4938 | return -1; | |||
4939 | ||||
4940 | for (i = 0; i < ARRAY_SIZE(live_range_tests)(sizeof(live_range_tests)/sizeof(*live_range_tests)); ++i) { | |||
4941 | domain = isl_union_set_read_from_str(ctx, | |||
4942 | live_range_tests[i].domain); | |||
4943 | flow = isl_union_map_read_from_str(ctx, | |||
4944 | live_range_tests[i].flow); | |||
4945 | condition = isl_union_map_read_from_str(ctx, | |||
4946 | live_range_tests[i].condition); | |||
4947 | validity = isl_union_map_read_from_str(ctx, | |||
4948 | live_range_tests[i].conditional_validity); | |||
4949 | sc = isl_schedule_constraints_on_domain(domain); | |||
4950 | sc = isl_schedule_constraints_set_validity(sc, | |||
4951 | isl_union_map_copy(flow)); | |||
4952 | sc = isl_schedule_constraints_set_proximity(sc, flow); | |||
4953 | sc = isl_schedule_constraints_set_conditional_validity(sc, | |||
4954 | condition, validity); | |||
4955 | schedule = isl_schedule_constraints_compute_schedule(sc); | |||
4956 | node = isl_schedule_get_root(schedule); | |||
4957 | while (node && | |||
4958 | isl_schedule_node_get_type(node) != isl_schedule_node_band) | |||
4959 | node = isl_schedule_node_first_child(node); | |||
4960 | n_member = isl_schedule_node_band_n_member(node); | |||
4961 | isl_schedule_node_free(node); | |||
4962 | isl_schedule_free(schedule); | |||
4963 | ||||
4964 | if (!schedule || n_member < 0) | |||
4965 | return -1; | |||
4966 | if (n_member != live_range_tests[i].outer_band_n) | |||
4967 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of members in outer band" , "polly/lib/External/isl/isl_test.c", 4969); return -1; } while (0) | |||
4968 | "unexpected number of members in outer band",do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of members in outer band" , "polly/lib/External/isl/isl_test.c", 4969); return -1; } while (0) | |||
4969 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of members in outer band" , "polly/lib/External/isl/isl_test.c", 4969); return -1; } while (0); | |||
4970 | } | |||
4971 | return 0; | |||
4972 | } | |||
4973 | ||||
4974 | /* Check that the schedule computed for the given instance set and | |||
4975 | * dependence relation strongly satisfies the dependences. | |||
4976 | * In particular, check that no instance is scheduled before | |||
4977 | * or together with an instance on which it depends. | |||
4978 | * Earlier versions of isl would produce a schedule that | |||
4979 | * only weakly satisfies the dependences. | |||
4980 | */ | |||
4981 | static int test_strongly_satisfying_schedule(isl_ctx *ctx) | |||
4982 | { | |||
4983 | const char *domain, *dep; | |||
4984 | isl_union_map *D, *schedule; | |||
4985 | isl_map *map, *ge; | |||
4986 | int empty; | |||
4987 | ||||
4988 | domain = "{ B[i0, i1] : 0 <= i0 <= 1 and 0 <= i1 <= 11; " | |||
4989 | "A[i0] : 0 <= i0 <= 1 }"; | |||
4990 | dep = "{ B[i0, i1] -> B[i0, 1 + i1] : 0 <= i0 <= 1 and 0 <= i1 <= 10; " | |||
4991 | "B[0, 11] -> A[1]; A[i0] -> B[i0, 0] : 0 <= i0 <= 1 }"; | |||
4992 | schedule = compute_schedule(ctx, domain, dep, dep); | |||
4993 | D = isl_union_map_read_from_str(ctx, dep); | |||
4994 | D = isl_union_map_apply_domain(D, isl_union_map_copy(schedule)); | |||
4995 | D = isl_union_map_apply_range(D, schedule); | |||
4996 | map = isl_map_from_union_map(D); | |||
4997 | ge = isl_map_lex_ge(isl_space_domain(isl_map_get_space(map))); | |||
4998 | map = isl_map_intersect(map, ge); | |||
4999 | empty = isl_map_is_empty(map); | |||
5000 | isl_map_free(map); | |||
5001 | ||||
5002 | if (empty < 0) | |||
5003 | return -1; | |||
5004 | if (!empty) | |||
5005 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "dependences not strongly satisfied" , "polly/lib/External/isl/isl_test.c", 5006); return -1; } while (0) | |||
5006 | "dependences not strongly satisfied", return -1)do { isl_handle_error(ctx, isl_error_unknown, "dependences not strongly satisfied" , "polly/lib/External/isl/isl_test.c", 5006); return -1; } while (0); | |||
5007 | ||||
5008 | return 0; | |||
5009 | } | |||
5010 | ||||
5011 | /* Compute a schedule for input where the instance set constraints | |||
5012 | * conflict with the context constraints. | |||
5013 | * Earlier versions of isl did not properly handle this situation. | |||
5014 | */ | |||
5015 | static int test_conflicting_context_schedule(isl_ctx *ctx) | |||
5016 | { | |||
5017 | isl_union_map *schedule; | |||
5018 | const char *domain, *context; | |||
5019 | ||||
5020 | domain = "[n] -> { A[] : n >= 0 }"; | |||
5021 | context = "[n] -> { : n < 0 }"; | |||
5022 | schedule = compute_schedule_with_context(ctx, | |||
5023 | domain, "{}", "{}", context); | |||
5024 | isl_union_map_free(schedule); | |||
5025 | ||||
5026 | if (!schedule) | |||
5027 | return -1; | |||
5028 | ||||
5029 | return 0; | |||
5030 | } | |||
5031 | ||||
5032 | /* Check that a set of schedule constraints that only allow for | |||
5033 | * a coalescing schedule still produces a schedule even if the user | |||
5034 | * request a non-coalescing schedule. Earlier versions of isl | |||
5035 | * would not handle this case correctly. | |||
5036 | */ | |||
5037 | static int test_coalescing_schedule(isl_ctx *ctx) | |||
5038 | { | |||
5039 | const char *domain, *dep; | |||
5040 | isl_union_set *I; | |||
5041 | isl_union_map *D; | |||
5042 | isl_schedule_constraints *sc; | |||
5043 | isl_schedule *schedule; | |||
5044 | int treat_coalescing; | |||
5045 | ||||
5046 | domain = "{ S[a, b] : 0 <= a <= 1 and 0 <= b <= 1 }"; | |||
5047 | dep = "{ S[a, b] -> S[a + b, 1 - b] }"; | |||
5048 | I = isl_union_set_read_from_str(ctx, domain); | |||
5049 | D = isl_union_map_read_from_str(ctx, dep); | |||
5050 | sc = isl_schedule_constraints_on_domain(I); | |||
5051 | sc = isl_schedule_constraints_set_validity(sc, D); | |||
5052 | treat_coalescing = isl_options_get_schedule_treat_coalescing(ctx); | |||
5053 | isl_options_set_schedule_treat_coalescing(ctx, 1); | |||
5054 | schedule = isl_schedule_constraints_compute_schedule(sc); | |||
5055 | isl_options_set_schedule_treat_coalescing(ctx, treat_coalescing); | |||
5056 | isl_schedule_free(schedule); | |||
5057 | if (!schedule) | |||
5058 | return -1; | |||
5059 | return 0; | |||
5060 | } | |||
5061 | ||||
5062 | /* Check that the scheduler does not perform any needless | |||
5063 | * compound skewing. Earlier versions of isl would compute | |||
5064 | * schedules in terms of transformed schedule coefficients and | |||
5065 | * would not accurately keep track of the sum of the original | |||
5066 | * schedule coefficients. It could then produce the schedule | |||
5067 | * S[t,i,j,k] -> [t, 2t + i, 2t + i + j, 2t + i + j + k] | |||
5068 | * for the input below instead of the schedule below. | |||
5069 | */ | |||
5070 | static int test_skewing_schedule(isl_ctx *ctx) | |||
5071 | { | |||
5072 | const char *D, *V, *P, *S; | |||
5073 | ||||
5074 | D = "[n] -> { S[t,i,j,k] : 0 <= t,i,j,k < n }"; | |||
5075 | V = "[n] -> { S[t,i,j,k] -> S[t+1,a,b,c] : 0 <= t,i,j,k,a,b,c < n and " | |||
5076 | "-2 <= a-i <= 2 and -1 <= a-i + b-j <= 1 and " | |||
5077 | "-1 <= a-i + b-j + c-k <= 1 }"; | |||
5078 | P = "{ }"; | |||
5079 | S = "{ S[t,i,j,k] -> [t, 2t + i, t + i + j, 2t + k] }"; | |||
5080 | ||||
5081 | return test_special_schedule(ctx, D, V, P, S); | |||
5082 | } | |||
5083 | ||||
5084 | int test_schedule(isl_ctx *ctx) | |||
5085 | { | |||
5086 | const char *D, *W, *R, *V, *P, *S; | |||
5087 | int max_coincidence; | |||
5088 | int treat_coalescing; | |||
5089 | ||||
5090 | /* Handle resulting schedule with zero bands. */ | |||
5091 | if (test_one_schedule(ctx, "{[]}", "{}", "{}", "{[] -> []}", 0, 0) < 0) | |||
5092 | return -1; | |||
5093 | ||||
5094 | /* Jacobi */ | |||
5095 | D = "[T,N] -> { S1[t,i] : 1 <= t <= T and 2 <= i <= N - 1 }"; | |||
5096 | W = "{ S1[t,i] -> a[t,i] }"; | |||
5097 | R = "{ S1[t,i] -> a[t-1,i]; S1[t,i] -> a[t-1,i-1]; " | |||
5098 | "S1[t,i] -> a[t-1,i+1] }"; | |||
5099 | S = "{ S1[t,i] -> [t,i] }"; | |||
5100 | if (test_one_schedule(ctx, D, W, R, S, 2, 0) < 0) | |||
5101 | return -1; | |||
5102 | ||||
5103 | /* Fig. 5 of CC2008 */ | |||
5104 | D = "[N] -> { S_0[i, j] : i >= 0 and i <= -1 + N and j >= 2 and " | |||
5105 | "j <= -1 + N }"; | |||
5106 | W = "[N] -> { S_0[i, j] -> a[i, j] : i >= 0 and i <= -1 + N and " | |||
5107 | "j >= 2 and j <= -1 + N }"; | |||
5108 | R = "[N] -> { S_0[i, j] -> a[j, i] : i >= 0 and i <= -1 + N and " | |||
5109 | "j >= 2 and j <= -1 + N; " | |||
5110 | "S_0[i, j] -> a[i, -1 + j] : i >= 0 and i <= -1 + N and " | |||
5111 | "j >= 2 and j <= -1 + N }"; | |||
5112 | S = "[N] -> { S_0[i, j] -> [0, i, 0, j, 0] }"; | |||
5113 | if (test_one_schedule(ctx, D, W, R, S, 2, 0) < 0) | |||
5114 | return -1; | |||
5115 | ||||
5116 | D = "{ S1[i] : 0 <= i <= 10; S2[i] : 0 <= i <= 9 }"; | |||
5117 | W = "{ S1[i] -> a[i] }"; | |||
5118 | R = "{ S2[i] -> a[i+1] }"; | |||
5119 | S = "{ S1[i] -> [0,i]; S2[i] -> [1,i] }"; | |||
5120 | if (test_one_schedule(ctx, D, W, R, S, 1, 1) < 0) | |||
5121 | return -1; | |||
5122 | ||||
5123 | D = "{ S1[i] : 0 <= i < 10; S2[i] : 0 <= i < 10 }"; | |||
5124 | W = "{ S1[i] -> a[i] }"; | |||
5125 | R = "{ S2[i] -> a[9-i] }"; | |||
5126 | S = "{ S1[i] -> [0,i]; S2[i] -> [1,i] }"; | |||
5127 | if (test_one_schedule(ctx, D, W, R, S, 1, 1) < 0) | |||
5128 | return -1; | |||
5129 | ||||
5130 | D = "[N] -> { S1[i] : 0 <= i < N; S2[i] : 0 <= i < N }"; | |||
5131 | W = "{ S1[i] -> a[i] }"; | |||
5132 | R = "[N] -> { S2[i] -> a[N-1-i] }"; | |||
5133 | S = "{ S1[i] -> [0,i]; S2[i] -> [1,i] }"; | |||
5134 | if (test_one_schedule(ctx, D, W, R, S, 1, 1) < 0) | |||
5135 | return -1; | |||
5136 | ||||
5137 | D = "{ S1[i] : 0 < i < 10; S2[i] : 0 <= i < 10 }"; | |||
5138 | W = "{ S1[i] -> a[i]; S2[i] -> b[i] }"; | |||
5139 | R = "{ S2[i] -> a[i]; S1[i] -> b[i-1] }"; | |||
5140 | S = "{ S1[i] -> [i,0]; S2[i] -> [i,1] }"; | |||
5141 | if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) | |||
5142 | return -1; | |||
5143 | ||||
5144 | D = "[N] -> { S1[i] : 1 <= i <= N; S2[i,j] : 1 <= i,j <= N }"; | |||
5145 | W = "{ S1[i] -> a[0,i]; S2[i,j] -> a[i,j] }"; | |||
5146 | R = "{ S2[i,j] -> a[i-1,j] }"; | |||
5147 | S = "{ S1[i] -> [0,i,0]; S2[i,j] -> [1,i,j] }"; | |||
5148 | if (test_one_schedule(ctx, D, W, R, S, 2, 1) < 0) | |||
5149 | return -1; | |||
5150 | ||||
5151 | D = "[N] -> { S1[i] : 1 <= i <= N; S2[i,j] : 1 <= i,j <= N }"; | |||
5152 | W = "{ S1[i] -> a[i,0]; S2[i,j] -> a[i,j] }"; | |||
5153 | R = "{ S2[i,j] -> a[i,j-1] }"; | |||
5154 | S = "{ S1[i] -> [0,i,0]; S2[i,j] -> [1,i,j] }"; | |||
5155 | if (test_one_schedule(ctx, D, W, R, S, 2, 1) < 0) | |||
5156 | return -1; | |||
5157 | ||||
5158 | D = "[N] -> { S_0[]; S_1[i] : i >= 0 and i <= -1 + N; S_2[] }"; | |||
5159 | W = "[N] -> { S_0[] -> a[0]; S_2[] -> b[0]; " | |||
5160 | "S_1[i] -> a[1 + i] : i >= 0 and i <= -1 + N }"; | |||
5161 | R = "[N] -> { S_2[] -> a[N]; S_1[i] -> a[i] : i >= 0 and i <= -1 + N }"; | |||
5162 | S = "[N] -> { S_1[i] -> [1, i, 0]; S_2[] -> [2, 0, 1]; " | |||
5163 | "S_0[] -> [0, 0, 0] }"; | |||
5164 | if (test_one_schedule(ctx, D, W, R, S, 1, 0) < 0) | |||
5165 | return -1; | |||
5166 | ctx->opt->schedule_parametric = 0; | |||
5167 | if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) | |||
5168 | return -1; | |||
5169 | ctx->opt->schedule_parametric = 1; | |||
5170 | ||||
5171 | D = "[N] -> { S1[i] : 1 <= i <= N; S2[i] : 1 <= i <= N; " | |||
5172 | "S3[i,j] : 1 <= i,j <= N; S4[i] : 1 <= i <= N }"; | |||
5173 | W = "{ S1[i] -> a[i,0]; S2[i] -> a[0,i]; S3[i,j] -> a[i,j] }"; | |||
5174 | R = "[N] -> { S3[i,j] -> a[i-1,j]; S3[i,j] -> a[i,j-1]; " | |||
5175 | "S4[i] -> a[i,N] }"; | |||
5176 | S = "{ S1[i] -> [0,i,0]; S2[i] -> [1,i,0]; S3[i,j] -> [2,i,j]; " | |||
5177 | "S4[i] -> [4,i,0] }"; | |||
5178 | max_coincidence = isl_options_get_schedule_maximize_coincidence(ctx); | |||
5179 | isl_options_set_schedule_maximize_coincidence(ctx, 0); | |||
5180 | if (test_one_schedule(ctx, D, W, R, S, 2, 0) < 0) | |||
5181 | return -1; | |||
5182 | isl_options_set_schedule_maximize_coincidence(ctx, max_coincidence); | |||
5183 | ||||
5184 | D = "[N] -> { S_0[i, j] : i >= 1 and i <= N and j >= 1 and j <= N }"; | |||
5185 | W = "[N] -> { S_0[i, j] -> s[0] : i >= 1 and i <= N and j >= 1 and " | |||
5186 | "j <= N }"; | |||
5187 | R = "[N] -> { S_0[i, j] -> s[0] : i >= 1 and i <= N and j >= 1 and " | |||
5188 | "j <= N; " | |||
5189 | "S_0[i, j] -> a[i, j] : i >= 1 and i <= N and j >= 1 and " | |||
5190 | "j <= N }"; | |||
5191 | S = "[N] -> { S_0[i, j] -> [0, i, 0, j, 0] }"; | |||
5192 | if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) | |||
5193 | return -1; | |||
5194 | ||||
5195 | D = "[N] -> { S_0[t] : t >= 0 and t <= -1 + N; " | |||
5196 | " S_2[t] : t >= 0 and t <= -1 + N; " | |||
5197 | " S_1[t, i] : t >= 0 and t <= -1 + N and i >= 0 and " | |||
5198 | "i <= -1 + N }"; | |||
5199 | W = "[N] -> { S_0[t] -> a[t, 0] : t >= 0 and t <= -1 + N; " | |||
5200 | " S_2[t] -> b[t] : t >= 0 and t <= -1 + N; " | |||
5201 | " S_1[t, i] -> a[t, 1 + i] : t >= 0 and t <= -1 + N and " | |||
5202 | "i >= 0 and i <= -1 + N }"; | |||
5203 | R = "[N] -> { S_1[t, i] -> a[t, i] : t >= 0 and t <= -1 + N and " | |||
5204 | "i >= 0 and i <= -1 + N; " | |||
5205 | " S_2[t] -> a[t, N] : t >= 0 and t <= -1 + N }"; | |||
5206 | S = "[N] -> { S_2[t] -> [0, t, 2]; S_1[t, i] -> [0, t, 1, i, 0]; " | |||
5207 | " S_0[t] -> [0, t, 0] }"; | |||
5208 | ||||
5209 | if (test_one_schedule(ctx, D, W, R, S, 2, 1) < 0) | |||
5210 | return -1; | |||
5211 | ctx->opt->schedule_parametric = 0; | |||
5212 | if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) | |||
5213 | return -1; | |||
5214 | ctx->opt->schedule_parametric = 1; | |||
5215 | ||||
5216 | D = "[N] -> { S1[i,j] : 0 <= i,j < N; S2[i,j] : 0 <= i,j < N }"; | |||
5217 | S = "{ S1[i,j] -> [0,i,j]; S2[i,j] -> [1,i,j] }"; | |||
5218 | if (test_one_schedule(ctx, D, "{}", "{}", S, 2, 2) < 0) | |||
5219 | return -1; | |||
5220 | ||||
5221 | D = "[M, N] -> { S_1[i] : i >= 0 and i <= -1 + M; " | |||
5222 | "S_0[i, j] : i >= 0 and i <= -1 + M and j >= 0 and j <= -1 + N }"; | |||
5223 | W = "[M, N] -> { S_0[i, j] -> a[j] : i >= 0 and i <= -1 + M and " | |||
5224 | "j >= 0 and j <= -1 + N; " | |||
5225 | "S_1[i] -> b[0] : i >= 0 and i <= -1 + M }"; | |||
5226 | R = "[M, N] -> { S_0[i, j] -> a[0] : i >= 0 and i <= -1 + M and " | |||
5227 | "j >= 0 and j <= -1 + N; " | |||
5228 | "S_1[i] -> b[0] : i >= 0 and i <= -1 + M }"; | |||
5229 | S = "[M, N] -> { S_1[i] -> [1, i, 0]; S_0[i, j] -> [0, i, 0, j, 0] }"; | |||
5230 | if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) | |||
5231 | return -1; | |||
5232 | ||||
5233 | D = "{ S_0[i] : i >= 0 }"; | |||
5234 | W = "{ S_0[i] -> a[i] : i >= 0 }"; | |||
5235 | R = "{ S_0[i] -> a[0] : i >= 0 }"; | |||
5236 | S = "{ S_0[i] -> [0, i, 0] }"; | |||
5237 | if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) | |||
5238 | return -1; | |||
5239 | ||||
5240 | D = "{ S_0[i] : i >= 0; S_1[i] : i >= 0 }"; | |||
5241 | W = "{ S_0[i] -> a[i] : i >= 0; S_1[i] -> b[i] : i >= 0 }"; | |||
5242 | R = "{ S_0[i] -> b[0] : i >= 0; S_1[i] -> a[i] : i >= 0 }"; | |||
5243 | S = "{ S_1[i] -> [0, i, 1]; S_0[i] -> [0, i, 0] }"; | |||
5244 | if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) | |||
5245 | return -1; | |||
5246 | ||||
5247 | D = "[n] -> { S_0[j, k] : j <= -1 + n and j >= 0 and " | |||
5248 | "k <= -1 + n and k >= 0 }"; | |||
5249 | W = "[n] -> { S_0[j, k] -> B[j] : j <= -1 + n and j >= 0 and " "k <= -1 + n and k >= 0 }"; | |||
5250 | R = "[n] -> { S_0[j, k] -> B[j] : j <= -1 + n and j >= 0 and " | |||
5251 | "k <= -1 + n and k >= 0; " | |||
5252 | "S_0[j, k] -> B[k] : j <= -1 + n and j >= 0 and " | |||
5253 | "k <= -1 + n and k >= 0; " | |||
5254 | "S_0[j, k] -> A[k] : j <= -1 + n and j >= 0 and " | |||
5255 | "k <= -1 + n and k >= 0 }"; | |||
5256 | S = "[n] -> { S_0[j, k] -> [2, j, k] }"; | |||
5257 | ctx->opt->schedule_outer_coincidence = 1; | |||
5258 | if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) | |||
5259 | return -1; | |||
5260 | ctx->opt->schedule_outer_coincidence = 0; | |||
5261 | ||||
5262 | D = "{Stmt_for_body24[i0, i1, i2, i3]:" | |||
5263 | "i0 >= 0 and i0 <= 1 and i1 >= 0 and i1 <= 6 and i2 >= 2 and " | |||
5264 | "i2 <= 6 - i1 and i3 >= 0 and i3 <= -1 + i2;" | |||
5265 | "Stmt_for_body24[i0, i1, 1, 0]:" | |||
5266 | "i0 >= 0 and i0 <= 1 and i1 >= 0 and i1 <= 5;" | |||
5267 | "Stmt_for_body7[i0, i1, i2]:" | |||
5268 | "i0 >= 0 and i0 <= 1 and i1 >= 0 and i1 <= 7 and i2 >= 0 and " | |||
5269 | "i2 <= 7 }"; | |||
5270 | ||||
5271 | V = "{Stmt_for_body24[0, i1, i2, i3] -> " | |||
5272 | "Stmt_for_body24[1, i1, i2, i3]:" | |||
5273 | "i3 >= 0 and i3 <= -1 + i2 and i1 >= 0 and i2 <= 6 - i1 and " | |||
5274 | "i2 >= 1;" | |||
5275 | "Stmt_for_body24[0, i1, i2, i3] -> " | |||
5276 | "Stmt_for_body7[1, 1 + i1 + i3, 1 + i1 + i2]:" | |||
5277 | "i3 <= -1 + i2 and i2 <= 6 - i1 and i2 >= 1 and i1 >= 0 and " | |||
5278 | "i3 >= 0;" | |||
5279 | "Stmt_for_body24[0, i1, i2, i3] ->" | |||
5280 | "Stmt_for_body7[1, i1, 1 + i1 + i3]:" | |||
5281 | "i3 >= 0 and i2 <= 6 - i1 and i1 >= 0 and i3 <= -1 + i2;" | |||
5282 | "Stmt_for_body7[0, i1, i2] -> Stmt_for_body7[1, i1, i2]:" | |||
5283 | "(i2 >= 1 + i1 and i2 <= 6 and i1 >= 0 and i1 <= 4) or " | |||
5284 | "(i2 >= 3 and i2 <= 7 and i1 >= 1 and i2 >= 1 + i1) or " | |||
5285 | "(i2 >= 0 and i2 <= i1 and i2 >= -7 + i1 and i1 <= 7);" | |||
5286 | "Stmt_for_body7[0, i1, 1 + i1] -> Stmt_for_body7[1, i1, 1 + i1]:" | |||
5287 | "i1 <= 6 and i1 >= 0;" | |||
5288 | "Stmt_for_body7[0, 0, 7] -> Stmt_for_body7[1, 0, 7];" | |||
5289 | "Stmt_for_body7[i0, i1, i2] -> " | |||
5290 | "Stmt_for_body24[i0, o1, -1 + i2 - o1, -1 + i1 - o1]:" | |||
5291 | "i0 >= 0 and i0 <= 1 and o1 >= 0 and i2 >= 1 + i1 and " | |||
5292 | "o1 <= -2 + i2 and i2 <= 7 and o1 <= -1 + i1;" | |||
5293 | "Stmt_for_body7[i0, i1, i2] -> " | |||
5294 | "Stmt_for_body24[i0, i1, o2, -1 - i1 + i2]:" | |||
5295 | "i0 >= 0 and i0 <= 1 and i1 >= 0 and o2 >= -i1 + i2 and " | |||
5296 | "o2 >= 1 and o2 <= 6 - i1 and i2 >= 1 + i1 }"; | |||
5297 | P = V; | |||
5298 | ||||
5299 | treat_coalescing = isl_options_get_schedule_treat_coalescing(ctx); | |||
5300 | isl_options_set_schedule_treat_coalescing(ctx, 0); | |||
5301 | if (test_has_schedule(ctx, D, V, P) < 0) | |||
5302 | return -1; | |||
5303 | isl_options_set_schedule_treat_coalescing(ctx, treat_coalescing); | |||
5304 | ||||
5305 | D = "{ S_0[i, j] : i >= 1 and i <= 10 and j >= 1 and j <= 8 }"; | |||
5306 | V = "{ S_0[i, j] -> S_0[i, 1 + j] : i >= 1 and i <= 10 and " | |||
5307 | "j >= 1 and j <= 7;" | |||
5308 | "S_0[i, j] -> S_0[1 + i, j] : i >= 1 and i <= 9 and " | |||
5309 | "j >= 1 and j <= 8 }"; | |||
5310 | P = "{ }"; | |||
5311 | S = "{ S_0[i, j] -> [i + j, i] }"; | |||
5312 | ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER1; | |||
5313 | if (test_special_schedule(ctx, D, V, P, S) < 0) | |||
5314 | return -1; | |||
5315 | ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL0; | |||
5316 | ||||
5317 | /* Fig. 1 from Feautrier's "Some Efficient Solutions..." pt. 2, 1992 */ | |||
5318 | D = "[N] -> { S_0[i, j] : i >= 0 and i <= -1 + N and " | |||
5319 | "j >= 0 and j <= -1 + i }"; | |||
5320 | V = "[N] -> { S_0[i, j] -> S_0[i, 1 + j] : j <= -2 + i and " | |||
5321 | "i <= -1 + N and j >= 0;" | |||
5322 | "S_0[i, -1 + i] -> S_0[1 + i, 0] : i >= 1 and " | |||
5323 | "i <= -2 + N }"; | |||
5324 | P = "{ }"; | |||
5325 | S = "{ S_0[i, j] -> [i, j] }"; | |||
5326 | ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER1; | |||
5327 | if (test_special_schedule(ctx, D, V, P, S) < 0) | |||
5328 | return -1; | |||
5329 | ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL0; | |||
5330 | ||||
5331 | /* Test both algorithms on a case with only proximity dependences. */ | |||
5332 | D = "{ S[i,j] : 0 <= i <= 10 }"; | |||
5333 | V = "{ }"; | |||
5334 | P = "{ S[i,j] -> S[i+1,j] : 0 <= i,j <= 10 }"; | |||
5335 | S = "{ S[i, j] -> [j, i] }"; | |||
5336 | ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER1; | |||
5337 | if (test_special_schedule(ctx, D, V, P, S) < 0) | |||
5338 | return -1; | |||
5339 | ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL0; | |||
5340 | if (test_special_schedule(ctx, D, V, P, S) < 0) | |||
5341 | return -1; | |||
5342 | ||||
5343 | D = "{ A[a]; B[] }"; | |||
5344 | V = "{}"; | |||
5345 | P = "{ A[a] -> B[] }"; | |||
5346 | if (test_has_schedule(ctx, D, V, P) < 0) | |||
5347 | return -1; | |||
5348 | ||||
5349 | if (test_padded_schedule(ctx) < 0) | |||
5350 | return -1; | |||
5351 | ||||
5352 | /* Check that check for progress is not confused by rational | |||
5353 | * solution. | |||
5354 | */ | |||
5355 | D = "[N] -> { S0[i, j] : i >= 0 and i <= N and j >= 0 and j <= N }"; | |||
5356 | V = "[N] -> { S0[i0, -1 + N] -> S0[2 + i0, 0] : i0 >= 0 and " | |||
5357 | "i0 <= -2 + N; " | |||
5358 | "S0[i0, i1] -> S0[i0, 1 + i1] : i0 >= 0 and " | |||
5359 | "i0 <= N and i1 >= 0 and i1 <= -1 + N }"; | |||
5360 | P = "{}"; | |||
5361 | ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER1; | |||
5362 | if (test_has_schedule(ctx, D, V, P) < 0) | |||
5363 | return -1; | |||
5364 | ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL0; | |||
5365 | ||||
5366 | /* Check that we allow schedule rows that are only non-trivial | |||
5367 | * on some full-dimensional domains. | |||
5368 | */ | |||
5369 | D = "{ S1[j] : 0 <= j <= 1; S0[]; S2[k] : 0 <= k <= 1 }"; | |||
5370 | V = "{ S0[] -> S1[j] : 0 <= j <= 1; S2[0] -> S0[];" | |||
5371 | "S1[j] -> S2[1] : 0 <= j <= 1 }"; | |||
5372 | P = "{}"; | |||
5373 | ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER1; | |||
5374 | if (test_has_schedule(ctx, D, V, P) < 0) | |||
5375 | return -1; | |||
5376 | ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL0; | |||
5377 | ||||
5378 | if (test_conditional_schedule_constraints(ctx) < 0) | |||
5379 | return -1; | |||
5380 | ||||
5381 | if (test_strongly_satisfying_schedule(ctx) < 0) | |||
5382 | return -1; | |||
5383 | ||||
5384 | if (test_conflicting_context_schedule(ctx) < 0) | |||
5385 | return -1; | |||
5386 | ||||
5387 | if (test_coalescing_schedule(ctx) < 0) | |||
5388 | return -1; | |||
5389 | if (test_skewing_schedule(ctx) < 0) | |||
5390 | return -1; | |||
5391 | ||||
5392 | return 0; | |||
5393 | } | |||
5394 | ||||
5395 | /* Perform scheduling tests using the whole component scheduler. | |||
5396 | */ | |||
5397 | static int test_schedule_whole(isl_ctx *ctx) | |||
5398 | { | |||
5399 | int whole; | |||
5400 | int r; | |||
5401 | ||||
5402 | whole = isl_options_get_schedule_whole_component(ctx); | |||
5403 | isl_options_set_schedule_whole_component(ctx, 1); | |||
5404 | r = test_schedule(ctx); | |||
5405 | isl_options_set_schedule_whole_component(ctx, whole); | |||
5406 | ||||
5407 | return r; | |||
5408 | } | |||
5409 | ||||
5410 | /* Perform scheduling tests using the incremental scheduler. | |||
5411 | */ | |||
5412 | static int test_schedule_incremental(isl_ctx *ctx) | |||
5413 | { | |||
5414 | int whole; | |||
5415 | int r; | |||
5416 | ||||
5417 | whole = isl_options_get_schedule_whole_component(ctx); | |||
5418 | isl_options_set_schedule_whole_component(ctx, 0); | |||
5419 | r = test_schedule(ctx); | |||
5420 | isl_options_set_schedule_whole_component(ctx, whole); | |||
5421 | ||||
5422 | return r; | |||
5423 | } | |||
5424 | ||||
5425 | int test_plain_injective(isl_ctx *ctx, const char *str, int injective) | |||
5426 | { | |||
5427 | isl_union_map *umap; | |||
5428 | int test; | |||
5429 | ||||
5430 | umap = isl_union_map_read_from_str(ctx, str); | |||
5431 | test = isl_union_map_plain_is_injective(umap); | |||
5432 | isl_union_map_free(umap); | |||
5433 | if (test < 0) | |||
5434 | return -1; | |||
5435 | if (test == injective) | |||
5436 | return 0; | |||
5437 | if (injective) | |||
5438 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "map not detected as injective" , "polly/lib/External/isl/isl_test.c", 5439); return -1; } while (0) | |||
5439 | "map not detected as injective", return -1)do { isl_handle_error(ctx, isl_error_unknown, "map not detected as injective" , "polly/lib/External/isl/isl_test.c", 5439); return -1; } while (0); | |||
5440 | else | |||
5441 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "map detected as injective" , "polly/lib/External/isl/isl_test.c", 5442); return -1; } while (0) | |||
5442 | "map detected as injective", return -1)do { isl_handle_error(ctx, isl_error_unknown, "map detected as injective" , "polly/lib/External/isl/isl_test.c", 5442); return -1; } while (0); | |||
5443 | } | |||
5444 | ||||
5445 | int test_injective(isl_ctx *ctx) | |||
5446 | { | |||
5447 | const char *str; | |||
5448 | ||||
5449 | if (test_plain_injective(ctx, "{S[i,j] -> A[0]; T[i,j] -> B[1]}", 0)) | |||
5450 | return -1; | |||
5451 | if (test_plain_injective(ctx, "{S[] -> A[0]; T[] -> B[0]}", 1)) | |||
5452 | return -1; | |||
5453 | if (test_plain_injective(ctx, "{S[] -> A[0]; T[] -> A[1]}", 1)) | |||
5454 | return -1; | |||
5455 | if (test_plain_injective(ctx, "{S[] -> A[0]; T[] -> A[0]}", 0)) | |||
5456 | return -1; | |||
5457 | if (test_plain_injective(ctx, "{S[i] -> A[i,0]; T[i] -> A[i,1]}", 1)) | |||
5458 | return -1; | |||
5459 | if (test_plain_injective(ctx, "{S[i] -> A[i]; T[i] -> A[i]}", 0)) | |||
5460 | return -1; | |||
5461 | if (test_plain_injective(ctx, "{S[] -> A[0,0]; T[] -> A[0,1]}", 1)) | |||
5462 | return -1; | |||
5463 | if (test_plain_injective(ctx, "{S[] -> A[0,0]; T[] -> A[1,0]}", 1)) | |||
5464 | return -1; | |||
5465 | ||||
5466 | str = "{S[] -> A[0,0]; T[] -> A[0,1]; U[] -> A[1,0]}"; | |||
5467 | if (test_plain_injective(ctx, str, 1)) | |||
5468 | return -1; | |||
5469 | str = "{S[] -> A[0,0]; T[] -> A[0,1]; U[] -> A[0,0]}"; | |||
5470 | if (test_plain_injective(ctx, str, 0)) | |||
5471 | return -1; | |||
5472 | ||||
5473 | return 0; | |||
5474 | } | |||
5475 | ||||
5476 | #undef BASEunion_pw_qpolynomial | |||
5477 | #define BASEunion_pw_qpolynomial aff | |||
5478 | #include "isl_test_plain_equal_templ.c" | |||
5479 | ||||
5480 | #undef BASEunion_pw_qpolynomial | |||
5481 | #define BASEunion_pw_qpolynomial pw_multi_aff | |||
5482 | #include "isl_test_plain_equal_templ.c" | |||
5483 | ||||
5484 | #undef BASEunion_pw_qpolynomial | |||
5485 | #define BASEunion_pw_qpolynomial union_pw_aff | |||
5486 | #include "isl_test_plain_equal_templ.c" | |||
5487 | ||||
5488 | /* Basic tests on isl_union_pw_aff. | |||
5489 | * | |||
5490 | * In particular, check that isl_union_pw_aff_aff_on_domain | |||
5491 | * aligns the parameters of the input objects and | |||
5492 | * that isl_union_pw_aff_param_on_domain_id properly | |||
5493 | * introduces the parameter. | |||
5494 | */ | |||
5495 | static int test_upa(isl_ctx *ctx) | |||
5496 | { | |||
5497 | const char *str; | |||
5498 | isl_id *id; | |||
5499 | isl_aff *aff; | |||
5500 | isl_union_set *domain; | |||
5501 | isl_union_pw_aff *upa; | |||
5502 | isl_stat ok; | |||
5503 | ||||
5504 | aff = isl_aff_read_from_str(ctx, "[N] -> { [N] }"); | |||
5505 | str = "[M] -> { A[i] : 0 <= i < M; B[] }"; | |||
5506 | domain = isl_union_set_read_from_str(ctx, str); | |||
5507 | upa = isl_union_pw_aff_aff_on_domain(domain, aff); | |||
5508 | str = "[N, M] -> { A[i] -> [N] : 0 <= i < M; B[] -> [N] }"; | |||
5509 | ok = union_pw_aff_check_plain_equal(upa, str); | |||
5510 | isl_union_pw_aff_free(upa); | |||
5511 | if (ok < 0) | |||
5512 | return -1; | |||
5513 | ||||
5514 | id = isl_id_alloc(ctx, "N", NULL((void*)0)); | |||
5515 | str = "[M] -> { A[i] : 0 <= i < M; B[] }"; | |||
5516 | domain = isl_union_set_read_from_str(ctx, str); | |||
5517 | upa = isl_union_pw_aff_param_on_domain_id(domain, id); | |||
5518 | str = "[N, M] -> { A[i] -> [N] : 0 <= i < M; B[] -> [N] }"; | |||
5519 | ok = union_pw_aff_check_plain_equal(upa, str); | |||
5520 | isl_union_pw_aff_free(upa); | |||
5521 | if (ok < 0) | |||
5522 | return -1; | |||
5523 | ||||
5524 | return 0; | |||
5525 | } | |||
5526 | ||||
5527 | struct { | |||
5528 | __isl_give isl_aff *(*fn)(__isl_take isl_aff *aff1, | |||
5529 | __isl_take isl_aff *aff2); | |||
5530 | } aff_bin_op[] = { | |||
5531 | ['+'] = { &isl_aff_add }, | |||
5532 | ['-'] = { &isl_aff_sub }, | |||
5533 | ['*'] = { &isl_aff_mul }, | |||
5534 | ['/'] = { &isl_aff_div }, | |||
5535 | }; | |||
5536 | ||||
5537 | struct { | |||
5538 | const char *arg1; | |||
5539 | unsigned char op; | |||
5540 | const char *arg2; | |||
5541 | const char *res; | |||
5542 | } aff_bin_tests[] = { | |||
5543 | { "{ [i] -> [i] }", '+', "{ [i] -> [i] }", | |||
5544 | "{ [i] -> [2i] }" }, | |||
5545 | { "{ [i] -> [i] }", '-', "{ [i] -> [i] }", | |||
5546 | "{ [i] -> [0] }" }, | |||
5547 | { "{ [i] -> [i] }", '*', "{ [i] -> [2] }", | |||
5548 | "{ [i] -> [2i] }" }, | |||
5549 | { "{ [i] -> [2] }", '*', "{ [i] -> [i] }", | |||
5550 | "{ [i] -> [2i] }" }, | |||
5551 | { "{ [i] -> [i] }", '/', "{ [i] -> [2] }", | |||
5552 | "{ [i] -> [i/2] }" }, | |||
5553 | { "{ [i] -> [2i] }", '/', "{ [i] -> [2] }", | |||
5554 | "{ [i] -> [i] }" }, | |||
5555 | { "{ [i] -> [i] }", '+', "{ [i] -> [NaN] }", | |||
5556 | "{ [i] -> [NaN] }" }, | |||
5557 | { "{ [i] -> [i] }", '-', "{ [i] -> [NaN] }", | |||
5558 | "{ [i] -> [NaN] }" }, | |||
5559 | { "{ [i] -> [i] }", '*', "{ [i] -> [NaN] }", | |||
5560 | "{ [i] -> [NaN] }" }, | |||
5561 | { "{ [i] -> [2] }", '*', "{ [i] -> [NaN] }", | |||
5562 | "{ [i] -> [NaN] }" }, | |||
5563 | { "{ [i] -> [i] }", '/', "{ [i] -> [NaN] }", | |||
5564 | "{ [i] -> [NaN] }" }, | |||
5565 | { "{ [i] -> [2] }", '/', "{ [i] -> [NaN] }", | |||
5566 | "{ [i] -> [NaN] }" }, | |||
5567 | { "{ [i] -> [NaN] }", '+', "{ [i] -> [i] }", | |||
5568 | "{ [i] -> [NaN] }" }, | |||
5569 | { "{ [i] -> [NaN] }", '-', "{ [i] -> [i] }", | |||
5570 | "{ [i] -> [NaN] }" }, | |||
5571 | { "{ [i] -> [NaN] }", '*', "{ [i] -> [2] }", | |||
5572 | "{ [i] -> [NaN] }" }, | |||
5573 | { "{ [i] -> [NaN] }", '*', "{ [i] -> [i] }", | |||
5574 | "{ [i] -> [NaN] }" }, | |||
5575 | { "{ [i] -> [NaN] }", '/', "{ [i] -> [2] }", | |||
5576 | "{ [i] -> [NaN] }" }, | |||
5577 | { "{ [i] -> [NaN] }", '/', "{ [i] -> [i] }", | |||
5578 | "{ [i] -> [NaN] }" }, | |||
5579 | { "{ [i] -> [i] }", '/', "{ [i] -> [0] }", | |||
5580 | "{ [i] -> [NaN] }" }, | |||
5581 | }; | |||
5582 | ||||
5583 | /* Perform some basic tests of binary operations on isl_aff objects. | |||
5584 | */ | |||
5585 | static int test_bin_aff(isl_ctx *ctx) | |||
5586 | { | |||
5587 | int i; | |||
5588 | isl_aff *aff1, *aff2, *res; | |||
5589 | __isl_give isl_aff *(*fn)(__isl_take isl_aff *aff1, | |||
5590 | __isl_take isl_aff *aff2); | |||
5591 | int ok; | |||
5592 | ||||
5593 | for (i = 0; i < ARRAY_SIZE(aff_bin_tests)(sizeof(aff_bin_tests)/sizeof(*aff_bin_tests)); ++i) { | |||
5594 | aff1 = isl_aff_read_from_str(ctx, aff_bin_tests[i].arg1); | |||
5595 | aff2 = isl_aff_read_from_str(ctx, aff_bin_tests[i].arg2); | |||
5596 | res = isl_aff_read_from_str(ctx, aff_bin_tests[i].res); | |||
5597 | fn = aff_bin_op[aff_bin_tests[i].op].fn; | |||
5598 | aff1 = fn(aff1, aff2); | |||
5599 | if (isl_aff_is_nan(res)) | |||
5600 | ok = isl_aff_is_nan(aff1); | |||
5601 | else | |||
5602 | ok = isl_aff_plain_is_equal(aff1, res); | |||
5603 | isl_aff_free(aff1); | |||
5604 | isl_aff_free(res); | |||
5605 | if (ok < 0) | |||
5606 | return -1; | |||
5607 | if (!ok) | |||
5608 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 5609); return -1; } while (0) | |||
5609 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 5609); return -1; } while (0); | |||
5610 | } | |||
5611 | ||||
5612 | return 0; | |||
5613 | } | |||
5614 | ||||
5615 | struct { | |||
5616 | __isl_give isl_pw_aff *(*fn)(__isl_take isl_pw_aff *pa1, | |||
5617 | __isl_take isl_pw_aff *pa2); | |||
5618 | } pw_aff_bin_op[] = { | |||
5619 | ['m'] = { &isl_pw_aff_min }, | |||
5620 | ['M'] = { &isl_pw_aff_max }, | |||
5621 | }; | |||
5622 | ||||
5623 | /* Inputs for binary isl_pw_aff operation tests. | |||
5624 | * "arg1" and "arg2" are the two arguments, "op" identifies the operation | |||
5625 | * defined by pw_aff_bin_op, and "res" is the expected result. | |||
5626 | */ | |||
5627 | struct { | |||
5628 | const char *arg1; | |||
5629 | unsigned char op; | |||
5630 | const char *arg2; | |||
5631 | const char *res; | |||
5632 | } pw_aff_bin_tests[] = { | |||
5633 | { "{ [i] -> [i] }", 'm', "{ [i] -> [i] }", | |||
5634 | "{ [i] -> [i] }" }, | |||
5635 | { "{ [i] -> [i] }", 'M', "{ [i] -> [i] }", | |||
5636 | "{ [i] -> [i] }" }, | |||
5637 | { "{ [i] -> [i] }", 'm', "{ [i] -> [0] }", | |||
5638 | "{ [i] -> [i] : i <= 0; [i] -> [0] : i > 0 }" }, | |||
5639 | { "{ [i] -> [i] }", 'M', "{ [i] -> [0] }", | |||
5640 | "{ [i] -> [i] : i >= 0; [i] -> [0] : i < 0 }" }, | |||
5641 | { "{ [i] -> [i] }", 'm', "{ [i] -> [NaN] }", | |||
5642 | "{ [i] -> [NaN] }" }, | |||
5643 | { "{ [i] -> [NaN] }", 'm', "{ [i] -> [i] }", | |||
5644 | "{ [i] -> [NaN] }" }, | |||
5645 | }; | |||
5646 | ||||
5647 | /* Perform some basic tests of binary operations on isl_pw_aff objects. | |||
5648 | */ | |||
5649 | static int test_bin_pw_aff(isl_ctx *ctx) | |||
5650 | { | |||
5651 | int i; | |||
5652 | isl_bool ok; | |||
5653 | isl_pw_aff *pa1, *pa2, *res; | |||
5654 | ||||
5655 | for (i = 0; i < ARRAY_SIZE(pw_aff_bin_tests)(sizeof(pw_aff_bin_tests)/sizeof(*pw_aff_bin_tests)); ++i) { | |||
5656 | pa1 = isl_pw_aff_read_from_str(ctx, pw_aff_bin_tests[i].arg1); | |||
5657 | pa2 = isl_pw_aff_read_from_str(ctx, pw_aff_bin_tests[i].arg2); | |||
5658 | res = isl_pw_aff_read_from_str(ctx, pw_aff_bin_tests[i].res); | |||
5659 | pa1 = pw_aff_bin_op[pw_aff_bin_tests[i].op].fn(pa1, pa2); | |||
5660 | if (isl_pw_aff_involves_nan(res)) | |||
5661 | ok = isl_pw_aff_involves_nan(pa1); | |||
5662 | else | |||
5663 | ok = isl_pw_aff_plain_is_equal(pa1, res); | |||
5664 | isl_pw_aff_free(pa1); | |||
5665 | isl_pw_aff_free(res); | |||
5666 | if (ok < 0) | |||
5667 | return -1; | |||
5668 | if (!ok) | |||
5669 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 5670); return -1; } while (0) | |||
5670 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 5670); return -1; } while (0); | |||
5671 | } | |||
5672 | ||||
5673 | return 0; | |||
5674 | } | |||
5675 | ||||
5676 | /* Inputs for basic tests of test operations on | |||
5677 | * isl_union_pw_multi_aff objects. | |||
5678 | * "fn" is the function that is being tested. | |||
5679 | * "arg" is a string description of the input. | |||
5680 | * "res" is the expected result. | |||
5681 | */ | |||
5682 | static struct { | |||
5683 | isl_bool (*fn)(__isl_keep isl_union_pw_multi_aff *upma1); | |||
5684 | const char *arg; | |||
5685 | isl_bool res; | |||
5686 | } upma_test_tests[] = { | |||
5687 | { &isl_union_pw_multi_aff_involves_nan, "{ A[] -> [0]; B[0] -> [1] }", | |||
5688 | isl_bool_false }, | |||
5689 | { &isl_union_pw_multi_aff_involves_nan, "{ A[] -> [NaN]; B[0] -> [1] }", | |||
5690 | isl_bool_true }, | |||
5691 | { &isl_union_pw_multi_aff_involves_nan, "{ A[] -> [0]; B[0] -> [NaN] }", | |||
5692 | isl_bool_true }, | |||
5693 | { &isl_union_pw_multi_aff_involves_nan, | |||
5694 | "{ A[] -> [0]; B[0] -> [1, NaN, 5] }", | |||
5695 | isl_bool_true }, | |||
5696 | { &isl_union_pw_multi_aff_involves_locals, | |||
5697 | "{ A[] -> [0]; B[0] -> [1] }", | |||
5698 | isl_bool_false }, | |||
5699 | { &isl_union_pw_multi_aff_involves_locals, | |||
5700 | "{ A[] -> [0]; B[x] -> [1] : x mod 2 = 0 }", | |||
5701 | isl_bool_true }, | |||
5702 | { &isl_union_pw_multi_aff_involves_locals, | |||
5703 | "{ A[] -> [0]; B[x] -> [x // 2] }", | |||
5704 | isl_bool_true }, | |||
5705 | { &isl_union_pw_multi_aff_involves_locals, | |||
5706 | "{ A[i] -> [i // 2]; B[0] -> [1] }", | |||
5707 | isl_bool_true }, | |||
5708 | }; | |||
5709 | ||||
5710 | /* Perform some basic tests of test operations on | |||
5711 | * isl_union_pw_multi_aff objects. | |||
5712 | */ | |||
5713 | static isl_stat test_upma_test(isl_ctx *ctx) | |||
5714 | { | |||
5715 | int i; | |||
5716 | isl_union_pw_multi_aff *upma; | |||
5717 | isl_bool res; | |||
5718 | ||||
5719 | for (i = 0; i < ARRAY_SIZE(upma_test_tests)(sizeof(upma_test_tests)/sizeof(*upma_test_tests)); ++i) { | |||
5720 | const char *str; | |||
5721 | ||||
5722 | str = upma_test_tests[i].arg; | |||
5723 | upma = isl_union_pw_multi_aff_read_from_str(ctx, str); | |||
5724 | res = upma_test_tests[i].fn(upma); | |||
5725 | isl_union_pw_multi_aff_free(upma); | |||
5726 | if (res < 0) | |||
5727 | return isl_stat_error; | |||
5728 | if (res != upma_test_tests[i].res) | |||
5729 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 5730); return isl_stat_error ; } while (0) | |||
5730 | "unexpected result", return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 5730); return isl_stat_error ; } while (0); | |||
5731 | } | |||
5732 | ||||
5733 | return isl_stat_ok; | |||
5734 | } | |||
5735 | ||||
5736 | struct { | |||
5737 | __isl_give isl_union_pw_multi_aff *(*fn)( | |||
5738 | __isl_take isl_union_pw_multi_aff *upma1, | |||
5739 | __isl_take isl_union_pw_multi_aff *upma2); | |||
5740 | const char *arg1; | |||
5741 | const char *arg2; | |||
5742 | const char *res; | |||
5743 | } upma_bin_tests[] = { | |||
5744 | { &isl_union_pw_multi_aff_add, "{ A[] -> [0]; B[0] -> [1] }", | |||
5745 | "{ B[x] -> [2] : x >= 0 }", "{ B[0] -> [3] }" }, | |||
5746 | { &isl_union_pw_multi_aff_union_add, "{ A[] -> [0]; B[0] -> [1] }", | |||
5747 | "{ B[x] -> [2] : x >= 0 }", | |||
5748 | "{ A[] -> [0]; B[0] -> [3]; B[x] -> [2] : x >= 1 }" }, | |||
5749 | { &isl_union_pw_multi_aff_pullback_union_pw_multi_aff, | |||
5750 | "{ A[] -> B[0]; C[x] -> B[1] : x < 10; C[y] -> B[2] : y >= 10 }", | |||
5751 | "{ D[i] -> A[] : i < 0; D[i] -> C[i + 5] : i >= 0 }", | |||
5752 | "{ D[i] -> B[0] : i < 0; D[i] -> B[1] : 0 <= i < 5; " | |||
5753 | "D[i] -> B[2] : i >= 5 }" }, | |||
5754 | { &isl_union_pw_multi_aff_union_add, "{ B[x] -> A[1] : x <= 0 }", | |||
5755 | "{ B[x] -> C[2] : x > 0 }", | |||
5756 | "{ B[x] -> A[1] : x <= 0; B[x] -> C[2] : x > 0 }" }, | |||
5757 | { &isl_union_pw_multi_aff_union_add, "{ B[x] -> A[1] : x <= 0 }", | |||
5758 | "{ B[x] -> A[2] : x >= 0 }", | |||
5759 | "{ B[x] -> A[1] : x < 0; B[x] -> A[2] : x > 0; B[0] -> A[3] }" }, | |||
5760 | { | |||
5761 | &isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff, | |||
5762 | "{ B[x] -> C[x + 2] }", | |||
5763 | "{ D[y] -> B[2y] }", | |||
5764 | "{ }" }, | |||
5765 | { | |||
5766 | &isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff, | |||
5767 | "{ [A[x] -> B[x + 1]] -> C[x + 2] }", | |||
5768 | "{ D[y] -> B[2y] }", | |||
5769 | "{ }" }, | |||
5770 | { | |||
5771 | &isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff, | |||
5772 | "{ [A[x] -> B[x + 1]] -> C[x + 2]; B[x] -> C[x + 2] }", | |||
5773 | "{ D[y] -> A[2y] }", | |||
5774 | "{ [D[y] -> B[2y + 1]] -> C[2y + 2] }" }, | |||
5775 | { | |||
5776 | &isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff, | |||
5777 | "{ T[A[x] -> B[x + 1]] -> C[x + 2]; B[x] -> C[x + 2] }", | |||
5778 | "{ D[y] -> A[2y] }", | |||
5779 | "{ T[D[y] -> B[2y + 1]] -> C[2y + 2] }" }, | |||
5780 | }; | |||
5781 | ||||
5782 | /* Perform some basic tests of binary operations on | |||
5783 | * isl_union_pw_multi_aff objects. | |||
5784 | */ | |||
5785 | static int test_bin_upma(isl_ctx *ctx) | |||
5786 | { | |||
5787 | int i; | |||
5788 | isl_union_pw_multi_aff *upma1, *upma2, *res; | |||
5789 | int ok; | |||
5790 | ||||
5791 | for (i = 0; i < ARRAY_SIZE(upma_bin_tests)(sizeof(upma_bin_tests)/sizeof(*upma_bin_tests)); ++i) { | |||
5792 | upma1 = isl_union_pw_multi_aff_read_from_str(ctx, | |||
5793 | upma_bin_tests[i].arg1); | |||
5794 | upma2 = isl_union_pw_multi_aff_read_from_str(ctx, | |||
5795 | upma_bin_tests[i].arg2); | |||
5796 | res = isl_union_pw_multi_aff_read_from_str(ctx, | |||
5797 | upma_bin_tests[i].res); | |||
5798 | upma1 = upma_bin_tests[i].fn(upma1, upma2); | |||
5799 | ok = isl_union_pw_multi_aff_plain_is_equal(upma1, res); | |||
5800 | isl_union_pw_multi_aff_free(upma1); | |||
5801 | isl_union_pw_multi_aff_free(res); | |||
5802 | if (ok < 0) | |||
5803 | return -1; | |||
5804 | if (!ok) | |||
5805 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 5806); return -1; } while (0) | |||
5806 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 5806); return -1; } while (0); | |||
5807 | } | |||
5808 | ||||
5809 | return 0; | |||
5810 | } | |||
5811 | ||||
5812 | struct { | |||
5813 | __isl_give isl_union_pw_multi_aff *(*fn)( | |||
5814 | __isl_take isl_union_pw_multi_aff *upma1, | |||
5815 | __isl_take isl_union_pw_multi_aff *upma2); | |||
5816 | const char *arg1; | |||
5817 | const char *arg2; | |||
5818 | } upma_bin_fail_tests[] = { | |||
5819 | { &isl_union_pw_multi_aff_union_add, "{ B[x] -> A[1] : x <= 0 }", | |||
5820 | "{ B[x] -> C[2] : x >= 0 }" }, | |||
5821 | }; | |||
5822 | ||||
5823 | /* Perform some basic tests of binary operations on | |||
5824 | * isl_union_pw_multi_aff objects that are expected to fail. | |||
5825 | */ | |||
5826 | static int test_bin_upma_fail(isl_ctx *ctx) | |||
5827 | { | |||
5828 | int i, n; | |||
5829 | isl_union_pw_multi_aff *upma1, *upma2; | |||
5830 | int on_error; | |||
5831 | ||||
5832 | on_error = isl_options_get_on_error(ctx); | |||
5833 | isl_options_set_on_error(ctx, ISL_ON_ERROR_CONTINUE1); | |||
5834 | n = ARRAY_SIZE(upma_bin_fail_tests)(sizeof(upma_bin_fail_tests)/sizeof(*upma_bin_fail_tests)); | |||
5835 | for (i = 0; i < n; ++i) { | |||
5836 | upma1 = isl_union_pw_multi_aff_read_from_str(ctx, | |||
5837 | upma_bin_fail_tests[i].arg1); | |||
5838 | upma2 = isl_union_pw_multi_aff_read_from_str(ctx, | |||
5839 | upma_bin_fail_tests[i].arg2); | |||
5840 | upma1 = upma_bin_fail_tests[i].fn(upma1, upma2); | |||
5841 | isl_union_pw_multi_aff_free(upma1); | |||
5842 | if (upma1) | |||
5843 | break; | |||
5844 | } | |||
5845 | isl_options_set_on_error(ctx, on_error); | |||
5846 | if (i < n) | |||
5847 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "operation not expected to succeed" , "polly/lib/External/isl/isl_test.c", 5848); return -1; } while (0) | |||
5848 | "operation not expected to succeed", return -1)do { isl_handle_error(ctx, isl_error_unknown, "operation not expected to succeed" , "polly/lib/External/isl/isl_test.c", 5848); return -1; } while (0); | |||
5849 | ||||
5850 | return 0; | |||
5851 | } | |||
5852 | ||||
5853 | /* Inputs for basic tests of binary operations on | |||
5854 | * pairs of isl_union_pw_multi_aff and isl_union_set objects. | |||
5855 | * "fn" is the function that is being tested. | |||
5856 | * "arg1" and "arg2" are string descriptions of the inputs. | |||
5857 | * "res" is a string description of the expected result. | |||
5858 | */ | |||
5859 | struct { | |||
5860 | __isl_give isl_union_pw_multi_aff *(*fn)( | |||
5861 | __isl_take isl_union_pw_multi_aff *upma, | |||
5862 | __isl_take isl_union_set *uset); | |||
5863 | const char *arg1; | |||
5864 | const char *arg2; | |||
5865 | const char *res; | |||
5866 | } upma_uset_tests[] = { | |||
5867 | { &isl_union_pw_multi_aff_intersect_domain_wrapped_range, | |||
5868 | "{ A[i] -> B[i] }", "{ B[0] }", | |||
5869 | "{ }" }, | |||
5870 | { &isl_union_pw_multi_aff_intersect_domain_wrapped_domain, | |||
5871 | "{ [A[i] -> B[i]] -> C[i + 1] }", "{ A[1]; B[0] }", | |||
5872 | "{ [A[1] -> B[1]] -> C[2] }" }, | |||
5873 | { &isl_union_pw_multi_aff_intersect_domain_wrapped_range, | |||
5874 | "{ [A[i] -> B[i]] -> C[i + 1] }", "{ A[1]; B[0] }", | |||
5875 | "{ [A[0] -> B[0]] -> C[1] }" }, | |||
5876 | { &isl_union_pw_multi_aff_intersect_domain_wrapped_range, | |||
5877 | "{ [A[i] -> B[i]] -> C[i + 1] }", "[N] -> { B[N] }", | |||
5878 | "[N] -> { [A[N] -> B[N]] -> C[N + 1] }" }, | |||
5879 | { &isl_union_pw_multi_aff_intersect_domain_wrapped_range, | |||
5880 | "[M] -> { [A[M] -> B[M]] -> C[M + 1] }", "[N] -> { B[N] }", | |||
5881 | "[N, M] -> { [A[N] -> B[N]] -> C[N + 1] : N = M }" }, | |||
5882 | { &isl_union_pw_multi_aff_intersect_domain_wrapped_range, | |||
5883 | "{ [A[] -> B[]] -> C[]; N[A[] -> B[]] -> D[]; [B[] -> A[]] -> E[] }", | |||
5884 | "{ B[] }", | |||
5885 | "{ [A[] -> B[]] -> C[]; N[A[] -> B[]] -> D[] }" }, | |||
5886 | }; | |||
5887 | ||||
5888 | /* Perform some basic tests of binary operations on | |||
5889 | * pairs of isl_union_pw_multi_aff and isl_union_set objects. | |||
5890 | */ | |||
5891 | static isl_stat test_upma_uset(isl_ctx *ctx) | |||
5892 | { | |||
5893 | int i; | |||
5894 | isl_bool ok; | |||
5895 | isl_union_pw_multi_aff *upma, *res; | |||
5896 | isl_union_set *uset; | |||
5897 | ||||
5898 | for (i = 0; i < ARRAY_SIZE(upma_uset_tests)(sizeof(upma_uset_tests)/sizeof(*upma_uset_tests)); ++i) { | |||
5899 | upma = isl_union_pw_multi_aff_read_from_str(ctx, | |||
5900 | upma_uset_tests[i].arg1); | |||
5901 | uset = isl_union_set_read_from_str(ctx, | |||
5902 | upma_uset_tests[i].arg2); | |||
5903 | res = isl_union_pw_multi_aff_read_from_str(ctx, | |||
5904 | upma_uset_tests[i].res); | |||
5905 | upma = upma_uset_tests[i].fn(upma, uset); | |||
5906 | ok = isl_union_pw_multi_aff_plain_is_equal(upma, res); | |||
5907 | isl_union_pw_multi_aff_free(upma); | |||
5908 | isl_union_pw_multi_aff_free(res); | |||
5909 | if (ok < 0) | |||
5910 | return isl_stat_error; | |||
5911 | if (!ok) | |||
5912 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 5913); return isl_stat_error ; } while (0) | |||
5913 | "unexpected result", return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 5913); return isl_stat_error ; } while (0); | |||
5914 | } | |||
5915 | ||||
5916 | return isl_stat_ok; | |||
5917 | } | |||
5918 | ||||
5919 | /* Inputs for basic tests of unary operations on isl_multi_pw_aff objects. | |||
5920 | * "fn" is the function that is tested. | |||
5921 | * "arg" is a string description of the input. | |||
5922 | * "res" is a string description of the expected result. | |||
5923 | */ | |||
5924 | struct { | |||
5925 | __isl_give isl_multi_pw_aff *(*fn)(__isl_take isl_multi_pw_aff *mpa); | |||
5926 | const char *arg; | |||
5927 | const char *res; | |||
5928 | } mpa_un_tests[] = { | |||
5929 | { &isl_multi_pw_aff_range_factor_domain, | |||
5930 | "{ A[x] -> [B[(1 : x >= 5)] -> C[(2 : x <= 10)]] }", | |||
5931 | "{ A[x] -> B[(1 : x >= 5)] }" }, | |||
5932 | { &isl_multi_pw_aff_range_factor_range, | |||
5933 | "{ A[x] -> [B[(1 : x >= 5)] -> C[(2 : x <= 10)]] }", | |||
5934 | "{ A[y] -> C[(2 : y <= 10)] }" }, | |||
5935 | { &isl_multi_pw_aff_range_factor_domain, | |||
5936 | "{ A[x] -> [B[(1 : x >= 5)] -> C[]] }", | |||
5937 | "{ A[x] -> B[(1 : x >= 5)] }" }, | |||
5938 | { &isl_multi_pw_aff_range_factor_range, | |||
5939 | "{ A[x] -> [B[(1 : x >= 5)] -> C[]] }", | |||
5940 | "{ A[y] -> C[] }" }, | |||
5941 | { &isl_multi_pw_aff_range_factor_domain, | |||
5942 | "{ A[x] -> [B[] -> C[(2 : x <= 10)]] }", | |||
5943 | "{ A[x] -> B[] }" }, | |||
5944 | { &isl_multi_pw_aff_range_factor_range, | |||
5945 | "{ A[x] -> [B[] -> C[(2 : x <= 10)]] }", | |||
5946 | "{ A[y] -> C[(2 : y <= 10)] }" }, | |||
5947 | { &isl_multi_pw_aff_range_factor_domain, | |||
5948 | "{ A[x] -> [B[] -> C[]] }", | |||
5949 | "{ A[x] -> B[] }" }, | |||
5950 | { &isl_multi_pw_aff_range_factor_range, | |||
5951 | "{ A[x] -> [B[] -> C[]] }", | |||
5952 | "{ A[y] -> C[] }" }, | |||
5953 | { &isl_multi_pw_aff_factor_range, | |||
5954 | "{ [B[] -> C[]] }", | |||
5955 | "{ C[] }" }, | |||
5956 | { &isl_multi_pw_aff_range_factor_domain, | |||
5957 | "{ A[x] -> [B[] -> C[]] : x >= 0 }", | |||
5958 | "{ A[x] -> B[] : x >= 0 }" }, | |||
5959 | { &isl_multi_pw_aff_range_factor_range, | |||
5960 | "{ A[x] -> [B[] -> C[]] : x >= 0 }", | |||
5961 | "{ A[y] -> C[] : y >= 0 }" }, | |||
5962 | { &isl_multi_pw_aff_factor_range, | |||
5963 | "[N] -> { [B[] -> C[]] : N >= 0 }", | |||
5964 | "[N] -> { C[] : N >= 0 }" }, | |||
5965 | }; | |||
5966 | ||||
5967 | /* Perform some basic tests of unary operations on isl_multi_pw_aff objects. | |||
5968 | */ | |||
5969 | static int test_un_mpa(isl_ctx *ctx) | |||
5970 | { | |||
5971 | int i; | |||
5972 | isl_bool ok; | |||
5973 | isl_multi_pw_aff *mpa, *res; | |||
5974 | ||||
5975 | for (i = 0; i < ARRAY_SIZE(mpa_un_tests)(sizeof(mpa_un_tests)/sizeof(*mpa_un_tests)); ++i) { | |||
5976 | mpa = isl_multi_pw_aff_read_from_str(ctx, mpa_un_tests[i].arg); | |||
5977 | res = isl_multi_pw_aff_read_from_str(ctx, mpa_un_tests[i].res); | |||
5978 | mpa = mpa_un_tests[i].fn(mpa); | |||
5979 | ok = isl_multi_pw_aff_plain_is_equal(mpa, res); | |||
5980 | isl_multi_pw_aff_free(mpa); | |||
5981 | isl_multi_pw_aff_free(res); | |||
5982 | if (ok < 0) | |||
5983 | return -1; | |||
5984 | if (!ok) | |||
5985 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 5986); return -1; } while (0) | |||
5986 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 5986); return -1; } while (0); | |||
5987 | } | |||
5988 | ||||
5989 | return 0; | |||
5990 | } | |||
5991 | ||||
5992 | /* Inputs for basic tests of binary operations on isl_multi_pw_aff objects. | |||
5993 | * "fn" is the function that is tested. | |||
5994 | * "arg1" and "arg2" are string descriptions of the inputs. | |||
5995 | * "res" is a string description of the expected result. | |||
5996 | */ | |||
5997 | struct { | |||
5998 | __isl_give isl_multi_pw_aff *(*fn)( | |||
5999 | __isl_take isl_multi_pw_aff *mpa1, | |||
6000 | __isl_take isl_multi_pw_aff *mpa2); | |||
6001 | const char *arg1; | |||
6002 | const char *arg2; | |||
6003 | const char *res; | |||
6004 | } mpa_bin_tests[] = { | |||
6005 | { &isl_multi_pw_aff_add, "{ A[] -> [1] }", "{ A[] -> [2] }", | |||
6006 | "{ A[] -> [3] }" }, | |||
6007 | { &isl_multi_pw_aff_add, "{ A[x] -> [(1 : x >= 5)] }", | |||
6008 | "{ A[x] -> [(x : x <= 10)] }", | |||
6009 | "{ A[x] -> [(1 + x : 5 <= x <= 10)] }" }, | |||
6010 | { &isl_multi_pw_aff_add, "{ A[x] -> [] : x >= 5 }", | |||
6011 | "{ A[x] -> [] : x <= 10 }", | |||
6012 | "{ A[x] -> [] : 5 <= x <= 10 }" }, | |||
6013 | { &isl_multi_pw_aff_add, "{ A[x] -> [] : x >= 5 }", | |||
6014 | "[N] -> { A[x] -> [] : x <= N }", | |||
6015 | "[N] -> { A[x] -> [] : 5 <= x <= N }" }, | |||
6016 | { &isl_multi_pw_aff_add, | |||
6017 | "[N] -> { A[x] -> [] : x <= N }", | |||
6018 | "{ A[x] -> [] : x >= 5 }", | |||
6019 | "[N] -> { A[x] -> [] : 5 <= x <= N }" }, | |||
6020 | { &isl_multi_pw_aff_range_product, "{ A[x] -> B[(1 : x >= 5)] }", | |||
6021 | "{ A[y] -> C[(2 : y <= 10)] }", | |||
6022 | "{ A[x] -> [B[(1 : x >= 5)] -> C[(2 : x <= 10)]] }" }, | |||
6023 | { &isl_multi_pw_aff_range_product, "{ A[x] -> B[1] : x >= 5 }", | |||
6024 | "{ A[y] -> C[2] : y <= 10 }", | |||
6025 | "{ A[x] -> [B[(1 : x >= 5)] -> C[(2 : x <= 10)]] }" }, | |||
6026 | { &isl_multi_pw_aff_range_product, "{ A[x] -> B[1] : x >= 5 }", | |||
6027 | "[N] -> { A[y] -> C[2] : y <= N }", | |||
6028 | "[N] -> { A[x] -> [B[(1 : x >= 5)] -> C[(2 : x <= N)]] }" }, | |||
6029 | { &isl_multi_pw_aff_range_product, "[N] -> { A[x] -> B[1] : x >= N }", | |||
6030 | "{ A[y] -> C[2] : y <= 10 }", | |||
6031 | "[N] -> { A[x] -> [B[(1 : x >= N)] -> C[(2 : x <= 10)]] }" }, | |||
6032 | { &isl_multi_pw_aff_range_product, "{ A[] -> B[1] }", "{ A[] -> C[2] }", | |||
6033 | "{ A[] -> [B[1] -> C[2]] }" }, | |||
6034 | { &isl_multi_pw_aff_range_product, "{ A[] -> B[] }", "{ A[] -> C[] }", | |||
6035 | "{ A[] -> [B[] -> C[]] }" }, | |||
6036 | { &isl_multi_pw_aff_range_product, "{ A[x] -> B[(1 : x >= 5)] }", | |||
6037 | "{ A[y] -> C[] : y <= 10 }", | |||
6038 | "{ A[x] -> [B[(1 : x >= 5)] -> C[]] : x <= 10 }" }, | |||
6039 | { &isl_multi_pw_aff_range_product, "{ A[y] -> C[] : y <= 10 }", | |||
6040 | "{ A[x] -> B[(1 : x >= 5)] }", | |||
6041 | "{ A[x] -> [C[] -> B[(1 : x >= 5)]] : x <= 10 }" }, | |||
6042 | { &isl_multi_pw_aff_product, "{ A[x] -> B[(1 : x >= 5)] }", | |||
6043 | "{ A[y] -> C[(2 : y <= 10)] }", | |||
6044 | "{ [A[x] -> A[y]] -> [B[(1 : x >= 5)] -> C[(2 : y <= 10)]] }" }, | |||
6045 | { &isl_multi_pw_aff_product, "{ A[x] -> B[(1 : x >= 5)] }", | |||
6046 | "{ A[y] -> C[] : y <= 10 }", | |||
6047 | "{ [A[x] -> A[y]] -> [B[(1 : x >= 5)] -> C[]] : y <= 10 }" }, | |||
6048 | { &isl_multi_pw_aff_product, "{ A[y] -> C[] : y <= 10 }", | |||
6049 | "{ A[x] -> B[(1 : x >= 5)] }", | |||
6050 | "{ [A[y] -> A[x]] -> [C[] -> B[(1 : x >= 5)]] : y <= 10 }" }, | |||
6051 | { &isl_multi_pw_aff_product, "{ A[x] -> B[(1 : x >= 5)] }", | |||
6052 | "[N] -> { A[y] -> C[] : y <= N }", | |||
6053 | "[N] -> { [A[x] -> A[y]] -> [B[(1 : x >= 5)] -> C[]] : y <= N }" }, | |||
6054 | { &isl_multi_pw_aff_product, "[N] -> { A[y] -> C[] : y <= N }", | |||
6055 | "{ A[x] -> B[(1 : x >= 5)] }", | |||
6056 | "[N] -> { [A[y] -> A[x]] -> [C[] -> B[(1 : x >= 5)]] : y <= N }" }, | |||
6057 | { &isl_multi_pw_aff_product, "{ A[x] -> B[] : x >= 5 }", | |||
6058 | "{ A[y] -> C[] : y <= 10 }", | |||
6059 | "{ [A[x] -> A[y]] -> [B[] -> C[]] : x >= 5 and y <= 10 }" }, | |||
6060 | { &isl_multi_pw_aff_product, "{ A[] -> B[1] }", "{ A[] -> C[2] }", | |||
6061 | "{ [A[] -> A[]] -> [B[1] -> C[2]] }" }, | |||
6062 | { &isl_multi_pw_aff_product, "{ A[] -> B[] }", "{ A[] -> C[] }", | |||
6063 | "{ [A[] -> A[]] -> [B[] -> C[]] }" }, | |||
6064 | { &isl_multi_pw_aff_pullback_multi_pw_aff, | |||
6065 | "{ B[i,j] -> C[i + 2j] }", "{ A[a,b] -> B[b,a] }", | |||
6066 | "{ A[a,b] -> C[b + 2a] }" }, | |||
6067 | { &isl_multi_pw_aff_pullback_multi_pw_aff, | |||
6068 | "{ B[i,j] -> C[i + 2j] }", | |||
6069 | "{ A[a,b] -> B[(b : b > a),(a : b > a)] }", | |||
6070 | "{ A[a,b] -> C[(b + 2a : b > a)] }" }, | |||
6071 | { &isl_multi_pw_aff_pullback_multi_pw_aff, | |||
6072 | "{ B[i,j] -> C[(i + 2j : j > 4)] }", | |||
6073 | "{ A[a,b] -> B[(b : b > a),(a : b > a)] }", | |||
6074 | "{ A[a,b] -> C[(b + 2a : b > a > 4)] }" }, | |||
6075 | { &isl_multi_pw_aff_pullback_multi_pw_aff, | |||
6076 | "{ B[i,j] -> C[] }", | |||
6077 | "{ A[a,b] -> B[(b : b > a),(a : b > a)] }", | |||
6078 | "{ A[a,b] -> C[] }" }, | |||
6079 | { &isl_multi_pw_aff_pullback_multi_pw_aff, | |||
6080 | "{ B[i,j] -> C[] : i > j }", | |||
6081 | "{ A[a,b] -> B[b,a] }", | |||
6082 | "{ A[a,b] -> C[] : b > a }" }, | |||
6083 | { &isl_multi_pw_aff_pullback_multi_pw_aff, | |||
6084 | "{ B[i,j] -> C[] : j > 5 }", | |||
6085 | "{ A[a,b] -> B[(b : b > a),(a : b > a)] }", | |||
6086 | "{ A[a,b] -> C[] : b > a > 5 }" }, | |||
6087 | { &isl_multi_pw_aff_pullback_multi_pw_aff, | |||
6088 | "[N] -> { B[i,j] -> C[] : j > N }", | |||
6089 | "{ A[a,b] -> B[(b : b > a),(a : b > a)] }", | |||
6090 | "[N] -> { A[a,b] -> C[] : b > a > N }" }, | |||
6091 | { &isl_multi_pw_aff_pullback_multi_pw_aff, | |||
6092 | "[M,N] -> { B[] -> C[] : N > 5 }", | |||
6093 | "[M,N] -> { A[] -> B[] : M > N }", | |||
6094 | "[M,N] -> { A[] -> C[] : M > N > 5 }" }, | |||
6095 | }; | |||
6096 | ||||
6097 | /* Perform some basic tests of binary operations on isl_multi_pw_aff objects. | |||
6098 | */ | |||
6099 | static int test_bin_mpa(isl_ctx *ctx) | |||
6100 | { | |||
6101 | int i; | |||
6102 | isl_bool ok; | |||
6103 | isl_multi_pw_aff *mpa1, *mpa2, *res; | |||
6104 | ||||
6105 | for (i = 0; i < ARRAY_SIZE(mpa_bin_tests)(sizeof(mpa_bin_tests)/sizeof(*mpa_bin_tests)); ++i) { | |||
6106 | mpa1 = isl_multi_pw_aff_read_from_str(ctx, | |||
6107 | mpa_bin_tests[i].arg1); | |||
6108 | mpa2 = isl_multi_pw_aff_read_from_str(ctx, | |||
6109 | mpa_bin_tests[i].arg2); | |||
6110 | res = isl_multi_pw_aff_read_from_str(ctx, | |||
6111 | mpa_bin_tests[i].res); | |||
6112 | mpa1 = mpa_bin_tests[i].fn(mpa1, mpa2); | |||
6113 | ok = isl_multi_pw_aff_plain_is_equal(mpa1, res); | |||
6114 | isl_multi_pw_aff_free(mpa1); | |||
6115 | isl_multi_pw_aff_free(res); | |||
6116 | if (ok < 0) | |||
6117 | return -1; | |||
6118 | if (!ok) | |||
6119 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6120); return -1; } while (0) | |||
6120 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6120); return -1; } while (0); | |||
6121 | } | |||
6122 | ||||
6123 | return 0; | |||
6124 | } | |||
6125 | ||||
6126 | /* Inputs for basic tests of unary operations on | |||
6127 | * isl_multi_union_pw_aff objects. | |||
6128 | * "fn" is the function that is tested. | |||
6129 | * "arg" is a string description of the input. | |||
6130 | * "res" is a string description of the expected result. | |||
6131 | */ | |||
6132 | struct { | |||
6133 | __isl_give isl_multi_union_pw_aff *(*fn)( | |||
6134 | __isl_take isl_multi_union_pw_aff *mupa); | |||
6135 | const char *arg; | |||
6136 | const char *res; | |||
6137 | } mupa_un_tests[] = { | |||
6138 | { &isl_multi_union_pw_aff_factor_range, | |||
6139 | "[B[{ A[] -> [1] }] -> C[{ A[] -> [2] }]]", | |||
6140 | "C[{ A[] -> [2] }]" }, | |||
6141 | { &isl_multi_union_pw_aff_factor_range, | |||
6142 | "[B[] -> C[{ A[] -> [2] }]]", | |||
6143 | "C[{ A[] -> [2] }]" }, | |||
6144 | { &isl_multi_union_pw_aff_factor_range, | |||
6145 | "[B[{ A[] -> [1] }] -> C[]]", | |||
6146 | "C[]" }, | |||
6147 | { &isl_multi_union_pw_aff_factor_range, | |||
6148 | "[B[] -> C[]]", | |||
6149 | "C[]" }, | |||
6150 | { &isl_multi_union_pw_aff_factor_range, | |||
6151 | "([B[] -> C[]] : { A[x] : x >= 0 })", | |||
6152 | "(C[] : { A[x] : x >= 0 })" }, | |||
6153 | { &isl_multi_union_pw_aff_factor_range, | |||
6154 | "[N] -> ([B[] -> C[]] : { A[x] : x <= N })", | |||
6155 | "[N] -> (C[] : { A[x] : x <= N })" }, | |||
6156 | { &isl_multi_union_pw_aff_factor_range, | |||
6157 | "[N] -> ([B[] -> C[]] : { : N >= 0 })", | |||
6158 | "[N] -> (C[] : { : N >= 0 })" }, | |||
6159 | }; | |||
6160 | ||||
6161 | /* Perform some basic tests of unary operations on | |||
6162 | * isl_multi_union_pw_aff objects. | |||
6163 | */ | |||
6164 | static int test_un_mupa(isl_ctx *ctx) | |||
6165 | { | |||
6166 | int i; | |||
6167 | isl_bool ok; | |||
6168 | isl_multi_union_pw_aff *mupa, *res; | |||
6169 | ||||
6170 | for (i = 0; i < ARRAY_SIZE(mupa_un_tests)(sizeof(mupa_un_tests)/sizeof(*mupa_un_tests)); ++i) { | |||
6171 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6172 | mupa_un_tests[i].arg); | |||
6173 | res = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6174 | mupa_un_tests[i].res); | |||
6175 | mupa = mupa_un_tests[i].fn(mupa); | |||
6176 | ok = isl_multi_union_pw_aff_plain_is_equal(mupa, res); | |||
6177 | isl_multi_union_pw_aff_free(mupa); | |||
6178 | isl_multi_union_pw_aff_free(res); | |||
6179 | if (ok < 0) | |||
6180 | return -1; | |||
6181 | if (!ok) | |||
6182 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6183); return -1; } while (0) | |||
6183 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6183); return -1; } while (0); | |||
6184 | } | |||
6185 | ||||
6186 | return 0; | |||
6187 | } | |||
6188 | ||||
6189 | /* Inputs for basic tests of binary operations on | |||
6190 | * isl_multi_union_pw_aff objects. | |||
6191 | * "fn" is the function that is tested. | |||
6192 | * "arg1" and "arg2" are string descriptions of the inputs. | |||
6193 | * "res" is a string description of the expected result. | |||
6194 | */ | |||
6195 | struct { | |||
6196 | __isl_give isl_multi_union_pw_aff *(*fn)( | |||
6197 | __isl_take isl_multi_union_pw_aff *mupa1, | |||
6198 | __isl_take isl_multi_union_pw_aff *mupa2); | |||
6199 | const char *arg1; | |||
6200 | const char *arg2; | |||
6201 | const char *res; | |||
6202 | } mupa_bin_tests[] = { | |||
6203 | { &isl_multi_union_pw_aff_add, "[{ A[] -> [1] }]", "[{ A[] -> [2] }]", | |||
6204 | "[{ A[] -> [3] }]" }, | |||
6205 | { &isl_multi_union_pw_aff_sub, "[{ A[] -> [1] }]", "[{ A[] -> [2] }]", | |||
6206 | "[{ A[] -> [-1] }]" }, | |||
6207 | { &isl_multi_union_pw_aff_add, | |||
6208 | "[{ A[] -> [1]; B[] -> [4] }]", | |||
6209 | "[{ A[] -> [2]; C[] -> [5] }]", | |||
6210 | "[{ A[] -> [3] }]" }, | |||
6211 | { &isl_multi_union_pw_aff_union_add, | |||
6212 | "[{ A[] -> [1]; B[] -> [4] }]", | |||
6213 | "[{ A[] -> [2]; C[] -> [5] }]", | |||
6214 | "[{ A[] -> [3]; B[] -> [4]; C[] -> [5] }]" }, | |||
6215 | { &isl_multi_union_pw_aff_add, "[{ A[x] -> [(1)] : x >= 5 }]", | |||
6216 | "[{ A[x] -> [(x)] : x <= 10 }]", | |||
6217 | "[{ A[x] -> [(1 + x)] : 5 <= x <= 10 }]" }, | |||
6218 | { &isl_multi_union_pw_aff_add, "([] : { A[x] : x >= 5 })", | |||
6219 | "([] : { A[x] : x <= 10 })", | |||
6220 | "([] : { A[x] : 5 <= x <= 10 })" }, | |||
6221 | { &isl_multi_union_pw_aff_add, "([] : { A[x] : x >= 5 })", | |||
6222 | "[N] -> ([] : { A[x] : x <= N })", | |||
6223 | "[N] -> ([] : { A[x] : 5 <= x <= N })" }, | |||
6224 | { &isl_multi_union_pw_aff_add, "[N] -> ([] : { A[x] : x >= N })", | |||
6225 | "([] : { A[x] : x <= 10 })", | |||
6226 | "[N] -> ([] : { A[x] : N <= x <= 10 })" }, | |||
6227 | { &isl_multi_union_pw_aff_union_add, "[{ A[x] -> [(1)] : x >= 5 }]", | |||
6228 | "[{ A[x] -> [(x)] : x <= 10 }]", | |||
6229 | "[{ A[x] -> [(1 + x)] : 5 <= x <= 10; " | |||
6230 | "A[x] -> [(1)] : x > 10; A[x] -> [(x)] : x < 5 }]" }, | |||
6231 | { &isl_multi_union_pw_aff_union_add, "([] : { A[x] : x >= 5 })", | |||
6232 | "([] : { A[x] : x <= 10 })", | |||
6233 | "([] : { A[x] })" }, | |||
6234 | { &isl_multi_union_pw_aff_union_add, "([] : { A[x] : x >= 0 })", | |||
6235 | "[N] -> ([] : { A[x] : x >= N })", | |||
6236 | "[N] -> ([] : { A[x] : x >= 0 or x >= N })" }, | |||
6237 | { &isl_multi_union_pw_aff_union_add, | |||
6238 | "[N] -> ([] : { A[] : N >= 0})", | |||
6239 | "[N] -> ([] : { A[] : N <= 0})", | |||
6240 | "[N] -> ([] : { A[] })" }, | |||
6241 | { &isl_multi_union_pw_aff_union_add, | |||
6242 | "[N] -> ([] : { A[] })", | |||
6243 | "[N] -> ([] : { : })", | |||
6244 | "[N] -> ([] : { : })" }, | |||
6245 | { &isl_multi_union_pw_aff_union_add, | |||
6246 | "[N] -> ([] : { : })", | |||
6247 | "[N] -> ([] : { A[] })", | |||
6248 | "[N] -> ([] : { : })" }, | |||
6249 | { &isl_multi_union_pw_aff_union_add, | |||
6250 | "[N] -> ([] : { : N >= 0})", | |||
6251 | "[N] -> ([] : { : N <= 0})", | |||
6252 | "[N] -> ([] : { : })" }, | |||
6253 | { &isl_multi_union_pw_aff_range_product, | |||
6254 | "B[{ A[] -> [1] }]", | |||
6255 | "C[{ A[] -> [2] }]", | |||
6256 | "[B[{ A[] -> [1] }] -> C[{ A[] -> [2] }]]" }, | |||
6257 | { &isl_multi_union_pw_aff_range_product, | |||
6258 | "(B[] : { A[x] : x >= 5 })", | |||
6259 | "(C[] : { A[x] : x <= 10 })", | |||
6260 | "([B[] -> C[]] : { A[x] : 5 <= x <= 10 })" }, | |||
6261 | { &isl_multi_union_pw_aff_range_product, | |||
6262 | "B[{ A[x] -> [x + 1] : x >= 5 }]", | |||
6263 | "(C[] : { A[x] : x <= 10 })", | |||
6264 | "[B[{ A[x] -> [x + 1] : 5 <= x <= 10 }] -> C[]]" }, | |||
6265 | { &isl_multi_union_pw_aff_range_product, | |||
6266 | "(C[] : { A[x] : x <= 10 })", | |||
6267 | "B[{ A[x] -> [x + 1] : x >= 5 }]", | |||
6268 | "[C[] -> B[{ A[x] -> [x + 1] : 5 <= x <= 10 }]]" }, | |||
6269 | { &isl_multi_union_pw_aff_range_product, | |||
6270 | "B[{ A[x] -> [x + 1] : x >= 5 }]", | |||
6271 | "[N] -> (C[] : { A[x] : x <= N })", | |||
6272 | "[N] -> [B[{ A[x] -> [x + 1] : 5 <= x <= N }] -> C[]]" }, | |||
6273 | { &isl_multi_union_pw_aff_range_product, | |||
6274 | "[N] -> (C[] : { A[x] : x <= N })", | |||
6275 | "B[{ A[x] -> [x + 1] : x >= 5 }]", | |||
6276 | "[N] -> [C[] -> B[{ A[x] -> [x + 1] : 5 <= x <= N }]]" }, | |||
6277 | { &isl_multi_union_pw_aff_range_product, | |||
6278 | "B[{ A[] -> [1]; D[] -> [3] }]", | |||
6279 | "C[{ A[] -> [2] }]", | |||
6280 | "[B[{ A[] -> [1]; D[] -> [3] }] -> C[{ A[] -> [2] }]]" }, | |||
6281 | { &isl_multi_union_pw_aff_range_product, | |||
6282 | "B[] }]", | |||
6283 | "(C[] : { A[x] })", | |||
6284 | "([B[] -> C[]] : { A[x] })" }, | |||
6285 | { &isl_multi_union_pw_aff_range_product, | |||
6286 | "(B[] : { A[x] })", | |||
6287 | "C[] }]", | |||
6288 | "([B[] -> C[]] : { A[x] })" }, | |||
6289 | }; | |||
6290 | ||||
6291 | /* Perform some basic tests of binary operations on | |||
6292 | * isl_multi_union_pw_aff objects. | |||
6293 | */ | |||
6294 | static int test_bin_mupa(isl_ctx *ctx) | |||
6295 | { | |||
6296 | int i; | |||
6297 | isl_bool ok; | |||
6298 | isl_multi_union_pw_aff *mupa1, *mupa2, *res; | |||
6299 | ||||
6300 | for (i = 0; i < ARRAY_SIZE(mupa_bin_tests)(sizeof(mupa_bin_tests)/sizeof(*mupa_bin_tests)); ++i) { | |||
6301 | mupa1 = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6302 | mupa_bin_tests[i].arg1); | |||
6303 | mupa2 = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6304 | mupa_bin_tests[i].arg2); | |||
6305 | res = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6306 | mupa_bin_tests[i].res); | |||
6307 | mupa1 = mupa_bin_tests[i].fn(mupa1, mupa2); | |||
6308 | ok = isl_multi_union_pw_aff_plain_is_equal(mupa1, res); | |||
6309 | isl_multi_union_pw_aff_free(mupa1); | |||
6310 | isl_multi_union_pw_aff_free(res); | |||
6311 | if (ok < 0) | |||
6312 | return -1; | |||
6313 | if (!ok) | |||
6314 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6315); return -1; } while (0) | |||
6315 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6315); return -1; } while (0); | |||
6316 | } | |||
6317 | ||||
6318 | return 0; | |||
6319 | } | |||
6320 | ||||
6321 | /* Inputs for basic tests of binary operations on | |||
6322 | * pairs of isl_multi_union_pw_aff and isl_set objects. | |||
6323 | * "fn" is the function that is tested. | |||
6324 | * "arg1" and "arg2" are string descriptions of the inputs. | |||
6325 | * "res" is a string description of the expected result. | |||
6326 | */ | |||
6327 | struct { | |||
6328 | __isl_give isl_multi_union_pw_aff *(*fn)( | |||
6329 | __isl_take isl_multi_union_pw_aff *mupa, | |||
6330 | __isl_take isl_setisl_map *set); | |||
6331 | const char *arg1; | |||
6332 | const char *arg2; | |||
6333 | const char *res; | |||
6334 | } mupa_set_tests[] = { | |||
6335 | { &isl_multi_union_pw_aff_intersect_range, | |||
6336 | "C[{ B[i,j] -> [i + 2j] }]", "{ C[1] }", | |||
6337 | "C[{ B[i,j] -> [i + 2j] : i + 2j = 1 }]" }, | |||
6338 | { &isl_multi_union_pw_aff_intersect_range, | |||
6339 | "C[{ B[i,j] -> [i + 2j] }]", "[N] -> { C[N] }", | |||
6340 | "[N] -> C[{ B[i,j] -> [i + 2j] : i + 2j = N }]" }, | |||
6341 | { &isl_multi_union_pw_aff_intersect_range, | |||
6342 | "[N] -> C[{ B[i,j] -> [i + 2j + N] }]", "{ C[1] }", | |||
6343 | "[N] -> C[{ B[i,j] -> [i + 2j + N] : i + 2j + N = 1 }]" }, | |||
6344 | { &isl_multi_union_pw_aff_intersect_range, | |||
6345 | "C[{ B[i,j] -> [i + 2j] }]", "[N] -> { C[x] : N >= 0 }", | |||
6346 | "[N] -> C[{ B[i,j] -> [i + 2j] : N >= 0 }]" }, | |||
6347 | { &isl_multi_union_pw_aff_intersect_range, | |||
6348 | "C[]", "{ C[] }", "C[]" }, | |||
6349 | { &isl_multi_union_pw_aff_intersect_range, | |||
6350 | "[N] -> (C[] : { : N >= 0 })", | |||
6351 | "{ C[] }", | |||
6352 | "[N] -> (C[] : { : N >= 0 })" }, | |||
6353 | { &isl_multi_union_pw_aff_intersect_range, | |||
6354 | "(C[] : { A[a,b] })", | |||
6355 | "{ C[] }", | |||
6356 | "(C[] : { A[a,b] })" }, | |||
6357 | { &isl_multi_union_pw_aff_intersect_range, | |||
6358 | "[N] -> (C[] : { A[a,b] : a,b <= N })", | |||
6359 | "{ C[] }", | |||
6360 | "[N] -> (C[] : { A[a,b] : a,b <= N })" }, | |||
6361 | { &isl_multi_union_pw_aff_intersect_range, | |||
6362 | "C[]", | |||
6363 | "[N] -> { C[] : N >= 0 }", | |||
6364 | "[N] -> (C[] : { : N >= 0 })" }, | |||
6365 | { &isl_multi_union_pw_aff_intersect_range, | |||
6366 | "(C[] : { A[a,b] })", | |||
6367 | "[N] -> { C[] : N >= 0 }", | |||
6368 | "[N] -> (C[] : { A[a,b] : N >= 0 })" }, | |||
6369 | { &isl_multi_union_pw_aff_intersect_range, | |||
6370 | "[N] -> (C[] : { : N >= 0 })", | |||
6371 | "[N] -> { C[] : N < 1024 }", | |||
6372 | "[N] -> (C[] : { : 0 <= N < 1024 })" }, | |||
6373 | { &isl_multi_union_pw_aff_intersect_params, | |||
6374 | "C[{ B[i,j] -> [i + 2j] }]", "[N] -> { : N >= 0 }", | |||
6375 | "[N] -> C[{ B[i,j] -> [i + 2j] : N >= 0}]" }, | |||
6376 | { &isl_multi_union_pw_aff_intersect_params, | |||
6377 | "[N] -> C[{ B[i,j] -> [i + 2j] : N <= 256 }]", "[N] -> { : N >= 0 }", | |||
6378 | "[N] -> C[{ B[i,j] -> [i + 2j] : 0 <= N <= 256 }]" }, | |||
6379 | { &isl_multi_union_pw_aff_intersect_params, | |||
6380 | "[N] -> C[{ B[i,j] -> [i + 2j] : N <= 256 }]", "{ : }", | |||
6381 | "[N] -> C[{ B[i,j] -> [i + 2j] : N <= 256 }]" }, | |||
6382 | { &isl_multi_union_pw_aff_intersect_params, | |||
6383 | "C[]", "[N] -> { : N >= 0 }", | |||
6384 | "[N] -> (C[] : { : N >= 0 })" }, | |||
6385 | { &isl_multi_union_pw_aff_intersect_params, | |||
6386 | "(C[] : { A[a,b] })", "[N] -> { : N >= 0 }", | |||
6387 | "[N] -> (C[] : { A[a,b] : N >= 0 })" }, | |||
6388 | { &isl_multi_union_pw_aff_intersect_params, | |||
6389 | "[N] -> (C[] : { A[a,N] })", "{ : }", | |||
6390 | "[N] -> (C[] : { A[a,N] })" }, | |||
6391 | { &isl_multi_union_pw_aff_intersect_params, | |||
6392 | "[N] -> (C[] : { A[a,b] : N <= 256 })", "[N] -> { : N >= 0 }", | |||
6393 | "[N] -> (C[] : { A[a,b] : 0 <= N <= 256 })" }, | |||
6394 | }; | |||
6395 | ||||
6396 | /* Perform some basic tests of binary operations on | |||
6397 | * pairs of isl_multi_union_pw_aff and isl_set objects. | |||
6398 | */ | |||
6399 | static int test_mupa_set(isl_ctx *ctx) | |||
6400 | { | |||
6401 | int i; | |||
6402 | isl_bool ok; | |||
6403 | isl_multi_union_pw_aff *mupa, *res; | |||
6404 | isl_setisl_map *set; | |||
6405 | ||||
6406 | for (i = 0; i < ARRAY_SIZE(mupa_set_tests)(sizeof(mupa_set_tests)/sizeof(*mupa_set_tests)); ++i) { | |||
6407 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6408 | mupa_set_tests[i].arg1); | |||
6409 | set = isl_set_read_from_str(ctx, mupa_set_tests[i].arg2); | |||
6410 | res = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6411 | mupa_set_tests[i].res); | |||
6412 | mupa = mupa_set_tests[i].fn(mupa, set); | |||
6413 | ok = isl_multi_union_pw_aff_plain_is_equal(mupa, res); | |||
6414 | isl_multi_union_pw_aff_free(mupa); | |||
6415 | isl_multi_union_pw_aff_free(res); | |||
6416 | if (ok < 0) | |||
6417 | return -1; | |||
6418 | if (!ok) | |||
6419 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6420); return -1; } while (0) | |||
6420 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6420); return -1; } while (0); | |||
6421 | } | |||
6422 | ||||
6423 | return 0; | |||
6424 | } | |||
6425 | ||||
6426 | /* Inputs for basic tests of binary operations on | |||
6427 | * pairs of isl_multi_union_pw_aff and isl_union_set objects. | |||
6428 | * "fn" is the function that is tested. | |||
6429 | * "arg1" and "arg2" are string descriptions of the inputs. | |||
6430 | * "res" is a string description of the expected result. | |||
6431 | */ | |||
6432 | struct { | |||
6433 | __isl_give isl_multi_union_pw_aff *(*fn)( | |||
6434 | __isl_take isl_multi_union_pw_aff *mupa, | |||
6435 | __isl_take isl_union_set *uset); | |||
6436 | const char *arg1; | |||
6437 | const char *arg2; | |||
6438 | const char *res; | |||
6439 | } mupa_uset_tests[] = { | |||
6440 | { &isl_multi_union_pw_aff_intersect_domain, | |||
6441 | "C[{ B[i,j] -> [i + 2j] }]", "{ B[i,i] }", | |||
6442 | "C[{ B[i,i] -> [3i] }]" }, | |||
6443 | { &isl_multi_union_pw_aff_intersect_domain, | |||
6444 | "(C[] : { B[i,j] })", "{ B[i,i] }", | |||
6445 | "(C[] : { B[i,i] })" }, | |||
6446 | { &isl_multi_union_pw_aff_intersect_domain, | |||
6447 | "(C[] : { B[i,j] })", "[N] -> { B[N,N] }", | |||
6448 | "[N] -> (C[] : { B[N,N] })" }, | |||
6449 | { &isl_multi_union_pw_aff_intersect_domain, | |||
6450 | "C[]", "{ B[i,i] }", | |||
6451 | "(C[] : { B[i,i] })" }, | |||
6452 | { &isl_multi_union_pw_aff_intersect_domain, | |||
6453 | "[N] -> (C[] : { : N >= 0 })", "{ B[i,i] }", | |||
6454 | "[N] -> (C[] : { B[i,i] : N >= 0 })" }, | |||
6455 | }; | |||
6456 | ||||
6457 | /* Perform some basic tests of binary operations on | |||
6458 | * pairs of isl_multi_union_pw_aff and isl_union_set objects. | |||
6459 | */ | |||
6460 | static int test_mupa_uset(isl_ctx *ctx) | |||
6461 | { | |||
6462 | int i; | |||
6463 | isl_bool ok; | |||
6464 | isl_multi_union_pw_aff *mupa, *res; | |||
6465 | isl_union_set *uset; | |||
6466 | ||||
6467 | for (i = 0; i < ARRAY_SIZE(mupa_uset_tests)(sizeof(mupa_uset_tests)/sizeof(*mupa_uset_tests)); ++i) { | |||
6468 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6469 | mupa_uset_tests[i].arg1); | |||
6470 | uset = isl_union_set_read_from_str(ctx, | |||
6471 | mupa_uset_tests[i].arg2); | |||
6472 | res = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6473 | mupa_uset_tests[i].res); | |||
6474 | mupa = mupa_uset_tests[i].fn(mupa, uset); | |||
6475 | ok = isl_multi_union_pw_aff_plain_is_equal(mupa, res); | |||
6476 | isl_multi_union_pw_aff_free(mupa); | |||
6477 | isl_multi_union_pw_aff_free(res); | |||
6478 | if (ok < 0) | |||
6479 | return -1; | |||
6480 | if (!ok) | |||
6481 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6482); return -1; } while (0) | |||
6482 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6482); return -1; } while (0); | |||
6483 | } | |||
6484 | ||||
6485 | return 0; | |||
6486 | } | |||
6487 | ||||
6488 | /* Inputs for basic tests of binary operations on | |||
6489 | * pairs of isl_multi_union_pw_aff and isl_multi_aff objects. | |||
6490 | * "fn" is the function that is tested. | |||
6491 | * "arg1" and "arg2" are string descriptions of the inputs. | |||
6492 | * "res" is a string description of the expected result. | |||
6493 | */ | |||
6494 | struct { | |||
6495 | __isl_give isl_multi_union_pw_aff *(*fn)( | |||
6496 | __isl_take isl_multi_union_pw_aff *mupa, | |||
6497 | __isl_take isl_multi_aff *ma); | |||
6498 | const char *arg1; | |||
6499 | const char *arg2; | |||
6500 | const char *res; | |||
6501 | } mupa_ma_tests[] = { | |||
6502 | { &isl_multi_union_pw_aff_apply_multi_aff, | |||
6503 | "C[{ A[i,j] -> [i]; B[i,j] -> [j] }, " | |||
6504 | "{ A[i,j] -> [j]; B[i,j] -> [i] }]", | |||
6505 | "{ C[a,b] -> D[b,a] }", | |||
6506 | "D[{ A[i,j] -> [j]; B[i,j] -> [i] }, " | |||
6507 | "{ A[i,j] -> [i]; B[i,j] -> [j] }]" }, | |||
6508 | { &isl_multi_union_pw_aff_apply_multi_aff, | |||
6509 | "C[{ A[i,j] -> [i] : i >= 0; B[i,j] -> [j] }, " | |||
6510 | "{ A[i,j] -> [j]; B[i,j] -> [i] }]", | |||
6511 | "{ C[a,b] -> D[b,a] }", | |||
6512 | "D[{ A[i,j] -> [j] : i >= 0; B[i,j] -> [i] }, " | |||
6513 | "{ A[i,j] -> [i] : i >= 0; B[i,j] -> [j] }]" }, | |||
6514 | { &isl_multi_union_pw_aff_apply_multi_aff, | |||
6515 | "C[{ A[i,j] -> [i]; B[i,j] -> [j] }]", | |||
6516 | "[N] -> { C[a] -> D[a + N] }", | |||
6517 | "[N] -> D[{ A[i,j] -> [i + N]; B[i,j] -> [j + N] }] " }, | |||
6518 | { &isl_multi_union_pw_aff_apply_multi_aff, | |||
6519 | "C[]", | |||
6520 | "{ C[] -> D[] }", | |||
6521 | "D[]" }, | |||
6522 | { &isl_multi_union_pw_aff_apply_multi_aff, | |||
6523 | "[N] -> (C[] : { : N >= 0 })", | |||
6524 | "{ C[] -> D[] }", | |||
6525 | "[N] -> (D[] : { : N >= 0 })" }, | |||
6526 | { &isl_multi_union_pw_aff_apply_multi_aff, | |||
6527 | "C[]", | |||
6528 | "[N] -> { C[] -> D[N] }", | |||
6529 | "[N] -> D[{ [N] }]" }, | |||
6530 | { &isl_multi_union_pw_aff_apply_multi_aff, | |||
6531 | "(C[] : { A[i,j] : i >= j })", | |||
6532 | "{ C[] -> D[] }", | |||
6533 | "(D[] : { A[i,j] : i >= j })" }, | |||
6534 | { &isl_multi_union_pw_aff_apply_multi_aff, | |||
6535 | "[N] -> (C[] : { A[i,j] : N >= 0 })", | |||
6536 | "{ C[] -> D[] }", | |||
6537 | "[N] -> (D[] : { A[i,j] : N >= 0 })" }, | |||
6538 | { &isl_multi_union_pw_aff_apply_multi_aff, | |||
6539 | "(C[] : { A[i,j] : i >= j })", | |||
6540 | "[N] -> { C[] -> D[N] }", | |||
6541 | "[N] -> (D[{ A[i,j] -> [N] : i >= j }])" }, | |||
6542 | }; | |||
6543 | ||||
6544 | /* Perform some basic tests of binary operations on | |||
6545 | * pairs of isl_multi_union_pw_aff and isl_multi_aff objects. | |||
6546 | */ | |||
6547 | static int test_mupa_ma(isl_ctx *ctx) | |||
6548 | { | |||
6549 | int i; | |||
6550 | isl_bool ok; | |||
6551 | isl_multi_union_pw_aff *mupa, *res; | |||
6552 | isl_multi_aff *ma; | |||
6553 | ||||
6554 | for (i = 0; i < ARRAY_SIZE(mupa_ma_tests)(sizeof(mupa_ma_tests)/sizeof(*mupa_ma_tests)); ++i) { | |||
6555 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6556 | mupa_ma_tests[i].arg1); | |||
6557 | ma = isl_multi_aff_read_from_str(ctx, mupa_ma_tests[i].arg2); | |||
6558 | res = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6559 | mupa_ma_tests[i].res); | |||
6560 | mupa = mupa_ma_tests[i].fn(mupa, ma); | |||
6561 | ok = isl_multi_union_pw_aff_plain_is_equal(mupa, res); | |||
6562 | isl_multi_union_pw_aff_free(mupa); | |||
6563 | isl_multi_union_pw_aff_free(res); | |||
6564 | if (ok < 0) | |||
6565 | return -1; | |||
6566 | if (!ok) | |||
6567 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6568); return -1; } while (0) | |||
6568 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6568); return -1; } while (0); | |||
6569 | } | |||
6570 | ||||
6571 | return 0; | |||
6572 | } | |||
6573 | ||||
6574 | /* Inputs for basic tests of binary operations on | |||
6575 | * pairs of isl_multi_union_pw_aff and isl_pw_aff objects. | |||
6576 | * "fn" is the function that is tested. | |||
6577 | * "arg1" and "arg2" are string descriptions of the inputs. | |||
6578 | * "res" is a string description of the expected result. | |||
6579 | */ | |||
6580 | struct { | |||
6581 | __isl_give isl_union_pw_aff *(*fn)( | |||
6582 | __isl_take isl_multi_union_pw_aff *mupa, | |||
6583 | __isl_take isl_pw_aff *pa); | |||
6584 | const char *arg1; | |||
6585 | const char *arg2; | |||
6586 | const char *res; | |||
6587 | } mupa_pa_tests[] = { | |||
6588 | { &isl_multi_union_pw_aff_apply_pw_aff, | |||
6589 | "C[{ A[i,j] -> [i]; B[i,j] -> [j] }]", | |||
6590 | "[N] -> { C[a] -> [a + N] }", | |||
6591 | "[N] -> { A[i,j] -> [i + N]; B[i,j] -> [j + N] }" }, | |||
6592 | { &isl_multi_union_pw_aff_apply_pw_aff, | |||
6593 | "C[{ A[i,j] -> [i]; B[i,j] -> [j] }]", | |||
6594 | "{ C[a] -> [a] : a >= 0; C[a] -> [-a] : a < 0 }", | |||
6595 | "{ A[i,j] -> [i] : i >= 0; A[i,j] -> [-i] : i < 0; " | |||
6596 | "B[i,j] -> [j] : j >= 0; B[i,j] -> [-j] : j < 0 }" }, | |||
6597 | { &isl_multi_union_pw_aff_apply_pw_aff, | |||
6598 | "C[]", | |||
6599 | "[N] -> { C[] -> [N] }", | |||
6600 | "[N] -> { [N] }" }, | |||
6601 | { &isl_multi_union_pw_aff_apply_pw_aff, | |||
6602 | "C[]", | |||
6603 | "[N] -> { C[] -> [N] : N >= 0; C[] -> [-N] : N < 0 }", | |||
6604 | "[N] -> { [N] : N >= 0; [-N] : N < 0 }" }, | |||
6605 | { &isl_multi_union_pw_aff_apply_pw_aff, | |||
6606 | "[N] -> (C[] : { : N >= 0 })", | |||
6607 | "[N] -> { C[] -> [N] }", | |||
6608 | "[N] -> { [N] : N >= 0 }" }, | |||
6609 | { &isl_multi_union_pw_aff_apply_pw_aff, | |||
6610 | "[N] -> (C[] : { : N >= 0 })", | |||
6611 | "[N] -> { C[] -> [N] : N >= 0; C[] -> [-N] : N < 0 }", | |||
6612 | "[N] -> { [N] : N >= 0 }" }, | |||
6613 | { &isl_multi_union_pw_aff_apply_pw_aff, | |||
6614 | "[N] -> (C[] : { : N >= 0 })", | |||
6615 | "{ C[] -> [0] }", | |||
6616 | "[N] -> { [0] : N >= 0 }" }, | |||
6617 | { &isl_multi_union_pw_aff_apply_pw_aff, | |||
6618 | "(C[] : { A[i,j] : i >= j })", | |||
6619 | "[N] -> { C[] -> [N] }", | |||
6620 | "[N] -> { A[i,j] -> [N] : i >= j }" }, | |||
6621 | { &isl_multi_union_pw_aff_apply_pw_aff, | |||
6622 | "(C[] : { A[i,j] : i >= j })", | |||
6623 | "[N] -> { C[] -> [N] : N >= 0 }", | |||
6624 | "[N] -> { A[i,j] -> [N] : i >= j and N >= 0 }" }, | |||
6625 | }; | |||
6626 | ||||
6627 | /* Perform some basic tests of binary operations on | |||
6628 | * pairs of isl_multi_union_pw_aff and isl_pw_aff objects. | |||
6629 | */ | |||
6630 | static int test_mupa_pa(isl_ctx *ctx) | |||
6631 | { | |||
6632 | int i; | |||
6633 | isl_bool ok; | |||
6634 | isl_multi_union_pw_aff *mupa; | |||
6635 | isl_union_pw_aff *upa, *res; | |||
6636 | isl_pw_aff *pa; | |||
6637 | ||||
6638 | for (i = 0; i < ARRAY_SIZE(mupa_pa_tests)(sizeof(mupa_pa_tests)/sizeof(*mupa_pa_tests)); ++i) { | |||
6639 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6640 | mupa_pa_tests[i].arg1); | |||
6641 | pa = isl_pw_aff_read_from_str(ctx, mupa_pa_tests[i].arg2); | |||
6642 | res = isl_union_pw_aff_read_from_str(ctx, | |||
6643 | mupa_pa_tests[i].res); | |||
6644 | upa = mupa_pa_tests[i].fn(mupa, pa); | |||
6645 | ok = isl_union_pw_aff_plain_is_equal(upa, res); | |||
6646 | isl_union_pw_aff_free(upa); | |||
6647 | isl_union_pw_aff_free(res); | |||
6648 | if (ok < 0) | |||
6649 | return -1; | |||
6650 | if (!ok) | |||
6651 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6652); return -1; } while (0) | |||
6652 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6652); return -1; } while (0); | |||
6653 | } | |||
6654 | ||||
6655 | return 0; | |||
6656 | } | |||
6657 | ||||
6658 | /* Inputs for basic tests of binary operations on | |||
6659 | * pairs of isl_multi_union_pw_aff and isl_pw_multi_aff objects. | |||
6660 | * "fn" is the function that is tested. | |||
6661 | * "arg1" and "arg2" are string descriptions of the inputs. | |||
6662 | * "res" is a string description of the expected result. | |||
6663 | */ | |||
6664 | struct { | |||
6665 | __isl_give isl_multi_union_pw_aff *(*fn)( | |||
6666 | __isl_take isl_multi_union_pw_aff *mupa, | |||
6667 | __isl_take isl_pw_multi_aff *pma); | |||
6668 | const char *arg1; | |||
6669 | const char *arg2; | |||
6670 | const char *res; | |||
6671 | } mupa_pma_tests[] = { | |||
6672 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6673 | "C[{ A[i,j] -> [i]; B[i,j] -> [j] }, " | |||
6674 | "{ A[i,j] -> [j]; B[i,j] -> [i] }]", | |||
6675 | "{ C[a,b] -> D[b,a] }", | |||
6676 | "D[{ A[i,j] -> [j]; B[i,j] -> [i] }, " | |||
6677 | "{ A[i,j] -> [i]; B[i,j] -> [j] }]" }, | |||
6678 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6679 | "C[{ A[i,j] -> [i] : i >= 0; B[i,j] -> [j] }, " | |||
6680 | "{ A[i,j] -> [j]; B[i,j] -> [i] }]", | |||
6681 | "{ C[a,b] -> D[b,a] }", | |||
6682 | "D[{ A[i,j] -> [j] : i >= 0; B[i,j] -> [i] }, " | |||
6683 | "{ A[i,j] -> [i] : i >= 0; B[i,j] -> [j] }]" }, | |||
6684 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6685 | "C[{ A[i,j] -> [i]; B[i,j] -> [j] }]", | |||
6686 | "[N] -> { C[a] -> D[a + N] }", | |||
6687 | "[N] -> D[{ A[i,j] -> [i + N]; B[i,j] -> [j + N] }]" }, | |||
6688 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6689 | "C[{ A[i,j] -> [i]; B[i,j] -> [j] }]", | |||
6690 | "{ C[a] -> D[a] : a >= 0; C[a] -> D[-a] : a < 0 }", | |||
6691 | "D[{ A[i,j] -> [i] : i >= 0; A[i,j] -> [-i] : i < 0; " | |||
6692 | "B[i,j] -> [j] : j >= 0; B[i,j] -> [-j] : j < 0 }]" }, | |||
6693 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6694 | "C[{ A[i,j] -> [i]; B[i,j] -> [j] }, " | |||
6695 | "{ A[i,j] -> [j]; B[i,j] -> [i] }]", | |||
6696 | "{ C[a,b] -> D[a,b] : a >= b; C[a,b] -> D[b,a] : a < b }", | |||
6697 | "D[{ A[i,j] -> [i] : i >= j; A[i,j] -> [j] : i < j; " | |||
6698 | "B[i,j] -> [j] : i <= j; B[i,j] -> [i] : i > j }, " | |||
6699 | "{ A[i,j] -> [j] : i >= j; A[i,j] -> [i] : i < j; " | |||
6700 | "B[i,j] -> [i] : i <= j; B[i,j] -> [j] : i > j }]" }, | |||
6701 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6702 | "C[]", | |||
6703 | "{ C[] -> D[] }", | |||
6704 | "D[]" }, | |||
6705 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6706 | "[N] -> (C[] : { : N >= 0 })", | |||
6707 | "{ C[] -> D[] }", | |||
6708 | "[N] -> (D[] : { : N >= 0 })" }, | |||
6709 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6710 | "C[]", | |||
6711 | "[N] -> { C[] -> D[N] }", | |||
6712 | "[N] -> D[{ [N] }]" }, | |||
6713 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6714 | "(C[] : { A[i,j] : i >= j })", | |||
6715 | "{ C[] -> D[] }", | |||
6716 | "(D[] : { A[i,j] : i >= j })" }, | |||
6717 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6718 | "[N] -> (C[] : { A[i,j] : N >= 0 })", | |||
6719 | "{ C[] -> D[] }", | |||
6720 | "[N] -> (D[] : { A[i,j] : N >= 0 })" }, | |||
6721 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6722 | "(C[] : { A[i,j] : i >= j })", | |||
6723 | "[N] -> { C[] -> D[N] }", | |||
6724 | "[N] -> (D[{ A[i,j] -> [N] : i >= j }])" }, | |||
6725 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6726 | "C[]", | |||
6727 | "[N] -> { C[] -> D[N] : N >= 0; C[] -> D[-N] : N < 0 }", | |||
6728 | "[N] -> D[{ [N] : N >= 0; [-N] : N < 0 }]" }, | |||
6729 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6730 | "[N] -> (C[] : { : N >= 0 })", | |||
6731 | "[N] -> { C[] -> D[N] }", | |||
6732 | "[N] -> D[{ [N] : N >= 0 }]" }, | |||
6733 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6734 | "[N] -> (C[] : { : N >= 0 })", | |||
6735 | "[N] -> { C[] -> D[N] : N >= 0; C[] -> D[-N] : N < 0 }", | |||
6736 | "[N] -> D[{ [N] : N >= 0 }]" }, | |||
6737 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6738 | "[N] -> (C[] : { : N >= 0 })", | |||
6739 | "{ C[] -> D[0] }", | |||
6740 | "[N] -> D[{ [0] : N >= 0 }]" }, | |||
6741 | { &isl_multi_union_pw_aff_apply_pw_multi_aff, | |||
6742 | "(C[] : { A[i,j] : i >= j })", | |||
6743 | "[N] -> { C[] -> D[N] : N >= 0 }", | |||
6744 | "[N] -> D[{ A[i,j] -> [N] : i >= j and N >= 0 }]" }, | |||
6745 | }; | |||
6746 | ||||
6747 | /* Perform some basic tests of binary operations on | |||
6748 | * pairs of isl_multi_union_pw_aff and isl_pw_multi_aff objects. | |||
6749 | */ | |||
6750 | static int test_mupa_pma(isl_ctx *ctx) | |||
6751 | { | |||
6752 | int i; | |||
6753 | isl_bool ok; | |||
6754 | isl_multi_union_pw_aff *mupa, *res; | |||
6755 | isl_pw_multi_aff *pma; | |||
6756 | ||||
6757 | for (i = 0; i < ARRAY_SIZE(mupa_pma_tests)(sizeof(mupa_pma_tests)/sizeof(*mupa_pma_tests)); ++i) { | |||
6758 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6759 | mupa_pma_tests[i].arg1); | |||
6760 | pma = isl_pw_multi_aff_read_from_str(ctx, | |||
6761 | mupa_pma_tests[i].arg2); | |||
6762 | res = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6763 | mupa_pma_tests[i].res); | |||
6764 | mupa = mupa_pma_tests[i].fn(mupa, pma); | |||
6765 | ok = isl_multi_union_pw_aff_plain_is_equal(mupa, res); | |||
6766 | isl_multi_union_pw_aff_free(mupa); | |||
6767 | isl_multi_union_pw_aff_free(res); | |||
6768 | if (ok < 0) | |||
6769 | return -1; | |||
6770 | if (!ok) | |||
6771 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6772); return -1; } while (0) | |||
6772 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6772); return -1; } while (0); | |||
6773 | } | |||
6774 | ||||
6775 | return 0; | |||
6776 | } | |||
6777 | ||||
6778 | /* Inputs for basic tests of binary operations on | |||
6779 | * pairs of isl_multi_union_pw_aff and isl_union_pw_multi_aff objects. | |||
6780 | * "fn" is the function that is tested. | |||
6781 | * "arg1" and "arg2" are string descriptions of the inputs. | |||
6782 | * "res" is a string description of the expected result. | |||
6783 | */ | |||
6784 | struct { | |||
6785 | __isl_give isl_multi_union_pw_aff *(*fn)( | |||
6786 | __isl_take isl_multi_union_pw_aff *mupa, | |||
6787 | __isl_take isl_union_pw_multi_aff *upma); | |||
6788 | const char *arg1; | |||
6789 | const char *arg2; | |||
6790 | const char *res; | |||
6791 | } mupa_upma_tests[] = { | |||
6792 | { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, | |||
6793 | "C[{ B[i,j] -> [i + 2j] }]", "{ A[a,b] -> B[b,a] }", | |||
6794 | "C[{ A[a,b] -> [b + 2a] }]" }, | |||
6795 | { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, | |||
6796 | "C[{ B[i,j] -> [i + 2j] }]", | |||
6797 | "{ A[a,b] -> B[b,a] : b > a }", | |||
6798 | "C[{ A[a,b] -> [b + 2a] : b > a }]" }, | |||
6799 | { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, | |||
6800 | "C[{ B[i,j] -> [i + 2j] : j > 4 }]", | |||
6801 | "{ A[a,b] -> B[b,a] : b > a }", | |||
6802 | "C[{ A[a,b] -> [b + 2a] : b > a > 4 }]" }, | |||
6803 | { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, | |||
6804 | "C[{ B[i,j] -> [i + 2j] }]", | |||
6805 | "{ A[a,b] -> B[b,a] : a > b; A[a,b] -> B[a,b] : a <= b }", | |||
6806 | "C[{ A[a,b] -> [b + 2a] : a > b; A[a,b] -> [a + 2b] : a <= b }]" }, | |||
6807 | { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, | |||
6808 | "(C[] : { B[a,b] })", | |||
6809 | "{ A[a,b] -> B[b,a] }", | |||
6810 | "(C[] : { A[a,b] })" }, | |||
6811 | { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, | |||
6812 | "(C[] : { B[a,b] })", | |||
6813 | "{ B[a,b] -> A[b,a] }", | |||
6814 | "(C[] : { })" }, | |||
6815 | { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, | |||
6816 | "(C[] : { B[a,b] })", | |||
6817 | "{ A[a,b] -> B[b,a] : a > b }", | |||
6818 | "(C[] : { A[a,b] : a > b })" }, | |||
6819 | { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, | |||
6820 | "(C[] : { B[a,b] : a > b })", | |||
6821 | "{ A[a,b] -> B[b,a] }", | |||
6822 | "(C[] : { A[a,b] : b > a })" }, | |||
6823 | { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, | |||
6824 | "[N] -> (C[] : { B[a,b] : a > N })", | |||
6825 | "{ A[a,b] -> B[b,a] : a > b }", | |||
6826 | "[N] -> (C[] : { A[a,b] : a > b > N })" }, | |||
6827 | { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, | |||
6828 | "(C[] : { B[a,b] : a > b })", | |||
6829 | "[N] -> { A[a,b] -> B[b,a] : a > N }", | |||
6830 | "[N] -> (C[] : { A[a,b] : b > a > N })" }, | |||
6831 | { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, | |||
6832 | "C[]", | |||
6833 | "{ A[a,b] -> B[b,a] }", | |||
6834 | "C[]" }, | |||
6835 | { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, | |||
6836 | "[N] -> (C[] : { : N >= 0 })", | |||
6837 | "{ A[a,b] -> B[b,a] }", | |||
6838 | "[N] -> (C[] : { : N >= 0 })" }, | |||
6839 | { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, | |||
6840 | "C[]", | |||
6841 | "[N] -> { A[a,b] -> B[b,a] : N >= 0 }", | |||
6842 | "[N] -> (C[] : { : N >= 0 })" }, | |||
6843 | }; | |||
6844 | ||||
6845 | /* Perform some basic tests of binary operations on | |||
6846 | * pairs of isl_multi_union_pw_aff and isl_union_pw_multi_aff objects. | |||
6847 | */ | |||
6848 | static int test_mupa_upma(isl_ctx *ctx) | |||
6849 | { | |||
6850 | int i; | |||
6851 | isl_bool ok; | |||
6852 | isl_multi_union_pw_aff *mupa, *res; | |||
6853 | isl_union_pw_multi_aff *upma; | |||
6854 | ||||
6855 | for (i = 0; i < ARRAY_SIZE(mupa_upma_tests)(sizeof(mupa_upma_tests)/sizeof(*mupa_upma_tests)); ++i) { | |||
6856 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6857 | mupa_upma_tests[i].arg1); | |||
6858 | upma = isl_union_pw_multi_aff_read_from_str(ctx, | |||
6859 | mupa_upma_tests[i].arg2); | |||
6860 | res = isl_multi_union_pw_aff_read_from_str(ctx, | |||
6861 | mupa_upma_tests[i].res); | |||
6862 | mupa = mupa_upma_tests[i].fn(mupa, upma); | |||
6863 | ok = isl_multi_union_pw_aff_plain_is_equal(mupa, res); | |||
6864 | isl_multi_union_pw_aff_free(mupa); | |||
6865 | isl_multi_union_pw_aff_free(res); | |||
6866 | if (ok < 0) | |||
6867 | return -1; | |||
6868 | if (!ok) | |||
6869 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6870); return -1; } while (0) | |||
6870 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6870); return -1; } while (0); | |||
6871 | } | |||
6872 | ||||
6873 | return 0; | |||
6874 | } | |||
6875 | ||||
6876 | /* Check that the input tuple of an isl_aff can be set properly. | |||
6877 | */ | |||
6878 | static isl_stat test_aff_set_tuple_id(isl_ctx *ctx) | |||
6879 | { | |||
6880 | isl_id *id; | |||
6881 | isl_aff *aff; | |||
6882 | isl_stat equal; | |||
6883 | ||||
6884 | aff = isl_aff_read_from_str(ctx, "{ [x] -> [x + 1] }"); | |||
6885 | id = isl_id_alloc(ctx, "A", NULL((void*)0)); | |||
6886 | aff = isl_aff_set_tuple_id(aff, isl_dim_in, id); | |||
6887 | equal = aff_check_plain_equal(aff, "{ A[x] -> [x + 1] }"); | |||
6888 | isl_aff_free(aff); | |||
6889 | if (equal < 0) | |||
6890 | return isl_stat_error; | |||
6891 | ||||
6892 | return isl_stat_ok; | |||
6893 | } | |||
6894 | ||||
6895 | /* Check that affine expressions get normalized on addition/subtraction. | |||
6896 | * In particular, check that (final) unused integer divisions get removed | |||
6897 | * such that an expression derived from expressions with integer divisions | |||
6898 | * is found to be obviously equal to one that is created directly. | |||
6899 | */ | |||
6900 | static isl_stat test_aff_normalize(isl_ctx *ctx) | |||
6901 | { | |||
6902 | isl_aff *aff, *aff2; | |||
6903 | isl_stat ok; | |||
6904 | ||||
6905 | aff = isl_aff_read_from_str(ctx, "{ [x] -> [x//2] }"); | |||
6906 | aff2 = isl_aff_read_from_str(ctx, "{ [x] -> [1 + x//2] }"); | |||
6907 | aff = isl_aff_sub(aff2, aff); | |||
6908 | ok = aff_check_plain_equal(aff, "{ [x] -> [1] }"); | |||
6909 | isl_aff_free(aff); | |||
6910 | ||||
6911 | return ok; | |||
6912 | } | |||
6913 | ||||
6914 | int test_aff(isl_ctx *ctx) | |||
6915 | { | |||
6916 | const char *str; | |||
6917 | isl_setisl_map *set; | |||
6918 | isl_space *space; | |||
6919 | isl_local_space *ls; | |||
6920 | isl_aff *aff; | |||
6921 | int zero; | |||
6922 | isl_stat equal; | |||
6923 | ||||
6924 | if (test_upa(ctx) < 0) | |||
6925 | return -1; | |||
6926 | if (test_bin_aff(ctx) < 0) | |||
6927 | return -1; | |||
6928 | if (test_bin_pw_aff(ctx) < 0) | |||
6929 | return -1; | |||
6930 | if (test_upma_test(ctx) < 0) | |||
6931 | return -1; | |||
6932 | if (test_bin_upma(ctx) < 0) | |||
6933 | return -1; | |||
6934 | if (test_bin_upma_fail(ctx) < 0) | |||
6935 | return -1; | |||
6936 | if (test_upma_uset(ctx) < 0) | |||
6937 | return -1; | |||
6938 | if (test_un_mpa(ctx) < 0) | |||
6939 | return -1; | |||
6940 | if (test_bin_mpa(ctx) < 0) | |||
6941 | return -1; | |||
6942 | if (test_un_mupa(ctx) < 0) | |||
6943 | return -1; | |||
6944 | if (test_bin_mupa(ctx) < 0) | |||
6945 | return -1; | |||
6946 | if (test_mupa_set(ctx) < 0) | |||
6947 | return -1; | |||
6948 | if (test_mupa_uset(ctx) < 0) | |||
6949 | return -1; | |||
6950 | if (test_mupa_ma(ctx) < 0) | |||
6951 | return -1; | |||
6952 | if (test_mupa_pa(ctx) < 0) | |||
6953 | return -1; | |||
6954 | if (test_mupa_pma(ctx) < 0) | |||
6955 | return -1; | |||
6956 | if (test_mupa_upma(ctx) < 0) | |||
6957 | return -1; | |||
6958 | ||||
6959 | space = isl_space_set_alloc(ctx, 0, 1); | |||
6960 | ls = isl_local_space_from_space(space); | |||
6961 | aff = isl_aff_zero_on_domain(ls); | |||
6962 | ||||
6963 | aff = isl_aff_add_coefficient_si(aff, isl_dim_in, 0, 1); | |||
6964 | aff = isl_aff_scale_down_ui(aff, 3); | |||
6965 | aff = isl_aff_floor(aff); | |||
6966 | aff = isl_aff_add_coefficient_si(aff, isl_dim_in, 0, 1); | |||
6967 | aff = isl_aff_scale_down_ui(aff, 2); | |||
6968 | aff = isl_aff_floor(aff); | |||
6969 | aff = isl_aff_add_coefficient_si(aff, isl_dim_in, 0, 1); | |||
6970 | ||||
6971 | str = "{ [10] }"; | |||
6972 | set = isl_set_read_from_str(ctx, str); | |||
6973 | aff = isl_aff_gist(aff, set); | |||
6974 | ||||
6975 | aff = isl_aff_add_constant_si(aff, -16); | |||
6976 | zero = isl_aff_plain_is_zero(aff); | |||
6977 | isl_aff_free(aff); | |||
6978 | ||||
6979 | if (zero < 0) | |||
6980 | return -1; | |||
6981 | if (!zero) | |||
6982 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 6982); return -1; } while (0); | |||
6983 | ||||
6984 | aff = isl_aff_read_from_str(ctx, "{ [-1] }"); | |||
6985 | aff = isl_aff_scale_down_ui(aff, 64); | |||
6986 | aff = isl_aff_floor(aff); | |||
6987 | equal = aff_check_plain_equal(aff, "{ [-1] }"); | |||
6988 | isl_aff_free(aff); | |||
6989 | if (equal < 0) | |||
6990 | return -1; | |||
6991 | ||||
6992 | if (test_aff_set_tuple_id(ctx) < 0) | |||
6993 | return -1; | |||
6994 | if (test_aff_normalize(ctx) < 0) | |||
6995 | return -1; | |||
6996 | ||||
6997 | return 0; | |||
6998 | } | |||
6999 | ||||
7000 | /* Inputs for isl_set_bind tests. | |||
7001 | * "set" is the input set. | |||
7002 | * "tuple" is the binding tuple. | |||
7003 | * "res" is the expected result. | |||
7004 | */ | |||
7005 | static | |||
7006 | struct { | |||
7007 | const char *set; | |||
7008 | const char *tuple; | |||
7009 | const char *res; | |||
7010 | } bind_set_tests[] = { | |||
7011 | { "{ A[M, N] : M mod 2 = 0 and N mod 8 = 3 }", | |||
7012 | "{ A[M, N] }", | |||
7013 | "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 }" }, | |||
7014 | { "{ B[N, M] : M mod 2 = 0 and N mod 8 = 3 }", | |||
7015 | "{ B[N, M] }", | |||
7016 | "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 }" }, | |||
7017 | { "[M] -> { C[N] : M mod 2 = 0 and N mod 8 = 3 }", | |||
7018 | "{ C[N] }", | |||
7019 | "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 }" }, | |||
7020 | { "[M] -> { D[x, N] : x mod 2 = 0 and N mod 8 = 3 and M >= 0 }", | |||
7021 | "{ D[M, N] }", | |||
7022 | "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 and M >= 0 }" }, | |||
7023 | }; | |||
7024 | ||||
7025 | /* Perform basic isl_set_bind tests. | |||
7026 | */ | |||
7027 | static isl_stat test_bind_set(isl_ctx *ctx) | |||
7028 | { | |||
7029 | int i; | |||
7030 | ||||
7031 | for (i = 0; i < ARRAY_SIZE(bind_set_tests)(sizeof(bind_set_tests)/sizeof(*bind_set_tests)); ++i) { | |||
7032 | const char *str; | |||
7033 | isl_setisl_map *set; | |||
7034 | isl_multi_id *tuple; | |||
7035 | isl_stat r; | |||
7036 | ||||
7037 | set = isl_set_read_from_str(ctx, bind_set_tests[i].set); | |||
7038 | str = bind_set_tests[i].tuple; | |||
7039 | tuple = isl_multi_id_read_from_str(ctx, str); | |||
7040 | set = isl_set_bind(set, tuple); | |||
7041 | r = set_check_equal(set, bind_set_tests[i].res); | |||
7042 | isl_set_free(set); | |||
7043 | if (r < 0) | |||
7044 | return isl_stat_error; | |||
7045 | } | |||
7046 | ||||
7047 | return isl_stat_ok; | |||
7048 | } | |||
7049 | ||||
7050 | /* Inputs for isl_map_bind_domain tests. | |||
7051 | * "map" is the input map. | |||
7052 | * "tuple" is the binding tuple. | |||
7053 | * "res" is the expected result. | |||
7054 | */ | |||
7055 | struct { | |||
7056 | const char *map; | |||
7057 | const char *tuple; | |||
7058 | const char *res; | |||
7059 | } bind_map_domain_tests[] = { | |||
7060 | { "{ A[M, N] -> [M + floor(N/2)] }", | |||
7061 | "{ A[M, N] }", | |||
7062 | "[M, N] -> { [M + floor(N/2)] }" }, | |||
7063 | { "{ B[N, M] -> [M + floor(N/2)] }", | |||
7064 | "{ B[N, M] }", | |||
7065 | "[N, M] -> { [M + floor(N/2)] }" }, | |||
7066 | { "[M] -> { C[N] -> [M + floor(N/2)] }", | |||
7067 | "{ C[N] }", | |||
7068 | "[M, N] -> { [M + floor(N/2)] }" }, | |||
7069 | { "[M] -> { C[x, N] -> [x + floor(N/2)] }", | |||
7070 | "{ C[M, N] }", | |||
7071 | "[M, N] -> { [M + floor(N/2)] }" }, | |||
7072 | { "[M] -> { C[x, N] -> [M + floor(N/2)] }", | |||
7073 | "{ C[M, N] }", | |||
7074 | "[M, N] -> { [M + floor(N/2)] }" }, | |||
7075 | { "[A, M] -> { C[N, x] -> [x + floor(N/2)] }", | |||
7076 | "{ C[N, M] }", | |||
7077 | "[A, N, M] -> { [M + floor(N/2)] }" }, | |||
7078 | }; | |||
7079 | ||||
7080 | /* Perform basic isl_map_bind_domain tests. | |||
7081 | */ | |||
7082 | static isl_stat test_bind_map_domain(isl_ctx *ctx) | |||
7083 | { | |||
7084 | int i; | |||
7085 | ||||
7086 | for (i = 0; i < ARRAY_SIZE(bind_map_domain_tests)(sizeof(bind_map_domain_tests)/sizeof(*bind_map_domain_tests) ); ++i) { | |||
7087 | const char *str; | |||
7088 | isl_map *map; | |||
7089 | isl_setisl_map *set; | |||
7090 | isl_multi_id *tuple; | |||
7091 | isl_stat r; | |||
7092 | ||||
7093 | str = bind_map_domain_tests[i].map; | |||
7094 | map = isl_map_read_from_str(ctx, str); | |||
7095 | str = bind_map_domain_tests[i].tuple; | |||
7096 | tuple = isl_multi_id_read_from_str(ctx, str); | |||
7097 | set = isl_map_bind_domain(map, tuple); | |||
7098 | str = bind_map_domain_tests[i].res; | |||
7099 | r = set_check_equal(set, str); | |||
7100 | isl_set_free(set); | |||
7101 | if (r < 0) | |||
7102 | return isl_stat_error; | |||
7103 | } | |||
7104 | ||||
7105 | return isl_stat_ok; | |||
7106 | } | |||
7107 | ||||
7108 | /* Inputs for isl_union_map_bind_range tests. | |||
7109 | * "map" is the input union map. | |||
7110 | * "tuple" is the binding tuple. | |||
7111 | * "res" is the expected result. | |||
7112 | */ | |||
7113 | struct { | |||
7114 | const char *map; | |||
7115 | const char *tuple; | |||
7116 | const char *res; | |||
7117 | } bind_umap_range_tests[] = { | |||
7118 | { "{ B[N, M] -> A[M, N] : M mod 2 = 0 and N mod 8 = 3 }", | |||
7119 | "{ A[M, N] }", | |||
7120 | "[M, N] -> { B[N, M] : M mod 2 = 0 and N mod 8 = 3 }" }, | |||
7121 | { "{ B[N, M] -> A[M, N] : M mod 2 = 0 and N mod 8 = 3 }", | |||
7122 | "{ B[M, N] }", | |||
7123 | "{ }" }, | |||
7124 | { "{ A[] -> B[]; C[] -> D[]; E[] -> B[] }", | |||
7125 | "{ B[] }", | |||
7126 | "{ A[]; E[] }" }, | |||
7127 | }; | |||
7128 | ||||
7129 | /* Perform basic isl_union_map_bind_range tests. | |||
7130 | */ | |||
7131 | static isl_stat test_bind_umap_range(isl_ctx *ctx) | |||
7132 | { | |||
7133 | int i; | |||
7134 | ||||
7135 | for (i = 0; i < ARRAY_SIZE(bind_umap_range_tests)(sizeof(bind_umap_range_tests)/sizeof(*bind_umap_range_tests) ); ++i) { | |||
7136 | const char *str; | |||
7137 | isl_union_map *umap; | |||
7138 | isl_union_set *uset; | |||
7139 | isl_multi_id *tuple; | |||
7140 | isl_stat r; | |||
7141 | ||||
7142 | str = bind_umap_range_tests[i].map; | |||
7143 | umap = isl_union_map_read_from_str(ctx, str); | |||
7144 | str = bind_umap_range_tests[i].tuple; | |||
7145 | tuple = isl_multi_id_read_from_str(ctx, str); | |||
7146 | uset = isl_union_map_bind_range(umap, tuple); | |||
7147 | str = bind_umap_range_tests[i].res; | |||
7148 | r = uset_check_equal(uset, str); | |||
7149 | isl_union_set_free(uset); | |||
7150 | if (r < 0) | |||
7151 | return isl_stat_error; | |||
7152 | } | |||
7153 | ||||
7154 | return isl_stat_ok; | |||
7155 | } | |||
7156 | ||||
7157 | /* Inputs for isl_pw_multi_aff_bind_domain tests. | |||
7158 | * "pma" is the input expression. | |||
7159 | * "tuple" is the binding tuple. | |||
7160 | * "res" is the expected result. | |||
7161 | */ | |||
7162 | struct { | |||
7163 | const char *pma; | |||
7164 | const char *tuple; | |||
7165 | const char *res; | |||
7166 | } bind_pma_domain_tests[] = { | |||
7167 | { "{ A[M, N] -> [M + floor(N/2)] }", | |||
7168 | "{ A[M, N] }", | |||
7169 | "[M, N] -> { [M + floor(N/2)] }" }, | |||
7170 | { "{ B[N, M] -> [M + floor(N/2)] }", | |||
7171 | "{ B[N, M] }", | |||
7172 | "[N, M] -> { [M + floor(N/2)] }" }, | |||
7173 | { "[M] -> { C[N] -> [M + floor(N/2)] }", | |||
7174 | "{ C[N] }", | |||
7175 | "[M, N] -> { [M + floor(N/2)] }" }, | |||
7176 | { "[M] -> { C[x, N] -> [x + floor(N/2)] }", | |||
7177 | "{ C[M, N] }", | |||
7178 | "[M, N] -> { [M + floor(N/2)] }" }, | |||
7179 | { "[M] -> { C[x, N] -> [M + floor(N/2)] }", | |||
7180 | "{ C[M, N] }", | |||
7181 | "[M, N] -> { [M + floor(N/2)] }" }, | |||
7182 | { "[A, M] -> { C[N, x] -> [x + floor(N/2)] }", | |||
7183 | "{ C[N, M] }", | |||
7184 | "[A, N, M] -> { [M + floor(N/2)] }" }, | |||
7185 | }; | |||
7186 | ||||
7187 | /* Perform basic isl_pw_multi_aff_bind_domain tests. | |||
7188 | */ | |||
7189 | static isl_stat test_bind_pma_domain(isl_ctx *ctx) | |||
7190 | { | |||
7191 | int i; | |||
7192 | ||||
7193 | for (i = 0; i < ARRAY_SIZE(bind_pma_domain_tests)(sizeof(bind_pma_domain_tests)/sizeof(*bind_pma_domain_tests) ); ++i) { | |||
7194 | const char *str; | |||
7195 | isl_pw_multi_aff *pma; | |||
7196 | isl_multi_id *tuple; | |||
7197 | isl_stat r; | |||
7198 | ||||
7199 | str = bind_pma_domain_tests[i].pma; | |||
7200 | pma = isl_pw_multi_aff_read_from_str(ctx, str); | |||
7201 | str = bind_pma_domain_tests[i].tuple; | |||
7202 | tuple = isl_multi_id_read_from_str(ctx, str); | |||
7203 | pma = isl_pw_multi_aff_bind_domain(pma, tuple); | |||
7204 | str = bind_pma_domain_tests[i].res; | |||
7205 | r = pw_multi_aff_check_plain_equal(pma, str); | |||
7206 | isl_pw_multi_aff_free(pma); | |||
7207 | if (r < 0) | |||
7208 | return isl_stat_error; | |||
7209 | } | |||
7210 | ||||
7211 | return isl_stat_ok; | |||
7212 | } | |||
7213 | ||||
7214 | /* Inputs for isl_pw_multi_aff_bind_domain_wrapped_domain tests. | |||
7215 | * "pma" is the input expression. | |||
7216 | * "tuple" is the binding tuple. | |||
7217 | * "res" is the expected result. | |||
7218 | */ | |||
7219 | struct { | |||
7220 | const char *pma; | |||
7221 | const char *tuple; | |||
7222 | const char *res; | |||
7223 | } bind_pma_domain_wrapped_tests[] = { | |||
7224 | { "{ [A[M, N] -> B[]] -> [M + floor(N/2)] }", | |||
7225 | "{ A[M, N] }", | |||
7226 | "[M, N] -> { B[] -> [M + floor(N/2)] }" }, | |||
7227 | { "{ [B[N, M] -> D[]] -> [M + floor(N/2)] }", | |||
7228 | "{ B[N, M] }", | |||
7229 | "[N, M] -> { D[] -> [M + floor(N/2)] }" }, | |||
7230 | { "[M] -> { [C[N] -> B[x]] -> [x + M + floor(N/2)] }", | |||
7231 | "{ C[N] }", | |||
7232 | "[M, N] -> { B[x] -> [x + M + floor(N/2)] }" }, | |||
7233 | { "[M] -> { [C[x, N] -> B[]] -> [x + floor(N/2)] }", | |||
7234 | "{ C[M, N] }", | |||
7235 | "[M, N] -> { B[] -> [M + floor(N/2)] }" }, | |||
7236 | { "[M] -> { [C[x, N] -> B[]] -> [M + floor(N/2)] }", | |||
7237 | "{ C[M, N] }", | |||
7238 | "[M, N] -> { B[] -> [M + floor(N/2)] }" }, | |||
7239 | { "[A, M] -> { [C[N, x] -> B[]] -> [x + floor(N/2)] }", | |||
7240 | "{ C[N, M] }", | |||
7241 | "[A, N, M] -> { B[] -> [M + floor(N/2)] }" }, | |||
7242 | }; | |||
7243 | ||||
7244 | /* Perform basic isl_pw_multi_aff_bind_domain_wrapped_domain tests. | |||
7245 | */ | |||
7246 | static isl_stat test_bind_pma_domain_wrapped(isl_ctx *ctx) | |||
7247 | { | |||
7248 | int i; | |||
7249 | ||||
7250 | for (i = 0; i < ARRAY_SIZE(bind_pma_domain_wrapped_tests)(sizeof(bind_pma_domain_wrapped_tests)/sizeof(*bind_pma_domain_wrapped_tests )); ++i) { | |||
7251 | const char *str; | |||
7252 | isl_pw_multi_aff *pma; | |||
7253 | isl_multi_id *tuple; | |||
7254 | isl_stat r; | |||
7255 | ||||
7256 | str = bind_pma_domain_wrapped_tests[i].pma; | |||
7257 | pma = isl_pw_multi_aff_read_from_str(ctx, str); | |||
7258 | str = bind_pma_domain_wrapped_tests[i].tuple; | |||
7259 | tuple = isl_multi_id_read_from_str(ctx, str); | |||
7260 | pma = isl_pw_multi_aff_bind_domain_wrapped_domain(pma, tuple); | |||
7261 | str = bind_pma_domain_wrapped_tests[i].res; | |||
7262 | r = pw_multi_aff_check_plain_equal(pma, str); | |||
7263 | isl_pw_multi_aff_free(pma); | |||
7264 | if (r < 0) | |||
7265 | return isl_stat_error; | |||
7266 | } | |||
7267 | ||||
7268 | return isl_stat_ok; | |||
7269 | } | |||
7270 | ||||
7271 | /* Inputs for isl_aff_bind_id tests. | |||
7272 | * "aff" is the input expression. | |||
7273 | * "id" is the binding id. | |||
7274 | * "res" is the expected result. | |||
7275 | */ | |||
7276 | static | |||
7277 | struct { | |||
7278 | const char *aff; | |||
7279 | const char *id; | |||
7280 | const char *res; | |||
7281 | } bind_aff_tests[] = { | |||
7282 | { "{ [4] }", "M", "[M = 4] -> { : }" }, | |||
7283 | { "{ B[x] -> [floor(x/2)] }", "M", "[M] -> { B[x] : M = floor(x/2) }" }, | |||
7284 | { "[M] -> { [4] }", "M", "[M = 4] -> { : }" }, | |||
7285 | { "[M] -> { [floor(M/2)] }", "M", "[M] -> { : floor(M/2) = M }" }, | |||
7286 | { "{ [NaN] }", "M", "{ : false }" }, | |||
7287 | { "{ A[x] -> [NaN] }", "M", "{ A[x] : false }" }, | |||
7288 | }; | |||
7289 | ||||
7290 | /* Perform basic isl_aff_bind_id tests. | |||
7291 | */ | |||
7292 | static isl_stat test_bind_aff(isl_ctx *ctx) | |||
7293 | { | |||
7294 | int i; | |||
7295 | ||||
7296 | for (i = 0; i < ARRAY_SIZE(bind_aff_tests)(sizeof(bind_aff_tests)/sizeof(*bind_aff_tests)); ++i) { | |||
7297 | isl_aff *aff; | |||
7298 | isl_setisl_map *res; | |||
7299 | isl_id *id; | |||
7300 | isl_stat r; | |||
7301 | ||||
7302 | aff = isl_aff_read_from_str(ctx, bind_aff_tests[i].aff); | |||
7303 | id = isl_id_read_from_str(ctx, bind_aff_tests[i].id); | |||
7304 | res = isl_set_from_basic_set(isl_aff_bind_id(aff, id)); | |||
7305 | r = set_check_equal(res, bind_aff_tests[i].res); | |||
7306 | isl_set_free(res); | |||
7307 | if (r < 0) | |||
7308 | return isl_stat_error; | |||
7309 | } | |||
7310 | ||||
7311 | return isl_stat_ok; | |||
7312 | } | |||
7313 | ||||
7314 | /* Inputs for isl_pw_aff_bind_id tests. | |||
7315 | * "pa" is the input expression. | |||
7316 | * "id" is the binding id. | |||
7317 | * "res" is the expected result. | |||
7318 | */ | |||
7319 | static | |||
7320 | struct { | |||
7321 | const char *pa; | |||
7322 | const char *id; | |||
7323 | const char *res; | |||
7324 | } bind_pa_tests[] = { | |||
7325 | { "{ [4] }", "M", "[M = 4] -> { : }" }, | |||
7326 | { "{ B[x] -> [floor(x/2)] }", "M", "[M] -> { B[x] : M = floor(x/2) }" }, | |||
7327 | { "[M] -> { [4] }", "M", "[M = 4] -> { : }" }, | |||
7328 | { "[M] -> { [floor(M/2)] }", "M", "[M] -> { : floor(M/2) = M }" }, | |||
7329 | { "[M] -> { [M] : M >= 0; [-M] : M < 0 }", "M", "[M] -> { : M >= 0 }" }, | |||
7330 | { "{ [NaN] }", "M", "{ : false }" }, | |||
7331 | { "{ A[x] -> [NaN] }", "M", "{ A[x] : false }" }, | |||
7332 | }; | |||
7333 | ||||
7334 | /* Perform basic isl_pw_aff_bind_id tests. | |||
7335 | */ | |||
7336 | static isl_stat test_bind_pa(isl_ctx *ctx) | |||
7337 | { | |||
7338 | int i; | |||
7339 | ||||
7340 | for (i = 0; i < ARRAY_SIZE(bind_pa_tests)(sizeof(bind_pa_tests)/sizeof(*bind_pa_tests)); ++i) { | |||
7341 | isl_pw_aff *pa; | |||
7342 | isl_setisl_map *res; | |||
7343 | isl_id *id; | |||
7344 | isl_stat r; | |||
7345 | ||||
7346 | pa = isl_pw_aff_read_from_str(ctx, bind_pa_tests[i].pa); | |||
7347 | id = isl_id_read_from_str(ctx, bind_pa_tests[i].id); | |||
7348 | res = isl_pw_aff_bind_id(pa, id); | |||
7349 | r = set_check_equal(res, bind_pa_tests[i].res); | |||
7350 | isl_set_free(res); | |||
7351 | if (r < 0) | |||
7352 | return isl_stat_error; | |||
7353 | } | |||
7354 | ||||
7355 | return isl_stat_ok; | |||
7356 | } | |||
7357 | ||||
7358 | /* Inputs for isl_multi_union_pw_aff_bind tests. | |||
7359 | * "mupa" is the input expression. | |||
7360 | * "tuple" is the binding tuple. | |||
7361 | * "res" is the expected result. | |||
7362 | */ | |||
7363 | static | |||
7364 | struct { | |||
7365 | const char *mupa; | |||
7366 | const char *tuple; | |||
7367 | const char *res; | |||
7368 | } bind_mupa_tests[] = { | |||
7369 | { "A[{ [4] }, { [5] }]", | |||
7370 | "{ A[M, N] }", | |||
7371 | "[M = 4, N = 5] -> { : }" }, | |||
7372 | { "A[{ B[x] -> [floor(x/2)] }, { B[y] -> [y + 5] }]", | |||
7373 | "{ A[M, N] }", | |||
7374 | "[M, N] -> { B[x] : M = floor(x/2) and N = x + 5 }" }, | |||
7375 | { "[M] -> A[{ [4] }, { [M + 1] }]", | |||
7376 | "{ A[M, N] }", | |||
7377 | "[M = 4, N = 5] -> { : }" }, | |||
7378 | }; | |||
7379 | ||||
7380 | /* Perform basic isl_multi_union_pw_aff_bind tests. | |||
7381 | */ | |||
7382 | static isl_stat test_bind_mupa(isl_ctx *ctx) | |||
7383 | { | |||
7384 | int i; | |||
7385 | ||||
7386 | for (i = 0; i < ARRAY_SIZE(bind_mupa_tests)(sizeof(bind_mupa_tests)/sizeof(*bind_mupa_tests)); ++i) { | |||
7387 | const char *str; | |||
7388 | isl_multi_union_pw_aff *mupa; | |||
7389 | isl_union_set *res; | |||
7390 | isl_multi_id *tuple; | |||
7391 | isl_stat r; | |||
7392 | ||||
7393 | str = bind_mupa_tests[i].mupa; | |||
7394 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); | |||
7395 | str = bind_mupa_tests[i].tuple; | |||
7396 | tuple = isl_multi_id_read_from_str(ctx, str); | |||
7397 | res = isl_multi_union_pw_aff_bind(mupa, tuple); | |||
7398 | r = uset_check_equal(res, bind_mupa_tests[i].res); | |||
7399 | isl_union_set_free(res); | |||
7400 | if (r < 0) | |||
7401 | return isl_stat_error; | |||
7402 | } | |||
7403 | ||||
7404 | return isl_stat_ok; | |||
7405 | } | |||
7406 | ||||
7407 | /* Perform tests that reinterpret dimensions as parameters. | |||
7408 | */ | |||
7409 | static int test_bind(isl_ctx *ctx) | |||
7410 | { | |||
7411 | if (test_bind_set(ctx) < 0) | |||
7412 | return -1; | |||
7413 | if (test_bind_map_domain(ctx) < 0) | |||
7414 | return -1; | |||
7415 | if (test_bind_umap_range(ctx) < 0) | |||
7416 | return -1; | |||
7417 | if (test_bind_pma_domain(ctx) < 0) | |||
7418 | return -1; | |||
7419 | if (test_bind_pma_domain_wrapped(ctx) < 0) | |||
7420 | return -1; | |||
7421 | if (test_bind_aff(ctx) < 0) | |||
7422 | return -1; | |||
7423 | if (test_bind_pa(ctx) < 0) | |||
7424 | return -1; | |||
7425 | if (test_bind_mupa(ctx) < 0) | |||
7426 | return -1; | |||
7427 | ||||
7428 | return 0; | |||
7429 | } | |||
7430 | ||||
7431 | /* Inputs for isl_set_unbind_params tests. | |||
7432 | * "set" is the input parameter domain. | |||
7433 | * "tuple" is the tuple of the constructed set. | |||
7434 | * "res" is the expected result. | |||
7435 | */ | |||
7436 | struct { | |||
7437 | const char *set; | |||
7438 | const char *tuple; | |||
7439 | const char *res; | |||
7440 | } unbind_set_tests[] = { | |||
7441 | { "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 }", | |||
7442 | "{ A[M, N] }", | |||
7443 | "{ A[M, N] : M mod 2 = 0 and N mod 8 = 3 }" }, | |||
7444 | { "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 }", | |||
7445 | "{ B[N, M] }", | |||
7446 | "{ B[N, M] : M mod 2 = 0 and N mod 8 = 3 }" }, | |||
7447 | { "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 }", | |||
7448 | "{ C[N] }", | |||
7449 | "[M] -> { C[N] : M mod 2 = 0 and N mod 8 = 3 }" }, | |||
7450 | { "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 }", | |||
7451 | "{ D[T, N] }", | |||
7452 | "[M] -> { D[x, N] : M mod 2 = 0 and N mod 8 = 3 }" }, | |||
7453 | }; | |||
7454 | ||||
7455 | /* Perform basic isl_set_unbind_params tests. | |||
7456 | */ | |||
7457 | static isl_stat test_unbind_set(isl_ctx *ctx) | |||
7458 | { | |||
7459 | int i; | |||
7460 | ||||
7461 | for (i = 0; i < ARRAY_SIZE(unbind_set_tests)(sizeof(unbind_set_tests)/sizeof(*unbind_set_tests)); ++i) { | |||
7462 | const char *str; | |||
7463 | isl_setisl_map *set; | |||
7464 | isl_multi_id *tuple; | |||
7465 | isl_stat r; | |||
7466 | ||||
7467 | set = isl_set_read_from_str(ctx, unbind_set_tests[i].set); | |||
7468 | str = unbind_set_tests[i].tuple; | |||
7469 | tuple = isl_multi_id_read_from_str(ctx, str); | |||
7470 | set = isl_set_unbind_params(set, tuple); | |||
7471 | r = set_check_equal(set, unbind_set_tests[i].res); | |||
7472 | isl_set_free(set); | |||
7473 | if (r < 0) | |||
7474 | return isl_stat_error; | |||
7475 | } | |||
7476 | ||||
7477 | return isl_stat_ok; | |||
7478 | } | |||
7479 | ||||
7480 | /* Inputs for isl_aff_unbind_params_insert_domain tests. | |||
7481 | * "aff" is the input affine expression defined over a parameter domain. | |||
7482 | * "tuple" is the tuple of the domain that gets introduced. | |||
7483 | * "res" is the expected result. | |||
7484 | */ | |||
7485 | struct { | |||
7486 | const char *aff; | |||
7487 | const char *tuple; | |||
7488 | const char *res; | |||
7489 | } unbind_aff_tests[] = { | |||
7490 | { "[M, N] -> { [M + floor(N/2)] }", | |||
7491 | "{ A[M, N] }", | |||
7492 | "{ A[M, N] -> [M + floor(N/2)] }" }, | |||
7493 | { "[M, N] -> { [M + floor(N/2)] }", | |||
7494 | "{ B[N, M] }", | |||
7495 | "{ B[N, M] -> [M + floor(N/2)] }" }, | |||
7496 | { "[M, N] -> { [M + floor(N/2)] }", | |||
7497 | "{ C[N] }", | |||
7498 | "[M] -> { C[N] -> [M + floor(N/2)] }" }, | |||
7499 | { "[M, N] -> { [M + floor(N/2)] }", | |||
7500 | "{ D[A, B, C, N, Z] }", | |||
7501 | "[M] -> { D[A, B, C, N, Z] -> [M + floor(N/2)] }" }, | |||
7502 | }; | |||
7503 | ||||
7504 | /* Perform basic isl_aff_unbind_params_insert_domain tests. | |||
7505 | */ | |||
7506 | static isl_stat test_unbind_aff(isl_ctx *ctx) | |||
7507 | { | |||
7508 | int i; | |||
7509 | ||||
7510 | for (i = 0; i < ARRAY_SIZE(unbind_aff_tests)(sizeof(unbind_aff_tests)/sizeof(*unbind_aff_tests)); ++i) { | |||
7511 | const char *str; | |||
7512 | isl_aff *aff; | |||
7513 | isl_multi_id *tuple; | |||
7514 | isl_stat r; | |||
7515 | ||||
7516 | aff = isl_aff_read_from_str(ctx, unbind_aff_tests[i].aff); | |||
7517 | str = unbind_aff_tests[i].tuple; | |||
7518 | tuple = isl_multi_id_read_from_str(ctx, str); | |||
7519 | aff = isl_aff_unbind_params_insert_domain(aff, tuple); | |||
7520 | r = aff_check_plain_equal(aff, unbind_aff_tests[i].res); | |||
7521 | isl_aff_free(aff); | |||
7522 | if (r < 0) | |||
7523 | return isl_stat_error; | |||
7524 | } | |||
7525 | ||||
7526 | return isl_stat_ok; | |||
7527 | } | |||
7528 | ||||
7529 | /* Inputs for isl_multi_aff_unbind_params_insert_domain tests. | |||
7530 | * "ma" is the input multi affine expression defined over a parameter domain. | |||
7531 | * "tuple" is the tuple of the domain that gets introduced. | |||
7532 | * "res" is the expected result. | |||
7533 | */ | |||
7534 | static struct { | |||
7535 | const char *ma; | |||
7536 | const char *tuple; | |||
7537 | const char *res; | |||
7538 | } unbind_multi_aff_tests[] = { | |||
7539 | { "[M, N] -> { T[M + floor(N/2)] }", | |||
7540 | "{ A[M, N] }", | |||
7541 | "{ A[M, N] -> T[M + floor(N/2)] }" }, | |||
7542 | { "[M, N] -> { [M + floor(N/2)] }", | |||
7543 | "{ B[N, M] }", | |||
7544 | "{ B[N, M] -> [M + floor(N/2)] }" }, | |||
7545 | { "[M, N] -> { [M + floor(N/2)] }", | |||
7546 | "{ C[N] }", | |||
7547 | "[M] -> { C[N] -> [M + floor(N/2)] }" }, | |||
7548 | { "[M, N] -> { [M + floor(N/2)] }", | |||
7549 | "{ D[A, B, C, N, Z] }", | |||
7550 | "[M] -> { D[A, B, C, N, Z] -> [M + floor(N/2)] }" }, | |||
7551 | { "[M, N] -> { T[M + floor(N/2), N + floor(M/3)] }", | |||
7552 | "{ A[M, N] }", | |||
7553 | "{ A[M, N] -> T[M + floor(N/2), N + floor(M/3)] }" }, | |||
7554 | }; | |||
7555 | ||||
7556 | /* Perform basic isl_multi_aff_unbind_params_insert_domain tests. | |||
7557 | */ | |||
7558 | static isl_stat test_unbind_multi_aff(isl_ctx *ctx) | |||
7559 | { | |||
7560 | int i; | |||
7561 | ||||
7562 | for (i = 0; i < ARRAY_SIZE(unbind_multi_aff_tests)(sizeof(unbind_multi_aff_tests)/sizeof(*unbind_multi_aff_tests )); ++i) { | |||
7563 | const char *str; | |||
7564 | isl_multi_aff *ma; | |||
7565 | isl_multi_id *tuple; | |||
7566 | isl_stat r; | |||
7567 | ||||
7568 | str = unbind_multi_aff_tests[i].ma; | |||
7569 | ma = isl_multi_aff_read_from_str(ctx, str); | |||
7570 | str = unbind_multi_aff_tests[i].tuple; | |||
7571 | tuple = isl_multi_id_read_from_str(ctx, str); | |||
7572 | ma = isl_multi_aff_unbind_params_insert_domain(ma, tuple); | |||
7573 | str = unbind_multi_aff_tests[i].res; | |||
7574 | r = multi_aff_check_plain_equal(ma, str); | |||
7575 | isl_multi_aff_free(ma); | |||
7576 | if (r < 0) | |||
7577 | return isl_stat_error; | |||
7578 | } | |||
7579 | ||||
7580 | return isl_stat_ok; | |||
7581 | } | |||
7582 | ||||
7583 | /* Perform tests that reinterpret parameters. | |||
7584 | */ | |||
7585 | static int test_unbind(isl_ctx *ctx) | |||
7586 | { | |||
7587 | if (test_unbind_set(ctx) < 0) | |||
7588 | return -1; | |||
7589 | if (test_unbind_aff(ctx) < 0) | |||
7590 | return -1; | |||
7591 | if (test_unbind_multi_aff(ctx) < 0) | |||
7592 | return -1; | |||
7593 | ||||
7594 | return 0; | |||
7595 | } | |||
7596 | ||||
7597 | /* Check that "pa" consists of a single expression. | |||
7598 | */ | |||
7599 | static int check_single_piece(isl_ctx *ctx, __isl_take isl_pw_aff *pa) | |||
7600 | { | |||
7601 | isl_size n; | |||
7602 | ||||
7603 | n = isl_pw_aff_n_piece(pa); | |||
7604 | isl_pw_aff_free(pa); | |||
7605 | ||||
7606 | if (n < 0) | |||
7607 | return -1; | |||
7608 | if (n != 1) | |||
7609 | isl_die(ctx, isl_error_unknown, "expecting single expression",do { isl_handle_error(ctx, isl_error_unknown, "expecting single expression" , "polly/lib/External/isl/isl_test.c", 7610); return -1; } while (0) | |||
7610 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "expecting single expression" , "polly/lib/External/isl/isl_test.c", 7610); return -1; } while (0); | |||
7611 | ||||
7612 | return 0; | |||
7613 | } | |||
7614 | ||||
7615 | /* Check that the computation below results in a single expression. | |||
7616 | * One or two expressions may result depending on which constraint | |||
7617 | * ends up being considered as redundant with respect to the other | |||
7618 | * constraints after the projection that is performed internally | |||
7619 | * by isl_set_dim_min. | |||
7620 | */ | |||
7621 | static int test_dim_max_1(isl_ctx *ctx) | |||
7622 | { | |||
7623 | const char *str; | |||
7624 | isl_setisl_map *set; | |||
7625 | isl_pw_aff *pa; | |||
7626 | ||||
7627 | str = "[n] -> { [a, b] : n >= 0 and 4a >= -4 + n and b >= 0 and " | |||
7628 | "-4a <= b <= 3 and b < n - 4a }"; | |||
7629 | set = isl_set_read_from_str(ctx, str); | |||
7630 | pa = isl_set_dim_min(set, 0); | |||
7631 | return check_single_piece(ctx, pa); | |||
7632 | } | |||
7633 | ||||
7634 | /* Check that the computation below results in a single expression. | |||
7635 | * The PIP problem corresponding to these constraints has a row | |||
7636 | * that causes a split of the solution domain. The solver should | |||
7637 | * first pick rows that split off empty parts such that the actual | |||
7638 | * solution domain does not get split. | |||
7639 | * Note that the description contains some redundant constraints. | |||
7640 | * If these constraints get removed first, then the row mentioned | |||
7641 | * above does not appear in the PIP problem. | |||
7642 | */ | |||
7643 | static int test_dim_max_2(isl_ctx *ctx) | |||
7644 | { | |||
7645 | const char *str; | |||
7646 | isl_setisl_map *set; | |||
7647 | isl_pw_aff *pa; | |||
7648 | ||||
7649 | str = "[P, N] -> { [a] : a < N and a >= 0 and N > P and a <= P and " | |||
7650 | "N > 0 and P >= 0 }"; | |||
7651 | set = isl_set_read_from_str(ctx, str); | |||
7652 | pa = isl_set_dim_max(set, 0); | |||
7653 | return check_single_piece(ctx, pa); | |||
7654 | } | |||
7655 | ||||
7656 | int test_dim_max(isl_ctx *ctx) | |||
7657 | { | |||
7658 | int equal; | |||
7659 | const char *str; | |||
7660 | isl_setisl_map *set1, *set2; | |||
7661 | isl_setisl_map *set; | |||
7662 | isl_map *map; | |||
7663 | isl_pw_aff *pwaff; | |||
7664 | ||||
7665 | if (test_dim_max_1(ctx) < 0) | |||
7666 | return -1; | |||
7667 | if (test_dim_max_2(ctx) < 0) | |||
7668 | return -1; | |||
7669 | ||||
7670 | str = "[N] -> { [i] : 0 <= i <= min(N,10) }"; | |||
7671 | set = isl_set_read_from_str(ctx, str); | |||
7672 | pwaff = isl_set_dim_max(set, 0); | |||
7673 | set1 = isl_set_from_pw_aff(pwaff); | |||
7674 | str = "[N] -> { [10] : N >= 10; [N] : N <= 9 and N >= 0 }"; | |||
7675 | set2 = isl_set_read_from_str(ctx, str); | |||
7676 | equal = isl_set_is_equal(set1, set2); | |||
7677 | isl_set_free(set1); | |||
7678 | isl_set_free(set2); | |||
7679 | if (equal < 0) | |||
7680 | return -1; | |||
7681 | if (!equal) | |||
7682 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 7682); return -1; } while (0); | |||
7683 | ||||
7684 | str = "[N] -> { [i] : 0 <= i <= max(2N,N+6) }"; | |||
7685 | set = isl_set_read_from_str(ctx, str); | |||
7686 | pwaff = isl_set_dim_max(set, 0); | |||
7687 | set1 = isl_set_from_pw_aff(pwaff); | |||
7688 | str = "[N] -> { [6 + N] : -6 <= N <= 5; [2N] : N >= 6 }"; | |||
7689 | set2 = isl_set_read_from_str(ctx, str); | |||
7690 | equal = isl_set_is_equal(set1, set2); | |||
7691 | isl_set_free(set1); | |||
7692 | isl_set_free(set2); | |||
7693 | if (equal < 0) | |||
7694 | return -1; | |||
7695 | if (!equal) | |||
7696 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 7696); return -1; } while (0); | |||
7697 | ||||
7698 | str = "[N] -> { [i] : 0 <= i <= 2N or 0 <= i <= N+6 }"; | |||
7699 | set = isl_set_read_from_str(ctx, str); | |||
7700 | pwaff = isl_set_dim_max(set, 0); | |||
7701 | set1 = isl_set_from_pw_aff(pwaff); | |||
7702 | str = "[N] -> { [6 + N] : -6 <= N <= 5; [2N] : N >= 6 }"; | |||
7703 | set2 = isl_set_read_from_str(ctx, str); | |||
7704 | equal = isl_set_is_equal(set1, set2); | |||
7705 | isl_set_free(set1); | |||
7706 | isl_set_free(set2); | |||
7707 | if (equal < 0) | |||
7708 | return -1; | |||
7709 | if (!equal) | |||
7710 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 7710); return -1; } while (0); | |||
7711 | ||||
7712 | str = "[N,M] -> { [i,j] -> [([i/16]), i%16, ([j/16]), j%16] : " | |||
7713 | "0 <= i < N and 0 <= j < M }"; | |||
7714 | map = isl_map_read_from_str(ctx, str); | |||
7715 | set = isl_map_range(map); | |||
7716 | ||||
7717 | pwaff = isl_set_dim_max(isl_set_copy(set), 0); | |||
7718 | set1 = isl_set_from_pw_aff(pwaff); | |||
7719 | str = "[N,M] -> { [([(N-1)/16])] : M,N > 0 }"; | |||
7720 | set2 = isl_set_read_from_str(ctx, str); | |||
7721 | equal = isl_set_is_equal(set1, set2); | |||
7722 | isl_set_free(set1); | |||
7723 | isl_set_free(set2); | |||
7724 | ||||
7725 | pwaff = isl_set_dim_max(isl_set_copy(set), 3); | |||
7726 | set1 = isl_set_from_pw_aff(pwaff); | |||
7727 | str = "[N,M] -> { [t] : t = min(M-1,15) and M,N > 0 }"; | |||
7728 | set2 = isl_set_read_from_str(ctx, str); | |||
7729 | if (equal >= 0 && equal) | |||
7730 | equal = isl_set_is_equal(set1, set2); | |||
7731 | isl_set_free(set1); | |||
7732 | isl_set_free(set2); | |||
7733 | ||||
7734 | isl_set_free(set); | |||
7735 | ||||
7736 | if (equal < 0) | |||
7737 | return -1; | |||
7738 | if (!equal) | |||
7739 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 7739); return -1; } while (0); | |||
7740 | ||||
7741 | /* Check that solutions are properly merged. */ | |||
7742 | str = "[n] -> { [a, b, c] : c >= -4a - 2b and " | |||
7743 | "c <= -1 + n - 4a - 2b and c >= -2b and " | |||
7744 | "4a >= -4 + n and c >= 0 }"; | |||
7745 | set = isl_set_read_from_str(ctx, str); | |||
7746 | pwaff = isl_set_dim_min(set, 2); | |||
7747 | set1 = isl_set_from_pw_aff(pwaff); | |||
7748 | str = "[n] -> { [(0)] : n >= 1 }"; | |||
7749 | set2 = isl_set_read_from_str(ctx, str); | |||
7750 | equal = isl_set_is_equal(set1, set2); | |||
7751 | isl_set_free(set1); | |||
7752 | isl_set_free(set2); | |||
7753 | ||||
7754 | if (equal < 0) | |||
7755 | return -1; | |||
7756 | if (!equal) | |||
7757 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 7757); return -1; } while (0); | |||
7758 | ||||
7759 | /* Check that empty solution lie in the right space. */ | |||
7760 | str = "[n] -> { [t,a] : 1 = 0 }"; | |||
7761 | set = isl_set_read_from_str(ctx, str); | |||
7762 | pwaff = isl_set_dim_max(set, 0); | |||
7763 | set1 = isl_set_from_pw_aff(pwaff); | |||
7764 | str = "[n] -> { [t] : 1 = 0 }"; | |||
7765 | set2 = isl_set_read_from_str(ctx, str); | |||
7766 | equal = isl_set_is_equal(set1, set2); | |||
7767 | isl_set_free(set1); | |||
7768 | isl_set_free(set2); | |||
7769 | ||||
7770 | if (equal < 0) | |||
7771 | return -1; | |||
7772 | if (!equal) | |||
7773 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 7773); return -1; } while (0); | |||
7774 | ||||
7775 | return 0; | |||
7776 | } | |||
7777 | ||||
7778 | /* Basic test for isl_pw_multi_aff_product. | |||
7779 | * | |||
7780 | * Check that multiple pieces are properly handled. | |||
7781 | */ | |||
7782 | static int test_product_pma(isl_ctx *ctx) | |||
7783 | { | |||
7784 | isl_stat equal; | |||
7785 | const char *str; | |||
7786 | isl_pw_multi_aff *pma1, *pma2; | |||
7787 | ||||
7788 | str = "{ A[i] -> B[1] : i < 0; A[i] -> B[2] : i >= 0 }"; | |||
7789 | pma1 = isl_pw_multi_aff_read_from_str(ctx, str); | |||
7790 | str = "{ C[] -> D[] }"; | |||
7791 | pma2 = isl_pw_multi_aff_read_from_str(ctx, str); | |||
7792 | pma1 = isl_pw_multi_aff_product(pma1, pma2); | |||
7793 | str = "{ [A[i] -> C[]] -> [B[(1)] -> D[]] : i < 0;" | |||
7794 | "[A[i] -> C[]] -> [B[(2)] -> D[]] : i >= 0 }"; | |||
7795 | equal = pw_multi_aff_check_plain_equal(pma1, str); | |||
7796 | isl_pw_multi_aff_free(pma1); | |||
7797 | if (equal < 0) | |||
7798 | return -1; | |||
7799 | ||||
7800 | return 0; | |||
7801 | } | |||
7802 | ||||
7803 | int test_product(isl_ctx *ctx) | |||
7804 | { | |||
7805 | const char *str; | |||
7806 | isl_setisl_map *set; | |||
7807 | isl_union_set *uset1, *uset2; | |||
7808 | int ok; | |||
7809 | ||||
7810 | str = "{ A[i] }"; | |||
7811 | set = isl_set_read_from_str(ctx, str); | |||
7812 | set = isl_set_product(set, isl_set_copy(set)); | |||
7813 | ok = isl_set_is_wrapping(set); | |||
7814 | isl_set_free(set); | |||
7815 | if (ok < 0) | |||
7816 | return -1; | |||
7817 | if (!ok) | |||
7818 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 7818); return -1; } while (0); | |||
7819 | ||||
7820 | str = "{ [] }"; | |||
7821 | uset1 = isl_union_set_read_from_str(ctx, str); | |||
7822 | uset1 = isl_union_set_product(uset1, isl_union_set_copy(uset1)); | |||
7823 | str = "{ [[] -> []] }"; | |||
7824 | uset2 = isl_union_set_read_from_str(ctx, str); | |||
7825 | ok = isl_union_set_is_equal(uset1, uset2); | |||
7826 | isl_union_set_free(uset1); | |||
7827 | isl_union_set_free(uset2); | |||
7828 | if (ok < 0) | |||
7829 | return -1; | |||
7830 | if (!ok) | |||
7831 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 7831); return -1; } while (0); | |||
7832 | ||||
7833 | if (test_product_pma(ctx) < 0) | |||
7834 | return -1; | |||
7835 | ||||
7836 | return 0; | |||
7837 | } | |||
7838 | ||||
7839 | /* Check that two sets are not considered disjoint just because | |||
7840 | * they have a different set of (named) parameters. | |||
7841 | */ | |||
7842 | static int test_disjoint(isl_ctx *ctx) | |||
7843 | { | |||
7844 | const char *str; | |||
7845 | isl_setisl_map *set, *set2; | |||
7846 | int disjoint; | |||
7847 | ||||
7848 | str = "[n] -> { [[]->[]] }"; | |||
7849 | set = isl_set_read_from_str(ctx, str); | |||
7850 | str = "{ [[]->[]] }"; | |||
7851 | set2 = isl_set_read_from_str(ctx, str); | |||
7852 | disjoint = isl_set_is_disjoint(set, set2); | |||
7853 | isl_set_free(set); | |||
7854 | isl_set_free(set2); | |||
7855 | if (disjoint < 0) | |||
7856 | return -1; | |||
7857 | if (disjoint) | |||
7858 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 7858); return -1; } while (0); | |||
7859 | ||||
7860 | return 0; | |||
7861 | } | |||
7862 | ||||
7863 | /* Inputs for isl_pw_multi_aff_is_equal tests. | |||
7864 | * "f1" and "f2" are the two function that need to be compared. | |||
7865 | * "equal" is the expected result. | |||
7866 | */ | |||
7867 | struct { | |||
7868 | int equal; | |||
7869 | const char *f1; | |||
7870 | const char *f2; | |||
7871 | } pma_equal_tests[] = { | |||
7872 | { 1, "[N] -> { [floor(N/2)] : 0 <= N <= 1 }", | |||
7873 | "[N] -> { [0] : 0 <= N <= 1 }" }, | |||
7874 | { 1, "[N] -> { [floor(N/2)] : 0 <= N <= 2 }", | |||
7875 | "[N] -> { [0] : 0 <= N <= 1; [1] : N = 2 }" }, | |||
7876 | { 0, "[N] -> { [floor(N/2)] : 0 <= N <= 2 }", | |||
7877 | "[N] -> { [0] : 0 <= N <= 1 }" }, | |||
7878 | { 0, "{ [NaN] }", "{ [NaN] }" }, | |||
7879 | }; | |||
7880 | ||||
7881 | int test_equal(isl_ctx *ctx) | |||
7882 | { | |||
7883 | int i; | |||
7884 | const char *str; | |||
7885 | isl_setisl_map *set, *set2; | |||
7886 | int equal; | |||
7887 | ||||
7888 | str = "{ S_6[i] }"; | |||
7889 | set = isl_set_read_from_str(ctx, str); | |||
7890 | str = "{ S_7[i] }"; | |||
7891 | set2 = isl_set_read_from_str(ctx, str); | |||
7892 | equal = isl_set_is_equal(set, set2); | |||
7893 | isl_set_free(set); | |||
7894 | isl_set_free(set2); | |||
7895 | if (equal < 0) | |||
7896 | return -1; | |||
7897 | if (equal) | |||
7898 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 7898); return -1; } while (0); | |||
7899 | ||||
7900 | for (i = 0; i < ARRAY_SIZE(pma_equal_tests)(sizeof(pma_equal_tests)/sizeof(*pma_equal_tests)); ++i) { | |||
7901 | int expected = pma_equal_tests[i].equal; | |||
7902 | isl_pw_multi_aff *f1, *f2; | |||
7903 | ||||
7904 | f1 = isl_pw_multi_aff_read_from_str(ctx, pma_equal_tests[i].f1); | |||
7905 | f2 = isl_pw_multi_aff_read_from_str(ctx, pma_equal_tests[i].f2); | |||
7906 | equal = isl_pw_multi_aff_is_equal(f1, f2); | |||
7907 | isl_pw_multi_aff_free(f1); | |||
7908 | isl_pw_multi_aff_free(f2); | |||
7909 | if (equal < 0) | |||
7910 | return -1; | |||
7911 | if (equal != expected) | |||
7912 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected equality result" , "polly/lib/External/isl/isl_test.c", 7913); return -1; } while (0) | |||
7913 | "unexpected equality result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected equality result" , "polly/lib/External/isl/isl_test.c", 7913); return -1; } while (0); | |||
7914 | } | |||
7915 | ||||
7916 | return 0; | |||
7917 | } | |||
7918 | ||||
7919 | static int test_plain_fixed(isl_ctx *ctx, __isl_take isl_map *map, | |||
7920 | enum isl_dim_type type, unsigned pos, int fixed) | |||
7921 | { | |||
7922 | isl_bool test; | |||
7923 | ||||
7924 | test = isl_map_plain_is_fixed(map, type, pos, NULL((void*)0)); | |||
7925 | isl_map_free(map); | |||
7926 | if (test < 0) | |||
7927 | return -1; | |||
7928 | if (test == fixed) | |||
7929 | return 0; | |||
7930 | if (fixed) | |||
7931 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "map not detected as fixed" , "polly/lib/External/isl/isl_test.c", 7932); return -1; } while (0) | |||
7932 | "map not detected as fixed", return -1)do { isl_handle_error(ctx, isl_error_unknown, "map not detected as fixed" , "polly/lib/External/isl/isl_test.c", 7932); return -1; } while (0); | |||
7933 | else | |||
7934 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "map detected as fixed" , "polly/lib/External/isl/isl_test.c", 7935); return -1; } while (0) | |||
7935 | "map detected as fixed", return -1)do { isl_handle_error(ctx, isl_error_unknown, "map detected as fixed" , "polly/lib/External/isl/isl_test.c", 7935); return -1; } while (0); | |||
7936 | } | |||
7937 | ||||
7938 | int test_fixed(isl_ctx *ctx) | |||
7939 | { | |||
7940 | const char *str; | |||
7941 | isl_map *map; | |||
7942 | ||||
7943 | str = "{ [i] -> [i] }"; | |||
7944 | map = isl_map_read_from_str(ctx, str); | |||
7945 | if (test_plain_fixed(ctx, map, isl_dim_out, 0, 0)) | |||
7946 | return -1; | |||
7947 | str = "{ [i] -> [1] }"; | |||
7948 | map = isl_map_read_from_str(ctx, str); | |||
7949 | if (test_plain_fixed(ctx, map, isl_dim_out, 0, 1)) | |||
7950 | return -1; | |||
7951 | str = "{ S_1[p1] -> [o0] : o0 = -2 and p1 >= 1 and p1 <= 7 }"; | |||
7952 | map = isl_map_read_from_str(ctx, str); | |||
7953 | if (test_plain_fixed(ctx, map, isl_dim_out, 0, 1)) | |||
7954 | return -1; | |||
7955 | map = isl_map_read_from_str(ctx, str); | |||
7956 | map = isl_map_neg(map); | |||
7957 | if (test_plain_fixed(ctx, map, isl_dim_out, 0, 1)) | |||
7958 | return -1; | |||
7959 | ||||
7960 | return 0; | |||
7961 | } | |||
7962 | ||||
7963 | struct isl_vertices_test_data { | |||
7964 | const char *set; | |||
7965 | int n; | |||
7966 | const char *vertex[6]; | |||
7967 | } vertices_tests[] = { | |||
7968 | { "{ A[t, i] : t = 12 and i >= 4 and i <= 12 }", | |||
7969 | 2, { "{ A[12, 4] }", "{ A[12, 12] }" } }, | |||
7970 | { "{ A[t, i] : t = 14 and i = 1 }", | |||
7971 | 1, { "{ A[14, 1] }" } }, | |||
7972 | { "[n, m] -> { [a, b, c] : b <= a and a <= n and b > 0 and c >= b and " | |||
7973 | "c <= m and m <= n and m > 0 }", | |||
7974 | 6, { | |||
7975 | "[n, m] -> { [n, m, m] : 0 < m <= n }", | |||
7976 | "[n, m] -> { [n, 1, m] : 0 < m <= n }", | |||
7977 | "[n, m] -> { [n, 1, 1] : 0 < m <= n }", | |||
7978 | "[n, m] -> { [m, m, m] : 0 < m <= n }", | |||
7979 | "[n, m] -> { [1, 1, m] : 0 < m <= n }", | |||
7980 | "[n, m] -> { [1, 1, 1] : 0 < m <= n }" | |||
7981 | } }, | |||
7982 | /* An input with implicit equality constraints among the parameters. */ | |||
7983 | { "[N, M] -> { [a, b] : M >= 3 and 9 + 3M <= a <= 29 + 2N + 11M and " | |||
7984 | "2b >= M + a and 5 - 2N - M + a <= 2b <= 3 + a and " | |||
7985 | "3b >= 15 + a }", | |||
7986 | 2, { | |||
7987 | "[N, M] -> { [(21), (12)] : M = 3 and N >= 0 }", | |||
7988 | "[N, M] -> { [(61 + 2N), (32 + N)] : M = 3 and N >= 0 }", | |||
7989 | } | |||
7990 | }, | |||
7991 | }; | |||
7992 | ||||
7993 | /* Check that "vertex" corresponds to one of the vertices in data->vertex. | |||
7994 | */ | |||
7995 | static isl_stat find_vertex(__isl_take isl_vertex *vertex, void *user) | |||
7996 | { | |||
7997 | struct isl_vertices_test_data *data = user; | |||
7998 | isl_ctx *ctx; | |||
7999 | isl_multi_aff *ma; | |||
8000 | isl_basic_setisl_basic_map *bset; | |||
8001 | isl_pw_multi_aff *pma; | |||
8002 | int i; | |||
8003 | isl_bool equal; | |||
| ||||
8004 | ||||
8005 | ctx = isl_vertex_get_ctx(vertex); | |||
8006 | bset = isl_vertex_get_domain(vertex); | |||
8007 | ma = isl_vertex_get_expr(vertex); | |||
8008 | pma = isl_pw_multi_aff_alloc(isl_set_from_basic_set(bset), ma); | |||
8009 | ||||
8010 | for (i = 0; i < data->n; ++i) { | |||
8011 | isl_pw_multi_aff *pma_i; | |||
8012 | ||||
8013 | pma_i = isl_pw_multi_aff_read_from_str(ctx, data->vertex[i]); | |||
8014 | equal = isl_pw_multi_aff_plain_is_equal(pma, pma_i); | |||
8015 | isl_pw_multi_aff_free(pma_i); | |||
8016 | ||||
8017 | if (equal < 0 || equal) | |||
8018 | break; | |||
8019 | } | |||
8020 | ||||
8021 | isl_pw_multi_aff_free(pma); | |||
8022 | isl_vertex_free(vertex); | |||
8023 | ||||
8024 | if (equal < 0) | |||
| ||||
8025 | return isl_stat_error; | |||
8026 | ||||
8027 | return equal ? isl_stat_ok : isl_stat_error; | |||
8028 | } | |||
8029 | ||||
8030 | int test_vertices(isl_ctx *ctx) | |||
8031 | { | |||
8032 | int i; | |||
8033 | ||||
8034 | for (i = 0; i < ARRAY_SIZE(vertices_tests)(sizeof(vertices_tests)/sizeof(*vertices_tests)); ++i) { | |||
8035 | isl_basic_setisl_basic_map *bset; | |||
8036 | isl_vertices *vertices; | |||
8037 | int ok = 1; | |||
8038 | isl_size n; | |||
8039 | ||||
8040 | bset = isl_basic_set_read_from_str(ctx, vertices_tests[i].set); | |||
8041 | vertices = isl_basic_set_compute_vertices(bset); | |||
8042 | n = isl_vertices_get_n_vertices(vertices); | |||
8043 | if (vertices_tests[i].n != n) | |||
8044 | ok = 0; | |||
8045 | if (isl_vertices_foreach_vertex(vertices, &find_vertex, | |||
8046 | &vertices_tests[i]) < 0) | |||
8047 | ok = 0; | |||
8048 | isl_vertices_free(vertices); | |||
8049 | isl_basic_set_free(bset); | |||
8050 | ||||
8051 | if (n < 0) | |||
8052 | return -1; | |||
8053 | if (!ok) | |||
8054 | isl_die(ctx, isl_error_unknown, "unexpected vertices",do { isl_handle_error(ctx, isl_error_unknown, "unexpected vertices" , "polly/lib/External/isl/isl_test.c", 8055); return -1; } while (0) | |||
8055 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected vertices" , "polly/lib/External/isl/isl_test.c", 8055); return -1; } while (0); | |||
8056 | } | |||
8057 | ||||
8058 | return 0; | |||
8059 | } | |||
8060 | ||||
8061 | /* Inputs for basic tests of unary operations on isl_union_map. | |||
8062 | * "fn" is the function that is being tested. | |||
8063 | * "arg" is a string description of the input. | |||
8064 | * "res" is a string description of the expected result. | |||
8065 | */ | |||
8066 | static struct { | |||
8067 | __isl_give isl_union_map *(*fn)(__isl_take isl_union_map *umap); | |||
8068 | const char *arg; | |||
8069 | const char *res; | |||
8070 | } umap_un_tests[] = { | |||
8071 | { &isl_union_map_range_reverse, | |||
8072 | "{ A[] -> [B[] -> C[]]; A[] -> B[]; A[0] -> N[B[1] -> B[2]] }", | |||
8073 | "{ A[] -> [C[] -> B[]]; A[0] -> N[B[2] -> B[1]] }" }, | |||
8074 | { &isl_union_map_range_reverse, | |||
8075 | "{ A[] -> N[B[] -> C[]] }", | |||
8076 | "{ A[] -> [C[] -> B[]] }" }, | |||
8077 | { &isl_union_map_range_reverse, | |||
8078 | "{ A[] -> N[B[x] -> B[y]] }", | |||
8079 | "{ A[] -> N[B[*] -> B[*]] }" }, | |||
8080 | }; | |||
8081 | ||||
8082 | /* Perform basic tests of unary operations on isl_union_map. | |||
8083 | */ | |||
8084 | static isl_stat test_un_union_map(isl_ctx *ctx) | |||
8085 | { | |||
8086 | int i; | |||
8087 | ||||
8088 | for (i = 0; i < ARRAY_SIZE(umap_un_tests)(sizeof(umap_un_tests)/sizeof(*umap_un_tests)); ++i) { | |||
8089 | const char *str; | |||
8090 | isl_union_map *umap, *res; | |||
8091 | isl_bool equal; | |||
8092 | ||||
8093 | str = umap_un_tests[i].arg; | |||
8094 | umap = isl_union_map_read_from_str(ctx, str); | |||
8095 | str = umap_un_tests[i].res; | |||
8096 | res = isl_union_map_read_from_str(ctx, str); | |||
8097 | umap = umap_un_tests[i].fn(umap); | |||
8098 | equal = isl_union_map_is_equal(umap, res); | |||
8099 | isl_union_map_free(umap); | |||
8100 | isl_union_map_free(res); | |||
8101 | if (equal < 0) | |||
8102 | return isl_stat_error; | |||
8103 | if (!equal) | |||
8104 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 8105); return isl_stat_error ; } while (0) | |||
8105 | "unexpected result", return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 8105); return isl_stat_error ; } while (0); | |||
8106 | } | |||
8107 | ||||
8108 | return isl_stat_ok; | |||
8109 | } | |||
8110 | ||||
8111 | /* Inputs for basic tests of binary operations on isl_union_map. | |||
8112 | * "fn" is the function that is being tested. | |||
8113 | * "arg1" and "arg2" are string descriptions of the inputs. | |||
8114 | * "res" is a string description of the expected result. | |||
8115 | */ | |||
8116 | static struct { | |||
8117 | __isl_give isl_union_map *(*fn)(__isl_take isl_union_map *umap1, | |||
8118 | __isl_take isl_union_map *umap2); | |||
8119 | const char *arg1; | |||
8120 | const char *arg2; | |||
8121 | const char *res; | |||
8122 | } umap_bin_tests[] = { | |||
8123 | { &isl_union_map_intersect, | |||
8124 | "[n] -> { A[i] -> [] : 0 <= i <= n; B[] -> [] }", | |||
8125 | "[m] -> { A[i] -> [] : 0 <= i <= m; C[] -> [] }", | |||
8126 | "[m, n] -> { A[i] -> [] : 0 <= i <= n and i <= m }" }, | |||
8127 | { &isl_union_map_intersect_domain_factor_domain, | |||
8128 | "{ [A[i] -> B[i + 1]] -> C[i + 2] }", | |||
8129 | "[N] -> { B[i] -> C[N] }", | |||
8130 | "{ }" }, | |||
8131 | { &isl_union_map_intersect_domain_factor_domain, | |||
8132 | "{ [A[i] -> B[i + 1]] -> C[i + 2] }", | |||
8133 | "[N] -> { A[i] -> C[N] }", | |||
8134 | "[N] -> { [A[N - 2] -> B[N - 1]] -> C[N] }" }, | |||
8135 | { &isl_union_map_intersect_domain_factor_domain, | |||
8136 | "{ T[A[i] -> B[i + 1]] -> C[i + 2] }", | |||
8137 | "[N] -> { A[i] -> C[N] }", | |||
8138 | "[N] -> { T[A[N - 2] -> B[N - 1]] -> C[N] }" }, | |||
8139 | { &isl_union_map_intersect_domain_factor_range, | |||
8140 | "{ [A[i] -> B[i + 1]] -> C[i + 2] }", | |||
8141 | "[N] -> { B[i] -> C[N] }", | |||
8142 | "[N] -> { [A[N - 2] -> B[N - 1]] -> C[N] }" }, | |||
8143 | { &isl_union_map_intersect_domain_factor_range, | |||
8144 | "{ T[A[i] -> B[i + 1]] -> C[i + 2] }", | |||
8145 | "[N] -> { B[i] -> C[N] }", | |||
8146 | "[N] -> { T[A[N - 2] -> B[N - 1]] -> C[N] }" }, | |||
8147 | { &isl_union_map_intersect_domain_factor_range, | |||
8148 | "{ [A[i] -> B[i + 1]] -> C[i + 2] }", | |||
8149 | "[N] -> { A[i] -> C[N] }", | |||
8150 | "{ }" }, | |||
8151 | { &isl_union_map_intersect_range_factor_domain, | |||
8152 | "{ A[i] -> [B[i + 1] -> C[i + 2]] }", | |||
8153 | "[N] -> { A[i] -> B[N] }", | |||
8154 | "[N] -> { A[N - 1] -> [B[N] -> C[N + 1]] }" }, | |||
8155 | { &isl_union_map_intersect_range_factor_domain, | |||
8156 | "{ A[i] -> T[B[i + 1] -> C[i + 2]] }", | |||
8157 | "[N] -> { A[i] -> B[N] }", | |||
8158 | "[N] -> { A[N - 1] -> T[B[N] -> C[N + 1]] }" }, | |||
8159 | { &isl_union_map_intersect_range_factor_domain, | |||
8160 | "{ A[i] -> [B[i + 1] -> C[i + 2]] }", | |||
8161 | "[N] -> { A[i] -> C[N] }", | |||
8162 | "{ }" }, | |||
8163 | { &isl_union_map_intersect_range_factor_range, | |||
8164 | "{ A[i] -> [B[i + 1] -> C[i + 2]] }", | |||
8165 | "[N] -> { A[i] -> C[N] }", | |||
8166 | "[N] -> { A[N - 2] -> [B[N - 1] -> C[N]] }" }, | |||
8167 | { &isl_union_map_intersect_range_factor_range, | |||
8168 | "{ A[i] -> T[B[i + 1] -> C[i + 2]] }", | |||
8169 | "[N] -> { A[i] -> C[N] }", | |||
8170 | "[N] -> { A[N - 2] -> T[B[N - 1] -> C[N]] }" }, | |||
8171 | { &isl_union_map_intersect_range_factor_range, | |||
8172 | "{ A[i] -> [B[i + 1] -> C[i + 2]] }", | |||
8173 | "[N] -> { A[i] -> B[N] }", | |||
8174 | "{ }" }, | |||
8175 | }; | |||
8176 | ||||
8177 | /* Perform basic tests of binary operations on isl_union_map. | |||
8178 | */ | |||
8179 | static isl_stat test_bin_union_map(isl_ctx *ctx) | |||
8180 | { | |||
8181 | int i; | |||
8182 | ||||
8183 | for (i = 0; i < ARRAY_SIZE(umap_bin_tests)(sizeof(umap_bin_tests)/sizeof(*umap_bin_tests)); ++i) { | |||
8184 | const char *str; | |||
8185 | isl_union_map *umap1, *umap2, *res; | |||
8186 | isl_bool equal; | |||
8187 | ||||
8188 | str = umap_bin_tests[i].arg1; | |||
8189 | umap1 = isl_union_map_read_from_str(ctx, str); | |||
8190 | str = umap_bin_tests[i].arg2; | |||
8191 | umap2 = isl_union_map_read_from_str(ctx, str); | |||
8192 | str = umap_bin_tests[i].res; | |||
8193 | res = isl_union_map_read_from_str(ctx, str); | |||
8194 | umap1 = umap_bin_tests[i].fn(umap1, umap2); | |||
8195 | equal = isl_union_map_is_equal(umap1, res); | |||
8196 | isl_union_map_free(umap1); | |||
8197 | isl_union_map_free(res); | |||
8198 | if (equal < 0) | |||
8199 | return isl_stat_error; | |||
8200 | if (!equal) | |||
8201 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 8202); return isl_stat_error ; } while (0) | |||
8202 | "unexpected result", return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 8202); return isl_stat_error ; } while (0); | |||
8203 | } | |||
8204 | ||||
8205 | return isl_stat_ok; | |||
8206 | } | |||
8207 | ||||
8208 | /* Check that isl_union_set_contains finds space independently | |||
8209 | * of the parameters. | |||
8210 | */ | |||
8211 | static isl_stat test_union_set_contains(isl_ctx *ctx) | |||
8212 | { | |||
8213 | const char *str; | |||
8214 | isl_bool ok; | |||
8215 | isl_space *space; | |||
8216 | isl_id *id; | |||
8217 | isl_union_set *uset; | |||
8218 | ||||
8219 | str = "[N] -> { A[0:N]; B[*,*] }"; | |||
8220 | uset = isl_union_set_read_from_str(ctx, str); | |||
8221 | space = isl_space_unit(ctx); | |||
8222 | id = isl_id_alloc(ctx, "A", NULL((void*)0)); | |||
8223 | space = isl_space_add_named_tuple_id_ui(space, id, 1); | |||
8224 | ok = isl_union_set_contains(uset, space); | |||
8225 | isl_space_free(space); | |||
8226 | isl_union_set_free(uset); | |||
8227 | ||||
8228 | if (ok < 0) | |||
8229 | return isl_stat_error; | |||
8230 | if (!ok) | |||
8231 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 8232); return isl_stat_error ; } while (0) | |||
8232 | "unexpected result", return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 8232); return isl_stat_error ; } while (0); | |||
8233 | ||||
8234 | return isl_stat_ok; | |||
8235 | } | |||
8236 | ||||
8237 | /* Perform basic tests of operations on isl_union_map or isl_union_set. | |||
8238 | */ | |||
8239 | static int test_union_map(isl_ctx *ctx) | |||
8240 | { | |||
8241 | if (test_un_union_map(ctx) < 0) | |||
8242 | return -1; | |||
8243 | if (test_bin_union_map(ctx) < 0) | |||
8244 | return -1; | |||
8245 | if (test_union_set_contains(ctx) < 0) | |||
8246 | return -1; | |||
8247 | return 0; | |||
8248 | } | |||
8249 | ||||
8250 | #undef BASEunion_pw_qpolynomial | |||
8251 | #define BASEunion_pw_qpolynomial union_pw_qpolynomial | |||
8252 | #include "isl_test_plain_equal_templ.c" | |||
8253 | ||||
8254 | /* Check that the result of applying "fn" to "a" and "b" | |||
8255 | * in (obviously) equal to "res". | |||
8256 | */ | |||
8257 | static isl_stat test_union_pw_op(isl_ctx *ctx, const char *a, const char *b, | |||
8258 | __isl_give isl_union_pw_qpolynomial *(*fn)( | |||
8259 | __isl_take isl_union_pw_qpolynomial *upwqp1, | |||
8260 | __isl_take isl_union_pw_qpolynomial *upwqp2), | |||
8261 | const char *res) | |||
8262 | { | |||
8263 | isl_stat r; | |||
8264 | isl_union_pw_qpolynomial *upwqp1, *upwqp2; | |||
8265 | ||||
8266 | upwqp1 = isl_union_pw_qpolynomial_read_from_str(ctx, a); | |||
8267 | upwqp2 = isl_union_pw_qpolynomial_read_from_str(ctx, b); | |||
8268 | upwqp1 = fn(upwqp1, upwqp2); | |||
8269 | r = union_pw_qpolynomial_check_plain_equal(upwqp1, res); | |||
8270 | isl_union_pw_qpolynomial_free(upwqp1); | |||
8271 | ||||
8272 | return r; | |||
8273 | } | |||
8274 | ||||
8275 | int test_union_pw(isl_ctx *ctx) | |||
8276 | { | |||
8277 | int equal; | |||
8278 | const char *str; | |||
8279 | isl_union_set *uset; | |||
8280 | isl_union_pw_qpolynomial *upwqp1, *upwqp2; | |||
8281 | const char *a, *b; | |||
8282 | ||||
8283 | str = "{ [x] -> x^2 }"; | |||
8284 | upwqp1 = isl_union_pw_qpolynomial_read_from_str(ctx, str); | |||
8285 | upwqp2 = isl_union_pw_qpolynomial_copy(upwqp1); | |||
8286 | uset = isl_union_pw_qpolynomial_domain(upwqp1); | |||
8287 | upwqp1 = isl_union_pw_qpolynomial_copy(upwqp2); | |||
8288 | upwqp1 = isl_union_pw_qpolynomial_intersect_domain(upwqp1, uset); | |||
8289 | equal = isl_union_pw_qpolynomial_plain_is_equal(upwqp1, upwqp2); | |||
8290 | isl_union_pw_qpolynomial_free(upwqp1); | |||
8291 | isl_union_pw_qpolynomial_free(upwqp2); | |||
8292 | if (equal < 0) | |||
8293 | return -1; | |||
8294 | if (!equal) | |||
8295 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 8295); return -1; } while (0); | |||
8296 | ||||
8297 | a = "{ A[x] -> x^2 : x >= 0; B[x] -> x }"; | |||
8298 | b = "{ A[x] -> x }"; | |||
8299 | str = "{ A[x] -> x^2 + x : x >= 0; A[x] -> x : x < 0; B[x] -> x }"; | |||
8300 | if (test_union_pw_op(ctx, a, b, &isl_union_pw_qpolynomial_add, str) < 0) | |||
8301 | return -1; | |||
8302 | str = "{ A[x] -> x^2 - x : x >= 0; A[x] -> -x : x < 0; B[x] -> x }"; | |||
8303 | if (test_union_pw_op(ctx, a, b, &isl_union_pw_qpolynomial_sub, str) < 0) | |||
8304 | return -1; | |||
8305 | ||||
8306 | str = "{ A[x] -> 0 }"; | |||
8307 | a = "{ A[x] -> 1 }"; | |||
8308 | b = "{ A[x] -> -1 }"; | |||
8309 | if (test_union_pw_op(ctx, a, b, &isl_union_pw_qpolynomial_add, str) < 0) | |||
8310 | return -1; | |||
8311 | a = "{ A[x] -> 1 }"; | |||
8312 | b = "{ A[x] -> 1 }"; | |||
8313 | if (test_union_pw_op(ctx, a, b, &isl_union_pw_qpolynomial_sub, str) < 0) | |||
8314 | return -1; | |||
8315 | ||||
8316 | return 0; | |||
8317 | } | |||
8318 | ||||
8319 | /* Inputs for basic tests of functions that select | |||
8320 | * subparts of the domain of an isl_multi_union_pw_aff. | |||
8321 | * "fn" is the function that is tested. | |||
8322 | * "arg" is a string description of the input. | |||
8323 | * "res" is a string description of the expected result. | |||
8324 | */ | |||
8325 | struct { | |||
8326 | __isl_give isl_union_set *(*fn)( | |||
8327 | __isl_take isl_multi_union_pw_aff *mupa); | |||
8328 | const char *arg; | |||
8329 | const char *res; | |||
8330 | } un_locus_tests[] = { | |||
8331 | { &isl_multi_union_pw_aff_zero_union_set, | |||
8332 | "F[{ A[i,j] -> [i]; B[i,j] -> [i] }]", | |||
8333 | "{ A[0,j]; B[0,j] }" }, | |||
8334 | { &isl_multi_union_pw_aff_zero_union_set, | |||
8335 | "F[{ A[i,j] -> [i-j]; B[i,j] -> [i-j] : i >= 0 }]", | |||
8336 | "{ A[i,i]; B[i,i] : i >= 0 }" }, | |||
8337 | { &isl_multi_union_pw_aff_zero_union_set, | |||
8338 | "(F[] : { A[i,j]; B[i,i] : i >= 0 })", | |||
8339 | "{ A[i,j]; B[i,i] : i >= 0 }" }, | |||
8340 | }; | |||
8341 | ||||
8342 | /* Perform some basic tests of functions that select | |||
8343 | * subparts of the domain of an isl_multi_union_pw_aff. | |||
8344 | */ | |||
8345 | static int test_un_locus(isl_ctx *ctx) | |||
8346 | { | |||
8347 | int i; | |||
8348 | isl_bool ok; | |||
8349 | isl_union_set *uset, *res; | |||
8350 | isl_multi_union_pw_aff *mupa; | |||
8351 | ||||
8352 | for (i = 0; i < ARRAY_SIZE(un_locus_tests)(sizeof(un_locus_tests)/sizeof(*un_locus_tests)); ++i) { | |||
8353 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, | |||
8354 | un_locus_tests[i].arg); | |||
8355 | res = isl_union_set_read_from_str(ctx, un_locus_tests[i].res); | |||
8356 | uset = un_locus_tests[i].fn(mupa); | |||
8357 | ok = isl_union_set_is_equal(uset, res); | |||
8358 | isl_union_set_free(uset); | |||
8359 | isl_union_set_free(res); | |||
8360 | if (ok < 0) | |||
8361 | return -1; | |||
8362 | if (!ok) | |||
8363 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 8364); return -1; } while (0) | |||
8364 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 8364); return -1; } while (0); | |||
8365 | } | |||
8366 | ||||
8367 | return 0; | |||
8368 | } | |||
8369 | ||||
8370 | /* Inputs for basic tests of functions that select | |||
8371 | * subparts of an isl_union_map based on a relation | |||
8372 | * specified by an isl_multi_union_pw_aff. | |||
8373 | * "fn" is the function that is tested. | |||
8374 | * "arg1" and "arg2" are string descriptions of the inputs. | |||
8375 | * "res" is a string description of the expected result. | |||
8376 | */ | |||
8377 | struct { | |||
8378 | __isl_give isl_union_map *(*fn)( | |||
8379 | __isl_take isl_union_map *umap, | |||
8380 | __isl_take isl_multi_union_pw_aff *mupa); | |||
8381 | const char *arg1; | |||
8382 | const char *arg2; | |||
8383 | const char *res; | |||
8384 | } bin_locus_tests[] = { | |||
8385 | { &isl_union_map_eq_at_multi_union_pw_aff, | |||
8386 | "{ A[i,j] -> B[i',j'] }", | |||
8387 | "F[{ A[i,j] -> [i]; B[i,j] -> [i] }]", | |||
8388 | "{ A[i,j] -> B[i,j'] }" }, | |||
8389 | { &isl_union_map_eq_at_multi_union_pw_aff, | |||
8390 | "{ A[i,j] -> B[i',j'] }", | |||
8391 | "F[{ A[i,j] -> [i]; B[i,j] -> [i] }, " | |||
8392 | "{ A[i,j] -> [j]; B[i,j] -> [j] }]", | |||
8393 | "{ A[i,j] -> B[i,j] }" }, | |||
8394 | { &isl_union_map_eq_at_multi_union_pw_aff, | |||
8395 | "{ A[i,j] -> B[i',j']; A[i,j] -> C[i',j'] }", | |||
8396 | "F[{ A[i,j] -> [i]; B[i,j] -> [i] }]", | |||
8397 | "{ A[i,j] -> B[i,j'] }" }, | |||
8398 | { &isl_union_map_eq_at_multi_union_pw_aff, | |||
8399 | "{ A[i,j] -> B[i',j']; A[i,j] -> C[i',j'] }", | |||
8400 | "F[{ A[i,j] -> [i]; B[i,j] -> [i]; C[i,j] -> [0] }]", | |||
8401 | "{ A[i,j] -> B[i,j']; A[0,j] -> C[i',j'] }" }, | |||
8402 | { &isl_union_map_eq_at_multi_union_pw_aff, | |||
8403 | "{ A[i,j] -> B[i',j'] }", | |||
8404 | "F[{ A[i,j] -> [i] : i > j; B[i,j] -> [i] }]", | |||
8405 | "{ A[i,j] -> B[i,j'] : i > j }" }, | |||
8406 | { &isl_union_map_lex_le_at_multi_union_pw_aff, | |||
8407 | "{ A[i,j] -> B[i',j'] }", | |||
8408 | "F[{ A[i,j] -> [i]; B[i,j] -> [i] }, " | |||
8409 | "{ A[i,j] -> [j]; B[i,j] -> [j] }]", | |||
8410 | "{ A[i,j] -> B[i',j'] : i,j <<= i',j' }" }, | |||
8411 | { &isl_union_map_lex_lt_at_multi_union_pw_aff, | |||
8412 | "{ A[i,j] -> B[i',j'] }", | |||
8413 | "F[{ A[i,j] -> [i]; B[i,j] -> [i] }, " | |||
8414 | "{ A[i,j] -> [j]; B[i,j] -> [j] }]", | |||
8415 | "{ A[i,j] -> B[i',j'] : i,j << i',j' }" }, | |||
8416 | { &isl_union_map_lex_ge_at_multi_union_pw_aff, | |||
8417 | "{ A[i,j] -> B[i',j'] }", | |||
8418 | "F[{ A[i,j] -> [i]; B[i,j] -> [i] }, " | |||
8419 | "{ A[i,j] -> [j]; B[i,j] -> [j] }]", | |||
8420 | "{ A[i,j] -> B[i',j'] : i,j >>= i',j' }" }, | |||
8421 | { &isl_union_map_lex_gt_at_multi_union_pw_aff, | |||
8422 | "{ A[i,j] -> B[i',j'] }", | |||
8423 | "F[{ A[i,j] -> [i]; B[i,j] -> [i] }, " | |||
8424 | "{ A[i,j] -> [j]; B[i,j] -> [j] }]", | |||
8425 | "{ A[i,j] -> B[i',j'] : i,j >> i',j' }" }, | |||
8426 | { &isl_union_map_eq_at_multi_union_pw_aff, | |||
8427 | "{ A[i,j] -> B[i',j']; A[i,j] -> C[i',j'] }", | |||
8428 | "(F[] : { A[i,j]; B[i,j] })", | |||
8429 | "{ A[i,j] -> B[i',j'] }" }, | |||
8430 | { &isl_union_map_eq_at_multi_union_pw_aff, | |||
8431 | "{ A[i,j] -> B[i',j'] }", | |||
8432 | "(F[] : { A[i,j] : i > j; B[i,j] : i < j })", | |||
8433 | "{ A[i,j] -> B[i',j'] : i > j and i' < j' }" }, | |||
8434 | { &isl_union_map_eq_at_multi_union_pw_aff, | |||
8435 | "[N] -> { A[i,j] -> B[i',j'] : i,i' <= N }", | |||
8436 | "(F[] : { A[i,j] : i > j; B[i,j] : i < j })", | |||
8437 | "[N] -> { A[i,j] -> B[i',j'] : i > j and i' < j' and i,i' <= N }" }, | |||
8438 | { &isl_union_map_eq_at_multi_union_pw_aff, | |||
8439 | "{ A[i,j] -> B[i',j'] }", | |||
8440 | "[N] -> (F[] : { A[i,j] : i < N; B[i,j] : i < N })", | |||
8441 | "[N] -> { A[i,j] -> B[i',j'] : i,i' < N }" }, | |||
8442 | { &isl_union_map_eq_at_multi_union_pw_aff, | |||
8443 | "{ A[i,j] -> B[i',j'] }", | |||
8444 | "[N] -> (F[] : { : N >= 0 })", | |||
8445 | "[N] -> { A[i,j] -> B[i',j'] : N >= 0 }" }, | |||
8446 | }; | |||
8447 | ||||
8448 | /* Perform some basic tests of functions that select | |||
8449 | * subparts of an isl_union_map based on a relation | |||
8450 | * specified by an isl_multi_union_pw_aff. | |||
8451 | */ | |||
8452 | static int test_bin_locus(isl_ctx *ctx) | |||
8453 | { | |||
8454 | int i; | |||
8455 | isl_bool ok; | |||
8456 | isl_union_map *umap, *res; | |||
8457 | isl_multi_union_pw_aff *mupa; | |||
8458 | ||||
8459 | for (i = 0; i < ARRAY_SIZE(bin_locus_tests)(sizeof(bin_locus_tests)/sizeof(*bin_locus_tests)); ++i) { | |||
8460 | umap = isl_union_map_read_from_str(ctx, | |||
8461 | bin_locus_tests[i].arg1); | |||
8462 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, | |||
8463 | bin_locus_tests[i].arg2); | |||
8464 | res = isl_union_map_read_from_str(ctx, bin_locus_tests[i].res); | |||
8465 | umap = bin_locus_tests[i].fn(umap, mupa); | |||
8466 | ok = isl_union_map_is_equal(umap, res); | |||
8467 | isl_union_map_free(umap); | |||
8468 | isl_union_map_free(res); | |||
8469 | if (ok < 0) | |||
8470 | return -1; | |||
8471 | if (!ok) | |||
8472 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 8473); return -1; } while (0) | |||
8473 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 8473); return -1; } while (0); | |||
8474 | } | |||
8475 | ||||
8476 | return 0; | |||
8477 | } | |||
8478 | ||||
8479 | /* Inputs for basic tests of functions that determine | |||
8480 | * the part of the domain where two isl_multi_aff objects | |||
8481 | * related to each other in a specific way. | |||
8482 | * "fn" is the function that is being tested. | |||
8483 | * "arg1" and "arg2" are string descriptions of the inputs. | |||
8484 | * "res" is a string description of the expected result. | |||
8485 | */ | |||
8486 | static struct { | |||
8487 | __isl_give isl_setisl_map *(*fn)(__isl_take isl_multi_aff *ma1, | |||
8488 | __isl_take isl_multi_aff *ma2); | |||
8489 | const char *arg1; | |||
8490 | const char *arg2; | |||
8491 | const char *res; | |||
8492 | } bin_locus_ma_tests[] = { | |||
8493 | { &isl_multi_aff_lex_le_set, "{ [] }", "{ [] }", "{ : }" }, | |||
8494 | { &isl_multi_aff_lex_lt_set, "{ [] }", "{ [] }", "{ : false }" }, | |||
8495 | { &isl_multi_aff_lex_le_set, | |||
8496 | "{ A[i] -> [i] }", "{ A[i] -> [0] }", | |||
8497 | "{ A[i] : i <= 0 }" }, | |||
8498 | { &isl_multi_aff_lex_lt_set, | |||
8499 | "{ A[i] -> [i] }", "{ A[i] -> [0] }", | |||
8500 | "{ A[i] : i < 0 }" }, | |||
8501 | { &isl_multi_aff_lex_le_set, | |||
8502 | "{ A[i] -> [i, i] }", "{ A[i] -> [0, 0] }", | |||
8503 | "{ A[i] : i <= 0 }" }, | |||
8504 | { &isl_multi_aff_lex_le_set, | |||
8505 | "{ A[i] -> [i, 0] }", "{ A[i] -> [0, 0] }", | |||
8506 | "{ A[i] : i <= 0 }" }, | |||
8507 | { &isl_multi_aff_lex_le_set, | |||
8508 | "{ A[i] -> [i, 1] }", "{ A[i] -> [0, 0] }", | |||
8509 | "{ A[i] : i < 0 }" }, | |||
8510 | }; | |||
8511 | ||||
8512 | /* Perform some basic tests of functions that determine | |||
8513 | * the part of the domain where two isl_multi_aff objects | |||
8514 | * related to each other in a specific way. | |||
8515 | */ | |||
8516 | static isl_stat test_bin_locus_ma(isl_ctx *ctx) | |||
8517 | { | |||
8518 | int i; | |||
8519 | ||||
8520 | for (i = 0; i < ARRAY_SIZE(bin_locus_ma_tests)(sizeof(bin_locus_ma_tests)/sizeof(*bin_locus_ma_tests)); ++i) { | |||
8521 | const char *str; | |||
8522 | isl_bool ok; | |||
8523 | isl_multi_aff *ma1, *ma2; | |||
8524 | isl_setisl_map *set, *res; | |||
8525 | ||||
8526 | str = bin_locus_ma_tests[i].arg1; | |||
8527 | ma1 = isl_multi_aff_read_from_str(ctx, str); | |||
8528 | str = bin_locus_ma_tests[i].arg2; | |||
8529 | ma2 = isl_multi_aff_read_from_str(ctx, str); | |||
8530 | res = isl_set_read_from_str(ctx, bin_locus_ma_tests[i].res); | |||
8531 | set = bin_locus_ma_tests[i].fn(ma1, ma2); | |||
8532 | ok = isl_set_is_equal(set, res); | |||
8533 | isl_set_free(set); | |||
8534 | isl_set_free(res); | |||
8535 | if (ok < 0) | |||
8536 | return isl_stat_error; | |||
8537 | if (!ok) | |||
8538 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 8539); return isl_stat_error ; } while (0) | |||
8539 | "unexpected result", return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 8539); return isl_stat_error ; } while (0); | |||
8540 | } | |||
8541 | ||||
8542 | return isl_stat_ok; | |||
8543 | } | |||
8544 | ||||
8545 | /* Perform basic locus tests. | |||
8546 | */ | |||
8547 | static int test_locus(isl_ctx *ctx) | |||
8548 | { | |||
8549 | if (test_un_locus(ctx) < 0) | |||
8550 | return -1; | |||
8551 | if (test_bin_locus(ctx) < 0) | |||
8552 | return -1; | |||
8553 | if (test_bin_locus_ma(ctx) < 0) | |||
8554 | return -1; | |||
8555 | return 0; | |||
8556 | } | |||
8557 | ||||
8558 | /* Test that isl_union_pw_qpolynomial_eval picks up the function | |||
8559 | * defined over the correct domain space. | |||
8560 | */ | |||
8561 | static int test_eval_1(isl_ctx *ctx) | |||
8562 | { | |||
8563 | const char *str; | |||
8564 | isl_point *pnt; | |||
8565 | isl_setisl_map *set; | |||
8566 | isl_union_pw_qpolynomial *upwqp; | |||
8567 | isl_val *v; | |||
8568 | int cmp; | |||
8569 | ||||
8570 | str = "{ A[x] -> x^2; B[x] -> -x^2 }"; | |||
8571 | upwqp = isl_union_pw_qpolynomial_read_from_str(ctx, str); | |||
8572 | str = "{ A[6] }"; | |||
8573 | set = isl_set_read_from_str(ctx, str); | |||
8574 | pnt = isl_set_sample_point(set); | |||
8575 | v = isl_union_pw_qpolynomial_eval(upwqp, pnt); | |||
8576 | cmp = isl_val_cmp_si(v, 36); | |||
8577 | isl_val_free(v); | |||
8578 | ||||
8579 | if (!v) | |||
8580 | return -1; | |||
8581 | if (cmp != 0) | |||
8582 | isl_die(ctx, isl_error_unknown, "unexpected value", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected value" , "polly/lib/External/isl/isl_test.c", 8582); return -1; } while (0); | |||
8583 | ||||
8584 | return 0; | |||
8585 | } | |||
8586 | ||||
8587 | /* Check that isl_qpolynomial_eval handles getting called on a void point. | |||
8588 | */ | |||
8589 | static int test_eval_2(isl_ctx *ctx) | |||
8590 | { | |||
8591 | const char *str; | |||
8592 | isl_point *pnt; | |||
8593 | isl_setisl_map *set; | |||
8594 | isl_qpolynomial *qp; | |||
8595 | isl_val *v; | |||
8596 | isl_bool ok; | |||
8597 | ||||
8598 | str = "{ A[x] -> [x] }"; | |||
8599 | qp = isl_qpolynomial_from_aff(isl_aff_read_from_str(ctx, str)); | |||
8600 | str = "{ A[x] : false }"; | |||
8601 | set = isl_set_read_from_str(ctx, str); | |||
8602 | pnt = isl_set_sample_point(set); | |||
8603 | v = isl_qpolynomial_eval(qp, pnt); | |||
8604 | ok = isl_val_is_nan(v); | |||
8605 | isl_val_free(v); | |||
8606 | ||||
8607 | if (ok < 0) | |||
8608 | return -1; | |||
8609 | if (!ok) | |||
8610 | isl_die(ctx, isl_error_unknown, "expecting NaN", return -1)do { isl_handle_error(ctx, isl_error_unknown, "expecting NaN" , "polly/lib/External/isl/isl_test.c", 8610); return -1; } while (0); | |||
8611 | ||||
8612 | return 0; | |||
8613 | } | |||
8614 | ||||
8615 | /* Check that a polynomial (without local variables) can be evaluated | |||
8616 | * in a rational point. | |||
8617 | */ | |||
8618 | static isl_stat test_eval_3(isl_ctx *ctx) | |||
8619 | { | |||
8620 | isl_pw_qpolynomial *pwqp; | |||
8621 | isl_point *pnt; | |||
8622 | isl_val *v; | |||
8623 | isl_stat r; | |||
8624 | ||||
8625 | pwqp = isl_pw_qpolynomial_read_from_str(ctx, "{ [x] -> x^2 }"); | |||
8626 | pnt = isl_point_zero(isl_pw_qpolynomial_get_domain_space(pwqp)); | |||
8627 | v = isl_val_read_from_str(ctx, "1/2"); | |||
8628 | pnt = isl_point_set_coordinate_val(pnt, isl_dim_set, 0, v); | |||
8629 | v = isl_pw_qpolynomial_eval(pwqp, pnt); | |||
8630 | r = val_check_equal(v, "1/4"); | |||
8631 | isl_val_free(v); | |||
8632 | ||||
8633 | return r; | |||
8634 | } | |||
8635 | ||||
8636 | /* Inputs for isl_pw_aff_eval test. | |||
8637 | * "f" is the affine function. | |||
8638 | * "p" is the point where the function should be evaluated. | |||
8639 | * "res" is the expected result. | |||
8640 | */ | |||
8641 | struct { | |||
8642 | const char *f; | |||
8643 | const char *p; | |||
8644 | const char *res; | |||
8645 | } aff_eval_tests[] = { | |||
8646 | { "{ [i] -> [2 * i] }", "{ [4] }", "8" }, | |||
8647 | { "{ [i] -> [2 * i] }", "{ [x] : false }", "NaN" }, | |||
8648 | { "{ [i] -> [i + floor(i/2) + floor(i/3)] }", "{ [0] }", "0" }, | |||
8649 | { "{ [i] -> [i + floor(i/2) + floor(i/3)] }", "{ [1] }", "1" }, | |||
8650 | { "{ [i] -> [i + floor(i/2) + floor(i/3)] }", "{ [2] }", "3" }, | |||
8651 | { "{ [i] -> [i + floor(i/2) + floor(i/3)] }", "{ [3] }", "5" }, | |||
8652 | { "{ [i] -> [i + floor(i/2) + floor(i/3)] }", "{ [4] }", "7" }, | |||
8653 | { "{ [i] -> [floor((3 * floor(i/2))/5)] }", "{ [0] }", "0" }, | |||
8654 | { "{ [i] -> [floor((3 * floor(i/2))/5)] }", "{ [1] }", "0" }, | |||
8655 | { "{ [i] -> [floor((3 * floor(i/2))/5)] }", "{ [2] }", "0" }, | |||
8656 | { "{ [i] -> [floor((3 * floor(i/2))/5)] }", "{ [3] }", "0" }, | |||
8657 | { "{ [i] -> [floor((3 * floor(i/2))/5)] }", "{ [4] }", "1" }, | |||
8658 | { "{ [i] -> [floor((3 * floor(i/2))/5)] }", "{ [6] }", "1" }, | |||
8659 | { "{ [i] -> [floor((3 * floor(i/2))/5)] }", "{ [8] }", "2" }, | |||
8660 | { "{ [i] -> [i] : i > 0; [i] -> [-i] : i < 0 }", "{ [4] }", "4" }, | |||
8661 | { "{ [i] -> [i] : i > 0; [i] -> [-i] : i < 0 }", "{ [-2] }", "2" }, | |||
8662 | { "{ [i] -> [i] : i > 0; [i] -> [-i] : i < 0 }", "{ [0] }", "NaN" }, | |||
8663 | { "[N] -> { [2 * N] }", "[N] -> { : N = 4 }", "8" }, | |||
8664 | { "{ [i, j] -> [(i + j)/2] }", "{ [1, 1] }", "1" }, | |||
8665 | { "{ [i, j] -> [(i + j)/2] }", "{ [1, 2] }", "3/2" }, | |||
8666 | { "{ [i] -> [i] : i mod 2 = 0 }", "{ [4] }", "4" }, | |||
8667 | { "{ [i] -> [i] : i mod 2 = 0 }", "{ [3] }", "NaN" }, | |||
8668 | { "{ [i] -> [i] : i mod 2 = 0 }", "{ [x] : false }", "NaN" }, | |||
8669 | { "[m, n] -> { [2m + 3n] }", "[n=1, m=10] -> { : }", "23" }, | |||
8670 | }; | |||
8671 | ||||
8672 | /* Perform basic isl_pw_aff_eval tests. | |||
8673 | */ | |||
8674 | static int test_eval_aff(isl_ctx *ctx) | |||
8675 | { | |||
8676 | int i; | |||
8677 | ||||
8678 | for (i = 0; i < ARRAY_SIZE(aff_eval_tests)(sizeof(aff_eval_tests)/sizeof(*aff_eval_tests)); ++i) { | |||
8679 | isl_stat r; | |||
8680 | isl_pw_aff *pa; | |||
8681 | isl_setisl_map *set; | |||
8682 | isl_point *pnt; | |||
8683 | isl_val *v; | |||
8684 | ||||
8685 | pa = isl_pw_aff_read_from_str(ctx, aff_eval_tests[i].f); | |||
8686 | set = isl_set_read_from_str(ctx, aff_eval_tests[i].p); | |||
8687 | pnt = isl_set_sample_point(set); | |||
8688 | v = isl_pw_aff_eval(pa, pnt); | |||
8689 | r = val_check_equal(v, aff_eval_tests[i].res); | |||
8690 | isl_val_free(v); | |||
8691 | if (r < 0) | |||
8692 | return -1; | |||
8693 | } | |||
8694 | return 0; | |||
8695 | } | |||
8696 | ||||
8697 | /* Perform basic evaluation tests. | |||
8698 | */ | |||
8699 | static int test_eval(isl_ctx *ctx) | |||
8700 | { | |||
8701 | if (test_eval_1(ctx) < 0) | |||
8702 | return -1; | |||
8703 | if (test_eval_2(ctx) < 0) | |||
8704 | return -1; | |||
8705 | if (test_eval_3(ctx) < 0) | |||
8706 | return -1; | |||
8707 | if (test_eval_aff(ctx) < 0) | |||
8708 | return -1; | |||
8709 | return 0; | |||
8710 | } | |||
8711 | ||||
8712 | /* Descriptions of sets that are tested for reparsing after printing. | |||
8713 | */ | |||
8714 | const char *output_tests[] = { | |||
8715 | "{ [1, y] : 0 <= y <= 1; [x, -x] : 0 <= x <= 1 }", | |||
8716 | "{ [x] : 1 = 0 }", | |||
8717 | "{ [x] : false }", | |||
8718 | "{ [x] : x mod 2 = 0 }", | |||
8719 | "{ [x] : x mod 2 = 1 }", | |||
8720 | "{ [x, y] : x mod 2 = 0 and 3*floor(y/2) < x }", | |||
8721 | "{ [y, x] : x mod 2 = 0 and 3*floor(y/2) < x }", | |||
8722 | "{ [x, y] : x mod 2 = 0 and 3*floor(y/2) = x + y }", | |||
8723 | "{ [y, x] : x mod 2 = 0 and 3*floor(y/2) = x + y }", | |||
8724 | "[n] -> { [y, x] : 2*((x + 2y) mod 3) = n }", | |||
8725 | "{ [x, y] : (2*floor(x/3) + 3*floor(y/4)) mod 5 = x }", | |||
8726 | }; | |||
8727 | ||||
8728 | /* Check that printing a set and reparsing a set from the printed output | |||
8729 | * results in the same set. | |||
8730 | */ | |||
8731 | static int test_output_set(isl_ctx *ctx) | |||
8732 | { | |||
8733 | int i; | |||
8734 | char *str; | |||
8735 | isl_setisl_map *set1, *set2; | |||
8736 | isl_bool equal; | |||
8737 | ||||
8738 | for (i = 0; i < ARRAY_SIZE(output_tests)(sizeof(output_tests)/sizeof(*output_tests)); ++i) { | |||
8739 | set1 = isl_set_read_from_str(ctx, output_tests[i]); | |||
8740 | str = isl_set_to_str(set1); | |||
8741 | set2 = isl_set_read_from_str(ctx, str); | |||
8742 | free(str); | |||
8743 | equal = isl_set_is_equal(set1, set2); | |||
8744 | isl_set_free(set1); | |||
8745 | isl_set_free(set2); | |||
8746 | if (equal < 0) | |||
8747 | return -1; | |||
8748 | if (!equal) | |||
8749 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "parsed output not the same" , "polly/lib/External/isl/isl_test.c", 8750); return -1; } while (0) | |||
8750 | "parsed output not the same", return -1)do { isl_handle_error(ctx, isl_error_unknown, "parsed output not the same" , "polly/lib/External/isl/isl_test.c", 8750); return -1; } while (0); | |||
8751 | } | |||
8752 | ||||
8753 | return 0; | |||
8754 | } | |||
8755 | ||||
8756 | /* Check that an isl_multi_aff is printed using a consistent space. | |||
8757 | */ | |||
8758 | static isl_stat test_output_ma(isl_ctx *ctx) | |||
8759 | { | |||
8760 | char *str; | |||
8761 | isl_bool equal; | |||
8762 | isl_aff *aff; | |||
8763 | isl_multi_aff *ma, *ma2; | |||
8764 | ||||
8765 | ma = isl_multi_aff_read_from_str(ctx, "{ [a, b] -> [a + b] }"); | |||
8766 | aff = isl_aff_read_from_str(ctx, "{ [c, d] -> [c + d] }"); | |||
8767 | ma = isl_multi_aff_set_aff(ma, 0, aff); | |||
8768 | str = isl_multi_aff_to_str(ma); | |||
8769 | ma2 = isl_multi_aff_read_from_str(ctx, str); | |||
8770 | free(str); | |||
8771 | equal = isl_multi_aff_plain_is_equal(ma, ma2); | |||
8772 | isl_multi_aff_free(ma2); | |||
8773 | isl_multi_aff_free(ma); | |||
8774 | ||||
8775 | if (equal < 0) | |||
8776 | return isl_stat_error; | |||
8777 | if (!equal) | |||
8778 | isl_die(ctx, isl_error_unknown, "bad conversion",do { isl_handle_error(ctx, isl_error_unknown, "bad conversion" , "polly/lib/External/isl/isl_test.c", 8779); return isl_stat_error ; } while (0) | |||
8779 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "bad conversion" , "polly/lib/External/isl/isl_test.c", 8779); return isl_stat_error ; } while (0); | |||
8780 | ||||
8781 | return isl_stat_ok; | |||
8782 | } | |||
8783 | ||||
8784 | /* Check that an isl_multi_pw_aff is printed using a consistent space. | |||
8785 | */ | |||
8786 | static isl_stat test_output_mpa(isl_ctx *ctx) | |||
8787 | { | |||
8788 | char *str; | |||
8789 | isl_bool equal; | |||
8790 | isl_pw_aff *pa; | |||
8791 | isl_multi_pw_aff *mpa, *mpa2; | |||
8792 | ||||
8793 | mpa = isl_multi_pw_aff_read_from_str(ctx, "{ [a, b] -> [a + b] }"); | |||
8794 | pa = isl_pw_aff_read_from_str(ctx, "{ [c, d] -> [c + d] }"); | |||
8795 | mpa = isl_multi_pw_aff_set_pw_aff(mpa, 0, pa); | |||
8796 | str = isl_multi_pw_aff_to_str(mpa); | |||
8797 | mpa2 = isl_multi_pw_aff_read_from_str(ctx, str); | |||
8798 | free(str); | |||
8799 | equal = isl_multi_pw_aff_plain_is_equal(mpa, mpa2); | |||
8800 | isl_multi_pw_aff_free(mpa2); | |||
8801 | isl_multi_pw_aff_free(mpa); | |||
8802 | ||||
8803 | if (equal < 0) | |||
8804 | return isl_stat_error; | |||
8805 | if (!equal) | |||
8806 | isl_die(ctx, isl_error_unknown, "bad conversion",do { isl_handle_error(ctx, isl_error_unknown, "bad conversion" , "polly/lib/External/isl/isl_test.c", 8807); return isl_stat_error ; } while (0) | |||
8807 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "bad conversion" , "polly/lib/External/isl/isl_test.c", 8807); return isl_stat_error ; } while (0); | |||
8808 | ||||
8809 | return isl_stat_ok; | |||
8810 | } | |||
8811 | ||||
8812 | int test_output(isl_ctx *ctx) | |||
8813 | { | |||
8814 | char *s; | |||
8815 | const char *str; | |||
8816 | isl_pw_aff *pa; | |||
8817 | isl_printer *p; | |||
8818 | int equal; | |||
8819 | ||||
8820 | if (test_output_set(ctx) < 0) | |||
8821 | return -1; | |||
8822 | if (test_output_ma(ctx) < 0) | |||
8823 | return -1; | |||
8824 | if (test_output_mpa(ctx) < 0) | |||
8825 | return -1; | |||
8826 | ||||
8827 | str = "[x] -> { [1] : x % 4 <= 2; [2] : x = 3 }"; | |||
8828 | pa = isl_pw_aff_read_from_str(ctx, str); | |||
8829 | ||||
8830 | p = isl_printer_to_str(ctx); | |||
8831 | p = isl_printer_set_output_format(p, ISL_FORMAT_C4); | |||
8832 | p = isl_printer_print_pw_aff(p, pa); | |||
8833 | s = isl_printer_get_str(p); | |||
8834 | isl_printer_free(p); | |||
8835 | isl_pw_aff_free(pa); | |||
8836 | if (!s) | |||
8837 | equal = -1; | |||
8838 | else | |||
8839 | equal = !strcmp(s, "4 * floord(x, 4) + 2 >= x ? 1 : 2"); | |||
8840 | free(s); | |||
8841 | if (equal < 0) | |||
8842 | return -1; | |||
8843 | if (!equal) | |||
8844 | isl_die(ctx, isl_error_unknown, "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 8844); return -1; } while (0); | |||
8845 | ||||
8846 | return 0; | |||
8847 | } | |||
8848 | ||||
8849 | int test_sample(isl_ctx *ctx) | |||
8850 | { | |||
8851 | const char *str; | |||
8852 | isl_basic_setisl_basic_map *bset1, *bset2; | |||
8853 | int empty, subset; | |||
8854 | ||||
8855 | str = "{ [a, b, c, d, e, f, g, h, i, j, k] : " | |||
8856 | "3i >= 1073741823b - c - 1073741823e + f and c >= 0 and " | |||
8857 | "3i >= -1 + 3221225466b + c + d - 3221225466e - f and " | |||
8858 | "2e >= a - b and 3e <= 2a and 3k <= -a and f <= -1 + a and " | |||
8859 | "3i <= 4 - a + 4b + 2c - e - 2f and 3k <= -a + c - f and " | |||
8860 | "3h >= -2 + a and 3g >= -3 - a and 3k >= -2 - a and " | |||
8861 | "3i >= -2 - a - 2c + 3e + 2f and 3h <= a + c - f and " | |||
8862 | "3h >= a + 2147483646b + 2c - 2147483646e - 2f and " | |||
8863 | "3g <= -1 - a and 3i <= 1 + c + d - f and a <= 1073741823 and " | |||
8864 | "f >= 1 - a + 1073741822b + c + d - 1073741822e and " | |||
8865 | "3i >= 1 + 2b - 2c + e + 2f + 3g and " | |||
8866 | "1073741822f <= 1073741822 - a + 1073741821b + 1073741822c +" | |||
8867 | "d - 1073741821e and " | |||
8868 | "3j <= 3 - a + 3b and 3g <= -2 - 2b + c + d - e - f and " | |||
8869 | "3j >= 1 - a + b + 2e and " | |||
8870 | "3f >= -3 + a + 3221225462b + 3c + d - 3221225465e and " | |||
8871 | "3i <= 4 - a + 4b - e and " | |||
8872 | "f <= 1073741822 + 1073741822b - 1073741822e and 3h <= a and " | |||
8873 | "f >= 0 and 2e <= 4 - a + 5b - d and 2e <= a - b + d and " | |||
8874 | "c <= -1 + a and 3i >= -2 - a + 3e and " | |||
8875 | "1073741822e <= 1073741823 - a + 1073741822b + c and " | |||
8876 | "3g >= -4 + 3221225464b + 3c + d - 3221225467e - 3f and " | |||
8877 | "3i >= -1 + 3221225466b + 3c + d - 3221225466e - 3f and " | |||
8878 | "1073741823e >= 1 + 1073741823b - d and " | |||
8879 | "3i >= 1073741823b + c - 1073741823e - f and " | |||
8880 | "3i >= 1 + 2b + e + 3g }"; | |||
8881 | bset1 = isl_basic_set_read_from_str(ctx, str); | |||
8882 | bset2 = isl_basic_set_sample(isl_basic_set_copy(bset1)); | |||
8883 | empty = isl_basic_set_is_empty(bset2); | |||
8884 | subset = isl_basic_set_is_subset(bset2, bset1); | |||
8885 | isl_basic_set_free(bset1); | |||
8886 | isl_basic_set_free(bset2); | |||
8887 | if (empty < 0 || subset < 0) | |||
8888 | return -1; | |||
8889 | if (empty) | |||
8890 | isl_die(ctx, isl_error_unknown, "point not found", return -1)do { isl_handle_error(ctx, isl_error_unknown, "point not found" , "polly/lib/External/isl/isl_test.c", 8890); return -1; } while (0); | |||
8891 | if (!subset) | |||
8892 | isl_die(ctx, isl_error_unknown, "bad point found", return -1)do { isl_handle_error(ctx, isl_error_unknown, "bad point found" , "polly/lib/External/isl/isl_test.c", 8892); return -1; } while (0); | |||
8893 | ||||
8894 | return 0; | |||
8895 | } | |||
8896 | ||||
8897 | /* Perform a projection on a basic set that is known to be empty | |||
8898 | * but that has not been assigned a canonical representation. | |||
8899 | * Earlier versions of isl would run into a stack overflow | |||
8900 | * on this example. | |||
8901 | */ | |||
8902 | static int test_empty_projection(isl_ctx *ctx) | |||
8903 | { | |||
8904 | const char *str; | |||
8905 | isl_bool empty; | |||
8906 | isl_basic_setisl_basic_map *bset; | |||
8907 | ||||
8908 | str = "{ [a, b, c, d, e, f, g, h] : 5f = 1 + 4a - b + 5c - d - 2e and " | |||
8909 | "3h = 2 + b + c and 14c >= 9 - 3a + 25b and " | |||
8910 | "4c <= 50 - 3a + 23b and 6b <= -39 + a and " | |||
8911 | "9g >= -6 + 3a + b + c and e < a + b - 2d and " | |||
8912 | "7d >= -5 + 2a + 2b and 5g >= -14 + a - 4b + d + 2e and " | |||
8913 | "9g <= -28 - 5b - 2c + 3d + 6e }"; | |||
8914 | bset = isl_basic_set_read_from_str(ctx, str); | |||
8915 | empty = isl_basic_set_is_empty(bset); | |||
8916 | bset = isl_basic_set_params(bset); | |||
8917 | isl_basic_set_free(bset); | |||
8918 | ||||
8919 | if (empty < 0) | |||
8920 | return -1; | |||
8921 | ||||
8922 | return 0; | |||
8923 | } | |||
8924 | ||||
8925 | int test_slice(isl_ctx *ctx) | |||
8926 | { | |||
8927 | const char *str; | |||
8928 | isl_map *map; | |||
8929 | int equal; | |||
8930 | ||||
8931 | str = "{ [i] -> [j] }"; | |||
8932 | map = isl_map_read_from_str(ctx, str); | |||
8933 | map = isl_map_equate(map, isl_dim_in, 0, isl_dim_out, 0); | |||
8934 | equal = map_check_equal(map, "{ [i] -> [i] }"); | |||
8935 | isl_map_free(map); | |||
8936 | if (equal < 0) | |||
8937 | return -1; | |||
8938 | ||||
8939 | str = "{ [i] -> [j] }"; | |||
8940 | map = isl_map_read_from_str(ctx, str); | |||
8941 | map = isl_map_equate(map, isl_dim_in, 0, isl_dim_in, 0); | |||
8942 | equal = map_check_equal(map, "{ [i] -> [j] }"); | |||
8943 | isl_map_free(map); | |||
8944 | if (equal < 0) | |||
8945 | return -1; | |||
8946 | ||||
8947 | str = "{ [i] -> [j] }"; | |||
8948 | map = isl_map_read_from_str(ctx, str); | |||
8949 | map = isl_map_oppose(map, isl_dim_in, 0, isl_dim_out, 0); | |||
8950 | equal = map_check_equal(map, "{ [i] -> [-i] }"); | |||
8951 | isl_map_free(map); | |||
8952 | if (equal < 0) | |||
8953 | return -1; | |||
8954 | ||||
8955 | str = "{ [i] -> [j] }"; | |||
8956 | map = isl_map_read_from_str(ctx, str); | |||
8957 | map = isl_map_oppose(map, isl_dim_in, 0, isl_dim_in, 0); | |||
8958 | equal = map_check_equal(map, "{ [0] -> [j] }"); | |||
8959 | isl_map_free(map); | |||
8960 | if (equal < 0) | |||
8961 | return -1; | |||
8962 | ||||
8963 | str = "{ [i] -> [j] }"; | |||
8964 | map = isl_map_read_from_str(ctx, str); | |||
8965 | map = isl_map_order_gt(map, isl_dim_in, 0, isl_dim_out, 0); | |||
8966 | equal = map_check_equal(map, "{ [i] -> [j] : i > j }"); | |||
8967 | isl_map_free(map); | |||
8968 | if (equal < 0) | |||
8969 | return -1; | |||
8970 | ||||
8971 | str = "{ [i] -> [j] }"; | |||
8972 | map = isl_map_read_from_str(ctx, str); | |||
8973 | map = isl_map_order_gt(map, isl_dim_in, 0, isl_dim_in, 0); | |||
8974 | equal = map_check_equal(map, "{ [i] -> [j] : false }"); | |||
8975 | isl_map_free(map); | |||
8976 | if (equal < 0) | |||
8977 | return -1; | |||
8978 | ||||
8979 | return 0; | |||
8980 | } | |||
8981 | ||||
8982 | int test_eliminate(isl_ctx *ctx) | |||
8983 | { | |||
8984 | const char *str; | |||
8985 | isl_map *map; | |||
8986 | int equal; | |||
8987 | ||||
8988 | str = "{ [i] -> [j] : i = 2j }"; | |||
8989 | map = isl_map_read_from_str(ctx, str); | |||
8990 | map = isl_map_eliminate(map, isl_dim_out, 0, 1); | |||
8991 | equal = map_check_equal(map, "{ [i] -> [j] : exists a : i = 2a }"); | |||
8992 | isl_map_free(map); | |||
8993 | if (equal < 0) | |||
8994 | return -1; | |||
8995 | ||||
8996 | return 0; | |||
8997 | } | |||
8998 | ||||
8999 | /* Check basic functionality of isl_map_deltas_map. | |||
9000 | */ | |||
9001 | static int test_deltas_map(isl_ctx *ctx) | |||
9002 | { | |||
9003 | const char *str; | |||
9004 | isl_map *map; | |||
9005 | int equal; | |||
9006 | ||||
9007 | str = "{ A[i] -> A[i + 1] }"; | |||
9008 | map = isl_map_read_from_str(ctx, str); | |||
9009 | map = isl_map_deltas_map(map); | |||
9010 | equal = map_check_equal(map, "{ [A[i] -> A[i + 1]] -> A[1] }"); | |||
9011 | isl_map_free(map); | |||
9012 | if (equal < 0) | |||
9013 | return -1; | |||
9014 | ||||
9015 | return 0; | |||
9016 | } | |||
9017 | ||||
9018 | /* Check that isl_set_dim_residue_class detects that the values of j | |||
9019 | * in the set below are all odd and that it does not detect any spurious | |||
9020 | * strides. | |||
9021 | */ | |||
9022 | static int test_residue_class(isl_ctx *ctx) | |||
9023 | { | |||
9024 | const char *str; | |||
9025 | isl_setisl_map *set; | |||
9026 | isl_int m, r; | |||
9027 | isl_stat res; | |||
9028 | ||||
9029 | str = "{ [i,j] : j = 4 i + 1 and 0 <= i <= 100; " | |||
9030 | "[i,j] : j = 4 i + 3 and 500 <= i <= 600 }"; | |||
9031 | set = isl_set_read_from_str(ctx, str); | |||
9032 | isl_int_init(m)isl_sioimath_init((m)); | |||
9033 | isl_int_init(r)isl_sioimath_init((r)); | |||
9034 | res = isl_set_dim_residue_class(set, 1, &m, &r); | |||
9035 | if (res >= 0 && | |||
9036 | (isl_int_cmp_si(m, 2)isl_sioimath_cmp_si(*(m), 2) != 0 || isl_int_cmp_si(r, 1)isl_sioimath_cmp_si(*(r), 1) != 0)) | |||
9037 | isl_die(ctx, isl_error_unknown, "incorrect residue class",do { isl_handle_error(ctx, isl_error_unknown, "incorrect residue class" , "polly/lib/External/isl/isl_test.c", 9038); res = isl_stat_error ; } while (0) | |||
9038 | res = isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "incorrect residue class" , "polly/lib/External/isl/isl_test.c", 9038); res = isl_stat_error ; } while (0); | |||
9039 | isl_int_clear(r)isl_sioimath_clear((r)); | |||
9040 | isl_int_clear(m)isl_sioimath_clear((m)); | |||
9041 | isl_set_free(set); | |||
9042 | ||||
9043 | return res; | |||
9044 | } | |||
9045 | ||||
9046 | static int test_align_parameters_1(isl_ctx *ctx) | |||
9047 | { | |||
9048 | const char *str; | |||
9049 | isl_space *space; | |||
9050 | isl_multi_aff *ma1, *ma2; | |||
9051 | int equal; | |||
9052 | ||||
9053 | str = "{ A[B[] -> C[]] -> D[E[] -> F[]] }"; | |||
9054 | ma1 = isl_multi_aff_read_from_str(ctx, str); | |||
9055 | ||||
9056 | space = isl_space_params_alloc(ctx, 1); | |||
9057 | space = isl_space_set_dim_name(space, isl_dim_param, 0, "N"); | |||
9058 | ma1 = isl_multi_aff_align_params(ma1, space); | |||
9059 | ||||
9060 | str = "[N] -> { A[B[] -> C[]] -> D[E[] -> F[]] }"; | |||
9061 | ma2 = isl_multi_aff_read_from_str(ctx, str); | |||
9062 | ||||
9063 | equal = isl_multi_aff_plain_is_equal(ma1, ma2); | |||
9064 | ||||
9065 | isl_multi_aff_free(ma1); | |||
9066 | isl_multi_aff_free(ma2); | |||
9067 | ||||
9068 | if (equal < 0) | |||
9069 | return -1; | |||
9070 | if (!equal) | |||
9071 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "result not as expected" , "polly/lib/External/isl/isl_test.c", 9072); return -1; } while (0) | |||
9072 | "result not as expected", return -1)do { isl_handle_error(ctx, isl_error_unknown, "result not as expected" , "polly/lib/External/isl/isl_test.c", 9072); return -1; } while (0); | |||
9073 | ||||
9074 | return 0; | |||
9075 | } | |||
9076 | ||||
9077 | /* Check the isl_multi_*_from_*_list operation in case inputs | |||
9078 | * have unaligned parameters. | |||
9079 | * In particular, older versions of isl would simply fail | |||
9080 | * (without printing any error message). | |||
9081 | */ | |||
9082 | static isl_stat test_align_parameters_2(isl_ctx *ctx) | |||
9083 | { | |||
9084 | isl_space *space; | |||
9085 | isl_map *map; | |||
9086 | isl_aff *aff; | |||
9087 | isl_multi_aff *ma; | |||
9088 | ||||
9089 | map = isl_map_read_from_str(ctx, "{ A[] -> M[x] }"); | |||
9090 | space = isl_map_get_space(map); | |||
9091 | isl_map_free(map); | |||
9092 | ||||
9093 | aff = isl_aff_read_from_str(ctx, "[N] -> { A[] -> [N] }"); | |||
9094 | ma = isl_multi_aff_from_aff_list(space, isl_aff_list_from_aff(aff)); | |||
9095 | isl_multi_aff_free(ma); | |||
9096 | ||||
9097 | if (!ma) | |||
9098 | return isl_stat_error; | |||
9099 | return isl_stat_ok; | |||
9100 | } | |||
9101 | ||||
9102 | /* Perform basic parameter alignment tests. | |||
9103 | */ | |||
9104 | static int test_align_parameters(isl_ctx *ctx) | |||
9105 | { | |||
9106 | if (test_align_parameters_1(ctx) < 0) | |||
9107 | return -1; | |||
9108 | if (test_align_parameters_2(ctx) < 0) | |||
9109 | return -1; | |||
9110 | ||||
9111 | return 0; | |||
9112 | } | |||
9113 | ||||
9114 | /* Check that isl_*_drop_unused_params actually drops the unused parameters | |||
9115 | * by comparing the result using isl_*_plain_is_equal. | |||
9116 | * Note that this assumes that isl_*_plain_is_equal does not consider | |||
9117 | * objects that only differ by unused parameters to be equal. | |||
9118 | */ | |||
9119 | int test_drop_unused_parameters(isl_ctx *ctx) | |||
9120 | { | |||
9121 | const char *str_with, *str_without; | |||
9122 | isl_basic_setisl_basic_map *bset1, *bset2; | |||
9123 | isl_setisl_map *set1, *set2; | |||
9124 | isl_pw_aff *pwa1, *pwa2; | |||
9125 | int equal; | |||
9126 | ||||
9127 | str_with = "[n, m, o] -> { [m] }"; | |||
9128 | str_without = "[m] -> { [m] }"; | |||
9129 | ||||
9130 | bset1 = isl_basic_set_read_from_str(ctx, str_with); | |||
9131 | bset2 = isl_basic_set_read_from_str(ctx, str_without); | |||
9132 | bset1 = isl_basic_set_drop_unused_params(bset1); | |||
9133 | equal = isl_basic_set_plain_is_equal(bset1, bset2); | |||
9134 | isl_basic_set_free(bset1); | |||
9135 | isl_basic_set_free(bset2); | |||
9136 | ||||
9137 | if (equal < 0) | |||
9138 | return -1; | |||
9139 | if (!equal) | |||
9140 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "result not as expected" , "polly/lib/External/isl/isl_test.c", 9141); return -1; } while (0) | |||
9141 | "result not as expected", return -1)do { isl_handle_error(ctx, isl_error_unknown, "result not as expected" , "polly/lib/External/isl/isl_test.c", 9141); return -1; } while (0); | |||
9142 | ||||
9143 | set1 = isl_set_read_from_str(ctx, str_with); | |||
9144 | set2 = isl_set_read_from_str(ctx, str_without); | |||
9145 | set1 = isl_set_drop_unused_params(set1); | |||
9146 | equal = isl_set_plain_is_equal(set1, set2); | |||
9147 | isl_set_free(set1); | |||
9148 | isl_set_free(set2); | |||
9149 | ||||
9150 | if (equal < 0) | |||
9151 | return -1; | |||
9152 | if (!equal) | |||
9153 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "result not as expected" , "polly/lib/External/isl/isl_test.c", 9154); return -1; } while (0) | |||
9154 | "result not as expected", return -1)do { isl_handle_error(ctx, isl_error_unknown, "result not as expected" , "polly/lib/External/isl/isl_test.c", 9154); return -1; } while (0); | |||
9155 | ||||
9156 | pwa1 = isl_pw_aff_read_from_str(ctx, str_with); | |||
9157 | pwa2 = isl_pw_aff_read_from_str(ctx, str_without); | |||
9158 | pwa1 = isl_pw_aff_drop_unused_params(pwa1); | |||
9159 | equal = isl_pw_aff_plain_is_equal(pwa1, pwa2); | |||
9160 | isl_pw_aff_free(pwa1); | |||
9161 | isl_pw_aff_free(pwa2); | |||
9162 | ||||
9163 | if (equal < 0) | |||
9164 | return -1; | |||
9165 | if (!equal) | |||
9166 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "result not as expected" , "polly/lib/External/isl/isl_test.c", 9167); return -1; } while (0) | |||
9167 | "result not as expected", return -1)do { isl_handle_error(ctx, isl_error_unknown, "result not as expected" , "polly/lib/External/isl/isl_test.c", 9167); return -1; } while (0); | |||
9168 | ||||
9169 | return 0; | |||
9170 | } | |||
9171 | ||||
9172 | static int test_list(isl_ctx *ctx) | |||
9173 | { | |||
9174 | isl_id *a, *b, *c, *d, *id; | |||
9175 | isl_id_list *list; | |||
9176 | isl_size n; | |||
9177 | int ok; | |||
9178 | ||||
9179 | a = isl_id_alloc(ctx, "a", NULL((void*)0)); | |||
9180 | b = isl_id_alloc(ctx, "b", NULL((void*)0)); | |||
9181 | c = isl_id_alloc(ctx, "c", NULL((void*)0)); | |||
9182 | d = isl_id_alloc(ctx, "d", NULL((void*)0)); | |||
9183 | ||||
9184 | list = isl_id_list_alloc(ctx, 4); | |||
9185 | list = isl_id_list_add(list, b); | |||
9186 | list = isl_id_list_insert(list, 0, a); | |||
9187 | list = isl_id_list_add(list, c); | |||
9188 | list = isl_id_list_add(list, d); | |||
9189 | list = isl_id_list_drop(list, 1, 1); | |||
9190 | ||||
9191 | n = isl_id_list_n_id(list); | |||
9192 | if (n < 0) | |||
9193 | return -1; | |||
9194 | if (n != 3) { | |||
9195 | isl_id_list_free(list); | |||
9196 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of elements in list" , "polly/lib/External/isl/isl_test.c", 9197); return -1; } while (0) | |||
9197 | "unexpected number of elements in list", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of elements in list" , "polly/lib/External/isl/isl_test.c", 9197); return -1; } while (0); | |||
9198 | } | |||
9199 | ||||
9200 | id = isl_id_list_get_id(list, 0); | |||
9201 | ok = id == a; | |||
9202 | isl_id_free(id); | |||
9203 | id = isl_id_list_get_id(list, 1); | |||
9204 | ok = ok && id == c; | |||
9205 | isl_id_free(id); | |||
9206 | id = isl_id_list_get_id(list, 2); | |||
9207 | ok = ok && id == d; | |||
9208 | isl_id_free(id); | |||
9209 | ||||
9210 | isl_id_list_free(list); | |||
9211 | ||||
9212 | if (!ok) | |||
9213 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected elements in list" , "polly/lib/External/isl/isl_test.c", 9214); return -1; } while (0) | |||
9214 | "unexpected elements in list", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected elements in list" , "polly/lib/External/isl/isl_test.c", 9214); return -1; } while (0); | |||
9215 | ||||
9216 | return 0; | |||
9217 | } | |||
9218 | ||||
9219 | /* Check the conversion from an isl_multi_aff to an isl_basic_set. | |||
9220 | */ | |||
9221 | static isl_stat test_ma_conversion(isl_ctx *ctx) | |||
9222 | { | |||
9223 | const char *str; | |||
9224 | isl_bool equal; | |||
9225 | isl_multi_aff *ma; | |||
9226 | isl_basic_setisl_basic_map *bset1, *bset2; | |||
9227 | ||||
9228 | str = "[N] -> { A[0, N + 1] }"; | |||
9229 | ma = isl_multi_aff_read_from_str(ctx, str); | |||
9230 | bset1 = isl_basic_set_read_from_str(ctx, str); | |||
9231 | bset2 = isl_basic_set_from_multi_aff(ma); | |||
9232 | equal = isl_basic_set_is_equal(bset1, bset2); | |||
9233 | isl_basic_set_free(bset1); | |||
9234 | isl_basic_set_free(bset2); | |||
9235 | if (equal < 0) | |||
9236 | return isl_stat_error; | |||
9237 | if (!equal) | |||
9238 | isl_die(ctx, isl_error_unknown, "bad conversion",do { isl_handle_error(ctx, isl_error_unknown, "bad conversion" , "polly/lib/External/isl/isl_test.c", 9239); return isl_stat_error ; } while (0) | |||
9239 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "bad conversion" , "polly/lib/External/isl/isl_test.c", 9239); return isl_stat_error ; } while (0); | |||
9240 | return isl_stat_ok; | |||
9241 | } | |||
9242 | ||||
9243 | const char *set_conversion_tests[] = { | |||
9244 | "[N] -> { [i] : N - 1 <= 2 i <= N }", | |||
9245 | "[N] -> { [i] : exists a : i = 4 a and N - 1 <= i <= N }", | |||
9246 | "[N] -> { [i,j] : exists a : i = 4 a and N - 1 <= i, 2j <= N }", | |||
9247 | "[N] -> { [[i]->[j]] : exists a : i = 4 a and N - 1 <= i, 2j <= N }", | |||
9248 | "[N] -> { [3*floor(N/2) + 5*floor(N/3)] }", | |||
9249 | "[a, b] -> { [c, d] : (4*floor((-a + c)/4) = -a + c and " | |||
9250 | "32*floor((-b + d)/32) = -b + d and 5 <= c <= 8 and " | |||
9251 | "-3 + c <= d <= 28 + c) }", | |||
9252 | }; | |||
9253 | ||||
9254 | /* Check that converting from isl_set to isl_pw_multi_aff and back | |||
9255 | * to isl_set produces the original isl_set. | |||
9256 | */ | |||
9257 | static int test_set_conversion(isl_ctx *ctx) | |||
9258 | { | |||
9259 | int i; | |||
9260 | const char *str; | |||
9261 | isl_setisl_map *set1, *set2; | |||
9262 | isl_pw_multi_aff *pma; | |||
9263 | int equal; | |||
9264 | ||||
9265 | for (i = 0; i < ARRAY_SIZE(set_conversion_tests)(sizeof(set_conversion_tests)/sizeof(*set_conversion_tests)); ++i) { | |||
9266 | str = set_conversion_tests[i]; | |||
9267 | set1 = isl_set_read_from_str(ctx, str); | |||
9268 | pma = isl_pw_multi_aff_from_set(isl_set_copy(set1)); | |||
9269 | set2 = isl_set_from_pw_multi_aff(pma); | |||
9270 | equal = isl_set_is_equal(set1, set2); | |||
9271 | isl_set_free(set1); | |||
9272 | isl_set_free(set2); | |||
9273 | ||||
9274 | if (equal < 0) | |||
9275 | return -1; | |||
9276 | if (!equal) | |||
9277 | isl_die(ctx, isl_error_unknown, "bad conversion",do { isl_handle_error(ctx, isl_error_unknown, "bad conversion" , "polly/lib/External/isl/isl_test.c", 9278); return -1; } while (0) | |||
9278 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "bad conversion" , "polly/lib/External/isl/isl_test.c", 9278); return -1; } while (0); | |||
9279 | } | |||
9280 | ||||
9281 | return 0; | |||
9282 | } | |||
9283 | ||||
9284 | const char *conversion_tests[] = { | |||
9285 | "{ [a, b, c, d] -> s0[a, b, e, f] : " | |||
9286 | "exists (e0 = [(a - 2c)/3], e1 = [(-4 + b - 5d)/9], " | |||
9287 | "e2 = [(-d + f)/9]: 3e0 = a - 2c and 9e1 = -4 + b - 5d and " | |||
9288 | "9e2 = -d + f and f >= 0 and f <= 8 and 9e >= -5 - 2a and " | |||
9289 | "9e <= -2 - 2a) }", | |||
9290 | "{ [a, b] -> [c] : exists (e0 = floor((-a - b + c)/5): " | |||
9291 | "5e0 = -a - b + c and c >= -a and c <= 4 - a) }", | |||
9292 | "{ [a, b] -> [c] : exists d : 18 * d = -3 - a + 2c and 1 <= c <= 3 }", | |||
9293 | }; | |||
9294 | ||||
9295 | /* Check that converting from isl_map to isl_pw_multi_aff and back | |||
9296 | * to isl_map produces the original isl_map. | |||
9297 | */ | |||
9298 | static int test_map_conversion(isl_ctx *ctx) | |||
9299 | { | |||
9300 | int i; | |||
9301 | isl_map *map1, *map2; | |||
9302 | isl_pw_multi_aff *pma; | |||
9303 | int equal; | |||
9304 | ||||
9305 | for (i = 0; i < ARRAY_SIZE(conversion_tests)(sizeof(conversion_tests)/sizeof(*conversion_tests)); ++i) { | |||
9306 | map1 = isl_map_read_from_str(ctx, conversion_tests[i]); | |||
9307 | pma = isl_pw_multi_aff_from_map(isl_map_copy(map1)); | |||
9308 | map2 = isl_map_from_pw_multi_aff(pma); | |||
9309 | equal = isl_map_is_equal(map1, map2); | |||
9310 | isl_map_free(map1); | |||
9311 | isl_map_free(map2); | |||
9312 | ||||
9313 | if (equal < 0) | |||
9314 | return -1; | |||
9315 | if (!equal) | |||
9316 | isl_die(ctx, isl_error_unknown, "bad conversion",do { isl_handle_error(ctx, isl_error_unknown, "bad conversion" , "polly/lib/External/isl/isl_test.c", 9317); return -1; } while (0) | |||
9317 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "bad conversion" , "polly/lib/External/isl/isl_test.c", 9317); return -1; } while (0); | |||
9318 | } | |||
9319 | ||||
9320 | return 0; | |||
9321 | } | |||
9322 | ||||
9323 | /* Descriptions of isl_pw_multi_aff objects for testing conversion | |||
9324 | * to isl_multi_pw_aff and back. | |||
9325 | */ | |||
9326 | const char *mpa_conversion_tests[] = { | |||
9327 | "{ [x] -> A[x] }", | |||
9328 | "{ [x] -> A[x] : x >= 0 }", | |||
9329 | "{ [x] -> A[x] : x >= 0; [x] -> A[-x] : x < 0 }", | |||
9330 | "{ [x] -> A[x, x + 1] }", | |||
9331 | "{ [x] -> A[] }", | |||
9332 | "{ [x] -> A[] : x >= 0 }", | |||
9333 | }; | |||
9334 | ||||
9335 | /* Check that conversion from isl_pw_multi_aff to isl_multi_pw_aff and | |||
9336 | * back to isl_pw_multi_aff preserves the original meaning. | |||
9337 | */ | |||
9338 | static int test_mpa_conversion(isl_ctx *ctx) | |||
9339 | { | |||
9340 | int i; | |||
9341 | isl_pw_multi_aff *pma1, *pma2; | |||
9342 | isl_multi_pw_aff *mpa; | |||
9343 | int equal; | |||
9344 | ||||
9345 | for (i = 0; i < ARRAY_SIZE(mpa_conversion_tests)(sizeof(mpa_conversion_tests)/sizeof(*mpa_conversion_tests)); ++i) { | |||
9346 | const char *str; | |||
9347 | str = mpa_conversion_tests[i]; | |||
9348 | pma1 = isl_pw_multi_aff_read_from_str(ctx, str); | |||
9349 | pma2 = isl_pw_multi_aff_copy(pma1); | |||
9350 | mpa = isl_multi_pw_aff_from_pw_multi_aff(pma1); | |||
9351 | pma1 = isl_pw_multi_aff_from_multi_pw_aff(mpa); | |||
9352 | equal = isl_pw_multi_aff_plain_is_equal(pma1, pma2); | |||
9353 | isl_pw_multi_aff_free(pma1); | |||
9354 | isl_pw_multi_aff_free(pma2); | |||
9355 | ||||
9356 | if (equal < 0) | |||
9357 | return -1; | |||
9358 | if (!equal) | |||
9359 | isl_die(ctx, isl_error_unknown, "bad conversion",do { isl_handle_error(ctx, isl_error_unknown, "bad conversion" , "polly/lib/External/isl/isl_test.c", 9360); return -1; } while (0) | |||
9360 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "bad conversion" , "polly/lib/External/isl/isl_test.c", 9360); return -1; } while (0); | |||
9361 | } | |||
9362 | ||||
9363 | return 0; | |||
9364 | } | |||
9365 | ||||
9366 | /* Descriptions of union maps that should be convertible | |||
9367 | * to an isl_multi_union_pw_aff. | |||
9368 | */ | |||
9369 | const char *umap_mupa_conversion_tests[] = { | |||
9370 | "{ [a, b, c, d] -> s0[a, b, e, f] : " | |||
9371 | "exists (e0 = [(a - 2c)/3], e1 = [(-4 + b - 5d)/9], " | |||
9372 | "e2 = [(-d + f)/9]: 3e0 = a - 2c and 9e1 = -4 + b - 5d and " | |||
9373 | "9e2 = -d + f and f >= 0 and f <= 8 and 9e >= -5 - 2a and " | |||
9374 | "9e <= -2 - 2a) }", | |||
9375 | "{ [a, b] -> [c] : exists (e0 = floor((-a - b + c)/5): " | |||
9376 | "5e0 = -a - b + c and c >= -a and c <= 4 - a) }", | |||
9377 | "{ [a, b] -> [c] : exists d : 18 * d = -3 - a + 2c and 1 <= c <= 3 }", | |||
9378 | "{ A[] -> B[0]; C[] -> B[1] }", | |||
9379 | "{ A[] -> B[]; C[] -> B[] }", | |||
9380 | }; | |||
9381 | ||||
9382 | /* Check that converting from isl_union_map to isl_multi_union_pw_aff and back | |||
9383 | * to isl_union_map produces the original isl_union_map. | |||
9384 | */ | |||
9385 | static int test_union_map_mupa_conversion(isl_ctx *ctx) | |||
9386 | { | |||
9387 | int i; | |||
9388 | isl_union_map *umap1, *umap2; | |||
9389 | isl_multi_union_pw_aff *mupa; | |||
9390 | int equal; | |||
9391 | ||||
9392 | for (i = 0; i < ARRAY_SIZE(umap_mupa_conversion_tests)(sizeof(umap_mupa_conversion_tests)/sizeof(*umap_mupa_conversion_tests )); ++i) { | |||
9393 | const char *str; | |||
9394 | str = umap_mupa_conversion_tests[i]; | |||
9395 | umap1 = isl_union_map_read_from_str(ctx, str); | |||
9396 | umap2 = isl_union_map_copy(umap1); | |||
9397 | mupa = isl_multi_union_pw_aff_from_union_map(umap2); | |||
9398 | umap2 = isl_union_map_from_multi_union_pw_aff(mupa); | |||
9399 | equal = isl_union_map_is_equal(umap1, umap2); | |||
9400 | isl_union_map_free(umap1); | |||
9401 | isl_union_map_free(umap2); | |||
9402 | ||||
9403 | if (equal < 0) | |||
9404 | return -1; | |||
9405 | if (!equal) | |||
9406 | isl_die(ctx, isl_error_unknown, "bad conversion",do { isl_handle_error(ctx, isl_error_unknown, "bad conversion" , "polly/lib/External/isl/isl_test.c", 9407); return -1; } while (0) | |||
9407 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "bad conversion" , "polly/lib/External/isl/isl_test.c", 9407); return -1; } while (0); | |||
9408 | } | |||
9409 | ||||
9410 | return 0; | |||
9411 | } | |||
9412 | ||||
9413 | static int test_conversion(isl_ctx *ctx) | |||
9414 | { | |||
9415 | if (test_ma_conversion(ctx) < 0) | |||
9416 | return -1; | |||
9417 | if (test_set_conversion(ctx) < 0) | |||
9418 | return -1; | |||
9419 | if (test_map_conversion(ctx) < 0) | |||
9420 | return -1; | |||
9421 | if (test_mpa_conversion(ctx) < 0) | |||
9422 | return -1; | |||
9423 | if (test_union_map_mupa_conversion(ctx) < 0) | |||
9424 | return -1; | |||
9425 | return 0; | |||
9426 | } | |||
9427 | ||||
9428 | /* Check that isl_basic_map_curry does not modify input. | |||
9429 | */ | |||
9430 | static int test_curry(isl_ctx *ctx) | |||
9431 | { | |||
9432 | const char *str; | |||
9433 | isl_basic_map *bmap1, *bmap2; | |||
9434 | int equal; | |||
9435 | ||||
9436 | str = "{ [A[] -> B[]] -> C[] }"; | |||
9437 | bmap1 = isl_basic_map_read_from_str(ctx, str); | |||
9438 | bmap2 = isl_basic_map_curry(isl_basic_map_copy(bmap1)); | |||
9439 | equal = isl_basic_map_is_equal(bmap1, bmap2); | |||
9440 | isl_basic_map_free(bmap1); | |||
9441 | isl_basic_map_free(bmap2); | |||
9442 | ||||
9443 | if (equal < 0) | |||
9444 | return -1; | |||
9445 | if (equal) | |||
9446 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "curried map should not be equal to original" , "polly/lib/External/isl/isl_test.c", 9448); return -1; } while (0) | |||
9447 | "curried map should not be equal to original",do { isl_handle_error(ctx, isl_error_unknown, "curried map should not be equal to original" , "polly/lib/External/isl/isl_test.c", 9448); return -1; } while (0) | |||
9448 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "curried map should not be equal to original" , "polly/lib/External/isl/isl_test.c", 9448); return -1; } while (0); | |||
9449 | ||||
9450 | return 0; | |||
9451 | } | |||
9452 | ||||
9453 | struct { | |||
9454 | const char *ma1; | |||
9455 | const char *ma; | |||
9456 | const char *res; | |||
9457 | } pullback_tests[] = { | |||
9458 | { "{ B[i,j] -> C[i + 2j] }" , "{ A[a,b] -> B[b,a] }", | |||
9459 | "{ A[a,b] -> C[b + 2a] }" }, | |||
9460 | { "{ B[i] -> C[2i] }", "{ A[a] -> B[(a)/2] }", "{ A[a] -> C[a] }" }, | |||
9461 | { "{ B[i] -> C[(i)/2] }", "{ A[a] -> B[2a] }", "{ A[a] -> C[a] }" }, | |||
9462 | { "{ B[i] -> C[(i)/2] }", "{ A[a] -> B[(a)/3] }", | |||
9463 | "{ A[a] -> C[(a)/6] }" }, | |||
9464 | { "{ B[i] -> C[2i] }", "{ A[a] -> B[5a] }", "{ A[a] -> C[10a] }" }, | |||
9465 | { "{ B[i] -> C[2i] }", "{ A[a] -> B[(a)/3] }", | |||
9466 | "{ A[a] -> C[(2a)/3] }" }, | |||
9467 | { "{ B[i,j] -> C[i + j] }", "{ A[a] -> B[a,a] }", "{ A[a] -> C[2a] }"}, | |||
9468 | { "{ B[a] -> C[a,a] }", "{ A[i,j] -> B[i + j] }", | |||
9469 | "{ A[i,j] -> C[i + j, i + j] }"}, | |||
9470 | { "{ B[i] -> C[([i/2])] }", "{ B[5] }", "{ C[2] }" }, | |||
9471 | { "[n] -> { B[i,j] -> C[([i/2]) + 2j] }", | |||
9472 | "[n] -> { B[n,[n/3]] }", "[n] -> { C[([n/2]) + 2*[n/3]] }", }, | |||
9473 | { "{ [i, j] -> [floor((i)/4) + floor((2*i+j)/5)] }", | |||
9474 | "{ [i, j] -> [floor((i)/3), j] }", | |||
9475 | "{ [i, j] -> [(floor((i)/12) + floor((j + 2*floor((i)/3))/5))] }" }, | |||
9476 | }; | |||
9477 | ||||
9478 | static int test_pullback(isl_ctx *ctx) | |||
9479 | { | |||
9480 | int i; | |||
9481 | isl_multi_aff *ma1, *ma2; | |||
9482 | isl_multi_aff *ma; | |||
9483 | int equal; | |||
9484 | ||||
9485 | for (i = 0; i < ARRAY_SIZE(pullback_tests)(sizeof(pullback_tests)/sizeof(*pullback_tests)); ++i) { | |||
9486 | ma1 = isl_multi_aff_read_from_str(ctx, pullback_tests[i].ma1); | |||
9487 | ma = isl_multi_aff_read_from_str(ctx, pullback_tests[i].ma); | |||
9488 | ma2 = isl_multi_aff_read_from_str(ctx, pullback_tests[i].res); | |||
9489 | ma1 = isl_multi_aff_pullback_multi_aff(ma1, ma); | |||
9490 | equal = isl_multi_aff_plain_is_equal(ma1, ma2); | |||
9491 | isl_multi_aff_free(ma1); | |||
9492 | isl_multi_aff_free(ma2); | |||
9493 | if (equal < 0) | |||
9494 | return -1; | |||
9495 | if (!equal) | |||
9496 | isl_die(ctx, isl_error_unknown, "bad pullback",do { isl_handle_error(ctx, isl_error_unknown, "bad pullback", "polly/lib/External/isl/isl_test.c", 9497); return -1; } while (0) | |||
9497 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "bad pullback", "polly/lib/External/isl/isl_test.c", 9497); return -1; } while (0); | |||
9498 | } | |||
9499 | ||||
9500 | return 0; | |||
9501 | } | |||
9502 | ||||
9503 | /* Check that negation is printed correctly and that equal expressions | |||
9504 | * are correctly identified. | |||
9505 | */ | |||
9506 | static int test_ast(isl_ctx *ctx) | |||
9507 | { | |||
9508 | isl_ast_expr *expr, *expr1, *expr2, *expr3; | |||
9509 | char *str; | |||
9510 | int ok, equal; | |||
9511 | ||||
9512 | expr1 = isl_ast_expr_from_id(isl_id_alloc(ctx, "A", NULL((void*)0))); | |||
9513 | expr2 = isl_ast_expr_from_id(isl_id_alloc(ctx, "B", NULL((void*)0))); | |||
9514 | expr = isl_ast_expr_add(expr1, expr2); | |||
9515 | expr2 = isl_ast_expr_copy(expr); | |||
9516 | expr = isl_ast_expr_neg(expr); | |||
9517 | expr2 = isl_ast_expr_neg(expr2); | |||
9518 | equal = isl_ast_expr_is_equal(expr, expr2); | |||
9519 | str = isl_ast_expr_to_C_str(expr); | |||
9520 | ok = str ? !strcmp(str, "-(A + B)") : -1; | |||
9521 | free(str); | |||
9522 | isl_ast_expr_free(expr); | |||
9523 | isl_ast_expr_free(expr2); | |||
9524 | ||||
9525 | if (ok < 0 || equal < 0) | |||
9526 | return -1; | |||
9527 | if (!equal) | |||
9528 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "equal expressions not considered equal" , "polly/lib/External/isl/isl_test.c", 9529); return -1; } while (0) | |||
9529 | "equal expressions not considered equal", return -1)do { isl_handle_error(ctx, isl_error_unknown, "equal expressions not considered equal" , "polly/lib/External/isl/isl_test.c", 9529); return -1; } while (0); | |||
9530 | if (!ok) | |||
9531 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "isl_ast_expr printed incorrectly" , "polly/lib/External/isl/isl_test.c", 9532); return -1; } while (0) | |||
9532 | "isl_ast_expr printed incorrectly", return -1)do { isl_handle_error(ctx, isl_error_unknown, "isl_ast_expr printed incorrectly" , "polly/lib/External/isl/isl_test.c", 9532); return -1; } while (0); | |||
9533 | ||||
9534 | expr1 = isl_ast_expr_from_id(isl_id_alloc(ctx, "A", NULL((void*)0))); | |||
9535 | expr2 = isl_ast_expr_from_id(isl_id_alloc(ctx, "B", NULL((void*)0))); | |||
9536 | expr = isl_ast_expr_add(expr1, expr2); | |||
9537 | expr3 = isl_ast_expr_from_id(isl_id_alloc(ctx, "C", NULL((void*)0))); | |||
9538 | expr = isl_ast_expr_sub(expr3, expr); | |||
9539 | str = isl_ast_expr_to_C_str(expr); | |||
9540 | ok = str ? !strcmp(str, "C - (A + B)") : -1; | |||
9541 | free(str); | |||
9542 | isl_ast_expr_free(expr); | |||
9543 | ||||
9544 | if (ok < 0) | |||
9545 | return -1; | |||
9546 | if (!ok) | |||
9547 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "isl_ast_expr printed incorrectly" , "polly/lib/External/isl/isl_test.c", 9548); return -1; } while (0) | |||
9548 | "isl_ast_expr printed incorrectly", return -1)do { isl_handle_error(ctx, isl_error_unknown, "isl_ast_expr printed incorrectly" , "polly/lib/External/isl/isl_test.c", 9548); return -1; } while (0); | |||
9549 | ||||
9550 | return 0; | |||
9551 | } | |||
9552 | ||||
9553 | /* Check that isl_ast_build_expr_from_set returns a valid expression | |||
9554 | * for an empty set. Note that isl_ast_build_expr_from_set getting | |||
9555 | * called on an empty set probably indicates a bug in the caller. | |||
9556 | */ | |||
9557 | static int test_ast_build(isl_ctx *ctx) | |||
9558 | { | |||
9559 | isl_setisl_map *set; | |||
9560 | isl_ast_build *build; | |||
9561 | isl_ast_expr *expr; | |||
9562 | ||||
9563 | set = isl_set_universe(isl_space_params_alloc(ctx, 0)); | |||
9564 | build = isl_ast_build_from_context(set); | |||
9565 | ||||
9566 | set = isl_set_empty(isl_space_params_alloc(ctx, 0)); | |||
9567 | expr = isl_ast_build_expr_from_set(build, set); | |||
9568 | ||||
9569 | isl_ast_expr_free(expr); | |||
9570 | isl_ast_build_free(build); | |||
9571 | ||||
9572 | if (!expr) | |||
9573 | return -1; | |||
9574 | ||||
9575 | return 0; | |||
9576 | } | |||
9577 | ||||
9578 | /* Internal data structure for before_for and after_for callbacks. | |||
9579 | * | |||
9580 | * depth is the current depth | |||
9581 | * before is the number of times before_for has been called | |||
9582 | * after is the number of times after_for has been called | |||
9583 | */ | |||
9584 | struct isl_test_codegen_data { | |||
9585 | int depth; | |||
9586 | int before; | |||
9587 | int after; | |||
9588 | }; | |||
9589 | ||||
9590 | /* This function is called before each for loop in the AST generated | |||
9591 | * from test_ast_gen1. | |||
9592 | * | |||
9593 | * Increment the number of calls and the depth. | |||
9594 | * Check that the space returned by isl_ast_build_get_schedule_space | |||
9595 | * matches the target space of the schedule returned by | |||
9596 | * isl_ast_build_get_schedule. | |||
9597 | * Return an isl_id that is checked by the corresponding call | |||
9598 | * to after_for. | |||
9599 | */ | |||
9600 | static __isl_give isl_id *before_for(__isl_keep isl_ast_build *build, | |||
9601 | void *user) | |||
9602 | { | |||
9603 | struct isl_test_codegen_data *data = user; | |||
9604 | isl_ctx *ctx; | |||
9605 | isl_space *space; | |||
9606 | isl_union_map *schedule; | |||
9607 | isl_union_set *uset; | |||
9608 | isl_setisl_map *set; | |||
9609 | isl_bool empty; | |||
9610 | isl_size n; | |||
9611 | char name[] = "d0"; | |||
9612 | ||||
9613 | ctx = isl_ast_build_get_ctx(build); | |||
9614 | ||||
9615 | if (data->before >= 3) | |||
9616 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of for nodes" , "polly/lib/External/isl/isl_test.c", 9617); return ((void*) 0); } while (0) | |||
9617 | "unexpected number of for nodes", return NULL)do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of for nodes" , "polly/lib/External/isl/isl_test.c", 9617); return ((void*) 0); } while (0); | |||
9618 | if (data->depth < 0 || data->depth >= 2) | |||
9619 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected depth" , "polly/lib/External/isl/isl_test.c", 9620); return ((void*) 0); } while (0) | |||
9620 | "unexpected depth", return NULL)do { isl_handle_error(ctx, isl_error_unknown, "unexpected depth" , "polly/lib/External/isl/isl_test.c", 9620); return ((void*) 0); } while (0); | |||
9621 | ||||
9622 | snprintf(name, sizeof(name), "d%d", data->depth)__builtin___snprintf_chk (name, sizeof(name), 2 - 1, __builtin_object_size (name, 2 > 1), "d%d", data->depth); | |||
9623 | data->before++; | |||
9624 | data->depth++; | |||
9625 | ||||
9626 | schedule = isl_ast_build_get_schedule(build); | |||
9627 | uset = isl_union_map_range(schedule); | |||
9628 | n = isl_union_set_n_set(uset); | |||
9629 | if (n != 1) { | |||
9630 | isl_union_set_free(uset); | |||
9631 | if (n < 0) | |||
9632 | return NULL((void*)0); | |||
9633 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "expecting single range space" , "polly/lib/External/isl/isl_test.c", 9634); return ((void*) 0); } while (0) | |||
9634 | "expecting single range space", return NULL)do { isl_handle_error(ctx, isl_error_unknown, "expecting single range space" , "polly/lib/External/isl/isl_test.c", 9634); return ((void*) 0); } while (0); | |||
9635 | } | |||
9636 | ||||
9637 | space = isl_ast_build_get_schedule_space(build); | |||
9638 | set = isl_union_set_extract_set(uset, space); | |||
9639 | isl_union_set_free(uset); | |||
9640 | empty = isl_set_is_empty(set); | |||
9641 | isl_set_free(set); | |||
9642 | ||||
9643 | if (empty < 0) | |||
9644 | return NULL((void*)0); | |||
9645 | if (empty) | |||
9646 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "spaces don't match" , "polly/lib/External/isl/isl_test.c", 9647); return ((void*) 0); } while (0) | |||
9647 | "spaces don't match", return NULL)do { isl_handle_error(ctx, isl_error_unknown, "spaces don't match" , "polly/lib/External/isl/isl_test.c", 9647); return ((void*) 0); } while (0); | |||
9648 | ||||
9649 | return isl_id_alloc(ctx, name, NULL((void*)0)); | |||
9650 | } | |||
9651 | ||||
9652 | /* This function is called after each for loop in the AST generated | |||
9653 | * from test_ast_gen1. | |||
9654 | * | |||
9655 | * Increment the number of calls and decrement the depth. | |||
9656 | * Check that the annotation attached to the node matches | |||
9657 | * the isl_id returned by the corresponding call to before_for. | |||
9658 | */ | |||
9659 | static __isl_give isl_ast_node *after_for(__isl_take isl_ast_node *node, | |||
9660 | __isl_keep isl_ast_build *build, void *user) | |||
9661 | { | |||
9662 | struct isl_test_codegen_data *data = user; | |||
9663 | isl_id *id; | |||
9664 | const char *name; | |||
9665 | int valid; | |||
9666 | ||||
9667 | data->after++; | |||
9668 | data->depth--; | |||
9669 | ||||
9670 | if (data->after > data->before) | |||
9671 | isl_die(isl_ast_node_get_ctx(node), isl_error_unknown,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_unknown , "mismatch in number of for nodes", "polly/lib/External/isl/isl_test.c" , 9673); return isl_ast_node_free(node); } while (0) | |||
9672 | "mismatch in number of for nodes",do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_unknown , "mismatch in number of for nodes", "polly/lib/External/isl/isl_test.c" , 9673); return isl_ast_node_free(node); } while (0) | |||
9673 | return isl_ast_node_free(node))do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_unknown , "mismatch in number of for nodes", "polly/lib/External/isl/isl_test.c" , 9673); return isl_ast_node_free(node); } while (0); | |||
9674 | ||||
9675 | id = isl_ast_node_get_annotation(node); | |||
9676 | if (!id) | |||
9677 | isl_die(isl_ast_node_get_ctx(node), isl_error_unknown,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_unknown , "missing annotation", "polly/lib/External/isl/isl_test.c", 9678 ); return isl_ast_node_free(node); } while (0) | |||
9678 | "missing annotation", return isl_ast_node_free(node))do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_unknown , "missing annotation", "polly/lib/External/isl/isl_test.c", 9678 ); return isl_ast_node_free(node); } while (0); | |||
9679 | ||||
9680 | name = isl_id_get_name(id); | |||
9681 | valid = name && atoi(name + 1) == data->depth; | |||
9682 | isl_id_free(id); | |||
9683 | ||||
9684 | if (!valid) | |||
9685 | isl_die(isl_ast_node_get_ctx(node), isl_error_unknown,do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_unknown , "wrong annotation", "polly/lib/External/isl/isl_test.c", 9686 ); return isl_ast_node_free(node); } while (0) | |||
9686 | "wrong annotation", return isl_ast_node_free(node))do { isl_handle_error(isl_ast_node_get_ctx(node), isl_error_unknown , "wrong annotation", "polly/lib/External/isl/isl_test.c", 9686 ); return isl_ast_node_free(node); } while (0); | |||
9687 | ||||
9688 | return node; | |||
9689 | } | |||
9690 | ||||
9691 | /* This function is called after node in the AST generated | |||
9692 | * from test_ast_gen1. | |||
9693 | * | |||
9694 | * Increment the count in "user" if this is a for node and | |||
9695 | * return true to indicate that descendant should also be visited. | |||
9696 | */ | |||
9697 | static isl_bool count_for(__isl_keep isl_ast_node *node, void *user) | |||
9698 | { | |||
9699 | int *count = user; | |||
9700 | ||||
9701 | if (isl_ast_node_get_type(node) == isl_ast_node_for) | |||
9702 | ++*count; | |||
9703 | ||||
9704 | return isl_bool_true; | |||
9705 | } | |||
9706 | ||||
9707 | /* If "node" is a block node, then replace it by its first child. | |||
9708 | */ | |||
9709 | static __isl_give isl_ast_node *select_first(__isl_take isl_ast_node *node, | |||
9710 | void *user) | |||
9711 | { | |||
9712 | isl_ast_node_list *children; | |||
9713 | isl_ast_node *child; | |||
9714 | ||||
9715 | if (isl_ast_node_get_type(node) != isl_ast_node_block) | |||
9716 | return node; | |||
9717 | ||||
9718 | children = isl_ast_node_block_get_children(node); | |||
9719 | child = isl_ast_node_list_get_at(children, 0); | |||
9720 | isl_ast_node_list_free(children); | |||
9721 | isl_ast_node_free(node); | |||
9722 | ||||
9723 | return child; | |||
9724 | } | |||
9725 | ||||
9726 | /* Check that the before_each_for and after_each_for callbacks | |||
9727 | * are called for each for loop in the generated code, | |||
9728 | * that they are called in the right order and that the isl_id | |||
9729 | * returned from the before_each_for callback is attached to | |||
9730 | * the isl_ast_node passed to the corresponding after_each_for call. | |||
9731 | * | |||
9732 | * Additionally, check the basic functionality of | |||
9733 | * isl_ast_node_foreach_descendant_top_down by counting the number | |||
9734 | * of for loops in the resulting AST, | |||
9735 | * as well as that of isl_ast_node_map_descendant_bottom_up | |||
9736 | * by replacing the block node by its first child and | |||
9737 | * counting the number of for loops again. | |||
9738 | */ | |||
9739 | static isl_stat test_ast_gen1(isl_ctx *ctx) | |||
9740 | { | |||
9741 | int count = 0; | |||
9742 | int modified_count = 0; | |||
9743 | const char *str; | |||
9744 | isl_setisl_map *set; | |||
9745 | isl_union_map *schedule; | |||
9746 | isl_ast_build *build; | |||
9747 | isl_ast_node *tree; | |||
9748 | struct isl_test_codegen_data data; | |||
9749 | ||||
9750 | str = "[N] -> { : N >= 10 }"; | |||
9751 | set = isl_set_read_from_str(ctx, str); | |||
9752 | str = "[N] -> { A[i,j] -> S[8,i,3,j] : 0 <= i,j <= N; " | |||
9753 | "B[i,j] -> S[8,j,9,i] : 0 <= i,j <= N }"; | |||
9754 | schedule = isl_union_map_read_from_str(ctx, str); | |||
9755 | ||||
9756 | data.before = 0; | |||
9757 | data.after = 0; | |||
9758 | data.depth = 0; | |||
9759 | build = isl_ast_build_from_context(set); | |||
9760 | build = isl_ast_build_set_before_each_for(build, | |||
9761 | &before_for, &data); | |||
9762 | build = isl_ast_build_set_after_each_for(build, | |||
9763 | &after_for, &data); | |||
9764 | tree = isl_ast_build_node_from_schedule_map(build, schedule); | |||
9765 | isl_ast_build_free(build); | |||
9766 | ||||
9767 | if (isl_ast_node_foreach_descendant_top_down(tree, | |||
9768 | &count_for, &count) < 0) | |||
9769 | tree = isl_ast_node_free(tree); | |||
9770 | ||||
9771 | tree = isl_ast_node_map_descendant_bottom_up(tree, &select_first, NULL((void*)0)); | |||
9772 | ||||
9773 | if (isl_ast_node_foreach_descendant_top_down(tree, &count_for, | |||
9774 | &modified_count) < 0) | |||
9775 | tree = isl_ast_node_free(tree); | |||
9776 | ||||
9777 | if (!tree) | |||
9778 | return isl_stat_error; | |||
9779 | ||||
9780 | isl_ast_node_free(tree); | |||
9781 | ||||
9782 | if (data.before != 3 || data.after != 3 || count != 3) | |||
9783 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of for nodes" , "polly/lib/External/isl/isl_test.c", 9785); return isl_stat_error ; } while (0) | |||
9784 | "unexpected number of for nodes",do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of for nodes" , "polly/lib/External/isl/isl_test.c", 9785); return isl_stat_error ; } while (0) | |||
9785 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of for nodes" , "polly/lib/External/isl/isl_test.c", 9785); return isl_stat_error ; } while (0); | |||
9786 | ||||
9787 | if (modified_count != 2) | |||
9788 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of for nodes after changes" , "polly/lib/External/isl/isl_test.c", 9790); return isl_stat_error ; } while (0) | |||
9789 | "unexpected number of for nodes after changes",do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of for nodes after changes" , "polly/lib/External/isl/isl_test.c", 9790); return isl_stat_error ; } while (0) | |||
9790 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of for nodes after changes" , "polly/lib/External/isl/isl_test.c", 9790); return isl_stat_error ; } while (0); | |||
9791 | ||||
9792 | return isl_stat_ok; | |||
9793 | } | |||
9794 | ||||
9795 | /* Check that the AST generator handles domains that are integrally disjoint | |||
9796 | * but not rationally disjoint. | |||
9797 | */ | |||
9798 | static int test_ast_gen2(isl_ctx *ctx) | |||
9799 | { | |||
9800 | const char *str; | |||
9801 | isl_setisl_map *set; | |||
9802 | isl_union_map *schedule; | |||
9803 | isl_union_map *options; | |||
9804 | isl_ast_build *build; | |||
9805 | isl_ast_node *tree; | |||
9806 | ||||
9807 | str = "{ A[i,j] -> [i,j] : 0 <= i,j <= 1 }"; | |||
9808 | schedule = isl_union_map_read_from_str(ctx, str); | |||
9809 | set = isl_set_universe(isl_space_params_alloc(ctx, 0)); | |||
9810 | build = isl_ast_build_from_context(set); | |||
9811 | ||||
9812 | str = "{ [i,j] -> atomic[1] : i + j = 1; [i,j] -> unroll[1] : i = j }"; | |||
9813 | options = isl_union_map_read_from_str(ctx, str); | |||
9814 | build = isl_ast_build_set_options(build, options); | |||
9815 | tree = isl_ast_build_node_from_schedule_map(build, schedule); | |||
9816 | isl_ast_build_free(build); | |||
9817 | if (!tree) | |||
9818 | return -1; | |||
9819 | isl_ast_node_free(tree); | |||
9820 | ||||
9821 | return 0; | |||
9822 | } | |||
9823 | ||||
9824 | /* Increment *user on each call. | |||
9825 | */ | |||
9826 | static __isl_give isl_ast_node *count_domains(__isl_take isl_ast_node *node, | |||
9827 | __isl_keep isl_ast_build *build, void *user) | |||
9828 | { | |||
9829 | int *n = user; | |||
9830 | ||||
9831 | (*n)++; | |||
9832 | ||||
9833 | return node; | |||
9834 | } | |||
9835 | ||||
9836 | /* Test that unrolling tries to minimize the number of instances. | |||
9837 | * In particular, for the schedule given below, make sure it generates | |||
9838 | * 3 nodes (rather than 101). | |||
9839 | */ | |||
9840 | static int test_ast_gen3(isl_ctx *ctx) | |||
9841 | { | |||
9842 | const char *str; | |||
9843 | isl_setisl_map *set; | |||
9844 | isl_union_map *schedule; | |||
9845 | isl_union_map *options; | |||
9846 | isl_ast_build *build; | |||
9847 | isl_ast_node *tree; | |||
9848 | int n_domain = 0; | |||
9849 | ||||
9850 | str = "[n] -> { A[i] -> [i] : 0 <= i <= 100 and n <= i <= n + 2 }"; | |||
9851 | schedule = isl_union_map_read_from_str(ctx, str); | |||
9852 | set = isl_set_universe(isl_space_params_alloc(ctx, 0)); | |||
9853 | ||||
9854 | str = "{ [i] -> unroll[0] }"; | |||
9855 | options = isl_union_map_read_from_str(ctx, str); | |||
9856 | ||||
9857 | build = isl_ast_build_from_context(set); | |||
9858 | build = isl_ast_build_set_options(build, options); | |||
9859 | build = isl_ast_build_set_at_each_domain(build, | |||
9860 | &count_domains, &n_domain); | |||
9861 | tree = isl_ast_build_node_from_schedule_map(build, schedule); | |||
9862 | isl_ast_build_free(build); | |||
9863 | if (!tree) | |||
9864 | return -1; | |||
9865 | ||||
9866 | isl_ast_node_free(tree); | |||
9867 | ||||
9868 | if (n_domain != 3) | |||
9869 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of for nodes" , "polly/lib/External/isl/isl_test.c", 9870); return -1; } while (0) | |||
9870 | "unexpected number of for nodes", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected number of for nodes" , "polly/lib/External/isl/isl_test.c", 9870); return -1; } while (0); | |||
9871 | ||||
9872 | return 0; | |||
9873 | } | |||
9874 | ||||
9875 | /* Check that if the ast_build_exploit_nested_bounds options is set, | |||
9876 | * we do not get an outer if node in the generated AST, | |||
9877 | * while we do get such an outer if node if the options is not set. | |||
9878 | */ | |||
9879 | static int test_ast_gen4(isl_ctx *ctx) | |||
9880 | { | |||
9881 | const char *str; | |||
9882 | isl_setisl_map *set; | |||
9883 | isl_union_map *schedule; | |||
9884 | isl_ast_build *build; | |||
9885 | isl_ast_node *tree; | |||
9886 | enum isl_ast_node_type type; | |||
9887 | int enb; | |||
9888 | ||||
9889 | enb = isl_options_get_ast_build_exploit_nested_bounds(ctx); | |||
9890 | str = "[N,M] -> { A[i,j] -> [i,j] : 0 <= i <= N and 0 <= j <= M }"; | |||
9891 | ||||
9892 | isl_options_set_ast_build_exploit_nested_bounds(ctx, 1); | |||
9893 | ||||
9894 | schedule = isl_union_map_read_from_str(ctx, str); | |||
9895 | set = isl_set_universe(isl_space_params_alloc(ctx, 0)); | |||
9896 | build = isl_ast_build_from_context(set); | |||
9897 | tree = isl_ast_build_node_from_schedule_map(build, schedule); | |||
9898 | isl_ast_build_free(build); | |||
9899 | if (!tree) | |||
9900 | return -1; | |||
9901 | ||||
9902 | type = isl_ast_node_get_type(tree); | |||
9903 | isl_ast_node_free(tree); | |||
9904 | ||||
9905 | if (type == isl_ast_node_if) | |||
9906 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "not expecting if node" , "polly/lib/External/isl/isl_test.c", 9907); return -1; } while (0) | |||
9907 | "not expecting if node", return -1)do { isl_handle_error(ctx, isl_error_unknown, "not expecting if node" , "polly/lib/External/isl/isl_test.c", 9907); return -1; } while (0); | |||
9908 | ||||
9909 | isl_options_set_ast_build_exploit_nested_bounds(ctx, 0); | |||
9910 | ||||
9911 | schedule = isl_union_map_read_from_str(ctx, str); | |||
9912 | set = isl_set_universe(isl_space_params_alloc(ctx, 0)); | |||
9913 | build = isl_ast_build_from_context(set); | |||
9914 | tree = isl_ast_build_node_from_schedule_map(build, schedule); | |||
9915 | isl_ast_build_free(build); | |||
9916 | if (!tree) | |||
9917 | return -1; | |||
9918 | ||||
9919 | type = isl_ast_node_get_type(tree); | |||
9920 | isl_ast_node_free(tree); | |||
9921 | ||||
9922 | if (type != isl_ast_node_if) | |||
9923 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "expecting if node" , "polly/lib/External/isl/isl_test.c", 9924); return -1; } while (0) | |||
9924 | "expecting if node", return -1)do { isl_handle_error(ctx, isl_error_unknown, "expecting if node" , "polly/lib/External/isl/isl_test.c", 9924); return -1; } while (0); | |||
9925 | ||||
9926 | isl_options_set_ast_build_exploit_nested_bounds(ctx, enb); | |||
9927 | ||||
9928 | return 0; | |||
9929 | } | |||
9930 | ||||
9931 | /* This function is called for each leaf in the AST generated | |||
9932 | * from test_ast_gen5. | |||
9933 | * | |||
9934 | * We finalize the AST generation by extending the outer schedule | |||
9935 | * with a zero-dimensional schedule. If this results in any for loops, | |||
9936 | * then this means that we did not pass along enough information | |||
9937 | * about the outer schedule to the inner AST generation. | |||
9938 | */ | |||
9939 | static __isl_give isl_ast_node *create_leaf(__isl_take isl_ast_build *build, | |||
9940 | void *user) | |||
9941 | { | |||
9942 | isl_union_map *schedule, *extra; | |||
9943 | isl_ast_node *tree; | |||
9944 | ||||
9945 | schedule = isl_ast_build_get_schedule(build); | |||
9946 | extra = isl_union_map_copy(schedule); | |||
9947 | extra = isl_union_map_from_domain(isl_union_map_domain(extra)); | |||
9948 | schedule = isl_union_map_range_product(schedule, extra); | |||
9949 | tree = isl_ast_build_node_from_schedule_map(build, schedule); | |||
9950 | isl_ast_build_free(build); | |||
9951 | ||||
9952 | if (!tree) | |||
9953 | return NULL((void*)0); | |||
9954 | ||||
9955 | if (isl_ast_node_get_type(tree) == isl_ast_node_for) | |||
9956 | isl_die(isl_ast_node_get_ctx(tree), isl_error_unknown,do { isl_handle_error(isl_ast_node_get_ctx(tree), isl_error_unknown , "code should not contain any for loop", "polly/lib/External/isl/isl_test.c" , 9958); return isl_ast_node_free(tree); } while (0) | |||
9957 | "code should not contain any for loop",do { isl_handle_error(isl_ast_node_get_ctx(tree), isl_error_unknown , "code should not contain any for loop", "polly/lib/External/isl/isl_test.c" , 9958); return isl_ast_node_free(tree); } while (0) | |||
9958 | return isl_ast_node_free(tree))do { isl_handle_error(isl_ast_node_get_ctx(tree), isl_error_unknown , "code should not contain any for loop", "polly/lib/External/isl/isl_test.c" , 9958); return isl_ast_node_free(tree); } while (0); | |||
9959 | ||||
9960 | return tree; | |||
9961 | } | |||
9962 | ||||
9963 | /* Check that we do not lose any information when going back and | |||
9964 | * forth between internal and external schedule. | |||
9965 | * | |||
9966 | * In particular, we create an AST where we unroll the only | |||
9967 | * non-constant dimension in the schedule. We therefore do | |||
9968 | * not expect any for loops in the AST. However, older versions | |||
9969 | * of isl would not pass along enough information about the outer | |||
9970 | * schedule when performing an inner code generation from a create_leaf | |||
9971 | * callback, resulting in the inner code generation producing a for loop. | |||
9972 | */ | |||
9973 | static int test_ast_gen5(isl_ctx *ctx) | |||
9974 | { | |||
9975 | const char *str; | |||
9976 | isl_setisl_map *set; | |||
9977 | isl_union_map *schedule, *options; | |||
9978 | isl_ast_build *build; | |||
9979 | isl_ast_node *tree; | |||
9980 | ||||
9981 | str = "{ A[] -> [1, 1, 2]; B[i] -> [1, i, 0] : i >= 1 and i <= 2 }"; | |||
9982 | schedule = isl_union_map_read_from_str(ctx, str); | |||
9983 | ||||
9984 | str = "{ [a, b, c] -> unroll[1] : exists (e0 = [(a)/4]: " | |||
9985 | "4e0 >= -1 + a - b and 4e0 <= -2 + a + b) }"; | |||
9986 | options = isl_union_map_read_from_str(ctx, str); | |||
9987 | ||||
9988 | set = isl_set_universe(isl_space_params_alloc(ctx, 0)); | |||
9989 | build = isl_ast_build_from_context(set); | |||
9990 | build = isl_ast_build_set_options(build, options); | |||
9991 | build = isl_ast_build_set_create_leaf(build, &create_leaf, NULL((void*)0)); | |||
9992 | tree = isl_ast_build_node_from_schedule_map(build, schedule); | |||
9993 | isl_ast_build_free(build); | |||
9994 | isl_ast_node_free(tree); | |||
9995 | if (!tree) | |||
9996 | return -1; | |||
9997 | ||||
9998 | return 0; | |||
9999 | } | |||
10000 | ||||
10001 | /* Check that the expression | |||
10002 | * | |||
10003 | * [n] -> { [n/2] : n <= 0 and n % 2 = 0; [0] : n > 0 } | |||
10004 | * | |||
10005 | * is not combined into | |||
10006 | * | |||
10007 | * min(n/2, 0) | |||
10008 | * | |||
10009 | * as this would result in n/2 being evaluated in parts of | |||
10010 | * the definition domain where n is not a multiple of 2. | |||
10011 | */ | |||
10012 | static int test_ast_expr(isl_ctx *ctx) | |||
10013 | { | |||
10014 | const char *str; | |||
10015 | isl_pw_aff *pa; | |||
10016 | isl_ast_build *build; | |||
10017 | isl_ast_expr *expr; | |||
10018 | int min_max; | |||
10019 | int is_min; | |||
10020 | ||||
10021 | min_max = isl_options_get_ast_build_detect_min_max(ctx); | |||
10022 | isl_options_set_ast_build_detect_min_max(ctx, 1); | |||
10023 | ||||
10024 | str = "[n] -> { [n/2] : n <= 0 and n % 2 = 0; [0] : n > 0 }"; | |||
10025 | pa = isl_pw_aff_read_from_str(ctx, str); | |||
10026 | build = isl_ast_build_alloc(ctx); | |||
10027 | expr = isl_ast_build_expr_from_pw_aff(build, pa); | |||
10028 | is_min = isl_ast_expr_get_type(expr) == isl_ast_expr_op && | |||
10029 | isl_ast_expr_get_op_type(expr) == isl_ast_expr_op_min; | |||
10030 | isl_ast_build_free(build); | |||
10031 | isl_ast_expr_free(expr); | |||
10032 | ||||
10033 | isl_options_set_ast_build_detect_min_max(ctx, min_max); | |||
10034 | ||||
10035 | if (!expr) | |||
10036 | return -1; | |||
10037 | if (is_min) | |||
10038 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "expressions should not be combined" , "polly/lib/External/isl/isl_test.c", 10039); return -1; } while (0) | |||
10039 | "expressions should not be combined", return -1)do { isl_handle_error(ctx, isl_error_unknown, "expressions should not be combined" , "polly/lib/External/isl/isl_test.c", 10039); return -1; } while (0); | |||
10040 | ||||
10041 | return 0; | |||
10042 | } | |||
10043 | ||||
10044 | static int test_ast_gen(isl_ctx *ctx) | |||
10045 | { | |||
10046 | if (test_ast_gen1(ctx) < 0) | |||
10047 | return -1; | |||
10048 | if (test_ast_gen2(ctx) < 0) | |||
10049 | return -1; | |||
10050 | if (test_ast_gen3(ctx) < 0) | |||
10051 | return -1; | |||
10052 | if (test_ast_gen4(ctx) < 0) | |||
10053 | return -1; | |||
10054 | if (test_ast_gen5(ctx) < 0) | |||
10055 | return -1; | |||
10056 | if (test_ast_expr(ctx) < 0) | |||
10057 | return -1; | |||
10058 | return 0; | |||
10059 | } | |||
10060 | ||||
10061 | /* Check if dropping output dimensions from an isl_pw_multi_aff | |||
10062 | * works properly. | |||
10063 | */ | |||
10064 | static int test_pw_multi_aff(isl_ctx *ctx) | |||
10065 | { | |||
10066 | const char *str; | |||
10067 | isl_pw_multi_aff *pma1, *pma2; | |||
10068 | int equal; | |||
10069 | ||||
10070 | str = "{ [i,j] -> [i+j, 4i-j] }"; | |||
10071 | pma1 = isl_pw_multi_aff_read_from_str(ctx, str); | |||
10072 | str = "{ [i,j] -> [4i-j] }"; | |||
10073 | pma2 = isl_pw_multi_aff_read_from_str(ctx, str); | |||
10074 | ||||
10075 | pma1 = isl_pw_multi_aff_drop_dims(pma1, isl_dim_out, 0, 1); | |||
10076 | ||||
10077 | equal = isl_pw_multi_aff_plain_is_equal(pma1, pma2); | |||
10078 | ||||
10079 | isl_pw_multi_aff_free(pma1); | |||
10080 | isl_pw_multi_aff_free(pma2); | |||
10081 | if (equal < 0) | |||
10082 | return -1; | |||
10083 | if (!equal) | |||
10084 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "expressions not equal" , "polly/lib/External/isl/isl_test.c", 10085); return -1; } while (0) | |||
10085 | "expressions not equal", return -1)do { isl_handle_error(ctx, isl_error_unknown, "expressions not equal" , "polly/lib/External/isl/isl_test.c", 10085); return -1; } while (0); | |||
10086 | ||||
10087 | return 0; | |||
10088 | } | |||
10089 | ||||
10090 | /* Check that we can properly parse multi piecewise affine expressions | |||
10091 | * where the piecewise affine expressions have different domains. | |||
10092 | */ | |||
10093 | static int test_multi_pw_aff_1(isl_ctx *ctx) | |||
10094 | { | |||
10095 | const char *str; | |||
10096 | isl_setisl_map *dom, *dom2; | |||
10097 | isl_multi_pw_aff *mpa1, *mpa2; | |||
10098 | isl_pw_aff *pa; | |||
10099 | int equal; | |||
10100 | int equal_domain; | |||
10101 | ||||
10102 | mpa1 = isl_multi_pw_aff_read_from_str(ctx, "{ [i] -> [i] }"); | |||
10103 | dom = isl_set_read_from_str(ctx, "{ [i] : i > 0 }"); | |||
10104 | mpa1 = isl_multi_pw_aff_intersect_domain(mpa1, dom); | |||
10105 | mpa2 = isl_multi_pw_aff_read_from_str(ctx, "{ [i] -> [2i] }"); | |||
10106 | mpa2 = isl_multi_pw_aff_flat_range_product(mpa1, mpa2); | |||
10107 | str = "{ [i] -> [(i : i > 0), 2i] }"; | |||
10108 | mpa1 = isl_multi_pw_aff_read_from_str(ctx, str); | |||
10109 | ||||
10110 | equal = isl_multi_pw_aff_plain_is_equal(mpa1, mpa2); | |||
10111 | ||||
10112 | pa = isl_multi_pw_aff_get_pw_aff(mpa1, 0); | |||
10113 | dom = isl_pw_aff_domain(pa); | |||
10114 | pa = isl_multi_pw_aff_get_pw_aff(mpa1, 1); | |||
10115 | dom2 = isl_pw_aff_domain(pa); | |||
10116 | equal_domain = isl_set_is_equal(dom, dom2); | |||
10117 | ||||
10118 | isl_set_free(dom); | |||
10119 | isl_set_free(dom2); | |||
10120 | isl_multi_pw_aff_free(mpa1); | |||
10121 | isl_multi_pw_aff_free(mpa2); | |||
10122 | ||||
10123 | if (equal < 0) | |||
10124 | return -1; | |||
10125 | if (!equal) | |||
10126 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "expressions not equal" , "polly/lib/External/isl/isl_test.c", 10127); return -1; } while (0) | |||
10127 | "expressions not equal", return -1)do { isl_handle_error(ctx, isl_error_unknown, "expressions not equal" , "polly/lib/External/isl/isl_test.c", 10127); return -1; } while (0); | |||
10128 | ||||
10129 | if (equal_domain < 0) | |||
10130 | return -1; | |||
10131 | if (equal_domain) | |||
10132 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "domains unexpectedly equal" , "polly/lib/External/isl/isl_test.c", 10133); return -1; } while (0) | |||
10133 | "domains unexpectedly equal", return -1)do { isl_handle_error(ctx, isl_error_unknown, "domains unexpectedly equal" , "polly/lib/External/isl/isl_test.c", 10133); return -1; } while (0); | |||
10134 | ||||
10135 | return 0; | |||
10136 | } | |||
10137 | ||||
10138 | /* Check that the dimensions in the explicit domain | |||
10139 | * of a multi piecewise affine expression are properly | |||
10140 | * taken into account. | |||
10141 | */ | |||
10142 | static int test_multi_pw_aff_2(isl_ctx *ctx) | |||
10143 | { | |||
10144 | const char *str; | |||
10145 | isl_bool involves1, involves2, involves3, equal; | |||
10146 | isl_multi_pw_aff *mpa, *mpa1, *mpa2; | |||
10147 | ||||
10148 | str = "{ A[x,y] -> B[] : x >= y }"; | |||
10149 | mpa = isl_multi_pw_aff_read_from_str(ctx, str); | |||
10150 | involves1 = isl_multi_pw_aff_involves_dims(mpa, isl_dim_in, 0, 2); | |||
10151 | mpa1 = isl_multi_pw_aff_copy(mpa); | |||
10152 | ||||
10153 | mpa = isl_multi_pw_aff_insert_dims(mpa, isl_dim_in, 0, 1); | |||
10154 | involves2 = isl_multi_pw_aff_involves_dims(mpa, isl_dim_in, 0, 1); | |||
10155 | involves3 = isl_multi_pw_aff_involves_dims(mpa, isl_dim_in, 1, 2); | |||
10156 | str = "{ [a,x,y] -> B[] : x >= y }"; | |||
10157 | mpa2 = isl_multi_pw_aff_read_from_str(ctx, str); | |||
10158 | equal = isl_multi_pw_aff_plain_is_equal(mpa, mpa2); | |||
10159 | isl_multi_pw_aff_free(mpa2); | |||
10160 | ||||
10161 | mpa = isl_multi_pw_aff_drop_dims(mpa, isl_dim_in, 0, 1); | |||
10162 | mpa = isl_multi_pw_aff_set_tuple_name(mpa, isl_dim_in, "A"); | |||
10163 | if (equal >= 0 && equal) | |||
10164 | equal = isl_multi_pw_aff_plain_is_equal(mpa, mpa1); | |||
10165 | isl_multi_pw_aff_free(mpa1); | |||
10166 | isl_multi_pw_aff_free(mpa); | |||
10167 | ||||
10168 | if (involves1 < 0 || involves2 < 0 || involves3 < 0 || equal < 0) | |||
10169 | return -1; | |||
10170 | if (!equal) | |||
10171 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "incorrect result of dimension insertion/removal" , "polly/lib/External/isl/isl_test.c", 10173); return isl_stat_error ; } while (0) | |||
10172 | "incorrect result of dimension insertion/removal",do { isl_handle_error(ctx, isl_error_unknown, "incorrect result of dimension insertion/removal" , "polly/lib/External/isl/isl_test.c", 10173); return isl_stat_error ; } while (0) | |||
10173 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "incorrect result of dimension insertion/removal" , "polly/lib/External/isl/isl_test.c", 10173); return isl_stat_error ; } while (0); | |||
10174 | if (!involves1 || involves2 || !involves3) | |||
10175 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "incorrect characterization of involved dimensions" , "polly/lib/External/isl/isl_test.c", 10177); return isl_stat_error ; } while (0) | |||
10176 | "incorrect characterization of involved dimensions",do { isl_handle_error(ctx, isl_error_unknown, "incorrect characterization of involved dimensions" , "polly/lib/External/isl/isl_test.c", 10177); return isl_stat_error ; } while (0) | |||
10177 | return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "incorrect characterization of involved dimensions" , "polly/lib/External/isl/isl_test.c", 10177); return isl_stat_error ; } while (0); | |||
10178 | ||||
10179 | return 0; | |||
10180 | } | |||
10181 | ||||
10182 | /* Check that isl_multi_union_pw_aff_multi_val_on_domain | |||
10183 | * sets the explicit domain of a zero-dimensional result, | |||
10184 | * such that it can be converted to an isl_union_map. | |||
10185 | */ | |||
10186 | static isl_stat test_multi_pw_aff_3(isl_ctx *ctx) | |||
10187 | { | |||
10188 | isl_space *space; | |||
10189 | isl_union_set *dom; | |||
10190 | isl_multi_val *mv; | |||
10191 | isl_multi_union_pw_aff *mupa; | |||
10192 | isl_union_map *umap; | |||
10193 | ||||
10194 | dom = isl_union_set_read_from_str(ctx, "{ A[]; B[] }"); | |||
10195 | space = isl_union_set_get_space(dom); | |||
10196 | mv = isl_multi_val_zero(isl_space_set_from_params(space)); | |||
10197 | mupa = isl_multi_union_pw_aff_multi_val_on_domain(dom, mv); | |||
10198 | umap = isl_union_map_from_multi_union_pw_aff(mupa); | |||
10199 | isl_union_map_free(umap); | |||
10200 | if (!umap) | |||
10201 | return isl_stat_error; | |||
10202 | ||||
10203 | return isl_stat_ok; | |||
10204 | } | |||
10205 | ||||
10206 | /* String descriptions of boxes that | |||
10207 | * are used for reconstructing box maps from their lower and upper bounds. | |||
10208 | */ | |||
10209 | static const char *multi_pw_aff_box_tests[] = { | |||
10210 | "{ A[x, y] -> [] : x + y >= 0 }", | |||
10211 | "[N] -> { A[x, y] -> [x] : x + y <= N }", | |||
10212 | "[N] -> { A[x, y] -> [x : y] : x + y <= N }", | |||
10213 | }; | |||
10214 | ||||
10215 | /* Check that map representations of boxes can be reconstructed | |||
10216 | * from their lower and upper bounds. | |||
10217 | */ | |||
10218 | static isl_stat test_multi_pw_aff_box(isl_ctx *ctx) | |||
10219 | { | |||
10220 | int i; | |||
10221 | ||||
10222 | for (i = 0; i < ARRAY_SIZE(multi_pw_aff_box_tests)(sizeof(multi_pw_aff_box_tests)/sizeof(*multi_pw_aff_box_tests )); ++i) { | |||
10223 | const char *str; | |||
10224 | isl_bool equal; | |||
10225 | isl_map *map, *box; | |||
10226 | isl_multi_pw_aff *min, *max; | |||
10227 | ||||
10228 | str = multi_pw_aff_box_tests[i]; | |||
10229 | map = isl_map_read_from_str(ctx, str); | |||
10230 | min = isl_map_min_multi_pw_aff(isl_map_copy(map)); | |||
10231 | max = isl_map_max_multi_pw_aff(isl_map_copy(map)); | |||
10232 | box = isl_map_universe(isl_map_get_space(map)); | |||
10233 | box = isl_map_lower_bound_multi_pw_aff(box, min); | |||
10234 | box = isl_map_upper_bound_multi_pw_aff(box, max); | |||
10235 | equal = isl_map_is_equal(map, box); | |||
10236 | isl_map_free(map); | |||
10237 | isl_map_free(box); | |||
10238 | if (equal < 0) | |||
10239 | return isl_stat_error; | |||
10240 | if (!equal) | |||
10241 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 10242); return isl_stat_error ; } while (0) | |||
10242 | "unexpected result", return isl_stat_error)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 10242); return isl_stat_error ; } while (0); | |||
10243 | } | |||
10244 | ||||
10245 | return isl_stat_ok; | |||
10246 | } | |||
10247 | ||||
10248 | /* Perform some tests on multi piecewise affine expressions. | |||
10249 | */ | |||
10250 | static int test_multi_pw_aff(isl_ctx *ctx) | |||
10251 | { | |||
10252 | if (test_multi_pw_aff_1(ctx) < 0) | |||
10253 | return -1; | |||
10254 | if (test_multi_pw_aff_2(ctx) < 0) | |||
10255 | return -1; | |||
10256 | if (test_multi_pw_aff_3(ctx) < 0) | |||
10257 | return -1; | |||
10258 | if (test_multi_pw_aff_box(ctx) < 0) | |||
10259 | return -1; | |||
10260 | return 0; | |||
10261 | } | |||
10262 | ||||
10263 | /* This is a regression test for a bug where isl_basic_map_simplify | |||
10264 | * would end up in an infinite loop. In particular, we construct | |||
10265 | * an empty basic set that is not obviously empty. | |||
10266 | * isl_basic_set_is_empty marks the basic set as empty. | |||
10267 | * After projecting out i3, the variable can be dropped completely, | |||
10268 | * but isl_basic_map_simplify refrains from doing so if the basic set | |||
10269 | * is empty and would end up in an infinite loop if it didn't test | |||
10270 | * explicitly for empty basic maps in the outer loop. | |||
10271 | */ | |||
10272 | static int test_simplify_1(isl_ctx *ctx) | |||
10273 | { | |||
10274 | const char *str; | |||
10275 | isl_basic_setisl_basic_map *bset; | |||
10276 | int empty; | |||
10277 | ||||
10278 | str = "{ [i0, i1, i2, i3] : i0 >= -2 and 6i2 <= 4 + i0 + 5i1 and " | |||
10279 | "i2 <= 22 and 75i2 <= 111 + 13i0 + 60i1 and " | |||
10280 | "25i2 >= 38 + 6i0 + 20i1 and i0 <= -1 and i2 >= 20 and " | |||
10281 | "i3 >= i2 }"; | |||
10282 | bset = isl_basic_set_read_from_str(ctx, str); | |||
10283 | empty = isl_basic_set_is_empty(bset); | |||
10284 | bset = isl_basic_set_project_out(bset, isl_dim_set, 3, 1); | |||
10285 | isl_basic_set_free(bset); | |||
10286 | if (!bset) | |||
10287 | return -1; | |||
10288 | if (!empty) | |||
10289 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "basic set should be empty" , "polly/lib/External/isl/isl_test.c", 10290); return -1; } while (0) | |||
10290 | "basic set should be empty", return -1)do { isl_handle_error(ctx, isl_error_unknown, "basic set should be empty" , "polly/lib/External/isl/isl_test.c", 10290); return -1; } while (0); | |||
10291 | ||||
10292 | return 0; | |||
10293 | } | |||
10294 | ||||
10295 | /* Check that the equality in the set description below | |||
10296 | * is simplified away. | |||
10297 | */ | |||
10298 | static int test_simplify_2(isl_ctx *ctx) | |||
10299 | { | |||
10300 | const char *str; | |||
10301 | isl_basic_setisl_basic_map *bset; | |||
10302 | isl_bool universe; | |||
10303 | ||||
10304 | str = "{ [a] : exists e0, e1: 32e1 = 31 + 31a + 31e0 }"; | |||
10305 | bset = isl_basic_set_read_from_str(ctx, str); | |||
10306 | universe = isl_basic_set_plain_is_universe(bset); | |||
10307 | isl_basic_set_free(bset); | |||
10308 | ||||
10309 | if (universe < 0) | |||
10310 | return -1; | |||
10311 | if (!universe) | |||
10312 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "equality not simplified away" , "polly/lib/External/isl/isl_test.c", 10313); return -1; } while (0) | |||
10313 | "equality not simplified away", return -1)do { isl_handle_error(ctx, isl_error_unknown, "equality not simplified away" , "polly/lib/External/isl/isl_test.c", 10313); return -1; } while (0); | |||
10314 | return 0; | |||
10315 | } | |||
10316 | ||||
10317 | /* Some simplification tests. | |||
10318 | */ | |||
10319 | static int test_simplify(isl_ctx *ctx) | |||
10320 | { | |||
10321 | if (test_simplify_1(ctx) < 0) | |||
10322 | return -1; | |||
10323 | if (test_simplify_2(ctx) < 0) | |||
10324 | return -1; | |||
10325 | return 0; | |||
10326 | } | |||
10327 | ||||
10328 | /* This is a regression test for a bug where isl_tab_basic_map_partial_lexopt | |||
10329 | * with gbr context would fail to disable the use of the shifted tableau | |||
10330 | * when transferring equalities for the input to the context, resulting | |||
10331 | * in invalid sample values. | |||
10332 | */ | |||
10333 | static int test_partial_lexmin(isl_ctx *ctx) | |||
10334 | { | |||
10335 | const char *str; | |||
10336 | isl_basic_setisl_basic_map *bset; | |||
10337 | isl_basic_map *bmap; | |||
10338 | isl_map *map; | |||
10339 | ||||
10340 | str = "{ [1, b, c, 1 - c] -> [e] : 2e <= -c and 2e >= -3 + c }"; | |||
10341 | bmap = isl_basic_map_read_from_str(ctx, str); | |||
10342 | str = "{ [a, b, c, d] : c <= 1 and 2d >= 6 - 4b - c }"; | |||
10343 | bset = isl_basic_set_read_from_str(ctx, str); | |||
10344 | map = isl_basic_map_partial_lexmin(bmap, bset, NULL((void*)0)); | |||
10345 | isl_map_free(map); | |||
10346 | ||||
10347 | if (!map) | |||
10348 | return -1; | |||
10349 | ||||
10350 | return 0; | |||
10351 | } | |||
10352 | ||||
10353 | /* Check that the variable compression performed on the existentially | |||
10354 | * quantified variables inside isl_basic_set_compute_divs is not confused | |||
10355 | * by the implicit equalities among the parameters. | |||
10356 | */ | |||
10357 | static int test_compute_divs(isl_ctx *ctx) | |||
10358 | { | |||
10359 | const char *str; | |||
10360 | isl_basic_setisl_basic_map *bset; | |||
10361 | isl_setisl_map *set; | |||
10362 | ||||
10363 | str = "[a, b, c, d, e] -> { [] : exists (e0: 2d = b and a <= 124 and " | |||
10364 | "b <= 2046 and b >= 0 and b <= 60 + 64a and 2e >= b + 2c and " | |||
10365 | "2e >= b and 2e <= 1 + b and 2e <= 1 + b + 2c and " | |||
10366 | "32768e0 >= -124 + a and 2097152e0 <= 60 + 64a - b) }"; | |||
10367 | bset = isl_basic_set_read_from_str(ctx, str); | |||
10368 | set = isl_basic_set_compute_divs(bset); | |||
10369 | isl_set_free(set); | |||
10370 | if (!set) | |||
10371 | return -1; | |||
10372 | ||||
10373 | return 0; | |||
10374 | } | |||
10375 | ||||
10376 | /* Check that isl_schedule_get_map is not confused by a schedule tree | |||
10377 | * with divergent filter node parameters, as can result from a call | |||
10378 | * to isl_schedule_intersect_domain. | |||
10379 | */ | |||
10380 | static int test_schedule_tree(isl_ctx *ctx) | |||
10381 | { | |||
10382 | const char *str; | |||
10383 | isl_union_set *uset; | |||
10384 | isl_schedule *sched1, *sched2; | |||
10385 | isl_union_map *umap; | |||
10386 | ||||
10387 | uset = isl_union_set_read_from_str(ctx, "{ A[i] }"); | |||
10388 | sched1 = isl_schedule_from_domain(uset); | |||
10389 | uset = isl_union_set_read_from_str(ctx, "{ B[] }"); | |||
10390 | sched2 = isl_schedule_from_domain(uset); | |||
10391 | ||||
10392 | sched1 = isl_schedule_sequence(sched1, sched2); | |||
10393 | str = "[n] -> { A[i] : 0 <= i < n; B[] }"; | |||
10394 | uset = isl_union_set_read_from_str(ctx, str); | |||
10395 | sched1 = isl_schedule_intersect_domain(sched1, uset); | |||
10396 | umap = isl_schedule_get_map(sched1); | |||
10397 | isl_schedule_free(sched1); | |||
10398 | isl_union_map_free(umap); | |||
10399 | if (!umap) | |||
10400 | return -1; | |||
10401 | ||||
10402 | return 0; | |||
10403 | } | |||
10404 | ||||
10405 | /* Check that a zero-dimensional prefix schedule keeps track | |||
10406 | * of the domain and outer filters. | |||
10407 | */ | |||
10408 | static int test_schedule_tree_prefix(isl_ctx *ctx) | |||
10409 | { | |||
10410 | const char *str; | |||
10411 | isl_bool equal; | |||
10412 | isl_union_set *uset; | |||
10413 | isl_union_set_list *filters; | |||
10414 | isl_multi_union_pw_aff *mupa, *mupa2; | |||
10415 | isl_schedule_node *node; | |||
10416 | ||||
10417 | str = "{ S1[i,j] : 0 <= i,j < 10; S2[i,j] : 0 <= i,j < 10 }"; | |||
10418 | uset = isl_union_set_read_from_str(ctx, str); | |||
10419 | node = isl_schedule_node_from_domain(uset); | |||
10420 | node = isl_schedule_node_child(node, 0); | |||
10421 | ||||
10422 | str = "{ S1[i,j] : i > j }"; | |||
10423 | uset = isl_union_set_read_from_str(ctx, str); | |||
10424 | filters = isl_union_set_list_from_union_set(uset); | |||
10425 | str = "{ S1[i,j] : i <= j; S2[i,j] }"; | |||
10426 | uset = isl_union_set_read_from_str(ctx, str); | |||
10427 | filters = isl_union_set_list_add(filters, uset); | |||
10428 | node = isl_schedule_node_insert_sequence(node, filters); | |||
10429 | ||||
10430 | node = isl_schedule_node_grandchild(node, 0, 0); | |||
10431 | mupa = isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(node); | |||
10432 | str = "([] : { S1[i,j] : i > j })"; | |||
10433 | mupa2 = isl_multi_union_pw_aff_read_from_str(ctx, str); | |||
10434 | equal = isl_multi_union_pw_aff_plain_is_equal(mupa, mupa2); | |||
10435 | isl_multi_union_pw_aff_free(mupa2); | |||
10436 | isl_multi_union_pw_aff_free(mupa); | |||
10437 | isl_schedule_node_free(node); | |||
10438 | ||||
10439 | if (equal < 0) | |||
10440 | return -1; | |||
10441 | if (!equal) | |||
10442 | isl_die(ctx, isl_error_unknown, "unexpected prefix schedule",do { isl_handle_error(ctx, isl_error_unknown, "unexpected prefix schedule" , "polly/lib/External/isl/isl_test.c", 10443); return -1; } while (0) | |||
10443 | return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected prefix schedule" , "polly/lib/External/isl/isl_test.c", 10443); return -1; } while (0); | |||
10444 | ||||
10445 | return 0; | |||
10446 | } | |||
10447 | ||||
10448 | /* Check that the reaching domain elements and the prefix schedule | |||
10449 | * at a leaf node are the same before and after grouping. | |||
10450 | */ | |||
10451 | static int test_schedule_tree_group_1(isl_ctx *ctx) | |||
10452 | { | |||
10453 | int equal; | |||
10454 | const char *str; | |||
10455 | isl_id *id; | |||
10456 | isl_union_set *uset; | |||
10457 | isl_multi_union_pw_aff *mupa; | |||
10458 | isl_union_pw_multi_aff *upma1, *upma2; | |||
10459 | isl_union_set *domain1, *domain2; | |||
10460 | isl_union_map *umap1, *umap2; | |||
10461 | isl_schedule_node *node; | |||
10462 | ||||
10463 | str = "{ S1[i,j] : 0 <= i,j < 10; S2[i,j] : 0 <= i,j < 10 }"; | |||
10464 | uset = isl_union_set_read_from_str(ctx, str); | |||
10465 | node = isl_schedule_node_from_domain(uset); | |||
10466 | node = isl_schedule_node_child(node, 0); | |||
10467 | str = "[{ S1[i,j] -> [i]; S2[i,j] -> [9 - i] }]"; | |||
10468 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); | |||
10469 | node = isl_schedule_node_insert_partial_schedule(node, mupa); | |||
10470 | node = isl_schedule_node_child(node, 0); | |||
10471 | str = "[{ S1[i,j] -> [j]; S2[i,j] -> [j] }]"; | |||
10472 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); | |||
10473 | node = isl_schedule_node_insert_partial_schedule(node, mupa); | |||
10474 | node = isl_schedule_node_child(node, 0); | |||
10475 | umap1 = isl_schedule_node_get_prefix_schedule_union_map(node); | |||
10476 | upma1 = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(node); | |||
10477 | domain1 = isl_schedule_node_get_domain(node); | |||
10478 | id = isl_id_alloc(ctx, "group", NULL((void*)0)); | |||
10479 | node = isl_schedule_node_parent(node); | |||
10480 | node = isl_schedule_node_group(node, id); | |||
10481 | node = isl_schedule_node_child(node, 0); | |||
10482 | umap2 = isl_schedule_node_get_prefix_schedule_union_map(node); | |||
10483 | upma2 = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(node); | |||
10484 | domain2 = isl_schedule_node_get_domain(node); | |||
10485 | equal = isl_union_pw_multi_aff_plain_is_equal(upma1, upma2); | |||
10486 | if (equal >= 0 && equal) | |||
10487 | equal = isl_union_set_is_equal(domain1, domain2); | |||
10488 | if (equal >= 0 && equal) | |||
10489 | equal = isl_union_map_is_equal(umap1, umap2); | |||
10490 | isl_union_map_free(umap1); | |||
10491 | isl_union_map_free(umap2); | |||
10492 | isl_union_set_free(domain1); | |||
10493 | isl_union_set_free(domain2); | |||
10494 | isl_union_pw_multi_aff_free(upma1); | |||
10495 | isl_union_pw_multi_aff_free(upma2); | |||
10496 | isl_schedule_node_free(node); | |||
10497 | ||||
10498 | if (equal < 0) | |||
10499 | return -1; | |||
10500 | if (!equal) | |||
10501 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "expressions not equal" , "polly/lib/External/isl/isl_test.c", 10502); return -1; } while (0) | |||
10502 | "expressions not equal", return -1)do { isl_handle_error(ctx, isl_error_unknown, "expressions not equal" , "polly/lib/External/isl/isl_test.c", 10502); return -1; } while (0); | |||
10503 | ||||
10504 | return 0; | |||
10505 | } | |||
10506 | ||||
10507 | /* Check that we can have nested groupings and that the union map | |||
10508 | * schedule representation is the same before and after the grouping. | |||
10509 | * Note that after the grouping, the union map representation contains | |||
10510 | * the domain constraints from the ranges of the expansion nodes, | |||
10511 | * while they are missing from the union map representation of | |||
10512 | * the tree without expansion nodes. | |||
10513 | * | |||
10514 | * Also check that the global expansion is as expected. | |||
10515 | */ | |||
10516 | static int test_schedule_tree_group_2(isl_ctx *ctx) | |||
10517 | { | |||
10518 | int equal, equal_expansion; | |||
10519 | const char *str; | |||
10520 | isl_id *id; | |||
10521 | isl_union_set *uset; | |||
10522 | isl_union_map *umap1, *umap2; | |||
10523 | isl_union_map *expansion1, *expansion2; | |||
10524 | isl_union_set_list *filters; | |||
10525 | isl_multi_union_pw_aff *mupa; | |||
10526 | isl_schedule *schedule; | |||
10527 | isl_schedule_node *node; | |||
10528 | ||||
10529 | str = "{ S1[i,j] : 0 <= i,j < 10; S2[i,j] : 0 <= i,j < 10; " | |||
10530 | "S3[i,j] : 0 <= i,j < 10 }"; | |||
10531 | uset = isl_union_set_read_from_str(ctx, str); | |||
10532 | node = isl_schedule_node_from_domain(uset); | |||
10533 | node = isl_schedule_node_child(node, 0); | |||
10534 | str = "[{ S1[i,j] -> [i]; S2[i,j] -> [i]; S3[i,j] -> [i] }]"; | |||
10535 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); | |||
10536 | node = isl_schedule_node_insert_partial_schedule(node, mupa); | |||
10537 | node = isl_schedule_node_child(node, 0); | |||
10538 | str = "{ S1[i,j] }"; | |||
10539 | uset = isl_union_set_read_from_str(ctx, str); | |||
10540 | filters = isl_union_set_list_from_union_set(uset); | |||
10541 | str = "{ S2[i,j]; S3[i,j] }"; | |||
10542 | uset = isl_union_set_read_from_str(ctx, str); | |||
10543 | filters = isl_union_set_list_add(filters, uset); | |||
10544 | node = isl_schedule_node_insert_sequence(node, filters); | |||
10545 | node = isl_schedule_node_grandchild(node, 1, 0); | |||
10546 | str = "{ S2[i,j] }"; | |||
10547 | uset = isl_union_set_read_from_str(ctx, str); | |||
10548 | filters = isl_union_set_list_from_union_set(uset); | |||
10549 | str = "{ S3[i,j] }"; | |||
10550 | uset = isl_union_set_read_from_str(ctx, str); | |||
10551 | filters = isl_union_set_list_add(filters, uset); | |||
10552 | node = isl_schedule_node_insert_sequence(node, filters); | |||
10553 | ||||
10554 | schedule = isl_schedule_node_get_schedule(node); | |||
10555 | umap1 = isl_schedule_get_map(schedule); | |||
10556 | uset = isl_schedule_get_domain(schedule); | |||
10557 | umap1 = isl_union_map_intersect_domain(umap1, uset); | |||
10558 | isl_schedule_free(schedule); | |||
10559 | ||||
10560 | node = isl_schedule_node_grandparent(node); | |||
10561 | id = isl_id_alloc(ctx, "group1", NULL((void*)0)); | |||
10562 | node = isl_schedule_node_group(node, id); | |||
10563 | node = isl_schedule_node_grandchild(node, 1, 0); | |||
10564 | id = isl_id_alloc(ctx, "group2", NULL((void*)0)); | |||
10565 | node = isl_schedule_node_group(node, id); | |||
10566 | ||||
10567 | schedule = isl_schedule_node_get_schedule(node); | |||
10568 | umap2 = isl_schedule_get_map(schedule); | |||
10569 | isl_schedule_free(schedule); | |||
10570 | ||||
10571 | node = isl_schedule_node_root(node); | |||
10572 | node = isl_schedule_node_child(node, 0); | |||
10573 | expansion1 = isl_schedule_node_get_subtree_expansion(node); | |||
10574 | isl_schedule_node_free(node); | |||
10575 | ||||
10576 | str = "{ group1[i] -> S1[i,j] : 0 <= i,j < 10; " | |||
10577 | "group1[i] -> S2[i,j] : 0 <= i,j < 10; " | |||
10578 | "group1[i] -> S3[i,j] : 0 <= i,j < 10 }"; | |||
10579 | ||||
10580 | expansion2 = isl_union_map_read_from_str(ctx, str); | |||
10581 | ||||
10582 | equal = isl_union_map_is_equal(umap1, umap2); | |||
10583 | equal_expansion = isl_union_map_is_equal(expansion1, expansion2); | |||
10584 | ||||
10585 | isl_union_map_free(umap1); | |||
10586 | isl_union_map_free(umap2); | |||
10587 | isl_union_map_free(expansion1); | |||
10588 | isl_union_map_free(expansion2); | |||
10589 | ||||
10590 | if (equal < 0 || equal_expansion < 0) | |||
10591 | return -1; | |||
10592 | if (!equal) | |||
10593 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "expressions not equal" , "polly/lib/External/isl/isl_test.c", 10594); return -1; } while (0) | |||
10594 | "expressions not equal", return -1)do { isl_handle_error(ctx, isl_error_unknown, "expressions not equal" , "polly/lib/External/isl/isl_test.c", 10594); return -1; } while (0); | |||
10595 | if (!equal_expansion) | |||
10596 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected expansion" , "polly/lib/External/isl/isl_test.c", 10597); return -1; } while (0) | |||
10597 | "unexpected expansion", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected expansion" , "polly/lib/External/isl/isl_test.c", 10597); return -1; } while (0); | |||
10598 | ||||
10599 | return 0; | |||
10600 | } | |||
10601 | ||||
10602 | /* Some tests for the isl_schedule_node_group function. | |||
10603 | */ | |||
10604 | static int test_schedule_tree_group(isl_ctx *ctx) | |||
10605 | { | |||
10606 | if (test_schedule_tree_group_1(ctx) < 0) | |||
10607 | return -1; | |||
10608 | if (test_schedule_tree_group_2(ctx) < 0) | |||
10609 | return -1; | |||
10610 | return 0; | |||
10611 | } | |||
10612 | ||||
10613 | struct { | |||
10614 | const char *set; | |||
10615 | const char *dual; | |||
10616 | } coef_tests[] = { | |||
10617 | { "{ rat: [i] : 0 <= i <= 10 }", | |||
10618 | "{ rat: coefficients[[cst] -> [a]] : cst >= 0 and 10a + cst >= 0 }" }, | |||
10619 | { "{ rat: [i] : FALSE }", | |||
10620 | "{ rat: coefficients[[cst] -> [a]] }" }, | |||
10621 | { "{ rat: [i] : }", | |||
10622 | "{ rat: coefficients[[cst] -> [0]] : cst >= 0 }" }, | |||
10623 | { "{ [0:,1,2:3] }", | |||
10624 | "{ rat: coefficients[[c_cst] -> [a, b, c]] : " | |||
10625 | "a >= 0 and 2c >= -c_cst - b and 3c >= -c_cst - b }" }, | |||
10626 | { "[M, N] -> { [x = (1 - N):-1, -4x:(M - 4x)] }", | |||
10627 | "{ rat: coefficients[[c_cst, c_M = 0:, c_N = 0:] -> [a, b = -c_M:]] :" | |||
10628 | "4b >= -c_N + a and 4b >= -c_cst - 2c_N + a }" }, | |||
10629 | { "{ rat : [x, y] : 1 <= 2x <= 9 and 2 <= 3y <= 16 }", | |||
10630 | "{ rat: coefficients[[c_cst] -> [c_x, c_y]] : " | |||
10631 | "4c_y >= -6c_cst - 3c_x and 4c_y >= -6c_cst - 27c_x and " | |||
10632 | "32c_y >= -6c_cst - 3c_x and 32c_y >= -6c_cst - 27c_x }" }, | |||
10633 | { "{ [x, y, z] : 3y <= 2x - 2 and y >= -2 + 2x and 2y >= 2 - x }", | |||
10634 | "{ rat: coefficients[[cst] -> [a, b, c]] }" }, | |||
10635 | }; | |||
10636 | ||||
10637 | struct { | |||
10638 | const char *set; | |||
10639 | const char *dual; | |||
10640 | } sol_tests[] = { | |||
10641 | { "{ rat: coefficients[[cst] -> [a]] : cst >= 0 and 10a + cst >= 0 }", | |||
10642 | "{ rat: [i] : 0 <= i <= 10 }" }, | |||
10643 | { "{ rat: coefficients[[cst] -> [a]] : FALSE }", | |||
10644 | "{ rat: [i] }" }, | |||
10645 | { "{ rat: coefficients[[cst] -> [a]] }", | |||
10646 | "{ rat: [i] : FALSE }" }, | |||
10647 | }; | |||
10648 | ||||
10649 | /* Test the basic functionality of isl_basic_set_coefficients and | |||
10650 | * isl_basic_set_solutions. | |||
10651 | */ | |||
10652 | static int test_dual(isl_ctx *ctx) | |||
10653 | { | |||
10654 | int i; | |||
10655 | ||||
10656 | for (i = 0; i < ARRAY_SIZE(coef_tests)(sizeof(coef_tests)/sizeof(*coef_tests)); ++i) { | |||
10657 | int equal; | |||
10658 | isl_basic_setisl_basic_map *bset1, *bset2; | |||
10659 | ||||
10660 | bset1 = isl_basic_set_read_from_str(ctx, coef_tests[i].set); | |||
10661 | bset2 = isl_basic_set_read_from_str(ctx, coef_tests[i].dual); | |||
10662 | bset1 = isl_basic_set_coefficients(bset1); | |||
10663 | equal = isl_basic_set_is_equal(bset1, bset2); | |||
10664 | isl_basic_set_free(bset1); | |||
10665 | isl_basic_set_free(bset2); | |||
10666 | if (equal < 0) | |||
10667 | return -1; | |||
10668 | if (!equal) | |||
10669 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "incorrect dual" , "polly/lib/External/isl/isl_test.c", 10670); return -1; } while (0) | |||
10670 | "incorrect dual", return -1)do { isl_handle_error(ctx, isl_error_unknown, "incorrect dual" , "polly/lib/External/isl/isl_test.c", 10670); return -1; } while (0); | |||
10671 | } | |||
10672 | ||||
10673 | for (i = 0; i < ARRAY_SIZE(sol_tests)(sizeof(sol_tests)/sizeof(*sol_tests)); ++i) { | |||
10674 | int equal; | |||
10675 | isl_basic_setisl_basic_map *bset1, *bset2; | |||
10676 | ||||
10677 | bset1 = isl_basic_set_read_from_str(ctx, sol_tests[i].set); | |||
10678 | bset2 = isl_basic_set_read_from_str(ctx, sol_tests[i].dual); | |||
10679 | bset1 = isl_basic_set_solutions(bset1); | |||
10680 | equal = isl_basic_set_is_equal(bset1, bset2); | |||
10681 | isl_basic_set_free(bset1); | |||
10682 | isl_basic_set_free(bset2); | |||
10683 | if (equal < 0) | |||
10684 | return -1; | |||
10685 | if (!equal) | |||
10686 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "incorrect dual" , "polly/lib/External/isl/isl_test.c", 10687); return -1; } while (0) | |||
10687 | "incorrect dual", return -1)do { isl_handle_error(ctx, isl_error_unknown, "incorrect dual" , "polly/lib/External/isl/isl_test.c", 10687); return -1; } while (0); | |||
10688 | } | |||
10689 | ||||
10690 | return 0; | |||
10691 | } | |||
10692 | ||||
10693 | struct { | |||
10694 | int scale_tile; | |||
10695 | int shift_point; | |||
10696 | const char *domain; | |||
10697 | const char *schedule; | |||
10698 | const char *sizes; | |||
10699 | const char *tile; | |||
10700 | const char *point; | |||
10701 | } tile_tests[] = { | |||
10702 | { 0, 0, "[n] -> { S[i,j] : 0 <= i,j < n }", | |||
10703 | "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", | |||
10704 | "{ [32,32] }", | |||
10705 | "[{ S[i,j] -> [floor(i/32)] }, { S[i,j] -> [floor(j/32)] }]", | |||
10706 | "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", | |||
10707 | }, | |||
10708 | { 1, 0, "[n] -> { S[i,j] : 0 <= i,j < n }", | |||
10709 | "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", | |||
10710 | "{ [32,32] }", | |||
10711 | "[{ S[i,j] -> [32*floor(i/32)] }, { S[i,j] -> [32*floor(j/32)] }]", | |||
10712 | "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", | |||
10713 | }, | |||
10714 | { 0, 1, "[n] -> { S[i,j] : 0 <= i,j < n }", | |||
10715 | "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", | |||
10716 | "{ [32,32] }", | |||
10717 | "[{ S[i,j] -> [floor(i/32)] }, { S[i,j] -> [floor(j/32)] }]", | |||
10718 | "[{ S[i,j] -> [i%32] }, { S[i,j] -> [j%32] }]", | |||
10719 | }, | |||
10720 | { 1, 1, "[n] -> { S[i,j] : 0 <= i,j < n }", | |||
10721 | "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", | |||
10722 | "{ [32,32] }", | |||
10723 | "[{ S[i,j] -> [32*floor(i/32)] }, { S[i,j] -> [32*floor(j/32)] }]", | |||
10724 | "[{ S[i,j] -> [i%32] }, { S[i,j] -> [j%32] }]", | |||
10725 | }, | |||
10726 | }; | |||
10727 | ||||
10728 | /* Basic tiling tests. Create a schedule tree with a domain and a band node, | |||
10729 | * tile the band and then check if the tile and point bands have the | |||
10730 | * expected partial schedule. | |||
10731 | */ | |||
10732 | static int test_tile(isl_ctx *ctx) | |||
10733 | { | |||
10734 | int i; | |||
10735 | int scale; | |||
10736 | int shift; | |||
10737 | ||||
10738 | scale = isl_options_get_tile_scale_tile_loops(ctx); | |||
10739 | shift = isl_options_get_tile_shift_point_loops(ctx); | |||
10740 | ||||
10741 | for (i = 0; i < ARRAY_SIZE(tile_tests)(sizeof(tile_tests)/sizeof(*tile_tests)); ++i) { | |||
10742 | int opt; | |||
10743 | int equal; | |||
10744 | const char *str; | |||
10745 | isl_union_set *domain; | |||
10746 | isl_multi_union_pw_aff *mupa, *mupa2; | |||
10747 | isl_schedule_node *node; | |||
10748 | isl_multi_val *sizes; | |||
10749 | ||||
10750 | opt = tile_tests[i].scale_tile; | |||
10751 | isl_options_set_tile_scale_tile_loops(ctx, opt); | |||
10752 | opt = tile_tests[i].shift_point; | |||
10753 | isl_options_set_tile_shift_point_loops(ctx, opt); | |||
10754 | ||||
10755 | str = tile_tests[i].domain; | |||
10756 | domain = isl_union_set_read_from_str(ctx, str); | |||
10757 | node = isl_schedule_node_from_domain(domain); | |||
10758 | node = isl_schedule_node_child(node, 0); | |||
10759 | str = tile_tests[i].schedule; | |||
10760 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); | |||
10761 | node = isl_schedule_node_insert_partial_schedule(node, mupa); | |||
10762 | str = tile_tests[i].sizes; | |||
10763 | sizes = isl_multi_val_read_from_str(ctx, str); | |||
10764 | node = isl_schedule_node_band_tile(node, sizes); | |||
10765 | ||||
10766 | str = tile_tests[i].tile; | |||
10767 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); | |||
10768 | mupa2 = isl_schedule_node_band_get_partial_schedule(node); | |||
10769 | equal = isl_multi_union_pw_aff_plain_is_equal(mupa, mupa2); | |||
10770 | isl_multi_union_pw_aff_free(mupa); | |||
10771 | isl_multi_union_pw_aff_free(mupa2); | |||
10772 | ||||
10773 | node = isl_schedule_node_child(node, 0); | |||
10774 | ||||
10775 | str = tile_tests[i].point; | |||
10776 | mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); | |||
10777 | mupa2 = isl_schedule_node_band_get_partial_schedule(node); | |||
10778 | if (equal >= 0 && equal) | |||
10779 | equal = isl_multi_union_pw_aff_plain_is_equal(mupa, | |||
10780 | mupa2); | |||
10781 | isl_multi_union_pw_aff_free(mupa); | |||
10782 | isl_multi_union_pw_aff_free(mupa2); | |||
10783 | ||||
10784 | isl_schedule_node_free(node); | |||
10785 | ||||
10786 | if (equal < 0) | |||
10787 | return -1; | |||
10788 | if (!equal) | |||
10789 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 10790); return -1; } while (0) | |||
10790 | "unexpected result", return -1)do { isl_handle_error(ctx, isl_error_unknown, "unexpected result" , "polly/lib/External/isl/isl_test.c", 10790); return -1; } while (0); | |||
10791 | } | |||
10792 | ||||
10793 | isl_options_set_tile_scale_tile_loops(ctx, scale); | |||
10794 | isl_options_set_tile_shift_point_loops(ctx, shift); | |||
10795 | ||||
10796 | return 0; | |||
10797 | } | |||
10798 | ||||
10799 | /* Check that the domain hash of a space is equal to the hash | |||
10800 | * of the domain of the space, both ignoring parameters. | |||
10801 | */ | |||
10802 | static int test_domain_hash(isl_ctx *ctx) | |||
10803 | { | |||
10804 | isl_map *map; | |||
10805 | isl_space *space; | |||
10806 | uint32_t hash1, hash2; | |||
10807 | ||||
10808 | map = isl_map_read_from_str(ctx, "[n] -> { A[B[x] -> C[]] -> D[] }"); | |||
10809 | space = isl_map_get_space(map); | |||
10810 | isl_map_free(map); | |||
10811 | hash1 = isl_space_get_tuple_domain_hash(space); | |||
10812 | space = isl_space_domain(space); | |||
10813 | hash2 = isl_space_get_tuple_hash(space); | |||
10814 | isl_space_free(space); | |||
10815 | ||||
10816 | if (!space) | |||
10817 | return -1; | |||
10818 | if (hash1 != hash2) | |||
10819 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "domain hash not equal to hash of domain" , "polly/lib/External/isl/isl_test.c", 10820); return -1; } while (0) | |||
10820 | "domain hash not equal to hash of domain", return -1)do { isl_handle_error(ctx, isl_error_unknown, "domain hash not equal to hash of domain" , "polly/lib/External/isl/isl_test.c", 10820); return -1; } while (0); | |||
10821 | ||||
10822 | return 0; | |||
10823 | } | |||
10824 | ||||
10825 | /* Check that a universe basic set that is not obviously equal to the universe | |||
10826 | * is still recognized as being equal to the universe. | |||
10827 | */ | |||
10828 | static int test_universe(isl_ctx *ctx) | |||
10829 | { | |||
10830 | const char *s; | |||
10831 | isl_basic_setisl_basic_map *bset; | |||
10832 | isl_bool is_univ; | |||
10833 | ||||
10834 | s = "{ [] : exists x, y : 3y <= 2x and y >= -3 + 2x and 2y >= 2 - x }"; | |||
10835 | bset = isl_basic_set_read_from_str(ctx, s); | |||
10836 | is_univ = isl_basic_set_is_universe(bset); | |||
10837 | isl_basic_set_free(bset); | |||
10838 | ||||
10839 | if (is_univ < 0) | |||
10840 | return -1; | |||
10841 | if (!is_univ) | |||
10842 | isl_die(ctx, isl_error_unknown,do { isl_handle_error(ctx, isl_error_unknown, "not recognized as universe set" , "polly/lib/External/isl/isl_test.c", 10843); return -1; } while (0) | |||
10843 | "not recognized as universe set", return -1)do { isl_handle_error(ctx, isl_error_unknown, "not recognized as universe set" , "polly/lib/External/isl/isl_test.c", 10843); return -1; } while (0); | |||
10844 | ||||
10845 | return 0; | |||
10846 | } | |||
10847 | ||||
10848 | /* Sets for which chambers are computed and checked. | |||
10849 | */ | |||
10850 | const char *chambers_tests[] = { | |||
10851 | "[A, B, C] -> { [x, y, z] : x >= 0 and y >= 0 and y <= A - x and " | |||
10852 | "z >= 0 and z <= C - y and z <= B - x - y }", | |||
10853 | }; | |||
10854 | ||||
10855 | /* Add the domain of "cell" to "cells". | |||
10856 | */ | |||
10857 | static isl_stat add_cell(__isl_take isl_cell *cell, void *user) | |||
10858 | { | |||
10859 | isl_basic_set_listisl_basic_map_list **cells = user; | |||
10860 | isl_basic_setisl_basic_map *dom; | |||
10861 | ||||
10862 | dom = isl_cell_get_domain(cell); | |||
10863 | isl_cell_free(cell); | |||
10864 | *cells = isl_basic_set_list_add(*cells, dom); | |||
10865 | ||||
10866 | return *cells ? isl_stat_ok : isl_stat_error; | |||
10867 | } | |||
10868 | ||||
10869 | /* Check that the elements of "list" are pairwise disjoint. | |||
10870 | */ | |||
10871 | static isl_stat check_pairwise_disjoint(__isl_keep isl_basic_set_listisl_basic_map_list *list) | |||
10872 | { | |||
10873 | int i, j; | |||
10874 | isl_size n; | |||
10875 | ||||
10876 | n = isl_basic_set_list_n_basic_set(list); | |||
10877 | if (n < 0) | |||
10878 | return isl_stat_error; | |||
10879 | ||||
10880 | for (i = 0; i < n; ++i) { | |||
10881 | isl_basic_setisl_basic_map *bset_i; | |||
10882 | ||||
10883 | bset_i = isl_basic_set_list_get_basic_set(list, i); | |||
10884 | for (j = i + 1; j < n; ++j) { | |||
10885 | isl_basic_setisl_basic_map *bset_j; | |||
10886 | isl_bool disjoint; | |||
10887 | ||||
10888 | bset_j = isl_basic_set_list_get_basic_set(list, j); | |||
10889 | disjoint = isl_basic_set_is_disjoint(bset_i, bset_j); | |||
10890 | isl_basic_set_free(bset_j); | |||
10891 | if (!disjoint) | |||
10892 | isl_die(isl_basic_set_list_get_ctx(list),do { isl_handle_error(isl_basic_set_list_get_ctx(list), isl_error_unknown , "not disjoint", "polly/lib/External/isl/isl_test.c", 10894) ; break; } while (0) | |||
10893 | isl_error_unknown, "not disjoint",do { isl_handle_error(isl_basic_set_list_get_ctx(list), isl_error_unknown , "not disjoint", "polly/lib/External/isl/isl_test.c", 10894) ; break; } while (0) | |||
10894 | break)do { isl_handle_error(isl_basic_set_list_get_ctx(list), isl_error_unknown , "not disjoint", "polly/lib/External/isl/isl_test.c", 10894) ; break; } while (0); | |||
10895 | if (disjoint < 0 || !disjoint) | |||
10896 | break; | |||
10897 | } | |||
10898 | isl_basic_set_free(bset_i); | |||
10899 | if (j < n) | |||
10900 | return isl_stat_error; | |||
10901 | } | |||
10902 | ||||
10903 | return isl_stat_ok; | |||
10904 | } | |||
10905 | ||||
10906 | /* Check that the chambers computed by isl_vertices_foreach_disjoint_cell | |||
10907 | * are pairwise disjoint. | |||
10908 | */ | |||
10909 | static int test_chambers(isl_ctx *ctx) | |||
10910 | { | |||
10911 | int i; | |||
10912 | ||||
10913 | for (i = 0; i < ARRAY_SIZE(chambers_tests)(sizeof(chambers_tests)/sizeof(*chambers_tests)); ++i) { | |||
10914 | isl_basic_setisl_basic_map *bset; | |||
10915 | isl_vertices *vertices; | |||
10916 | isl_basic_set_listisl_basic_map_list *cells; | |||
10917 | isl_stat ok; | |||
10918 | ||||
10919 | bset = isl_basic_set_read_from_str(ctx, chambers_tests[i]); | |||
10920 | vertices = isl_basic_set_compute_vertices(bset); | |||
10921 | cells = isl_basic_set_list_alloc(ctx, 0); | |||
10922 | if (isl_vertices_foreach_disjoint_cell(vertices, &add_cell, | |||
10923 | &cells) < 0) | |||
10924 | cells = isl_basic_set_list_free(cells); | |||
10925 | ok = check_pairwise_disjoint(cells); | |||
10926 | isl_basic_set_list_free(cells); | |||
10927 | isl_vertices_free(vertices); | |||
10928 | isl_basic_set_free(bset); | |||
10929 | ||||
10930 | if (ok < 0) | |||
10931 | return -1; | |||
10932 | } | |||
10933 | ||||
10934 | return 0; | |||
10935 | } | |||
10936 | ||||
10937 | struct { | |||
10938 | const char *name; | |||
10939 | int (*fn)(isl_ctx *ctx); | |||
10940 | } tests [] = { | |||
10941 | { "universe", &test_universe }, | |||
10942 | { "domain hash", &test_domain_hash }, | |||
10943 | { "dual", &test_dual }, | |||
10944 | { "dependence analysis", &test_flow }, | |||
10945 | { "val", &test_val }, | |||
10946 | { "compute divs", &test_compute_divs }, | |||
10947 | { "partial lexmin", &test_partial_lexmin }, | |||
10948 | { "simplify", &test_simplify }, | |||
10949 | { "curry", &test_curry }, | |||
10950 | { "piecewise multi affine expressions", &test_pw_multi_aff }, | |||
10951 | { "multi piecewise affine expressions", &test_multi_pw_aff }, | |||
10952 | { "conversion", &test_conversion }, | |||
10953 | { "list", &test_list }, | |||
10954 | { "align parameters", &test_align_parameters }, | |||
10955 | { "drop unused parameters", &test_drop_unused_parameters }, | |||
10956 | { "pullback", &test_pullback }, | |||
10957 | { "AST", &test_ast }, | |||
10958 | { "AST build", &test_ast_build }, | |||
10959 | { "AST generation", &test_ast_gen }, | |||
10960 | { "eliminate", &test_eliminate }, | |||
10961 | { "deltas_map", &test_deltas_map }, | |||
10962 | { "residue class", &test_residue_class }, | |||
10963 | { "div", &test_div }, | |||
10964 | { "slice", &test_slice }, | |||
10965 | { "sample", &test_sample }, | |||
10966 | { "empty projection", &test_empty_projection }, | |||
10967 | { "output", &test_output }, | |||
10968 | { "vertices", &test_vertices }, | |||
10969 | { "chambers", &test_chambers }, | |||
10970 | { "fixed", &test_fixed }, | |||
10971 | { "equal", &test_equal }, | |||
10972 | { "disjoint", &test_disjoint }, | |||
10973 | { "product", &test_product }, | |||
10974 | { "dim_max", &test_dim_max }, | |||
10975 | { "affine", &test_aff }, | |||
10976 | { "injective", &test_injective }, | |||
10977 | { "schedule (whole component)", &test_schedule_whole }, | |||
10978 | { "schedule (incremental)", &test_schedule_incremental }, | |||
10979 | { "schedule tree", &test_schedule_tree }, | |||
10980 | { "schedule tree prefix", &test_schedule_tree_prefix }, | |||
10981 | { "schedule tree grouping", &test_schedule_tree_group }, | |||
10982 | { "tile", &test_tile }, | |||
10983 | { "union map", &test_union_map }, | |||
10984 | { "union_pw", &test_union_pw }, | |||
10985 | { "locus", &test_locus }, | |||
10986 | { "eval", &test_eval }, | |||
10987 | { "parse", &test_parse }, | |||
10988 | { "single-valued", &test_sv }, | |||
10989 | { "recession cone", &test_recession_cone }, | |||
10990 | { "affine hull", &test_affine_hull }, | |||
10991 | { "simple_hull", &test_simple_hull }, | |||
10992 | { "box hull", &test_box_hull }, | |||
10993 | { "coalesce", &test_coalesce }, | |||
10994 | { "factorize", &test_factorize }, | |||
10995 | { "subset", &test_subset }, | |||
10996 | { "subtract", &test_subtract }, | |||
10997 | { "intersect", &test_intersect }, | |||
10998 | { "lexmin", &test_lexmin }, | |||
10999 | { "min", &test_min }, | |||
11000 | { "set lower bounds", &test_min_mpa }, | |||
11001 | { "gist", &test_gist }, | |||
11002 | { "piecewise quasi-polynomials", &test_pwqp }, | |||
11003 | { "lift", &test_lift }, | |||
11004 | { "bind parameters", &test_bind }, | |||
11005 | { "unbind parameters", &test_unbind }, | |||
11006 | { "bound", &test_bound }, | |||
11007 | { "get lists", &test_get_list }, | |||
11008 | { "union", &test_union }, | |||
11009 | { "split periods", &test_split_periods }, | |||
11010 | { "lexicographic order", &test_lex }, | |||
11011 | { "bijectivity", &test_bijective }, | |||
11012 | { "dataflow analysis", &test_dep }, | |||
11013 | { "reading", &test_read }, | |||
11014 | { "bounded", &test_bounded }, | |||
11015 | { "construction", &test_construction }, | |||
11016 | { "dimension manipulation", &test_dim }, | |||
11017 | { "map application", &test_application }, | |||
11018 | { "convex hull", &test_convex_hull }, | |||
11019 | { "transitive closure", &test_closure }, | |||
11020 | { "isl_bool", &test_isl_bool}, | |||
11021 | }; | |||
11022 | ||||
11023 | int main(int argc, char **argv) | |||
11024 | { | |||
11025 | int i; | |||
11026 | struct isl_ctx *ctx; | |||
11027 | struct isl_options *options; | |||
11028 | ||||
11029 | options = isl_options_new_with_defaults(); | |||
11030 | assert(options)((void) sizeof ((options) ? 1 : 0), __extension__ ({ if (options ) ; else __assert_fail ("options", "polly/lib/External/isl/isl_test.c" , 11030, __extension__ __PRETTY_FUNCTION__); })); | |||
11031 | argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL(1 << 0)); | |||
11032 | ||||
11033 | ctx = isl_ctx_alloc_with_options(&isl_options_args, options); | |||
11034 | for (i = 0; i < ARRAY_SIZE(tests)(sizeof(tests)/sizeof(*tests)); ++i) { | |||
11035 | printf("%s\n", tests[i].name)__printf_chk (2 - 1, "%s\n", tests[i].name); | |||
11036 | if (tests[i].fn(ctx) < 0) | |||
11037 | goto error; | |||
11038 | } | |||
11039 | isl_ctx_free(ctx); | |||
11040 | return 0; | |||
11041 | error: | |||
11042 | isl_ctx_free(ctx); | |||
11043 | return -1; | |||
11044 | } |