diff options
author | Xinliang David Li <davidxl@google.com> | 2017-06-01 00:12:41 +0000 |
---|---|---|
committer | Xinliang David Li <davidxl@google.com> | 2017-06-01 00:12:41 +0000 |
commit | 32c5e809beae6c184c644abfd205d43f6bdd8b0d (patch) | |
tree | 3bb02466abf1c821b086c2733eb9b1861c4166a4 /llvm/lib/Transforms/IPO | |
parent | 062f8f00ae72544654a849c21bd01d7fcee72719 (diff) | |
download | bcm5719-llvm-32c5e809beae6c184c644abfd205d43f6bdd8b0d.tar.gz bcm5719-llvm-32c5e809beae6c184c644abfd205d43f6bdd8b0d.zip |
[PartialInlining] Reduce outlining overhead by removing unneeded live-out(s)
Differential Revision: http://reviews.llvm.org/D33694
llvm-svn: 304375
Diffstat (limited to 'llvm/lib/Transforms/IPO')
-rw-r--r-- | llvm/lib/Transforms/IPO/PartialInlining.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/IPO/PartialInlining.cpp b/llvm/lib/Transforms/IPO/PartialInlining.cpp index 4c417f1c55e..bc0967448cd 100644 --- a/llvm/lib/Transforms/IPO/PartialInlining.cpp +++ b/llvm/lib/Transforms/IPO/PartialInlining.cpp @@ -652,12 +652,21 @@ Function *PartialInlinerImpl::unswitchFunction(Function *F) { // only split block when necessary: PHINode *FirstPhi = getFirstPHI(PreReturn); unsigned NumPredsFromEntries = OI->ReturnBlockPreds.size(); + auto IsTrivialPhi = [](PHINode *PN) -> Value * { + Value *CommonValue = PN->getIncomingValue(0); + if (all_of(PN->incoming_values(), + [&](Value *V) { return V == CommonValue; })) + return CommonValue; + return nullptr; + }; + if (FirstPhi && FirstPhi->getNumIncomingValues() > NumPredsFromEntries + 1) { NewReturnBlock = NewReturnBlock->splitBasicBlock( NewReturnBlock->getFirstNonPHI()->getIterator()); BasicBlock::iterator I = PreReturn->begin(); Instruction *Ins = &NewReturnBlock->front(); + SmallVector<Instruction *, 4> DeadPhis; while (I != PreReturn->end()) { PHINode *OldPhi = dyn_cast<PHINode>(I); if (!OldPhi) @@ -674,8 +683,22 @@ Function *PartialInlinerImpl::unswitchFunction(Function *F) { RetPhi->addIncoming(OldPhi->getIncomingValueForBlock(NewE), NewE); OldPhi->removeIncomingValue(NewE); } + + // After incoming values splitting, the old phi may become trivial. + // Keeping the trivial phi can introduce definition inside the outline + // region which is live-out, causing necessary overhead (load, store + // arg passing etc). + if (auto *OldPhiVal = IsTrivialPhi(OldPhi)) { + OldPhi->replaceAllUsesWith(OldPhiVal); + DeadPhis.push_back(OldPhi); + } + ++I; } + + for (auto *DP : DeadPhis) + DP->eraseFromParent(); + for (auto E : OI->ReturnBlockPreds) { BasicBlock *NewE = cast<BasicBlock>(VMap[E]); NewE->getTerminator()->replaceUsesOfWith(PreReturn, NewReturnBlock); |