From 759982a84af37b63e3a4a0d33b8a02c88911f858 Mon Sep 17 00:00:00 2001 From: Massinissa Merouani Date: Sun, 26 Jul 2026 12:00:21 +0400 Subject: [PATCH] Avoid AST generation for illegal schedules and handle duplicate targets --- src/actions.cc | 15 +++++++++++---- src/utils.cc | 10 ++++++++-- tests/actions_test.cc | 12 ++++++++++++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/actions.cc b/src/actions.cc index a3ef9ee..352bbd7 100644 --- a/src/actions.cc +++ b/src/actions.cc @@ -450,10 +450,17 @@ Result schedule_str_to_result(std::string function_name, std::string schedule_st // earlier may have been invalidated by a later interchange/tiling. is_legal &= tiramisu::check_legality_of_parallelism(); result.legality = is_legal; - implicit_function->gen_time_space_domain(); - implicit_function->gen_isl_ast(); - std::string isl_ast = implicit_function->generate_isl_ast_representation_string(nullptr, 0, ""); - result.isl_ast = isl_ast; + // Code-generation AST construction is only valid after the transformed + // schedule passes legality. Besides avoiding work for rejected schedules, + // this keeps illegal helper/update domains out of ISL's AST builder. + if (is_legal) + { + implicit_function->gen_time_space_domain(); + implicit_function->gen_isl_ast(); + result.isl_ast = + implicit_function->generate_isl_ast_representation_string( + nullptr, 0, ""); + } bool should_execute = operation == Operation::execution || operation == Operation::execution_no_check; diff --git a/src/utils.cc b/src/utils.cc index 9a47218..85667e0 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -1,5 +1,6 @@ #include #include +#include // #include "function_floyd_warshall_MINI_wrapper.h" using namespace tiramisu; @@ -47,16 +48,21 @@ std::string get_first_comp(std::string comps_str) std::vector get_comps(std::string comps_str, tiramisu::function *implicit_function) { std::vector comps; + std::unordered_set seen; std::string delimiter = ","; size_t pos = 0; std::string token; while ((pos = comps_str.find(delimiter)) != std::string::npos) { token = comps_str.substr(0, pos); - comps.push_back(get_computation_by_name(token, implicit_function)); + auto comp = get_computation_by_name(token, implicit_function); + if (seen.insert(comp).second) + comps.push_back(comp); comps_str.erase(0, pos + delimiter.length()); } - comps.push_back(get_computation_by_name(comps_str, implicit_function)); + auto comp = get_computation_by_name(comps_str, implicit_function); + if (seen.insert(comp).second) + comps.push_back(comp); return comps; } diff --git a/tests/actions_test.cc b/tests/actions_test.cc index 6eb3ebe..9cabeaa 100644 --- a/tests/actions_test.cc +++ b/tests/actions_test.cc @@ -233,6 +233,17 @@ TEST(TiraLibCppTest, DuplicateParallelizationTargetsAreIdempotent) EXPECT_EQ(clean_halide_ir(duplicate_ir), clean_halide_ir(unique_ir)); } +TEST(TiraLibCppTest, DuplicateTilingTargetsAreIdempotent) +{ + auto [unique_result, unique_ir] = apply_schedule_blur( + "T2(L0,L1,4,4,comps=['comp_blur'])"); + auto [duplicate_result, duplicate_ir] = apply_schedule_blur( + "T2(L0,L1,4,4,comps=['comp_blur','comp_blur','comp_blur'])"); + + EXPECT_EQ(duplicate_result.legality, unique_result.legality); + EXPECT_EQ(clean_halide_ir(duplicate_ir), clean_halide_ir(unique_ir)); +} + TEST(TiraLibCppTest, Tiling2D) { std::string schedule = "T2(L0,L1,32,32,comps=['comp_blur'])"; @@ -591,6 +602,7 @@ TEST(TiraLibCppTest, IllegalAction) std::string halide_ir = std::get<1>(result); EXPECT_EQ(resultInstance.legality, false); + EXPECT_TRUE(resultInstance.isl_ast.empty()); } std::tuple apply_schedule_skewing_sample(std::string schedule)