Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mlir][Interfaces] LoopLikeOpInterface: Add helpers to get region iter_args and inits #66925

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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