22 namespace polyhedral {
24 struct ScheduleTreeMatcher;
26 bool matchOne(ScheduleTreeMatcher matcher,
const detail::ScheduleTree* tree);
29 struct ScheduleTreeMatcher {
30 friend bool matchOne(ScheduleTreeMatcher,
const detail::ScheduleTree*);
32 template <
typename... Args>
33 ScheduleTreeMatcher(detail::ScheduleTreeType type, Args... args)
36 propertyMatcher_([](
const detail::ScheduleTree*) {
return true; }),
39 detail::ScheduleTreeType type_;
40 std::vector<ScheduleTreeMatcher> children_;
41 std::function<bool(const detail::ScheduleTree*)> propertyMatcher_;
49 template <
typename... Args>
50 inline ScheduleTreeMatcher sequence(Args... children) {
51 return ScheduleTreeMatcher(detail::ScheduleTreeType::Sequence, children...);
54 template <
typename... Args>
55 inline ScheduleTreeMatcher domain(Args... children) {
56 return ScheduleTreeMatcher(detail::ScheduleTreeType::Domain, children...);
59 template <
typename... Args>
60 inline ScheduleTreeMatcher context(Args... children) {
61 return ScheduleTreeMatcher(detail::ScheduleTreeType::Context, children...);
64 template <
typename... Args>
65 inline ScheduleTreeMatcher filter(
66 std::function<
bool(isl::union_set)> propertyMatcher,
68 ScheduleTreeMatcher m(detail::ScheduleTreeType::Filter, children...);
69 m.propertyMatcher_ = [propertyMatcher](
const detail::ScheduleTree* tree) {
70 return propertyMatcher(
71 tree->elemAs<detail::ScheduleTreeElemFilter>()->filter_);
76 template <
typename... Args>
77 inline ScheduleTreeMatcher filter(
78 std::function<
bool(
const detail::ScheduleTree* tree)> propertyMatcher,
80 ScheduleTreeMatcher m(detail::ScheduleTreeType::Filter, children...);
81 m.propertyMatcher_ = propertyMatcher;
90 typename =
typename std::enable_if<
91 std::is_same<First, ScheduleTreeMatcher>::value>::type>
92 inline ScheduleTreeMatcher filter(First first, Args... children) {
93 return ScheduleTreeMatcher(
94 detail::ScheduleTreeType::Filter, first, children...);
97 inline ScheduleTreeMatcher filter() {
98 return ScheduleTreeMatcher(detail::ScheduleTreeType::Filter);
103 template <
typename... Args>
104 inline ScheduleTreeMatcher mapping_filter(
105 std::function<
bool(isl::union_set)> propertyMatcher,
107 ScheduleTreeMatcher m(detail::ScheduleTreeType::MappingFilter, children...);
108 m.propertyMatcher_ = [propertyMatcher](
const detail::ScheduleTree* tree) {
109 return propertyMatcher(
110 tree->elemAs<detail::ScheduleTreeElemMappingFilter>()->filter_);
115 template <
typename... Args>
116 inline ScheduleTreeMatcher mapping_filter(
117 std::function<
bool(
const detail::ScheduleTree* tree)> propertyMatcher,
119 ScheduleTreeMatcher m(detail::ScheduleTreeType::MappingFilter, children...);
120 m.propertyMatcher_ = propertyMatcher;
130 typename =
typename std::enable_if<
131 std::is_same<First, ScheduleTreeMatcher>::value>::type>
132 inline ScheduleTreeMatcher mapping_filter(First first, Args... children) {
133 return ScheduleTreeMatcher(
134 detail::ScheduleTreeType::MappingFilter, first, children...);
137 inline ScheduleTreeMatcher mapping_filter() {
138 return ScheduleTreeMatcher(detail::ScheduleTreeType::MappingFilter);
141 template <
typename... Args>
142 inline ScheduleTreeMatcher band(
144 isl::multi_union_pw_aff mupa,
146 std::vector<bool> coincident,
147 std::vector<bool> unroll)> propertyMatcher,
149 ScheduleTreeMatcher m(detail::ScheduleTreeType::Band, children...);
150 m.propertyMatcher_ = [propertyMatcher](
const detail::ScheduleTree* tree) {
151 auto band = tree->elemAs<detail::ScheduleTreeElemBand>();
152 return propertyMatcher(
153 band->mupa_, band->permutable_, band->coincident_, band->unroll_);
161 typename =
typename std::enable_if<
162 std::is_same<First, ScheduleTreeMatcher>::value>::type>
163 inline ScheduleTreeMatcher band(First first, Args... children) {
164 return ScheduleTreeMatcher(
165 detail::ScheduleTreeType::Band, first, children...);
168 inline ScheduleTreeMatcher band() {
169 return ScheduleTreeMatcher(detail::ScheduleTreeType::Band);
172 template <
typename... Args>
173 inline ScheduleTreeMatcher extension(
174 std::function<
bool(isl::union_map)> propertyMatcher,
176 ScheduleTreeMatcher m(detail::ScheduleTreeType::Extension, children...);
177 m.propertyMatcher_ = [propertyMatcher](
const detail::ScheduleTree* tree) {
178 return propertyMatcher(
179 tree->elemAs<detail::ScheduleTreeElemExtension>()->extension_);
187 typename =
typename std::enable_if<
188 std::is_same<First, ScheduleTreeMatcher>::value>::type>
189 inline ScheduleTreeMatcher extension(First first, Args... children) {
190 return ScheduleTreeMatcher(
191 detail::ScheduleTreeType::Extension, first, children...);
194 inline ScheduleTreeMatcher extension() {
195 return ScheduleTreeMatcher(detail::ScheduleTreeType::Extension);
208 inline ScheduleTreeMatcher any() {
209 ScheduleTreeMatcher m(detail::ScheduleTreeType::Any);
214 inline bool matchOne(
215 ScheduleTreeMatcher matcher,
216 const detail::ScheduleTree* tree) {
220 if (matcher.wildcard) {
223 if (matcher.type_ != tree->type_) {
226 if (!matcher.propertyMatcher_(tree)) {
231 if (matcher.children_.size() == 0 || tree->numChildren() == 0) {
232 if (matcher.children_.size() != tree->numChildren()) {
238 if (!matcher.children_.back().wildcard &&
239 matcher.children_.size() != tree->numChildren()) {
243 if (matcher.children_.size() > tree->numChildren()) {
254 for (
size_t i = 0; i < matcher.children_.size(); ++i) {
255 CHECK(!matcher.children_[i].wildcard || i == matcher.children_.size() - 1)
256 <<
"Error in matcher structure, wildcard must be the last child!";
257 if (!matchOne(matcher.children_[i], tree->child({i}))) {
269 inline std::vector<const detail::ScheduleTree*> matchDFSPreorder(
270 ScheduleTreeMatcher matcher,
271 const detail::ScheduleTree* tree) {
272 std::vector<const detail::ScheduleTree*> res;
273 for (
auto t : detail::ScheduleTree::collectDFSPreorder(tree)) {
274 if (matchOne(matcher, t)) {
282 inline std::vector<const detail::ScheduleTree*> match(
283 ScheduleTreeMatcher matcher,
284 const detail::ScheduleTree* tree) {
285 return matchDFSPreorder(matcher, tree);