forked from OSchip/llvm-project
[EDSC] Cleanup declarative builder insertion point with blocks
Declarative builders want to provide the same nesting interface for blocks and loops. MLIR on the other hand has different behaviors: 1. when an AffineForOp is created the insertion point does not enter the loop body; 2. when a Block is created, the insertion point does enter the block body. Guard against the second behavior in EDSC to make the interface unsurprising. This also surfaces two places in the eager branch API where I was guarding against this behavior indirectly by creating a new ScopedContext. Instead, uniformize everything to properly reset the insertion point in the unique place that builds the mlir::Block*. PiperOrigin-RevId: 237619513
This commit is contained in:
parent
497d645337
commit
861eb87471
|
@ -125,8 +125,14 @@ InstructionHandle::create(StringRef name, ArrayRef<ValueHandle> operands,
|
|||
}
|
||||
|
||||
BlockHandle mlir::edsc::BlockHandle::create(ArrayRef<Type> argTypes) {
|
||||
auto *currentB = ScopedContext::getBuilder();
|
||||
auto *ib = currentB->getInsertionBlock();
|
||||
auto ip = currentB->getInsertionPoint();
|
||||
BlockHandle res;
|
||||
res.block = ScopedContext::getBuilder()->createBlock();
|
||||
// createBlock sets the insertion point inside the block.
|
||||
// We do not want this behavior when using declarative builders with nesting.
|
||||
currentB->setInsertionPoint(ib, ip);
|
||||
for (auto t : argTypes) {
|
||||
res.block->addArgument(t);
|
||||
}
|
||||
|
|
|
@ -51,14 +51,7 @@ InstructionHandle mlir::edsc::intrinsics::BR(BlockHandle *bh,
|
|||
ArrayRef<ValueHandle> operands) {
|
||||
assert(!*bh && "Unexpected already captured BlockHandle");
|
||||
enforceEmptyCapturesMatchOperands(captures, operands);
|
||||
{ // Clone the scope explicitly to avoid modifying the insertion point in the
|
||||
// current scope which result in surprising usage.
|
||||
auto *currentB = ScopedContext::getBuilder();
|
||||
FuncBuilder b(currentB->getInsertionBlock(), currentB->getInsertionPoint());
|
||||
Location loc = ScopedContext::getLocation();
|
||||
ScopedContext scope(b, loc);
|
||||
BlockBuilder(bh, captures)({/* no body */});
|
||||
} // Release before adding the branch to the eagerly created block.
|
||||
BlockBuilder(bh, captures)({/* no body */});
|
||||
SmallVector<Value *, 4> ops(operands.begin(), operands.end());
|
||||
return InstructionHandle::create<BranchOp>(bh->getBlock(), ops);
|
||||
}
|
||||
|
@ -83,14 +76,8 @@ InstructionHandle mlir::edsc::intrinsics::COND_BR(
|
|||
assert(!*falseBranch && "Unexpected already captured BlockHandle");
|
||||
enforceEmptyCapturesMatchOperands(trueCaptures, trueOperands);
|
||||
enforceEmptyCapturesMatchOperands(falseCaptures, falseOperands);
|
||||
{ // Clone the scope explicitly.
|
||||
auto *currentB = ScopedContext::getBuilder();
|
||||
FuncBuilder b(currentB->getInsertionBlock(), currentB->getInsertionPoint());
|
||||
Location loc = ScopedContext::getLocation();
|
||||
ScopedContext scope(b, loc);
|
||||
BlockBuilder(trueBranch, trueCaptures)({/* no body */});
|
||||
BlockBuilder(falseBranch, falseCaptures)({/* no body */});
|
||||
} // Release before adding the branch to the eagerly created block.
|
||||
BlockBuilder(trueBranch, trueCaptures)({/* no body */});
|
||||
BlockBuilder(falseBranch, falseCaptures)({/* no body */});
|
||||
SmallVector<Value *, 4> trueOps(trueOperands.begin(), trueOperands.end());
|
||||
SmallVector<Value *, 4> falseOps(falseOperands.begin(), falseOperands.end());
|
||||
return InstructionHandle::create<CondBranchOp>(
|
||||
|
|
|
@ -401,6 +401,29 @@ TEST_FUNC(custom_ops) {
|
|||
f->print(llvm::outs());
|
||||
}
|
||||
|
||||
TEST_FUNC(insertion_in_block) {
|
||||
using namespace edsc;
|
||||
using namespace edsc::intrinsics;
|
||||
using namespace edsc::op;
|
||||
auto indexType = IndexType::get(&globalContext());
|
||||
auto f = makeFunction("insertion_in_block", {}, {indexType, indexType});
|
||||
ScopedContext scope(f.get());
|
||||
BlockHandle b1;
|
||||
// clang-format off
|
||||
ValueHandle::create<ConstantIntOp>(0, 32);
|
||||
BlockBuilder(&b1, {})({
|
||||
ValueHandle::create<ConstantIntOp>(1, 32)
|
||||
});
|
||||
ValueHandle::create<ConstantIntOp>(2, 32);
|
||||
// CHECK-LABEL: @insertion_in_block
|
||||
// CHECK: {{.*}} = constant 0 : i32
|
||||
// CHECK: {{.*}} = constant 2 : i32
|
||||
// CHECK: ^bb1: // no predecessors
|
||||
// CHECK: {{.*}} = constant 1 : i32
|
||||
// clang-format on
|
||||
f->print(llvm::outs());
|
||||
}
|
||||
|
||||
int main() {
|
||||
RUN_TESTS();
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue