diff options
author | Kazu Hirata <kazu@google.com> | 2019-11-05 09:46:57 -0800 |
---|---|---|
committer | Kazu Hirata <kazu@google.com> | 2019-11-05 09:46:57 -0800 |
commit | 893afb9ca148e41404679e1755b31129107ba5e8 (patch) | |
tree | 6d83c1f1dcef883293b86ecb57f22a2d1a1170e7 | |
parent | e64f7bfefe4f1e8b1d4fb4af8a1633f06b56640a (diff) | |
download | bcm5719-llvm-893afb9ca148e41404679e1755b31129107ba5e8.tar.gz bcm5719-llvm-893afb9ca148e41404679e1755b31129107ba5e8.zip |
[JumpThreading] Factor out code to merge basic blocks (NFC)
Summary:
This patch factors out code to merge a basic block with its sole
successor -- partly for readability and partly to facilitate an
upcoming patch of my own.
Reviewers: wmi
Subscribers: hiraditya, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69852
-rw-r--r-- | llvm/include/llvm/Transforms/Scalar/JumpThreading.h | 1 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/JumpThreading.cpp | 95 |
2 files changed, 53 insertions, 43 deletions
diff --git a/llvm/include/llvm/Transforms/Scalar/JumpThreading.h b/llvm/include/llvm/Transforms/Scalar/JumpThreading.h index 3ebbddc8f41..591247277d2 100644 --- a/llvm/include/llvm/Transforms/Scalar/JumpThreading.h +++ b/llvm/include/llvm/Transforms/Scalar/JumpThreading.h @@ -109,6 +109,7 @@ public: void FindLoopHeaders(Function &F); bool ProcessBlock(BasicBlock *BB); + bool MaybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB); void UpdateSSA(BasicBlock *BB, BasicBlock *NewBB, DenseMap<Instruction *, Value *> &ValueMapping); bool ThreadEdge(BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs, diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index e36c7a4c512..8582d295aa8 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -1002,49 +1002,8 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { // successor, merge the blocks. This encourages recursive jump threading // because now the condition in this block can be threaded through // predecessors of our predecessor block. - if (BasicBlock *SinglePred = BB->getSinglePredecessor()) { - const Instruction *TI = SinglePred->getTerminator(); - if (!TI->isExceptionalTerminator() && TI->getNumSuccessors() == 1 && - SinglePred != BB && !hasAddressTakenAndUsed(BB)) { - // If SinglePred was a loop header, BB becomes one. - if (LoopHeaders.erase(SinglePred)) - LoopHeaders.insert(BB); - - LVI->eraseBlock(SinglePred); - MergeBasicBlockIntoOnlyPred(BB, DTU); - - // Now that BB is merged into SinglePred (i.e. SinglePred Code followed by - // BB code within one basic block `BB`), we need to invalidate the LVI - // information associated with BB, because the LVI information need not be - // true for all of BB after the merge. For example, - // Before the merge, LVI info and code is as follows: - // SinglePred: <LVI info1 for %p val> - // %y = use of %p - // call @exit() // need not transfer execution to successor. - // assume(%p) // from this point on %p is true - // br label %BB - // BB: <LVI info2 for %p val, i.e. %p is true> - // %x = use of %p - // br label exit - // - // Note that this LVI info for blocks BB and SinglPred is correct for %p - // (info2 and info1 respectively). After the merge and the deletion of the - // LVI info1 for SinglePred. We have the following code: - // BB: <LVI info2 for %p val> - // %y = use of %p - // call @exit() - // assume(%p) - // %x = use of %p <-- LVI info2 is correct from here onwards. - // br label exit - // LVI info2 for BB is incorrect at the beginning of BB. - - // Invalidate LVI information for BB if the LVI is not provably true for - // all of BB. - if (!isGuaranteedToTransferExecutionToSuccessor(BB)) - LVI->eraseBlock(BB); - return true; - } - } + if (MaybeMergeBasicBlockIntoOnlyPred(BB)) + return true; if (TryToUnfoldSelectInCurrBB(BB)) return true; @@ -1920,6 +1879,56 @@ static void AddPHINodeEntriesForMappedBlock(BasicBlock *PHIBB, } } +/// Merge basic block BB into its sole predecessor if possible. +bool JumpThreadingPass::MaybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB) { + BasicBlock *SinglePred = BB->getSinglePredecessor(); + if (!SinglePred) + return false; + + const Instruction *TI = SinglePred->getTerminator(); + if (TI->isExceptionalTerminator() || TI->getNumSuccessors() != 1 || + SinglePred == BB || hasAddressTakenAndUsed(BB)) + return false; + + // If SinglePred was a loop header, BB becomes one. + if (LoopHeaders.erase(SinglePred)) + LoopHeaders.insert(BB); + + LVI->eraseBlock(SinglePred); + MergeBasicBlockIntoOnlyPred(BB, DTU); + + // Now that BB is merged into SinglePred (i.e. SinglePred Code followed by + // BB code within one basic block `BB`), we need to invalidate the LVI + // information associated with BB, because the LVI information need not be + // true for all of BB after the merge. For example, + // Before the merge, LVI info and code is as follows: + // SinglePred: <LVI info1 for %p val> + // %y = use of %p + // call @exit() // need not transfer execution to successor. + // assume(%p) // from this point on %p is true + // br label %BB + // BB: <LVI info2 for %p val, i.e. %p is true> + // %x = use of %p + // br label exit + // + // Note that this LVI info for blocks BB and SinglPred is correct for %p + // (info2 and info1 respectively). After the merge and the deletion of the + // LVI info1 for SinglePred. We have the following code: + // BB: <LVI info2 for %p val> + // %y = use of %p + // call @exit() + // assume(%p) + // %x = use of %p <-- LVI info2 is correct from here onwards. + // br label exit + // LVI info2 for BB is incorrect at the beginning of BB. + + // Invalidate LVI information for BB if the LVI is not provably true for + // all of BB. + if (!isGuaranteedToTransferExecutionToSuccessor(BB)) + LVI->eraseBlock(BB); + return true; +} + /// Update the SSA form. NewBB contains instructions that are copied from BB. /// ValueMapping maps old values in BB to new ones in NewBB. void JumpThreadingPass::UpdateSSA( |