Skip to content

Commit 23b794f

Browse files
[mlir][Affine][NFC] Define AffineForOp operands in ODS (#67694)
Modernize affine dialect ops: Define LB, UB, step and inits as operands in TableGen.
1 parent 1e00423 commit 23b794f

File tree

12 files changed

+122
-164
lines changed

12 files changed

+122
-164
lines changed

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

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -499,27 +499,28 @@ class AffineBound {
499499
AffineForOp getAffineForOp() { return op; }
500500
AffineMap getMap() { return map; }
501501

502-
unsigned getNumOperands() { return opEnd - opStart; }
503-
Value getOperand(unsigned idx) { return op.getOperand(opStart + idx); }
502+
unsigned getNumOperands() { return operands.size(); }
503+
Value getOperand(unsigned idx) {
504+
return op.getOperand(operands.getBeginOperandIndex() + idx);
505+
}
504506

505507
using operand_iterator = AffineForOp::operand_iterator;
506508
using operand_range = AffineForOp::operand_range;
507509

508-
operand_iterator operandBegin() { return op.operand_begin() + opStart; }
509-
operand_iterator operandEnd() { return op.operand_begin() + opEnd; }
510+
operand_iterator operandBegin() { return operands.begin(); }
511+
operand_iterator operandEnd() { return operands.end(); }
510512
operand_range getOperands() { return {operandBegin(), operandEnd()}; }
511513

512514
private:
513515
// 'affine.for' operation that contains this bound.
514516
AffineForOp op;
515-
// Start and end positions of this affine bound operands in the list of
516-
// the containing 'affine.for' operation operands.
517-
unsigned opStart, opEnd;
517+
// Operands of the affine map.
518+
OperandRange operands;
518519
// Affine map for this bound.
519520
AffineMap map;
520521

521-
AffineBound(AffineForOp op, unsigned opStart, unsigned opEnd, AffineMap map)
522-
: op(op), opStart(opStart), opEnd(opEnd), map(map) {}
522+
AffineBound(AffineForOp op, OperandRange operands, AffineMap map)
523+
: op(op), operands(operands), map(map) {}
523524

524525
friend class AffineForOp;
525526
};

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

Lines changed: 14 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ def AffineApplyOp : Affine_Op<"apply", [Pure]> {
117117
}
118118

119119
def AffineForOp : Affine_Op<"for",
120-
[AutomaticAllocationScope, ImplicitAffineTerminator, ConditionallySpeculatable,
120+
[AttrSizedOperandSegments, AutomaticAllocationScope,
121+
ImplicitAffineTerminator, ConditionallySpeculatable,
121122
RecursiveMemoryEffects, DeclareOpInterfaceMethods<LoopLikeOpInterface,
122123
["getSingleInductionVar", "getSingleLowerBound", "getSingleStep",
123124
"getSingleUpperBound", "replaceWithAdditionalYields"]>,
@@ -147,7 +148,7 @@ def AffineForOp : Affine_Op<"for",
147148
from a lower bound to an upper bound by a stride. The stride, represented by
148149
`step`, is a positive constant integer which defaults to "1" if not present.
149150
The lower and upper bounds specify a half-open range: the range includes the
150-
lower bound but does not include the upper bound.
151+
lower bound but does not include the upper bound.
151152

152153
The lower and upper bounds of a `affine.for` operation are represented as an
153154
application of an affine mapping to a list of SSA values passed to the map.
@@ -229,7 +230,12 @@ def AffineForOp : Affine_Op<"for",
229230
explicitly present. The number and types of the "affine.for" results must
230231
match the initial values in the `iter_args` binding and the yield operands.
231232
}];
232-
let arguments = (ins Variadic<AnyType>);
233+
let arguments = (ins Variadic<Index>:$lowerBoundOperands,
234+
Variadic<Index>:$upperBoundOperands,
235+
Variadic<AnyType>:$inits,
236+
AffineMapAttr:$lowerBoundMap,
237+
AffineMapAttr:$upperBoundMap,
238+
IndexAttr:$step);
233239
let results = (outs Variadic<AnyType>:$results);
234240
let regions = (region SizedRegion<1>:$region);
235241

@@ -251,26 +257,10 @@ def AffineForOp : Affine_Op<"for",
251257
using BodyBuilderFn =
252258
function_ref<void(OpBuilder &, Location, Value, ValueRange)>;
253259

254-
static StringRef getStepAttrStrName() { return "step"; }
255-
static StringRef getLowerBoundAttrStrName() { return "lower_bound"; }
256-
static StringRef getUpperBoundAttrStrName() { return "upper_bound"; }
257-
258260
BlockArgument getInductionVar() { return getBody()->getArgument(0); }
259261
Block::BlockArgListType getRegionIterArgs() {
260262
return getBody()->getArguments().drop_front();
261263
}
262-
Operation::operand_range getInits() {
263-
return getOperands().drop_front(getNumControlOperands());
264-
}
265-
266-
// TODO: provide iterators for the lower and upper bound operands
267-
// if the current access via getLowerBound(), getUpperBound() is too slow.
268-
269-
/// Returns operands for the lower bound map.
270-
operand_range getLowerBoundOperands();
271-
272-
/// Returns operands for the upper bound map.
273-
operand_range getUpperBoundOperands();
274264

275265
/// Returns operands for the lower and upper bound maps with the operands
276266
/// for the lower bound map in front of those for the upper bound map.
@@ -283,20 +273,7 @@ def AffineForOp : Affine_Op<"for",
283273
AffineBound getUpperBound();
284274

285275
/// Returns loop step.
286-
int64_t getStep() {
287-
return ::llvm::cast<IntegerAttr>(*(*this)->getInherentAttr(getStepAttrStrName())).getInt();
288-
}
289-
290-
/// Returns affine map for the lower bound.
291-
AffineMap getLowerBoundMap() { return getLowerBoundMapAttr().getValue(); }
292-
AffineMapAttr getLowerBoundMapAttr() {
293-
return ::llvm::cast<AffineMapAttr>(*(*this)->getInherentAttr(getLowerBoundAttrStrName()));
294-
}
295-
/// Returns affine map for the upper bound. The upper bound is exclusive.
296-
AffineMap getUpperBoundMap() { return getUpperBoundMapAttr().getValue(); }
297-
AffineMapAttr getUpperBoundMapAttr() {
298-
return ::llvm::cast<AffineMapAttr>(*(*this)->getInherentAttr(getUpperBoundAttrStrName()));
299-
}
276+
int64_t getStepAsInt() { return getStep().getSExtValue(); }
300277

301278
/// Set lower bound. The new bound must have the same number of operands as
302279
/// the current bound map. Otherwise, 'replaceForLowerBound' should be used.
@@ -305,18 +282,10 @@ def AffineForOp : Affine_Op<"for",
305282
/// current bound map. Otherwise, 'replaceForUpperBound' should be used.
306283
void setUpperBound(ValueRange operands, AffineMap map);
307284

308-
/// Set the lower bound map without changing operands.
309-
void setLowerBoundMap(AffineMap map);
310-
311-
/// Set the upper bound map without changing operands.
312-
void setUpperBoundMap(AffineMap map);
313-
314285
/// Set loop step.
315286
void setStep(int64_t step) {
316287
assert(step > 0 && "step has to be a positive integer constant");
317-
auto *context = getLowerBoundMap().getContext();
318-
(*this)->setAttr(StringAttr::get(context, getStepAttrStrName()),
319-
IntegerAttr::get(IndexType::get(context), step));
288+
setStep(APInt(/*numBits=*/64, step, /*isSigned=*/true));
320289
}
321290

322291
/// Returns number of region arguments for loop-carried values.
@@ -325,7 +294,9 @@ def AffineForOp : Affine_Op<"for",
325294
}
326295

