@@ -69,6 +69,7 @@ __isl_give isl_ast_build *isl_ast_build_set_options(
__isl_give isl_ast_build *isl_ast_build_set_iterators(
__isl_take isl_ast_build *build,
__isl_take isl_id_list *iterators);
+__isl_export
__isl_give isl_ast_build *isl_ast_build_set_at_each_domain(
__isl_take isl_ast_build *build,
__isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node,
@@ -225,6 +225,47 @@ static void test_schedule_tree(isl::ctx ctx)
assert(domain.is_equal(filters).is_true());
}
+/* Test basic AST generation from a schedule tree.
+ *
+ * In particular, create a simple schedule tree and
+ * - perform some generic tests
+ * - test at_each_domain in the failing case
+ */
+static void test_ast_build(isl::ctx ctx)
+{
+ auto schedule = test_ast_build_generic(ctx);
+
+ bool do_fail = true;
+ int count_ast_fail = 0;
+ auto fail_inc_count_ast =
+ [&count_ast_fail, &do_fail](isl::ast_node node,
+ isl::ast_build build) {
+ count_ast_fail++;
+ return do_fail ? isl::ast_node() : node;
+ };
+ auto build = isl::ast_build(ctx);
+ build = build.set_at_each_domain(fail_inc_count_ast);
+ auto ast = build.node_from(schedule);
+ assert(ast.is_null());
+ assert(count_ast_fail > 0);
+ auto build_copy = build;
+ int count_ast = 0;
+ auto inc_count_ast =
+ [&count_ast](isl::ast_node node, isl::ast_build build) {
+ count_ast++;
+ return node;
+ };
+ build_copy = build_copy.set_at_each_domain(inc_count_ast);
+ ast = build_copy.node_from(schedule);
+ assert(!ast.is_null());
+ assert(count_ast == 2);
+ count_ast_fail = 0;
+ do_fail = false;
+ ast = build.node_from(schedule);
+ assert(!ast.is_null());
+ assert(count_ast_fail == 2);
+}
+
/* Test the isl checked C++ interface
*
* This includes:
@@ -277,11 +277,29 @@ static isl::schedule_node test_schedule_tree_generic(isl::ctx ctx)
*
* In particular, create a simple schedule tree and
* - generate an AST from the schedule tree
+ * - test at_each_domain in the successful case
*/
-static void test_ast_build(isl::ctx ctx)
+static isl::schedule test_ast_build_generic(isl::ctx ctx)
{
auto schedule = construct_schedule_tree(ctx);
+ int count_ast = 0;
+ auto inc_count_ast =
+ [&count_ast](isl::ast_node node, isl::ast_build build) {
+ count_ast++;
+ return node;
+ };
auto build = isl::ast_build(ctx);
+ auto build_copy = build.set_at_each_domain(inc_count_ast);
auto ast = build.node_from(schedule);
+ assert(count_ast == 0);
+ count_ast = 0;
+ ast = build_copy.node_from(schedule);
+ assert(count_ast == 2);
+ build = build_copy;
+ count_ast = 0;
+ ast = build.node_from(schedule);
+ assert(count_ast == 2);
+
+ return schedule;
}
@@ -237,6 +237,52 @@ static void test_schedule_tree(isl::ctx ctx)
assert(domain.is_equal(filters));
}
+/* Test basic AST generation from a schedule tree.
+ *
+ * In particular, create a simple schedule tree and
+ * - perform some generic tests
+ * - test at_each_domain in the failing case
+ */
+static void test_ast_build(isl::ctx ctx)
+{
+ auto schedule = test_ast_build_generic(ctx);
+
+ bool do_fail = true;
+ int count_ast_fail = 0;
+ auto fail_inc_count_ast =
+ [&count_ast_fail, &do_fail](isl::ast_node node,
+ isl::ast_build build) {
+ count_ast_fail++;
+ if (do_fail)
+ throw "fail";
+ return node;
+ };
+ auto build = isl::ast_build(ctx);
+ build = build.set_at_each_domain(fail_inc_count_ast);
+ auto caught = false;
+ try {
+ auto ast = build.node_from(schedule);
+ } catch (char const *s) {
+ caught = true;
+ }
+ assert(caught);
+ assert(count_ast_fail > 0);
+ auto build_copy = build;
+ int count_ast = 0;
+ auto inc_count_ast =
+ [&count_ast](isl::ast_node node, isl::ast_build build) {
+ count_ast++;
+ return node;
+ };
+ build_copy = build_copy.set_at_each_domain(inc_count_ast);
+ auto ast = build_copy.node_from(schedule);
+ assert(count_ast == 2);
+ count_ast_fail = 0;
+ do_fail = false;
+ ast = build.node_from(schedule);
+ assert(count_ast_fail == 2);
+}
+
/* Test the (unchecked) isl C++ interface
*
* This includes:
@@ -322,12 +322,53 @@ def test_schedule_tree():
#
# In particular, create a simple schedule tree and
# - generate an AST from the schedule tree
+# - test at_each_domain
#
def test_ast_build():
schedule = construct_schedule_tree()
+ count_ast = [0]
+ def inc_count_ast(node, build):
+ count_ast[0] += 1
+ return node
+
+ build = isl.ast_build()
+ build_copy = build.set_at_each_domain(inc_count_ast)
+ ast = build.node_from(schedule)
+ assert(count_ast[0] == 0)
+ count_ast[0] = 0
+ ast = build_copy.node_from(schedule)
+ assert(count_ast[0] == 2)
+ build = build_copy
+ count_ast[0] = 0
+ ast = build.node_from(schedule)
+ assert(count_ast[0] == 2)
+
+ do_fail = True;
+ count_ast_fail = [0]
+ def fail_inc_count_ast(node, build):
+ count_ast_fail[0] += 1
+ if do_fail:
+ raise "fail"
+ return node
build = isl.ast_build()
+ build = build.set_at_each_domain(fail_inc_count_ast)
+ caught = False
+ try:
+ ast = build.node_from(schedule)
+ except:
+ caught = True
+ assert(caught)
+ assert(count_ast_fail[0] > 0)
+ build_copy = build
+ build_copy = build_copy.set_at_each_domain(inc_count_ast)
+ count_ast[0] = 0
+ ast = build_copy.node_from(schedule)
+ assert(count_ast[0] == 2)
+ count_ast_fail[0] = 0
+ do_fail = False;
ast = build.node_from(schedule)
+ assert(count_ast_fail[0] == 2)
# Test the isl Python interface
#