[mlir][IR] Insert operations before SingleBlock's terminator (#65959)

Change `SingleBlock::{insert,push_back}` to avoid inserting the argument
operation after the block's terminator. This allows removing
`SingleBlockImplicitTerminator`'s functions with the same name.

Define `Block::hasTerminator` checking whether the block has a
terminator operation.

Signed-off-by: Victor Perez <victor.perez@codeplay.com>
This commit is contained in:
vic 2023-09-15 16:17:35 +02:00 committed by GitHub
parent b64bf895e5
commit 87d77d3cfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 13 additions and 32 deletions

View File

@ -214,6 +214,9 @@ public:
/// the block has a valid terminator operation.
Operation *getTerminator();
/// Check whether this block has a terminator.
bool hasTerminator();
//===--------------------------------------------------------------------===//
// Predecessors and successors.
//===--------------------------------------------------------------------===//

View File

@ -932,6 +932,10 @@ public:
}
template <typename OpT = ConcreteType>
enable_if_single_region<OpT> insert(Block::iterator insertPt, Operation *op) {
Block *body = getBody();
// Insert op before the block's terminator if it has one
if (insertPt == body->end() && body->hasTerminator())
insertPt = Block::iterator(body->getTerminator());
getBody()->getOperations().insert(insertPt, op);
}
};
@ -997,37 +1001,6 @@ struct SingleBlockImplicitTerminator {
::mlir::impl::ensureRegionTerminator(region, builder, loc,
buildTerminator);
}
//===------------------------------------------------------------------===//
// Single Region Utilities
//===------------------------------------------------------------------===//
template <typename OpT, typename T = void>
using enable_if_single_region =
std::enable_if_t<OpT::template hasTrait<OneRegion>(), T>;
/// Insert the operation into the back of the body, before the terminator.
template <typename OpT = ConcreteType>
enable_if_single_region<OpT> push_back(Operation *op) {
Block *body = static_cast<SingleBlock<ConcreteType> *>(this)->getBody();
insert(Block::iterator(body->getTerminator()), op);
}
/// Insert the operation at the given insertion point. Note: The operation
/// is never inserted after the terminator, even if the insertion point is
/// end().
template <typename OpT = ConcreteType>
enable_if_single_region<OpT> insert(Operation *insertPt, Operation *op) {
insert(Block::iterator(insertPt), op);
}
template <typename OpT = ConcreteType>
enable_if_single_region<OpT> insert(Block::iterator insertPt,
Operation *op) {
Block *body = static_cast<SingleBlock<ConcreteType> *>(this)->getBody();
if (insertPt == body->end())
insertPt = Block::iterator(body->getTerminator());
body->getOperations().insert(insertPt, op);
}
};
};

View File

@ -236,10 +236,15 @@ void Block::eraseArguments(function_ref<bool(BlockArgument)> shouldEraseFn) {
/// Get the terminator operation of this block. This function asserts that
/// the block has a valid terminator operation.
Operation *Block::getTerminator() {
assert(!empty() && back().mightHaveTrait<OpTrait::IsTerminator>());
assert(hasTerminator());
return &back();
}
/// Check whether this block has a terminator.
bool Block::hasTerminator() {
return !empty() && back().mightHaveTrait<OpTrait::IsTerminator>();
}
// Indexed successor access.
unsigned Block::getNumSuccessors() {
return empty() ? 0 : back().getNumSuccessors();