327296
/// Number of operands controlling the loop: lb and ub.
328-
unsigned getNumControlOperands() { return getOperation()->getNumOperands() - getNumIterOperands(); }
297+
unsigned getNumControlOperands() {
298+
return getOperation()->getNumOperands() - getNumIterOperands();
299+
}
329300

330301
/// Get the number of loop-carried values.
331302
unsigned getNumIterOperands();

mlir/lib/Conversion/AffineToStandard/AffineToStandard.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ class AffineForLowering : public OpRewritePattern<AffineForOp> {
156156
Location loc = op.getLoc();
157157
Value lowerBound = lowerAffineLowerBound(op, rewriter);
158158
Value upperBound = lowerAffineUpperBound(op, rewriter);
159-
Value step = rewriter.create<arith::ConstantIndexOp>(loc, op.getStep());
159+
Value step =
160+
rewriter.create<arith::ConstantIndexOp>(loc, op.getStepAsInt());
160161
auto scfForOp = rewriter.create<scf::ForOp>(loc, lowerBound, upperBound,
161162
step, op.getInits());
162163
rewriter.eraseBlock(scfForOp.getBody());

mlir/lib/Conversion/SCFToGPU/SCFToGPU.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static Operation::operand_range getUpperBoundOperands(AffineForOp forOp) {
8686
// materialize a corresponding constant using builder.
8787
static Value getOrCreateStep(AffineForOp forOp, OpBuilder &builder) {
8888
return builder.create<arith::ConstantIndexOp>(forOp.getLoc(),
89-
forOp.getStep());
89+
forOp.getStepAsInt());
9090
}
9191

9292
// Get a Value for the loop lower bound. If the value requires computation,

mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ FlatAffineValueConstraints::addAffineForOpDomain(AffineForOp forOp) {
7474
return failure();
7575
}
7676

77-
int64_t step = forOp.getStep();
77+
int64_t step = forOp.getStepAsInt();
7878
if (step != 1) {
7979
if (!forOp.hasConstantLowerBound())
8080
LLVM_DEBUG(forOp.emitWarning("domain conservatively approximated"));

mlir/lib/Dialect/Affine/Analysis/LoopAnalysis.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ void mlir::affine::getTripCountMapAndOperands(
3939
AffineForOp forOp, AffineMap *tripCountMap,
4040
SmallVectorImpl<Value> *tripCountOperands) {
4141
MLIRContext *context = forOp.getContext();
42-
int64_t step = forOp.getStep();
42+
int64_t step = forOp.getStepAsInt();
4343
int64_t loopSpan;
4444
if (forOp.hasConstantBounds()) {
4545
int64_t lb = forOp.getConstantLowerBound();

0 commit comments

Comments
 (0)