summaryrefslogtreecommitdiffstats
path: root/mlir/lib/IR
diff options
context:
space:
mode:
authorRiver Riddle <riverriddle@google.com>2019-11-05 11:57:03 -0800
committerA. Unique TensorFlower <gardener@tensorflow.org>2019-11-05 11:57:38 -0800
commit2366561a39d80c3c6f0f5b1257760b5a9ed2f7bd (patch)
treecb79fed502c6e9d437b34cc1b89b5039952de79e /mlir/lib/IR
parent6d2432561c7822235091d5c58df3b8abb8732610 (diff)
downloadbcm5719-llvm-2366561a39d80c3c6f0f5b1257760b5a9ed2f7bd.tar.gz
bcm5719-llvm-2366561a39d80c3c6f0f5b1257760b5a9ed2f7bd.zip
Add a PatternRewriter hook to merge blocks, and use it to support for folding branches.
A pattern rewriter hook, mergeBlock, is added that allows for merging the operations of one block into the end of another. This is used to support a canonicalization pattern for branch operations that folds the branch when the successor has a single predecessor(the branch block). Example: ^bb0: %c0_i32 = constant 0 : i32 br ^bb1(%c0_i32 : i32) ^bb1(%x : i32): return %x : i32 becomes: ^bb0: %c0_i32 = constant 0 : i32 return %c0_i32 : i32 PiperOrigin-RevId: 278677825
Diffstat (limited to 'mlir/lib/IR')
-rw-r--r--mlir/lib/IR/PatternMatch.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/mlir/lib/IR/PatternMatch.cpp b/mlir/lib/IR/PatternMatch.cpp
index 1f9b9b060aa..b8ecab97552 100644
--- a/mlir/lib/IR/PatternMatch.cpp
+++ b/mlir/lib/IR/PatternMatch.cpp
@@ -109,6 +109,35 @@ void PatternRewriter::eraseOp(Operation *op) {
op->erase();
}
+/// Merge the operations of block 'source' into the end of block 'dest'.
+/// 'source's predecessors must be empty or only contain 'dest`.
+/// 'argValues' is used to replace the block arguments of 'source' after
+/// merging.
+void PatternRewriter::mergeBlocks(Block *source, Block *dest,
+ ArrayRef<Value *> argValues) {
+ assert(llvm::all_of(source->getPredecessors(),
+ [dest](Block *succ) { return succ == dest; }) &&
+ "expected 'source' to have no predecessors or only 'dest'");
+ assert(argValues.size() == source->getNumArguments() &&
+ "incorrect # of argument replacement values");
+
+ // Replace all of the successor arguments with the provided values.
+ for (auto it : llvm::zip(source->getArguments(), argValues))
+ std::get<0>(it)->replaceAllUsesWith(std::get<1>(it));
+
+ // Splice the operations of the 'source' block into the 'dest' block and erase
+ // it.
+ dest->getOperations().splice(dest->end(), source->getOperations());
+ source->dropAllUses();
+ source->erase();
+}
+
+/// Split the operations starting at "before" (inclusive) out of the given
+/// block into a new block, and return it.
+Block *PatternRewriter::splitBlock(Block *block, Block::iterator before) {
+ return block->splitBlock(before);
+}
+
/// op and newOp are known to have the same number of results, replace the
/// uses of op with uses of newOp
void PatternRewriter::replaceOpWithResultsOfAnotherOp(
OpenPOWER on IntegriCloud