Skip to content

Commit 3bd7a9b

Browse files
[mlir][Interfaces] LoopLikeOpInterface: Add helpers to get region iter_args and inits (llvm#66925)
`AffineForOp::getInitOperands` is renamed to `getInits` to be consistent with MLIR operand getter naming conventions. ("get" + operand name)
1 parent 604a231 commit 3bd7a9b

File tree

11 files changed

+53
-21
lines changed

11 files changed

+53
-21
lines changed

mlir/include/mlir/Dialect/Affine/IR/AffineOps.td

+1-1
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ def AffineForOp : Affine_Op<"for",
259259
Block::BlockArgListType getRegionIterArgs() {
260260
return getBody()->getArguments().drop_front();
261261
}
262-
Operation::operand_range getIterOperands() {
262+
Operation::operand_range getInits() {
263263
return getOperands().drop_front(getNumControlOperands());
264264
}
265265

mlir/include/mlir/Dialect/SCF/IR/SCFOps.td

+3-3
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ def ExecuteRegionOp : SCF_Op<"execute_region", [
120120

121121
def ForOp : SCF_Op<"for",
122122
[AutomaticAllocationScope, DeclareOpInterfaceMethods<LoopLikeOpInterface,
123-
["getSingleInductionVar", "getSingleLowerBound", "getSingleStep",
124-
"getSingleUpperBound", "promoteIfSingleIteration"]>,
123+
["getInits", "getSingleInductionVar", "getSingleLowerBound",
124+
"getSingleStep", "getSingleUpperBound", "promoteIfSingleIteration"]>,
125125
AllTypesMatch<["lowerBound", "upperBound", "step"]>,
126126
ConditionallySpeculatable,
127127
DeclareOpInterfaceMethods<RegionBranchOpInterface,
@@ -948,7 +948,7 @@ def ReduceReturnOp :
948948
def WhileOp : SCF_Op<"while",
949949
[DeclareOpInterfaceMethods<RegionBranchOpInterface,
950950
["getEntrySuccessorOperands"]>,
951-
DeclareOpInterfaceMethods<LoopLikeOpInterface>,
951+
DeclareOpInterfaceMethods<LoopLikeOpInterface, ["getRegionIterArgs"]>,
952952
RecursiveMemoryEffects, SingleBlock]> {
953953
let summary = "a generic 'while' loop";
954954
let description = [{

mlir/include/mlir/Interfaces/LoopLikeInterface.td

+25
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,31 @@ def LoopLikeOpInterface : OpInterface<"LoopLikeOpInterface"> {
116116
return std::nullopt;
117117
}]
118118
>,
119+
InterfaceMethod<[{
120+
Return the "init" operands that are used as initialization values for
121+
the region "iter_args" of this loop.
122+
}],
123+
/*retTy=*/"::mlir::OperandRange",
124+
/*methodName=*/"getInits",
125+
/*args=*/(ins),
126+
/*methodBody=*/"",
127+
/*defaultImplementation=*/[{
128+
return ::mlir::OperandRange($_op->operand_end(), $_op->operand_end());
129+
}]
130+
>,
131+
InterfaceMethod<[{
132+
Return the region "iter_args" (block arguments) that correspond to the
133+
"init" operands. If the op has multiple regions, return the
134+
corresponding block arguments of the entry region.
135+
}],
136+
/*retTy=*/"::mlir::Block::BlockArgListType",
137+
/*methodName=*/"getRegionIterArgs",
138+
/*args=*/(ins),
139+
/*methodBody=*/"",
140+
/*defaultImplementation=*/[{
141+
return ::mlir::Block::BlockArgListType();
142+
}]
143+
>,
119144
];
120145

121146
let extraClassDeclaration = [{

mlir/lib/Conversion/AffineToStandard/AffineToStandard.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ class AffineForLowering : public OpRewritePattern<AffineForOp> {
158158
Value upperBound = lowerAffineUpperBound(op, rewriter);
159159
Value step = rewriter.create<arith::ConstantIndexOp>(loc, op.getStep());
160160
auto scfForOp = rewriter.create<scf::ForOp>(loc, lowerBound, upperBound,
161-
step, op.getIterOperands());
161+
step, op.getInits());
162162
rewriter.eraseBlock(scfForOp.getBody());
163163
rewriter.inlineRegionBefore(op.getRegion(), scfForOp.getRegion(),
164164
scfForOp.getRegion().end());

mlir/lib/Dialect/Affine/IR/AffineOps.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -2209,7 +2209,7 @@ void AffineForOp::print(OpAsmPrinter &p) {
22092209
if (getNumIterOperands() > 0) {
22102210
p << " iter_args(";
22112211
auto regionArgs = getRegionIterArgs();
2212-
auto operands = getIterOperands();
2212+
auto operands = getInits();
22132213

22142214
llvm::interleaveComma(llvm::zip(regionArgs, operands), p, [&](auto it) {
22152215
p << std::get<0>(it) << " = " << std::get<1>(it);
@@ -2331,7 +2331,7 @@ struct AffineForEmptyLoopFolder : public OpRewritePattern<AffineForOp> {
23312331
if (tripCount && *tripCount == 0) {
23322332
// The initial values of the iteration arguments would be the op's
23332333
// results.
2334-
rewriter.replaceOp(forOp, forOp.getIterOperands());
2334+
rewriter.replaceOp(forOp, forOp.getInits());
23352335
return success();
23362336
}
23372337
SmallVector<Value, 4> replacements;
@@ -2352,7 +2352,7 @@ struct AffineForEmptyLoopFolder : public OpRewritePattern<AffineForOp> {
23522352
unsigned pos = std::distance(iterArgs.begin(), iterArgIt);
23532353
if (pos != i)
23542354
iterArgsNotInOrder = true;
2355-
replacements.push_back(forOp.getIterOperands()[pos]);
2355+
replacements.push_back(forOp.getInits()[pos]);
23562356
}
23572357
}
23582358
// Bail out when the trip count is unknown and the loop returns any value
@@ -2384,7 +2384,7 @@ OperandRange AffineForOp::getEntrySuccessorOperands(RegionBranchPoint point) {
23842384

23852385
// The initial operands map to the loop arguments after the induction
23862386
// variable or are forwarded to the results when the trip count is zero.
2387-
return getIterOperands();
2387+
return getInits();
23882388
}
23892389

23902390
/// Given the region at `index`, or the parent operation if `index` is None,
@@ -2440,7 +2440,7 @@ LogicalResult AffineForOp::fold(FoldAdaptor adaptor,
24402440
// does not return any results. Since ops that do not return results cannot
24412441
// be folded away, we would enter an infinite loop of folds on the same
24422442
// affine.for op.
2443-
results.assign(getIterOperands().begin(), getIterOperands().end());
2443+
results.assign(getInits().begin(), getInits().end());
24442444
folded = true;
24452445
}
24462446
return success(folded);
@@ -2466,7 +2466,7 @@ void AffineForOp::setLowerBound(ValueRange lbOperands, AffineMap map) {
24662466

24672467
auto ubOperands = getUpperBoundOperands();
24682468
newOperands.append(ubOperands.begin(), ubOperands.end());
2469-
auto iterOperands = getIterOperands();
2469+
auto iterOperands = getInits();
24702470
newOperands.append(iterOperands.begin(), iterOperands.end());
24712471
(*this)->setOperands(newOperands);
24722472

@@ -2479,7 +2479,7 @@ void AffineForOp::setUpperBound(ValueRange ubOperands, AffineMap map) {
24792479

24802480
SmallVector<Value, 4> newOperands(getLowerBoundOperands());
24812481
newOperands.append(ubOperands.begin(), ubOperands.end());
2482-
auto iterOperands = getIterOperands();
2482+
auto iterOperands = getInits();
24832483
newOperands.append(iterOperands.begin(), iterOperands.end());
24842484
(*this)->setOperands(newOperands);
24852485

@@ -2745,7 +2745,7 @@ AffineForOp mlir::affine::replaceForOpWithNewYields(OpBuilder &b,
27452745
// Create a new loop before the existing one, with the extra operands.
27462746
OpBuilder::InsertionGuard g(b);
27472747
b.setInsertionPoint(loop);
2748-
auto operands = llvm::to_vector<4>(loop.getIterOperands());
2748+
auto operands = llvm::to_vector<4>(loop.getInits());
27492749
operands.append(newIterOperands.begin(), newIterOperands.end());
27502750
SmallVector<Value, 4> lbOperands(loop.getLowerBoundOperands());
27512751
SmallVector<Value, 4> ubOperands(loop.getUpperBoundOperands());

mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -1315,13 +1315,13 @@ static Operation *vectorizeAffineForOp(AffineForOp forOp,
13151315
// Vectorize 'iter_args'.
13161316
SmallVector<Value, 8> vecIterOperands;
13171317
if (!isLoopVecDim) {
1318-
for (auto operand : forOp.getIterOperands())
1318+
for (auto operand : forOp.getInits())
13191319
vecIterOperands.push_back(vectorizeOperand(operand, state));
13201320
} else {
13211321
// For reduction loops we need to pass a vector of neutral elements as an
13221322
// initial value of the accumulator. We will add the original initial value
13231323
// later.
1324-
for (auto redAndOperand : llvm::zip(reductions, forOp.getIterOperands())) {
1324+
for (auto redAndOperand : llvm::zip(reductions, forOp.getInits())) {
13251325
vecIterOperands.push_back(createInitialVector(
13261326
std::get<0>(redAndOperand).kind, std::get<1>(redAndOperand), state));
13271327
}
@@ -1450,7 +1450,7 @@ static Operation *vectorizeAffineYieldOp(AffineYieldOp yieldOp,
14501450
assert(reducedVal && "expect non-null value for parallel reduction loop");
14511451
assert(combinerOps.size() == 1 && "expect only one combiner op");
14521452
// IterOperands are neutral element vectors.
1453-
Value neutralVal = cast<AffineForOp>(newParentOp).getIterOperands()[i];
1453+
Value neutralVal = cast<AffineForOp>(newParentOp).getInits()[i];
14541454
state.builder.setInsertionPoint(combinerOps.back());
14551455
Value maskedReducedVal = state.builder.create<arith::SelectOp>(
14561456
reducedVal.getLoc(), mask, reducedVal, neutralVal);

mlir/lib/Dialect/Affine/Utils/LoopFusionUtils.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ static LogicalResult promoteSingleIterReductionLoop(AffineForOp forOp,
361361
std::optional<uint64_t> tripCount = getConstantTripCount(forOp);
362362
if (!tripCount || *tripCount != 1)
363363
return failure();
364-
auto iterOperands = forOp.getIterOperands();
364+
auto iterOperands = forOp.getInits();
365365
auto *parentOp = forOp->getParentOp();
366366
if (!isa<AffineForOp>(parentOp))
367367
return failure();

mlir/lib/Dialect/Affine/Utils/LoopUtils.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ getCleanupLoopLowerBound(AffineForOp forOp, unsigned unrollFactor,
114114
/// yield values while promoting single iteration affine.for ops.
115115
static void replaceIterArgsAndYieldResults(AffineForOp forOp) {
116116
// Replace uses of iter arguments with iter operands (initial values).
117-
auto iterOperands = forOp.getIterOperands();
117+
auto iterOperands = forOp.getInits();
118118
auto iterArgs = forOp.getRegionIterArgs();
119119
for (auto e : llvm::zip(iterOperands, iterArgs))
120120
std::get<1>(e).replaceAllUsesWith(std::get<0>(e));
@@ -987,7 +987,7 @@ static LogicalResult generateCleanupLoopForUnroll(AffineForOp forOp,
987987
// and produce results for the original users of `forOp` results.
988988
auto results = forOp.getResults();
989989
auto cleanupResults = cleanupForOp.getResults();
990-
auto cleanupIterOperands = cleanupForOp.getIterOperands();
990+
auto cleanupIterOperands = cleanupForOp.getInits();
991991

992992
for (auto e : llvm::zip(results, cleanupResults, cleanupIterOperands)) {
993993
std::get<0>(e).replaceAllUsesWith(std::get<1>(e));
@@ -1200,7 +1200,7 @@ LogicalResult mlir::affine::loopUnrollJamByFactor(AffineForOp forOp,
12001200
OpBuilder builder(forOp.getContext());
12011201
for (AffineForOp oldForOp : loopsWithIterArgs) {
12021202
SmallVector<Value, 4> dupIterOperands, dupIterArgs, dupYieldOperands;
1203-
ValueRange oldIterOperands = oldForOp.getIterOperands();
1203+
ValueRange oldIterOperands = oldForOp.getInits();
12041204
ValueRange oldIterArgs = oldForOp.getRegionIterArgs();
12051205
ValueRange oldYieldOperands =
12061206
cast<AffineYieldOp>(oldForOp.getBody()->getTerminator()).getOperands();

mlir/lib/Dialect/Affine/Utils/Utils.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ mlir::affine::affineParallelize(AffineForOp forOp,
377377
SmallVector<Value> newResults;
378378
newResults.reserve(numReductions);
379379
for (unsigned i = 0; i < numReductions; ++i) {
380-
Value init = forOp.getIterOperands()[i];
380+
Value init = forOp.getInits()[i];
381381
// This works because we are only handling single-op reductions at the
382382
// moment. A switch on reduction kind or a mechanism to collect operations
383383
// participating in the reduction will be necessary for multi-op reductions.

mlir/lib/Dialect/SCF/IR/SCF.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,8 @@ ParseResult ForOp::parse(OpAsmParser &parser, OperationState &result) {
532532

533533
SmallVector<Region *> ForOp::getLoopRegions() { return {&getRegion()}; }
534534

535+
OperandRange ForOp::getInits() { return getInitArgs(); }
536+
535537
ForOp mlir::scf::getForInductionVarOwner(Value val) {
536538
auto ivArg = llvm::dyn_cast<BlockArgument>(val);
537539
if (!ivArg)
@@ -3183,6 +3185,10 @@ Block::BlockArgListType WhileOp::getAfterArguments() {
31833185
return getAfterBody()->getArguments();
31843186
}
31853187

3188+
Block::BlockArgListType WhileOp::getRegionIterArgs() {
3189+
return getBeforeArguments();
3190+
}
3191+
31863192
void WhileOp::getSuccessorRegions(RegionBranchPoint point,
31873193
SmallVectorImpl<RegionSuccessor> &regions) {
31883194
// The parent op always branches to the condition region.

mlir/lib/Interfaces/LoopLikeInterface.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "mlir/Interfaces/LoopLikeInterface.h"
10+
1011
#include "mlir/Interfaces/FunctionInterfaces.h"
1112
#include "llvm/ADT/DenseSet.h"
1213

0 commit comments

Comments
 (0)