/1.diff Secret
Created
February 24, 2018 07:08
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/Transforms/Scalar/CallSiteSplitting.cpp b/lib/Transforms/Scalar/CallSiteSplitting.cpp | |
index 2e841b2ac94..6ea74218886 100644 | |
--- a/lib/Transforms/Scalar/CallSiteSplitting.cpp | |
+++ b/lib/Transforms/Scalar/CallSiteSplitting.cpp | |
@@ -209,8 +209,6 @@ static bool canSplitCallSite(CallSite CS, TargetTransformInfo &TTI) { | |
return CallSiteBB->canSplitPredecessors(); | |
} | |
-/// Return true if the CS is split into its new predecessors. | |
-/// | |
/// For each (predecessor, conditions from predecessors) pair, it will split the | |
/// basic block containing the call site, hook it up to the predecessor and | |
/// replace the call instruction with new call instructions, which contain | |
@@ -255,12 +253,25 @@ static bool canSplitCallSite(CallSite CS, TargetTransformInfo &TTI) { | |
static void splitCallSite( | |
CallSite CS, | |
const SmallVectorImpl<std::pair<BasicBlock *, ConditionsTy>> &Preds) { | |
+ bool IsMustTail = CS.isMustTailCall(); | |
Instruction *Instr = CS.getInstruction(); | |
BasicBlock *TailBB = Instr->getParent(); | |
PHINode *CallPN = nullptr; | |
- if (Instr->getNumUses()) | |
+ | |
+ Instruction *StopAt; | |
+ if (IsMustTail) { | |
+ // We need to copy everything including the terminator of the Tail block, | |
+ // since musttail must be followed by optional bitcast and ret. | |
+ // | |
+ StopAt = new UnreachableInst(TailBB->getContext(), TailBB); | |
+ | |
+ // musttail call results are used just once - no need to create phi. | |
+ } else if (Instr->getNumUses()) { | |
CallPN = PHINode::Create(Instr->getType(), Preds.size(), "phi.call"); | |
+ StopAt = &*std::next(Instr->getIterator()); | |
+ } | |
+ | |
DEBUG(dbgs() << "split call-site : " << *Instr << " into \n"); | |
@@ -271,11 +282,17 @@ static void splitCallSite( | |
for (unsigned i = 0; i < Preds.size(); i++) { | |
BasicBlock *PredBB = Preds[i].first; | |
BasicBlock *SplitBlock = DuplicateInstructionsInSplitBetween( | |
- TailBB, PredBB, &*std::next(Instr->getIterator()), ValueToValueMaps[i]); | |
+ TailBB, PredBB, StopAt, ValueToValueMaps[i]); | |
assert(SplitBlock && "Unexpected new basic block split."); | |
- Instruction *NewCI = | |
- &*std::prev(SplitBlock->getTerminator()->getIterator()); | |
+ Instruction *NewCI; | |
+ | |
+ if (IsMustTail) { | |
+ NewCI = dyn_cast<Instruction>(&*ValueToValueMaps[i][Instr]); | |
+ SplitBlock->getTerminator()->removeFromParent(); | |
+ } else { | |
+ NewCI = &*std::prev(SplitBlock->getTerminator()->getIterator()); | |
+ } | |
CallSite NewCS(NewCI); | |
addConditions(NewCS, Preds[i].second); | |
@@ -309,7 +326,7 @@ static void splitCallSite( | |
// instruction, so we do not end up deleting them. By using reverse-order, we | |
// do not introduce unnecessary PHI nodes for def-use chains from the call | |
// instruction to the beginning of the block. | |
- auto I = Instr->getReverseIterator(); | |
+ auto I = (&*std::prev(StopAt->getIterator()))->getReverseIterator(); | |
while (I != TailBB->rend()) { | |
Instruction *CurrentI = &*I++; | |
if (!CurrentI->use_empty()) { | |
@@ -330,6 +347,9 @@ static void splitCallSite( | |
break; | |
} | |
+ if (IsMustTail) | |
+ TailBB->eraseFromParent(); | |
+ | |
NumCallSiteSplit++; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment