diff --git a/mlir/include/mlir/Dialect/StandardOps/EDSC/Intrinsics.h b/mlir/include/mlir/Dialect/StandardOps/EDSC/Intrinsics.h --- a/mlir/include/mlir/Dialect/StandardOps/EDSC/Intrinsics.h +++ b/mlir/include/mlir/Dialect/StandardOps/EDSC/Intrinsics.h @@ -47,63 +47,14 @@ using std_zero_extendi = ValueBuilder; using std_sign_extendi = ValueBuilder; -/// Branches into the mlir::Block* captured by BlockHandle `b` with `operands`. -/// -/// Prerequisites: -/// All Handles have already captured previously constructed IR objects. -BranchOp std_br(BlockHandle bh, ValueRange operands); +/// Branches into `block` with `operands`. BranchOp std_br(Block *block, ValueRange operands); -/// Creates a new mlir::Block* and branches to it from the current block. -/// Argument types are specified by `operands`. -/// Captures the new block in `bh` and the actual `operands` in `captures`. To -/// insert the new mlir::Block*, a local ScopedContext is constructed and -/// released to the current block. The branch operation is then added to the -/// new block. -/// -/// Prerequisites: -/// `b` has not yet captured an mlir::Block*. -/// No `captures` have captured any mlir::Value. -/// All `operands` have already captured an mlir::Value -/// captures.size() == operands.size() -/// captures and operands are pairwise of the same type. -BranchOp std_br(BlockHandle *bh, ArrayRef types, - MutableArrayRef captures, ValueRange operands); - -/// Branches into the mlir::Block* captured by BlockHandle `trueBranch` with -/// `trueOperands` if `cond` evaluates to `true` (resp. `falseBranch` and -/// `falseOperand` if `cond` evaluates to `false`). -/// -/// Prerequisites: -/// All Handles have captured previously constructed IR objects. -CondBranchOp std_cond_br(Value cond, BlockHandle trueBranch, - ValueRange trueOperands, BlockHandle falseBranch, - ValueRange falseOperands); +/// Branches into `trueBranch` with `trueOperands` if `cond` evaluates to `true` +/// or to `falseBranch` and `falseOperand` if `cond` evaluates to `false`. CondBranchOp std_cond_br(Value cond, Block *trueBranch, ValueRange trueOperands, Block *falseBranch, ValueRange falseOperands); -/// Eagerly creates new mlir::Block* with argument types specified by -/// `trueOperands`/`falseOperands`. -/// Captures the new blocks in `trueBranch`/`falseBranch` and the arguments in -/// `trueCaptures/falseCaptures`. -/// To insert the new mlir::Block*, a local ScopedContext is constructed and -/// released. The branch operation is then added in the original location and -/// targeting the eagerly constructed blocks. -/// -/// Prerequisites: -/// `trueBranch`/`falseBranch` has not yet captured an mlir::Block*. -/// No `trueCaptures`/`falseCaptures` have captured any mlir::Value. -/// All `trueOperands`/`trueOperands` have already captured an mlir::Value -/// `trueCaptures`.size() == `trueOperands`.size() -/// `falseCaptures`.size() == `falseOperands`.size() -/// `trueCaptures` and `trueOperands` are pairwise of the same type -/// `falseCaptures` and `falseOperands` are pairwise of the same type. -CondBranchOp -std_cond_br(Value cond, BlockHandle *trueBranch, ArrayRef trueTypes, - MutableArrayRef trueCaptures, ValueRange trueOperands, - BlockHandle *falseBranch, ArrayRef falseTypes, - MutableArrayRef falseCaptures, ValueRange falseOperands); - /// Provide an index notation around sdt_load and std_store. using StdIndexedValue = TemplatedIndexedValue; diff --git a/mlir/include/mlir/EDSC/Builders.h b/mlir/include/mlir/EDSC/Builders.h --- a/mlir/include/mlir/EDSC/Builders.h +++ b/mlir/include/mlir/EDSC/Builders.h @@ -23,7 +23,6 @@ class OperationFolder; namespace edsc { -class BlockHandle; class NestedBuilder; /// Helper class to transparently handle builder insertion points by RAII. @@ -147,96 +146,6 @@ ScopedContext *bodyScope = nullptr; }; -// This class exists solely to handle the C++ vexing parse case when -// trying to enter a Block that has already been constructed. -class Append {}; - -/// Deprecated. Use buildInNewBlock or appendToBlock instead. -/// -/// A BlockBuilder is a NestedBuilder for mlir::Block*. -/// This exists by opposition to LoopBuilder which is not related to an -/// mlir::Block* but to a mlir::Value. -/// It is meant to be used as a temporary object for representing any nested -/// MLIR construct that is "related to" an mlir::Block*. -class BlockBuilder : public NestedBuilder { -public: - /// Enters the mlir::Block* previously captured by `bh` and sets the insertion - /// point to its end. If the block already contains a terminator, set the - /// insertion point before the terminator. - BlockBuilder(BlockHandle bh, Append); - - /// Constructs a new mlir::Block with argument types derived from `args`. - /// Captures the new block in `bh` and its arguments into `args`. - /// Enters the new mlir::Block* and sets the insertion point to its end. - /// - /// Prerequisites: - /// The Value `args` are typed delayed Values; i.e. they are - /// not yet bound to mlir::Value. - BlockBuilder(BlockHandle *bh) : BlockBuilder(bh, {}, {}) {} - BlockBuilder(BlockHandle *bh, ArrayRef types, - MutableArrayRef args); - - /// Constructs a new mlir::Block with argument types derived from `args` and - /// appends it as the last block in the region. - /// Captures the new block in `bh` and its arguments into `args`. - /// Enters the new mlir::Block* and sets the insertion point to its end. - /// - /// Prerequisites: - /// The Value `args` are typed delayed Values; i.e. they are - /// not yet bound to mlir::Value. - BlockBuilder(BlockHandle *bh, Region ®ion, ArrayRef types, - MutableArrayRef args); - - /// The only purpose of this operator is to serve as a sequence point so that - /// the evaluation of `fun` (which build IR snippets in a scoped fashion) is - /// scoped within a BlockBuilder. - void operator()(function_ref fun = nullptr); - -private: - BlockBuilder(BlockBuilder &) = delete; - BlockBuilder &operator=(BlockBuilder &other) = delete; -}; - -/// Deprecated. Use Block * instead. -/// -/// A BlockHandle represents a (potentially "delayed") Block abstraction. -/// This extra abstraction is necessary because an mlir::Block is not an -/// mlir::Value. -/// A BlockHandle should be captured by pointer but otherwise passed by Value -/// everywhere. -class BlockHandle { -public: - /// A BlockHandle constructed without an mlir::Block* represents a "delayed" - /// Block. A delayed Block represents the declaration (in the PL sense) of a - /// placeholder for an mlir::Block* that will be constructed and captured at - /// some later point in the program. - BlockHandle() : block(nullptr) {} - - /// A BlockHandle constructed with an mlir::Block* represents an "eager" - /// Block. An eager Block represents both the declaration and the definition - /// (in the PL sense) of a placeholder for an mlir::Block* that has already - /// been constructed in the past and that is captured "now" in the program. - BlockHandle(mlir::Block *block) : block(block) {} - - /// BlockHandle is a value type, use the default copy constructor and - /// assignment operator. - BlockHandle(const BlockHandle &) = default; - BlockHandle &operator=(const BlockHandle &) = default; - - /// Delegates block creation to MLIR and wrap the resulting mlir::Block. - static BlockHandle create(ArrayRef argTypes); - - /// Delegates block creation to MLIR and wrap the resulting mlir::Block. - static BlockHandle createInRegion(Region ®ion, ArrayRef argTypes); - - operator bool() { return block != nullptr; } - operator mlir::Block *() { return block; } - mlir::Block *getBlock() { return block; } - -private: - mlir::Block *block; -}; - /// Creates a block in the region that contains the insertion block of the /// OpBuilder currently at the top of ScopedContext stack (appends the block to /// the region). Be aware that this will NOT update the insertion point of the diff --git a/mlir/lib/Dialect/StandardOps/EDSC/Intrinsics.cpp b/mlir/lib/Dialect/StandardOps/EDSC/Intrinsics.cpp --- a/mlir/lib/Dialect/StandardOps/EDSC/Intrinsics.cpp +++ b/mlir/lib/Dialect/StandardOps/EDSC/Intrinsics.cpp @@ -12,25 +12,10 @@ using namespace mlir; using namespace mlir::edsc; -BranchOp mlir::edsc::intrinsics::std_br(BlockHandle bh, ValueRange operands) { - assert(bh && "Expected already captured BlockHandle"); - SmallVector ops(operands.begin(), operands.end()); - return OperationBuilder(bh.getBlock(), ops); -} - BranchOp mlir::edsc::intrinsics::std_br(Block *block, ValueRange operands) { return OperationBuilder(block, operands); } -BranchOp mlir::edsc::intrinsics::std_br(BlockHandle *bh, ArrayRef types, - MutableArrayRef captures, - ValueRange operands) { - assert(!*bh && "Unexpected already captured BlockHandle"); - BlockBuilder(bh, types, captures)(/* no body */); - SmallVector ops(operands.begin(), operands.end()); - return OperationBuilder(bh->getBlock(), ops); -} - CondBranchOp mlir::edsc::intrinsics::std_cond_br(Value cond, Block *trueBranch, ValueRange trueOperands, Block *falseBranch, @@ -38,29 +23,3 @@ return OperationBuilder(cond, trueBranch, trueOperands, falseBranch, falseOperands); } - -CondBranchOp mlir::edsc::intrinsics::std_cond_br(Value cond, - BlockHandle trueBranch, - ValueRange trueOperands, - BlockHandle falseBranch, - ValueRange falseOperands) { - SmallVector trueOps(trueOperands.begin(), trueOperands.end()); - SmallVector falseOps(falseOperands.begin(), falseOperands.end()); - return OperationBuilder(cond, trueBranch.getBlock(), trueOps, - falseBranch.getBlock(), falseOps); -} - -CondBranchOp mlir::edsc::intrinsics::std_cond_br( - Value cond, BlockHandle *trueBranch, ArrayRef trueTypes, - MutableArrayRef trueCaptures, ValueRange trueOperands, - BlockHandle *falseBranch, ArrayRef falseTypes, - MutableArrayRef falseCaptures, ValueRange falseOperands) { - assert(!*trueBranch && "Unexpected already captured BlockHandle"); - assert(!*falseBranch && "Unexpected already captured BlockHandle"); - BlockBuilder(trueBranch, trueTypes, trueCaptures)(/* no body */); - BlockBuilder(falseBranch, falseTypes, falseCaptures)(/* no body */); - SmallVector trueOps(trueOperands.begin(), trueOperands.end()); - SmallVector falseOps(falseOperands.begin(), falseOperands.end()); - return OperationBuilder(cond, trueBranch->getBlock(), trueOps, - falseBranch->getBlock(), falseOps); -} diff --git a/mlir/lib/EDSC/Builders.cpp b/mlir/lib/EDSC/Builders.cpp --- a/mlir/lib/EDSC/Builders.cpp +++ b/mlir/lib/EDSC/Builders.cpp @@ -58,35 +58,6 @@ return getBuilderRef().getContext(); } -BlockHandle mlir::edsc::BlockHandle::create(ArrayRef argTypes) { - auto ¤tB = ScopedContext::getBuilderRef(); - auto *ib = currentB.getInsertionBlock(); - auto ip = currentB.getInsertionPoint(); - BlockHandle res; - res.block = ScopedContext::getBuilderRef().createBlock(ib->getParent()); - // 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); - } - return res; -} - -BlockHandle mlir::edsc::BlockHandle::createInRegion(Region ®ion, - ArrayRef argTypes) { - BlockHandle res; - region.push_back(new Block); - res.block = ®ion.back(); - // createBlock sets the insertion point inside the block. - // We do not want this behavior when using declarative builders with nesting. - OpBuilder::InsertionGuard g(ScopedContext::getBuilderRef()); - ScopedContext::getBuilderRef().setInsertionPoint(res.block, - res.block->begin()); - res.block->addArguments(argTypes); - return res; -} - Block *mlir::edsc::createBlock(TypeRange argTypes) { assert(ScopedContext::getContext() != nullptr && "ScopedContext not set up"); OpBuilder &builder = ScopedContext::getBuilderRef(); @@ -140,46 +111,3 @@ return block; } -mlir::edsc::BlockBuilder::BlockBuilder(BlockHandle bh, Append) { - assert(bh && "Expected already captured BlockHandle"); - enter(bh.getBlock()); -} - -mlir::edsc::BlockBuilder::BlockBuilder(BlockHandle *bh, ArrayRef types, - MutableArrayRef args) { - assert(!*bh && "BlockHandle already captures a block, use " - "the explicit BockBuilder(bh, Append())({}) syntax instead."); - assert((args.empty() || args.size() == types.size()) && - "if args captures are specified, their number must match the number " - "of types"); - *bh = BlockHandle::create(types); - if (!args.empty()) - for (auto it : llvm::zip(args, bh->getBlock()->getArguments())) - std::get<0>(it) = Value(std::get<1>(it)); - enter(bh->getBlock()); -} - -mlir::edsc::BlockBuilder::BlockBuilder(BlockHandle *bh, Region ®ion, - ArrayRef types, - MutableArrayRef args) { - assert(!*bh && "BlockHandle already captures a block, use " - "the explicit BockBuilder(bh, Append())({}) syntax instead."); - assert((args.empty() || args.size() == types.size()) && - "if args captures are specified, their number must match the number " - "of types"); - *bh = BlockHandle::createInRegion(region, types); - if (!args.empty()) - for (auto it : llvm::zip(args, bh->getBlock()->getArguments())) - std::get<0>(it) = Value(std::get<1>(it)); - enter(bh->getBlock()); -} - -/// Only serves as an ordering point between entering nested block and creating -/// stmts. -void mlir::edsc::BlockBuilder::operator()(function_ref fun) { - // Call to `exit` must be explicit and asymmetric (cannot happen in the - // destructor) because of ordering wrt comma operator. - if (fun) - fun(); - exit(); -}