Skip to content

Commit

Permalink
[mlir][Interfaces] LoopLikeOpInterface: Add helpers to get region i…
Browse files Browse the repository at this point in the history
…ter_args and inits (#66925)

`AffineForOp::getInitOperands` is renamed to `getInits` to be consistent
with MLIR operand getter naming conventions. ("get" + operand name)
  • Loading branch information
matthias-springer authored Sep 21, 2023
1 parent 604a231 commit 3bd7a9b
Show file tree
Hide file tree
Showing 11 changed files with 53 additions and 21 deletions.
2 changes: 1 addition & 1 deletion mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def AffineForOp : Affine_Op<"for",
Block::BlockArgListType getRegionIterArgs() {
return getBody()->getArguments().drop_front();
}
Operation::operand_range getIterOperands() {
Operation::operand_range getInits() {
return getOperands().drop_front(getNumControlOperands());
}

Expand Down
6 changes: 3 additions & 3 deletions mlir/include/mlir/Dialect/SCF/IR/SCFOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ def ExecuteRegionOp : SCF_Op<"execute_region", [

def ForOp : SCF_Op<"for",
[AutomaticAllocationScope, DeclareOpInterfaceMethods<LoopLikeOpInterface,
["getSingleInductionVar", "getSingleLowerBound", "getSingleStep",
"getSingleUpperBound", "promoteIfSingleIteration"]>,
["getInits", "getSingleInductionVar", "getSingleLowerBound",
"getSingleStep", "getSingleUpperBound", "promoteIfSingleIteration"]>,
AllTypesMatch<["lowerBound", "upperBound", "step"]>,
ConditionallySpeculatable,
DeclareOpInterfaceMethods<RegionBranchOpInterface,
Expand Down Expand Up @@ -948,7 +948,7 @@ def ReduceReturnOp :
def WhileOp : SCF_Op<"while",
[DeclareOpInterfaceMethods<RegionBranchOpInterface,
["getEntrySuccessorOperands"]>,
DeclareOpInterfaceMethods<LoopLikeOpInterface>,
DeclareOpInterfaceMethods<LoopLikeOpInterface, ["getRegionIterArgs"]>,
RecursiveMemoryEffects, SingleBlock]> {
let summary = "a generic 'while' loop";
let description = [{
Expand Down
25 changes: 25 additions & 0 deletions mlir/include/mlir/Interfaces/LoopLikeInterface.td
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,31 @@ def LoopLikeOpInterface : OpInterface<"LoopLikeOpInterface"> {
return std::nullopt;
}]
>,
InterfaceMethod<[{
Return the "init" operands that are used as initialization values for
the region "iter_args" of this loop.
}],
/*retTy=*/"::mlir::OperandRange",
/*methodName=*/"getInits",
/*args=*/(ins),
/*methodBody=*/"",
/*defaultImplementation=*/[{
return ::mlir::OperandRange($_op->operand_end(), $_op->operand_end());
}]
>,
InterfaceMethod<[{
Return the region "iter_args" (block arguments) that correspond to the
"init" operands. If the op has multiple regions, return the
corresponding block arguments of the entry region.
}],
/*retTy=*/"::mlir::Block::BlockArgListType",
/*methodName=*/"getRegionIterArgs",
/*args=*/(ins),
/*methodBody=*/"",
/*defaultImplementation=*/[{
return ::mlir::Block::BlockArgListType();
}]
>,
];

let extraClassDeclaration = [{
Expand Down
2 changes: 1 addition & 1 deletion mlir/lib/Conversion/AffineToStandard/AffineToStandard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ class AffineForLowering : public OpRewritePattern<AffineForOp> {
Value upperBound = lowerAffineUpperBound(op, rewriter);
Value step = rewriter.create<arith::ConstantIndexOp>(loc, op.getStep());
auto scfForOp = rewriter.create<scf::ForOp>(loc, lowerBound, upperBound,
step, op.getIterOperands());
step, op.getInits());
rewriter.eraseBlock(scfForOp.getBody());
rewriter.inlineRegionBefore(op.getRegion(), scfForOp.getRegion(),
scfForOp.getRegion().end());
Expand Down
16 changes: 8 additions & 8 deletions mlir/lib/Dialect/Affine/IR/AffineOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2209,7 +2209,7 @@ void AffineForOp::print(OpAsmPrinter &p) {
if (getNumIterOperands() > 0) {
p << " iter_args(";
auto regionArgs = getRegionIterArgs();
auto operands = getIterOperands();
auto operands = getInits();

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

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

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

auto ubOperands = getUpperBoundOperands();
newOperands.append(ubOperands.begin(), ubOperands.end());
auto iterOperands = getIterOperands();
auto iterOperands = getInits();
newOperands.append(iterOperands.begin(), iterOperands.end());
(*this)->setOperands(newOperands);

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

SmallVector<Value, 4> newOperands(getLowerBoundOperands());
newOperands.append(ubOperands.begin(), ubOperands.end());
auto iterOperands = getIterOperands();
auto iterOperands = getInits();
newOperands.append(iterOperands.begin(), iterOperands.end());
(*this)->setOperands(newOperands);

Expand Down Expand Up @@ -2745,7 +2745,7 @@ AffineForOp mlir::affine::replaceForOpWithNewYields(OpBuilder &b,
// Create a new loop before the existing one, with the extra operands.
OpBuilder::InsertionGuard g(b);
b.setInsertionPoint(loop);
auto operands = llvm::to_vector<4>(loop.getIterOperands());
auto operands = llvm::to_vector<4>(loop.getInits());
operands.append(newIterOperands.begin(), newIterOperands.end());
SmallVector<Value, 4> lbOperands(loop.getLowerBoundOperands());
SmallVector<Value, 4> ubOperands(loop.getUpperBoundOperands());
Expand Down
6 changes: 3 additions & 3 deletions mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1315,13 +1315,13 @@ static Operation *vectorizeAffineForOp(AffineForOp forOp,
// Vectorize 'iter_args'.
SmallVector<Value, 8> vecIterOperands;
if (!isLoopVecDim) {
for (auto operand : forOp.getIterOperands())
for (auto operand : forOp.getInits())
vecIterOperands.push_back(vectorizeOperand(operand, state));
} else {
// For reduction loops we need to pass a vector of neutral elements as an
// initial value of the accumulator. We will add the original initial value
// later.
for (auto redAndOperand : llvm::zip(reductions, forOp.getIterOperands())) {
for (auto redAndOperand : llvm::zip(reductions, forOp.getInits())) {
vecIterOperands.push_back(createInitialVector(
std::get<0>(redAndOperand).kind, std::get<1>(redAndOperand), state));
}
Expand Down Expand Up @@ -1450,7 +1450,7 @@ static Operation *vectorizeAffineYieldOp(AffineYieldOp yieldOp,
assert(reducedVal && "expect non-null value for parallel reduction loop");
assert(combinerOps.size() == 1 && "expect only one combiner op");
// IterOperands are neutral element vectors.
Value neutralVal = cast<AffineForOp>(newParentOp).getIterOperands()[i];
Value neutralVal = cast<AffineForOp>(newParentOp).getInits()[i];
state.builder.setInsertionPoint(combinerOps.back());
Value maskedReducedVal = state.builder.create<arith::SelectOp>(
reducedVal.getLoc(), mask, reducedVal, neutralVal);
Expand Down
2 changes: 1 addition & 1 deletion mlir/lib/Dialect/Affine/Utils/LoopFusionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ static LogicalResult promoteSingleIterReductionLoop(AffineForOp forOp,
std::optional<uint64_t> tripCount = getConstantTripCount(forOp);
if (!tripCount || *tripCount != 1)
return failure();
auto iterOperands = forOp.getIterOperands();
auto iterOperands = forOp.getInits();
auto *parentOp = forOp->getParentOp();
if (!isa<AffineForOp>(parentOp))
return failure();
Expand Down
6 changes: 3 additions & 3 deletions mlir/lib/Dialect/Affine/Utils/LoopUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ getCleanupLoopLowerBound(AffineForOp forOp, unsigned unrollFactor,
/// yield values while promoting single iteration affine.for ops.
static void replaceIterArgsAndYieldResults(AffineForOp forOp) {
// Replace uses of iter arguments with iter operands (initial values).
auto iterOperands = forOp.getIterOperands();
auto iterOperands = forOp.getInits();
auto iterArgs = forOp.getRegionIterArgs();
for (auto e : llvm::zip(iterOperands, iterArgs))
std::get<1>(e).replaceAllUsesWith(std::get<0>(e));
Expand Down Expand Up @@ -987,7 +987,7 @@ static LogicalResult generateCleanupLoopForUnroll(AffineForOp forOp,
// and produce results for the original users of `forOp` results.
auto results = forOp.getResults();
auto cleanupResults = cleanupForOp.getResults();
auto cleanupIterOperands = cleanupForOp.getIterOperands();
auto cleanupIterOperands = cleanupForOp.getInits();

for (auto e : llvm::zip(results, cleanupResults, cleanupIterOperands)) {
std::get<0>(e).replaceAllUsesWith(std::get<1>(e));
Expand Down Expand Up @@ -1200,7 +1200,7 @@ LogicalResult mlir::affine::loopUnrollJamByFactor(AffineForOp forOp,
OpBuilder builder(forOp.getContext());
for (AffineForOp oldForOp : loopsWithIterArgs) {
SmallVector<Value, 4> dupIterOperands, dupIterArgs, dupYieldOperands;
ValueRange oldIterOperands = oldForOp.getIterOperands();
ValueRange oldIterOperands = oldForOp.getInits();
ValueRange oldIterArgs = oldForOp.getRegionIterArgs();
ValueRange oldYieldOperands =
cast<AffineYieldOp>(oldForOp.getBody()->getTerminator()).getOperands();
Expand Down
2 changes: 1 addition & 1 deletion mlir/lib/Dialect/Affine/Utils/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ mlir::affine::affineParallelize(AffineForOp forOp,
SmallVector<Value> newResults;
newResults.reserve(numReductions);
for (unsigned i = 0; i < numReductions; ++i) {
Value init = forOp.getIterOperands()[i];
Value init = forOp.getInits()[i];
// This works because we are only handling single-op reductions at the
// moment. A switch on reduction kind or a mechanism to collect operations
// participating in the reduction will be necessary for multi-op reductions.
Expand Down
6 changes: 6 additions & 0 deletions mlir/lib/Dialect/SCF/IR/SCF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,8 @@ ParseResult ForOp::parse(OpAsmParser &parser, OperationState &result) {

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

OperandRange ForOp::getInits() { return getInitArgs(); }

ForOp mlir::scf::getForInductionVarOwner(Value val) {
auto ivArg = llvm::dyn_cast<BlockArgument>(val);
if (!ivArg)
Expand Down Expand Up @@ -3183,6 +3185,10 @@ Block::BlockArgListType WhileOp::getAfterArguments() {
return getAfterBody()->getArguments();
}

Block::BlockArgListType WhileOp::getRegionIterArgs() {
return getBeforeArguments();
}

void WhileOp::getSuccessorRegions(RegionBranchPoint point,
SmallVectorImpl<RegionSuccessor> &regions) {
// The parent op always branches to the condition region.
Expand Down
1 change: 1 addition & 0 deletions mlir/lib/Interfaces/LoopLikeInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "mlir/Interfaces/LoopLikeInterface.h"

#include "mlir/Interfaces/FunctionInterfaces.h"
#include "llvm/ADT/DenseSet.h"

Expand Down

0 comments on commit 3bd7a9b

Please sign in to comment.