Many ops with this trait have `getBody()` and `getBodyBuilder()` methods defined in `extraClassDeclaration` in tablegen. `getBody()` implementation is the same accross all these ops, but `getBodyBuilder()` can return builders with varying insertion points set. In this PR, `getBody()` is moved into `SingleImplicitBlockTerminator` struct and `getBodyBuilder()` is replaced with `OpBuilder::atBlock(End|Terminator)(op.getBody);`.
Differential Revision: https://reviews.llvm.org/D78864
/// Does loop set (and return) the final value of the control variable?
bool hasLastValue() { return lastVal().size(); }
- /// Get the body of the loop
- mlir::Block *getBody() { return ®ion().front(); }
-
/// Get the block argument corresponding to the loop control value (PHI)
mlir::Value getInductionVar() { return getBody()->getArgument(0); }
- /// Get a builder to insert operations into the LoopOp
- mlir::OpBuilder getBodyBuilder() {
- return mlir::OpBuilder(getBody(), std::prev(getBody()->end()));
- }
-
void setLowerBound(mlir::Value bound) {
getOperation()->setOperand(0, bound);
}
static StringRef getLowerBoundAttrName() { return "lower_bound"; }
static StringRef getUpperBoundAttrName() { return "upper_bound"; }
- Block *getBody() { return ®ion().front(); }
Value getInductionVar() { return getBody()->getArgument(0); }
- OpBuilder getBodyBuilder() {
- return OpBuilder(getBody(), std::prev(getBody()->end()));
- }
// TODO: provide iterators for the lower and upper bound operands
// if the current access via getLowerBound(), getUpperBound() is too slow.
];
let extraClassDeclaration = [{
- Block *getBody() { return ®ion().front(); }
Value getInductionVar() { return getBody()->getArgument(0); }
- OpBuilder getBodyBuilder() {
- return OpBuilder(getBody(), std::prev(getBody()->end()));
- }
Block::BlockArgListType getRegionIterArgs() {
return getBody()->getArguments().drop_front();
}
let extraClassDeclaration = [{
OpBuilder getThenBodyBuilder() {
- assert(!thenRegion().empty() && "Unexpected empty 'then' region.");
- Block &body = thenRegion().front();
- return OpBuilder(&body,
- results().empty() ? std::prev(body.end()) : body.end());
+ Block* body = getBody(0);
+ return results().empty() ? OpBuilder::atBlockTerminator(body)
+ : OpBuilder::atBlockEnd(body);
}
OpBuilder getElseBodyBuilder() {
- assert(!elseRegion().empty() && "Unexpected empty 'else' region.");
- Block &body = elseRegion().front();
- return OpBuilder(&body,
- results().empty() ? std::prev(body.end()) : body.end());
+ Block* body = getBody(1);
+ return results().empty() ? OpBuilder::atBlockTerminator(body)
+ : OpBuilder::atBlockEnd(body);
}
}];
}
];
let extraClassDeclaration = [{
- Block *getBody() { return ®ion().front(); }
ValueRange getInductionVars() {
return getBody()->getArguments();
}
];
let extraClassDeclaration = [{
- OpBuilder getBodyBuilder() {
- assert(!body().empty() && "Unexpected empty 'body' region.");
- Block &block = body().front();
- return OpBuilder(&block, block.end());
- }
// The value stored in memref[ivs].
Value getCurrentValue() {
return body().front().getArgument(0);
}
/// Create a builder and set the insertion point to before the first operation
- /// in the block but still inside th block.
+ /// in the block but still inside the block.
static OpBuilder atBlockBegin(Block *block) {
return OpBuilder(block, block->begin());
}
return OpBuilder(block, block->end());
}
+ /// Create a builder and set the insertion point to before the block
+ /// terminator.
+ static OpBuilder atBlockTerminator(Block *block) {
+ auto *terminator = block->getTerminator();
+ assert(terminator != nullptr && "the block has no terminator");
+ return OpBuilder(block, terminator->getIterator());
+ }
+
/// This class represents a saved insertion point.
class InsertPoint {
public:
OpTy::build(this, state, std::forward<Args>(args)...);
auto *op = createOperation(state);
auto result = dyn_cast<OpTy>(op);
- assert(result && "Builder didn't return the right type");
+ assert(result && "builder didn't return the right type");
return result;
}
::mlir::impl::template ensureRegionTerminator<TerminatorOpType>(
region, builder, loc);
}
+
+ Block *getBody(unsigned idx = 0) {
+ Region ®ion = this->getOperation()->getRegion(idx);
+ assert(!region.empty() && "unexpected empty region");
+ return ®ion.front();
+ }
};
};
BlockAndValueMapping operandMap;
- OpBuilder bodyBuilder = loopChunk.getBodyBuilder();
+ auto bodyBuilder = OpBuilder::atBlockTerminator(loopChunk.getBody());
for (auto it = opGroupQueue.begin() + offset, e = opGroupQueue.end(); it != e;
++it) {
uint64_t shift = it->first;
// Builder to insert unrolled bodies just before the terminator of the body of
// 'forOp'.
- OpBuilder builder = forOp.getBodyBuilder();
+ auto builder = OpBuilder::atBlockTerminator(forOp.getBody());
// Keep a pointer to the last non-terminator operation in the original block
// so that we know what to clone (since we are doing this in-place).
SmallVector<AffineForOp, 8> innerLoops;
for (auto t : targets) {
// Insert newForOp before the terminator of `t`.
- OpBuilder b = t.getBodyBuilder();
+ auto b = OpBuilder::atBlockTerminator(t.getBody());
auto newForOp = b.create<AffineForOp>(t.getLoc(), lbOperands, lbMap,
ubOperands, ubMap, originalStep);
auto begin = t.getBody()->begin();
auto nOps = t.getBody()->getOperations().size();
// Insert newForOp before the terminator of `t`.
- OpBuilder b(t.getBodyBuilder());
+ auto b = OpBuilder::atBlockTerminator((t.getBody()));
Value stepped = b.create<AddIOp>(t.getLoc(), iv, forOp.step());
Value less = b.create<CmpIOp>(t.getLoc(), CmpIPredicate::slt,
forOp.upperBound(), stepped);
if (d == 0)
copyNestRoot = forOp;
- b = forOp.getBodyBuilder();
+ b = OpBuilder::atBlockTerminator(forOp.getBody());
auto fastBufOffsetMap =
AffineMap::get(lbOperands.size(), 0, fastBufOffsets[d]);
AffineForOp fullTileLoop = createCanonicalizedAffineForOp(
b, loop.getLoc(), lbVmap.getOperands(), lbVmap.getAffineMap(),
ubVmap.getOperands(), ubVmap.getAffineMap());
- b = fullTileLoop.getBodyBuilder();
+ b = OpBuilder::atBlockTerminator(fullTileLoop.getBody());
fullTileLoops.push_back(fullTileLoop);
}
for (auto loopEn : llvm::enumerate(inputNest))
operandMap.map(loopEn.value().getInductionVar(),
fullTileLoops[loopEn.index()].getInductionVar());
- b = fullTileLoops.back().getBodyBuilder();
+ b = OpBuilder::atBlockTerminator(fullTileLoops.back().getBody());
for (auto &op : inputNest.back().getBody()->without_terminator())
b.clone(op, operandMap);
return success();