Insert signature-converted blocks into a region with a parent operation.
This keeps the IR valid and consistent as it is expected that each block should have a valid parent region/operation. Previously, converted blocks were kept floating without a valid parent region. PiperOrigin-RevId: 285821687 Change-Id: I9650b562d25b3956becc1c8b46c7af5e83694eae
This commit is contained in:
parent
e1666f32ba
commit
8f2154320a
6
third_party/mlir/include/mlir/IR/Block.h
vendored
6
third_party/mlir/include/mlir/IR/Block.h
vendored
@ -56,10 +56,14 @@ public:
|
|||||||
/// Return if this block is the entry block in the parent region.
|
/// Return if this block is the entry block in the parent region.
|
||||||
bool isEntryBlock();
|
bool isEntryBlock();
|
||||||
|
|
||||||
/// Insert this block (which must not already be in a function) right before
|
/// Insert this block (which must not already be in a region) right before
|
||||||
/// the specified block.
|
/// the specified block.
|
||||||
void insertBefore(Block *block);
|
void insertBefore(Block *block);
|
||||||
|
|
||||||
|
/// Unlink this block from its current region and insert it right before the
|
||||||
|
/// specific block.
|
||||||
|
void moveBefore(Block *block);
|
||||||
|
|
||||||
/// Unlink this Block from its parent region and delete it.
|
/// Unlink this Block from its parent region and delete it.
|
||||||
void erase();
|
void erase();
|
||||||
|
|
||||||
|
10
third_party/mlir/lib/IR/Block.cpp
vendored
10
third_party/mlir/lib/IR/Block.cpp
vendored
@ -57,7 +57,15 @@ bool Block::isEntryBlock() { return this == &getParent()->front(); }
|
|||||||
void Block::insertBefore(Block *block) {
|
void Block::insertBefore(Block *block) {
|
||||||
assert(!getParent() && "already inserted into a block!");
|
assert(!getParent() && "already inserted into a block!");
|
||||||
assert(block->getParent() && "cannot insert before a block without a parent");
|
assert(block->getParent() && "cannot insert before a block without a parent");
|
||||||
block->getParent()->getBlocks().insert(Region::iterator(block), this);
|
block->getParent()->getBlocks().insert(block->getIterator(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unlink this block from its current region and insert it right before the
|
||||||
|
/// specific block.
|
||||||
|
void Block::moveBefore(Block *block) {
|
||||||
|
assert(block->getParent() && "cannot insert before a block without a parent");
|
||||||
|
block->getParent()->getBlocks().splice(
|
||||||
|
block->getIterator(), getParent()->getBlocks(), getIterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unlink this Block from its parent Region and delete it.
|
/// Unlink this Block from its parent Region and delete it.
|
||||||
|
@ -164,9 +164,10 @@ struct ArgConverter {
|
|||||||
// Rewrite Application
|
// Rewrite Application
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// Erase any rewrites registered for the current block that is about to be
|
/// Erase any rewrites registered for the blocks within the given operation
|
||||||
/// removed. This merely drops the rewrites without undoing them.
|
/// which is about to be removed. This merely drops the rewrites without
|
||||||
void notifyBlockRemoved(Block *block);
|
/// undoing them.
|
||||||
|
void notifyOpRemoved(Operation *op);
|
||||||
|
|
||||||
/// Cleanup and undo any generated conversions for the arguments of block.
|
/// Cleanup and undo any generated conversions for the arguments of block.
|
||||||
/// This method replaces the new block with the original, reverting the IR to
|
/// This method replaces the new block with the original, reverting the IR to
|
||||||
@ -194,9 +195,16 @@ struct ArgConverter {
|
|||||||
Block *block, TypeConverter::SignatureConversion &signatureConversion,
|
Block *block, TypeConverter::SignatureConversion &signatureConversion,
|
||||||
ConversionValueMapping &mapping);
|
ConversionValueMapping &mapping);
|
||||||
|
|
||||||
|
/// Insert a new conversion into the cache.
|
||||||
|
void insertConversion(Block *newBlock, ConvertedBlockInfo &&info);
|
||||||
|
|
||||||
/// A collection of blocks that have had their arguments converted.
|
/// A collection of blocks that have had their arguments converted.
|
||||||
llvm::MapVector<Block *, ConvertedBlockInfo> conversionInfo;
|
llvm::MapVector<Block *, ConvertedBlockInfo> conversionInfo;
|
||||||
|
|
||||||
|
/// A mapping from valid regions, to those containing the original blocks of a
|
||||||
|
/// conversion.
|
||||||
|
DenseMap<Region *, std::unique_ptr<Region>> regionMapping;
|
||||||
|
|
||||||
/// An instance of the unknown location that is used when materializing
|
/// An instance of the unknown location that is used when materializing
|
||||||
/// conversions.
|
/// conversions.
|
||||||
Location loc;
|
Location loc;
|
||||||
@ -212,18 +220,26 @@ struct ArgConverter {
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Rewrite Application
|
// Rewrite Application
|
||||||
|
|
||||||
void ArgConverter::notifyBlockRemoved(Block *block) {
|
void ArgConverter::notifyOpRemoved(Operation *op) {
|
||||||
auto it = conversionInfo.find(block);
|
for (Region ®ion : op->getRegions()) {
|
||||||
if (it == conversionInfo.end())
|
for (Block &block : region) {
|
||||||
return;
|
// Drop any rewrites from within.
|
||||||
|
for (Operation &nestedOp : block)
|
||||||
|
if (nestedOp.getNumRegions())
|
||||||
|
notifyOpRemoved(&nestedOp);
|
||||||
|
|
||||||
// Drop all uses of the original arguments and delete the original block.
|
// Check if this block was converted.
|
||||||
Block *origBlock = it->second.origBlock;
|
auto it = conversionInfo.find(&block);
|
||||||
for (BlockArgument *arg : origBlock->getArguments())
|
if (it == conversionInfo.end())
|
||||||
arg->dropAllUses();
|
return;
|
||||||
delete origBlock;
|
|
||||||
|
|
||||||
conversionInfo.erase(it);
|
// Drop all uses of the original arguments and delete the original block.
|
||||||
|
Block *origBlock = it->second.origBlock;
|
||||||
|
for (BlockArgument *arg : origBlock->getArguments())
|
||||||
|
arg->dropAllUses();
|
||||||
|
conversionInfo.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArgConverter::discardRewrites(Block *block) {
|
void ArgConverter::discardRewrites(Block *block) {
|
||||||
@ -239,7 +255,7 @@ void ArgConverter::discardRewrites(Block *block) {
|
|||||||
|
|
||||||
// Move the operations back the original block and the delete the new block.
|
// Move the operations back the original block and the delete the new block.
|
||||||
origBlock->getOperations().splice(origBlock->end(), block->getOperations());
|
origBlock->getOperations().splice(origBlock->end(), block->getOperations());
|
||||||
origBlock->insertBefore(block);
|
origBlock->moveBefore(block);
|
||||||
block->erase();
|
block->erase();
|
||||||
|
|
||||||
conversionInfo.erase(it);
|
conversionInfo.erase(it);
|
||||||
@ -301,9 +317,6 @@ void ArgConverter::applyRewrites(ConversionValueMapping &mapping) {
|
|||||||
if (castValue->use_empty())
|
if (castValue->use_empty())
|
||||||
castValue->getDefiningOp()->erase();
|
castValue->getDefiningOp()->erase();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drop the original block now the rewrites were applied.
|
|
||||||
delete origBlock;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,11 +390,24 @@ Block *ArgConverter::applySignatureConversion(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove the original block from the region and return the new one.
|
// Remove the original block from the region and return the new one.
|
||||||
newBlock->getParent()->getBlocks().remove(block);
|
insertConversion(newBlock, std::move(info));
|
||||||
conversionInfo.insert({newBlock, std::move(info)});
|
|
||||||
return newBlock;
|
return newBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArgConverter::insertConversion(Block *newBlock,
|
||||||
|
ConvertedBlockInfo &&info) {
|
||||||
|
// Get a region to insert the old block.
|
||||||
|
Region *region = newBlock->getParent();
|
||||||
|
std::unique_ptr<Region> &mappedRegion = regionMapping[region];
|
||||||
|
if (!mappedRegion)
|
||||||
|
mappedRegion = std::make_unique<Region>(region->getParentOp());
|
||||||
|
|
||||||
|
// Move the original block to the mapped region and emplace the conversion.
|
||||||
|
mappedRegion->getBlocks().splice(mappedRegion->end(), region->getBlocks(),
|
||||||
|
info.origBlock->getIterator());
|
||||||
|
conversionInfo.insert({newBlock, std::move(info)});
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// ConversionPatternRewriterImpl
|
// ConversionPatternRewriterImpl
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -642,11 +668,8 @@ void ConversionPatternRewriterImpl::applyRewrites() {
|
|||||||
|
|
||||||
// If this operation defines any regions, drop any pending argument
|
// If this operation defines any regions, drop any pending argument
|
||||||
// rewrites.
|
// rewrites.
|
||||||
if (argConverter.typeConverter && repl.op->getNumRegions()) {
|
if (argConverter.typeConverter && repl.op->getNumRegions())
|
||||||
for (auto ®ion : repl.op->getRegions())
|
argConverter.notifyOpRemoved(repl.op);
|
||||||
for (auto &block : region)
|
|
||||||
argConverter.notifyBlockRemoved(&block);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// In a second pass, erase all of the replaced operations in reverse. This
|
// In a second pass, erase all of the replaced operations in reverse. This
|
||||||
|
Loading…
Reference in New Issue
Block a user