Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 9 additions & 17 deletions islutils/matchers-inl.h
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
#include <type_traits>

namespace {
template <typename Arg, typename... Args>
inline typename std::enable_if<sizeof...(Args) != 0, void>::type
appendVarargToVector(std::vector<Arg> &vec, Args... args) {
vec.push_back(std::get<0>(std::tuple<Args...>(args...)));
appendVarargToVector<Arg>(vec, args...);
}

template <typename Arg, typename... Args>
inline typename std::enable_if<sizeof...(Args) == 0, void>::type
appendVarargToVector(std::vector<Arg> &vec, Args...) {
(void)vec;
}

template <typename R, typename... Args>
std::vector<R> varargToVector(Args... args) {
std::vector<R> result;
appendVarargToVector<R, Args...>(result, args...);
template <typename... Args>
std::vector<typename std::common_type<Args...>::type>
varargToVector(Args... args) {
std::vector<typename std::common_type<Args...>::type> result;
result.reserve(sizeof...(Args));
for (const auto &a :
{static_cast<typename std::common_type<Args...>::type>(args)...}) {
result.emplace_back(a);
}
return result;
}
} // namespace
Expand Down
70 changes: 70 additions & 0 deletions islutils/matchers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,74 @@ bool ScheduleNodeMatcher::isMatching(const ScheduleNodeMatcher &matcher,
return true;
}

static bool hasPreviousSiblingImpl(isl::schedule_node node,
const ScheduleNodeMatcher &siblingMatcher) {
while (isl_schedule_node_has_previous_sibling(node.get()) == isl_bool_true) {
node = isl::manage(isl_schedule_node_previous_sibling(node.release()));
if (ScheduleNodeMatcher::isMatching(siblingMatcher, node)) {
return true;
}
}
return false;
}

static bool hasNextSiblingImpl(isl::schedule_node node,
const ScheduleNodeMatcher &siblingMatcher) {
while (isl_schedule_node_has_next_sibling(node.get()) == isl_bool_true) {
node = isl::manage(isl_schedule_node_next_sibling(node.release()));
if (ScheduleNodeMatcher::isMatching(siblingMatcher, node)) {
return true;
}
}
return false;
}

std::function<bool(isl::schedule_node)>
hasPreviousSibling(const ScheduleNodeMatcher &siblingMatcher) {
return std::bind(hasPreviousSiblingImpl, std::placeholders::_1,
siblingMatcher);
}

std::function<bool(isl::schedule_node)>
hasNextSibling(const ScheduleNodeMatcher &siblingMatcher) {
return std::bind(hasNextSiblingImpl, std::placeholders::_1, siblingMatcher);
}

std::function<bool(isl::schedule_node)>
hasSibling(const ScheduleNodeMatcher &siblingMatcher) {
return [siblingMatcher](isl::schedule_node node) {
return hasPreviousSiblingImpl(node, siblingMatcher) ||
hasNextSiblingImpl(node, siblingMatcher);
};
}

std::function<bool(isl::schedule_node)>
hasDescendant(const ScheduleNodeMatcher &descendantMatcher) {
isl::schedule_node n;
return [descendantMatcher](isl::schedule_node node) {
// Cannot use capturing lambdas as C function pointers.
struct Data {
bool found;
const ScheduleNodeMatcher &descendantMatcher;
};
Data data{false, descendantMatcher};

auto r = isl_schedule_node_foreach_descendant_top_down(
node.get(),
[](__isl_keep isl_schedule_node *cn, void *user) -> isl_bool {
auto data = static_cast<Data *>(user);
if (data->found) {
return isl_bool_false;
}

auto n = isl::manage_copy(cn);
data->found =
ScheduleNodeMatcher::isMatching(data->descendantMatcher, n);
return data->found ? isl_bool_false : isl_bool_true;
},
&data);
return r == isl_stat_ok && data.found;
};
}

} // namespace matchers
15 changes: 14 additions & 1 deletion islutils/matchers.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,27 @@ class ScheduleNodeMatcher {
#undef DECL_FRIEND_TYPE_MATCH

public:
bool isMatching(const ScheduleNodeMatcher &matcher, isl::schedule_node node);
static bool isMatching(const ScheduleNodeMatcher &matcher,
isl::schedule_node node);

private:
isl_schedule_node_type current_;
std::vector<ScheduleNodeMatcher> children_;
std::function<bool(isl::schedule_node)> nodeCallback_;
};

std::function<bool(isl::schedule_node)>
hasPreviousSibling(const ScheduleNodeMatcher &siblingMatcher);

std::function<bool(isl::schedule_node)>
hasNextSibling(const ScheduleNodeMatcher &siblingMatcher);

std::function<bool(isl::schedule_node)>
hasSibling(const ScheduleNodeMatcher &siblingMatcher);

std::function<bool(isl::schedule_node)>
hasDescendant(const ScheduleNodeMatcher &descendantMatcher);

#include "matchers-inl.h"

} // namespace matchers