13 #ifndef MLIR_IR_VISITORS_H
14 #define MLIR_IR_VISITORS_H
18 #include "llvm/ADT/STLExtras.h"
22 class InFlightDiagnostic;
64 bool isAfterRegion(
int region)
const {
return nextRegion == region + 1; }
79 template <
typename Ret,
typename Arg,
typename... Rest>
81 template <
typename Ret,
typename F,
typename Arg,
typename... Rest>
83 template <
typename Ret,
typename F,
typename Arg,
typename... Rest>
101 template <typename Iterator>
106 for (
auto ®ion : Iterator::makeIterable(*op)) {
109 for (
auto &block : Iterator::makeIterable(region)) {
110 for (
auto &nestedOp : Iterator::makeIterable(block))
111 walk<Iterator>(&nestedOp, callback, order);
118 template <
typename Iterator>
121 for (
auto ®ion : Iterator::makeIterable(*op)) {
124 llvm::make_early_inc_range(Iterator::makeIterable(region))) {
127 for (
auto &nestedOp : Iterator::makeIterable(block))
128 walk<Iterator>(&nestedOp, callback, order);
135 template <
typename Iterator>
142 for (
auto ®ion : Iterator::makeIterable(*op)) {
143 for (
auto &block : Iterator::makeIterable(region)) {
145 for (
auto &nestedOp :
146 llvm::make_early_inc_range(Iterator::makeIterable(block)))
147 walk<Iterator>(&nestedOp, callback, order);
165 template <
typename Iterator>
170 for (
auto ®ion : Iterator::makeIterable(*op)) {
178 for (
auto &block : Iterator::makeIterable(region)) {
179 for (
auto &nestedOp : Iterator::makeIterable(block))
180 if (walk<Iterator>(&nestedOp, callback, order).wasInterrupted())
184 if (callback(®ion).wasInterrupted())
193 template <
typename Iterator>
196 for (
auto ®ion : Iterator::makeIterable(*op)) {
199 llvm::make_early_inc_range(Iterator::makeIterable(region))) {
207 for (
auto &nestedOp : Iterator::makeIterable(block))
208 if (walk<Iterator>(&nestedOp, callback, order).wasInterrupted())
211 if (callback(&block).wasInterrupted())
221 template <
typename Iterator>
234 for (
auto ®ion : Iterator::makeIterable(*op)) {
235 for (
auto &block : Iterator::makeIterable(region)) {
237 for (
auto &nestedOp :
238 llvm::make_early_inc_range(Iterator::makeIterable(block))) {
239 if (walk<Iterator>(&nestedOp, callback, order).wasInterrupted())
274 typename RetT = decltype(std::declval<FuncTy>()(std::declval<ArgT>()))>
275 std::enable_if_t<llvm::is_one_of<ArgT, Operation *, Region *, Block *>::value,
278 return detail::walk<Iterator>(op,
function_ref<RetT(ArgT)>(callback), Order);
296 typename RetT = decltype(std::declval<FuncTy>()(std::declval<ArgT>()))>
298 !llvm::is_one_of<ArgT, Operation *, Region *, Block *>::value &&
299 std::is_same<RetT, void>::value,
303 if (
auto derivedOp = dyn_cast<ArgT>(op))
333 typename RetT = decltype(std::declval<FuncTy>()(std::declval<ArgT>()))>
335 !llvm::is_one_of<ArgT, Operation *, Region *, Block *>::value &&
336 std::is_same<RetT, WalkResult>::value,
340 if (
auto derivedOp = dyn_cast<ArgT>(op))
341 return callback(derivedOp);
373 template <
typename FuncTy,
typename ArgT = detail::first_argument<FuncTy>,
374 typename RetT = decltype(std::declval<FuncTy>()(
375 std::declval<ArgT>(), std::declval<const WalkStage &>()))>
376 std::enable_if_t<std::is_same<ArgT, Operation *>::value, RetT>
388 template <
typename FuncTy,
typename ArgT = detail::first_argument<FuncTy>,
389 typename RetT = decltype(std::declval<FuncTy>()(
390 std::declval<ArgT>(), std::declval<const WalkStage &>()))>
391 std::enable_if_t<!std::is_same<ArgT, Operation *>::value &&
392 std::is_same<RetT, void>::value,
396 if (
auto derivedOp = dyn_cast<ArgT>(op))
397 callback(derivedOp, stage);
413 template <
typename FuncTy,
typename ArgT = detail::first_argument<FuncTy>,
414 typename RetT = decltype(std::declval<FuncTy>()(
415 std::declval<ArgT>(), std::declval<const WalkStage &>()))>
416 std::enable_if_t<!std::is_same<ArgT, Operation *>::value &&
417 std::is_same<RetT, WalkResult>::value,
421 if (
auto derivedOp = dyn_cast<ArgT>(op))
422 return callback(derivedOp, stage);
430 template <
typename FnT>
Block represents an ordered list of Operations.
Operation is the basic unit of execution within MLIR.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
A utility result that is used to signal how to proceed with an ongoing walk:
bool wasSkipped() const
Returns true if the walk was skipped.
static WalkResult advance()
bool wasInterrupted() const
Returns true if the walk was interrupted.
static WalkResult interrupt()
A utility class to encode the current walk stage for "generic" walkers.
void advance()
Advance the walk stage.
int getNextRegion() const
Returns the next region that will be visited.
bool isBeforeRegion(int region) const
Returns true if parent operation is being visited just before visiting region number region.
bool isAfterAllRegions() const
Return true if parent operation is being visited after all regions.
bool isAfterRegion(int region) const
Returns true if parent operation is being visited just after visiting region number region.
bool isBeforeAllRegions() const
Return true if parent operation is being visited before all regions.
void walk(Operation *op, function_ref< void(Region *)> callback, WalkOrder order)
Walk all of the regions, blocks, or operations nested under (and including) the given operation.
decltype(walk(nullptr, std::declval< FnT >())) walkResultType
Utility to provide the return type of a templated walk method.
decltype(first_argument_type(&F::operator())) first_argument_type(F)
decltype(first_argument_type(std::declval< T >())) first_argument
Type definition of the first argument to the given callable 'T'.
Include the generated interface declarations.
WalkOrder
Traversal order for region, block and operation walk utilities.
This iterator enumerates the elements in "forward" order.
static MutableArrayRef< Region > makeIterable(Operation &range)
Make operations iterable: return the list of regions.
static constexpr T & makeIterable(T &range)
Regions and block are already iterable.