16 #include "mlir/Interfaces/LoopLikeInterface.cpp.inc"
18 bool LoopLikeOpInterface::blockIsInLoop(
Block *block) {
22 if (isa<LoopLikeOpInterface>(parent) ||
27 if (!isa<FunctionOpInterface>(parent))
29 if (blockIsInLoop(parentBlock))
37 stack.push_back(block);
38 while (!stack.empty()) {
39 Block *current = stack.pop_back_val();
40 auto [it, inserted] = visited.insert(current);
50 stack.push_back(successor);
58 auto loopLikeOp = cast<LoopLikeOpInterface>(op);
61 if (loopLikeOp.getInits().size() != loopLikeOp.getRegionIterArgs().size())
62 return op->
emitOpError(
"different number of inits and region iter_args: ")
63 << loopLikeOp.getInits().size()
64 <<
" != " << loopLikeOp.getRegionIterArgs().size();
65 if (!loopLikeOp.getYieldedValues().empty() &&
66 loopLikeOp.getRegionIterArgs().size() !=
67 loopLikeOp.getYieldedValues().size())
69 "different number of region iter_args and yielded values: ")
70 << loopLikeOp.getRegionIterArgs().size()
71 <<
" != " << loopLikeOp.getYieldedValues().size();
72 if (loopLikeOp.getLoopResults() && loopLikeOp.getLoopResults()->size() !=
73 loopLikeOp.getRegionIterArgs().size())
75 "different number of loop results and region iter_args: ")
76 << loopLikeOp.getLoopResults()->size()
77 <<
" != " << loopLikeOp.getRegionIterArgs().size();
81 auto yieldedValues = loopLikeOp.getYieldedValues();
82 for (
const auto [index, init, regionIterArg] :
83 llvm::enumerate(loopLikeOp.getInits(), loopLikeOp.getRegionIterArgs())) {
84 if (init.getType() != regionIterArg.getType())
86 <<
"-th init and " << index
87 <<
"-th region iter_arg have different type: " << init.getType()
88 <<
" != " << regionIterArg.getType();
89 if (!yieldedValues.empty()) {
90 if (regionIterArg.getType() != yieldedValues[index].getType())
92 <<
"-th region iter_arg and " << index
93 <<
"-th yielded value have different type: "
94 << regionIterArg.getType()
95 <<
" != " << yieldedValues[index].getType();
100 if (loopLikeOp.getLoopResults()) {
101 for (
const auto it : llvm::zip_equal(loopLikeOp.getRegionIterArgs(),
102 *loopLikeOp.getLoopResults())) {
105 <<
"-th region iter_arg and " << i
106 <<
"-th loop result have different type: "
107 << std::get<0>(it).getType()
108 <<
" != " << 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.