12 #include "llvm/ADT/DenseSet.h"
17 #include "mlir/Interfaces/LoopLikeInterface.cpp.inc"
19 bool LoopLikeOpInterface::blockIsInLoop(
Block *block) {
23 if (isa<LoopLikeOpInterface>(parent) ||
28 if (!isa<FunctionOpInterface>(parent))
30 if (blockIsInLoop(parentBlock))
38 stack.push_back(block);
39 while (!stack.empty()) {
40 Block *current = stack.pop_back_val();
41 auto [it, inserted] = visited.insert(current);
51 stack.push_back(successor);
59 auto loopLikeOp = cast<LoopLikeOpInterface>(op);
62 if (loopLikeOp.getInits().size() != loopLikeOp.getRegionIterArgs().size())
63 return op->
emitOpError(
"different number of inits and region iter_args: ")
64 << loopLikeOp.getInits().size()
65 <<
" != " << loopLikeOp.getRegionIterArgs().size();
66 if (!loopLikeOp.getYieldedValues().empty() &&
67 loopLikeOp.getRegionIterArgs().size() !=
68 loopLikeOp.getYieldedValues().size())
70 "different number of region iter_args and yielded values: ")
71 << loopLikeOp.getRegionIterArgs().size()
72 <<
" != " << loopLikeOp.getYieldedValues().size();
73 if (loopLikeOp.getLoopResults() && loopLikeOp.getLoopResults()->size() !=
74 loopLikeOp.getRegionIterArgs().size())
76 "different number of loop results and region iter_args: ")
77 << loopLikeOp.getLoopResults()->size()
78 <<
" != " << loopLikeOp.getRegionIterArgs().size();
82 auto yieldedValues = loopLikeOp.getYieldedValues();
83 for (
const auto [index, init, regionIterArg] :
84 llvm::enumerate(loopLikeOp.getInits(), loopLikeOp.getRegionIterArgs())) {
85 if (init.getType() != regionIterArg.getType())
87 <<
"-th init and " << index
88 <<
"-th region iter_arg have different type: " << init.getType()
89 <<
" != " << regionIterArg.getType();
90 if (!yieldedValues.empty()) {
91 if (regionIterArg.getType() != yieldedValues[index].getType())
93 <<
"-th region iter_arg and " << index
94 <<
"-th yielded value have different type: "
95 << regionIterArg.getType()
96 <<
" != " << yieldedValues[index].getType();
101 if (loopLikeOp.getLoopResults()) {
102 for (
const auto it : llvm::zip_equal(loopLikeOp.getRegionIterArgs(),
103 *loopLikeOp.getLoopResults())) {
106 <<
"-th region iter_arg and " << i
107 <<
"-th loop result have different type: "
108 << std::get<0>(it).getType()
109 <<
" != " << std::get<1>(it).getType();
Block represents an ordered list of Operations.
unsigned getNumSuccessors()
SuccessorRange getSuccessors()
Operation * getParentOp()
Returns the closest surrounding operation that contains this block.
Operation is the basic unit of execution within MLIR.
Block * getBlock()
Returns the operation block that contains this operation.
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
LogicalResult verifyLoopLikeOpInterface(Operation *op)
Verify invariants of the LoopLikeOpInterface.
Include the generated interface declarations.
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.