From 5d2ce80e77ba512a96039c4f221a448bfee57805 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 7 Aug 2017 11:48:05 +0200 Subject: [PATCH] add isl_union_map_every_map This function checks whether the callback function returns true on each map in the union map and stops checking as soon as one of the calls returns false. In principle, the same effect can be obtained by using isl_union_map_foreach_map, keeping track of the results separately and returning isl_stat_error as soon as processing can stop. Even though this mechanism is commonly used inside isl, it does constitute a slight abuse of the exception handling and should not be exposed to the user. The new isl_union_map_every_map exposes the desired functionality in a more obvious way. Signed-off-by: Sven Verdoolaege --- doc/user.pod | 8 ++++++++ include/isl/union_map.h | 2 ++ isl_union_map.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/doc/user.pod b/doc/user.pod index 5acb756b..c2259488 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -2182,11 +2182,19 @@ To iterate over all the sets or maps in a union set or map, use __isl_keep isl_union_map *umap, isl_stat (*fn)(__isl_take isl_map *map, void *user), void *user); + isl_bool isl_union_map_every_map( + __isl_keep isl_union_map *umap, + isl_bool (*test)(__isl_keep isl_map *map, + void *user), + void *user); These functions call the callback function once for each (pair of) space(s) for which there are elements in the input. The argument to the callback contains all elements in the input with that (pair of) space(s). +The C variant check whether each +call to the callback returns true and stops checking as soon as one +of these calls returns false. The number of sets or maps in a union set or map can be obtained from diff --git a/include/isl/union_map.h b/include/isl/union_map.h index 0420a628..27c0ee1b 100644 --- a/include/isl/union_map.h +++ b/include/isl/union_map.h @@ -229,6 +229,8 @@ int isl_union_map_n_map(__isl_keep isl_union_map *umap); __isl_export isl_stat isl_union_map_foreach_map(__isl_keep isl_union_map *umap, isl_stat (*fn)(__isl_take isl_map *map, void *user), void *user); +isl_bool isl_union_map_every_map(__isl_keep isl_union_map *umap, + isl_bool (*test)(__isl_keep isl_map *map, void *user), void *user); isl_bool isl_union_map_contains(__isl_keep isl_union_map *umap, __isl_keep isl_space *space); __isl_give isl_map *isl_union_map_extract_map(__isl_keep isl_union_map *umap, diff --git a/isl_union_map.c b/isl_union_map.c index c5f73d52..b9f4ad72 100644 --- a/isl_union_map.c +++ b/isl_union_map.c @@ -483,6 +483,58 @@ isl_stat isl_union_map_foreach_map(__isl_keep isl_union_map *umap, &call_on_copy, &data); } +/* Internal data structure for isl_union_map_every_map. + * + * "test" is the user-specified callback function. + * "user" is the user-specified callback function argument. + * + * "failed" is initialized to 0 and set to 1 if "test" fails + * on any map. + */ +struct isl_union_map_every_data { + isl_bool (*test)(__isl_keep isl_map *map, void *user); + void *user; + int failed; +}; + +/* Call data->test on "map". + * If this fails, then set data->failed and abort. + */ +static isl_stat call_every(void **entry, void *user) +{ + isl_map *map = *entry; + struct isl_union_map_every_data *data = user; + isl_bool r; + + r = data->test(map, data->user); + if (r < 0) + return isl_stat_error; + if (r) + return isl_stat_ok; + data->failed = 1; + return isl_stat_error; +} + +/* Does "test" succeed on every map in "umap"? + */ +isl_bool isl_union_map_every_map(__isl_keep isl_union_map *umap, + isl_bool (*test)(__isl_keep isl_map *map, void *user), void *user) +{ + struct isl_union_map_every_data data = { test, user, 0 }; + isl_stat r; + + if (!umap) + return isl_bool_error; + + r = isl_hash_table_foreach(isl_union_map_get_ctx(umap), &umap->table, + &call_every, &data); + if (r >= 0) + return isl_bool_true; + if (data.failed) + return isl_bool_false; + return isl_bool_error; +} + static isl_stat copy_map(void **entry, void *user) { isl_map *map = *entry; -- 2.11.4.GIT