diff options
Diffstat (limited to 'lib/Transforms/Scalar/JumpThreading.cpp')
-rw-r--r-- | lib/Transforms/Scalar/JumpThreading.cpp | 312 |
1 files changed, 140 insertions, 172 deletions
diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp index c0b0cbe..8f12ee0 100644 --- a/lib/Transforms/Scalar/JumpThreading.cpp +++ b/lib/Transforms/Scalar/JumpThreading.cpp @@ -24,6 +24,7 @@ #include "llvm/Transforms/Utils/SSAUpdater.h" #include "llvm/Target/TargetData.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" @@ -43,15 +44,6 @@ Threshold("jump-threading-threshold", cl::desc("Max block size to duplicate for jump threading"), cl::init(6), cl::Hidden); -// Turn on use of LazyValueInfo. -static cl::opt<bool> -EnableLVI("enable-jump-threading-lvi", - cl::desc("Use LVI for jump threading"), - cl::init(true), - cl::ReallyHidden); - - - namespace { /// This pass performs 'jump threading', which looks at blocks that have /// multiple predecessors and multiple successors. If one or more of the @@ -77,15 +69,32 @@ namespace { #else SmallSet<AssertingVH<BasicBlock>, 16> LoopHeaders; #endif + DenseSet<std::pair<Value*, BasicBlock*> > RecursionSet; + + // RAII helper for updating the recursion stack. + struct RecursionSetRemover { + DenseSet<std::pair<Value*, BasicBlock*> > &TheSet; + std::pair<Value*, BasicBlock*> ThePair; + + RecursionSetRemover(DenseSet<std::pair<Value*, BasicBlock*> > &S, + std::pair<Value*, BasicBlock*> P) + : TheSet(S), ThePair(P) { } + + ~RecursionSetRemover() { + TheSet.erase(ThePair); + } + }; public: static char ID; // Pass identification - JumpThreading() : FunctionPass(ID) {} + JumpThreading() : FunctionPass(ID) { + initializeJumpThreadingPass(*PassRegistry::getPassRegistry()); + } bool runOnFunction(Function &F); virtual void getAnalysisUsage(AnalysisUsage &AU) const { - if (EnableLVI) - AU.addRequired<LazyValueInfo>(); + AU.addRequired<LazyValueInfo>(); + AU.addPreserved<LazyValueInfo>(); } void FindLoopHeaders(Function &F); @@ -114,8 +123,11 @@ namespace { } char JumpThreading::ID = 0; -INITIALIZE_PASS(JumpThreading, "jump-threading", - "Jump Threading", false, false); +INITIALIZE_PASS_BEGIN(JumpThreading, "jump-threading", + "Jump Threading", false, false) +INITIALIZE_PASS_DEPENDENCY(LazyValueInfo) +INITIALIZE_PASS_END(JumpThreading, "jump-threading", + "Jump Threading", false, false) // Public interface to the Jump Threading pass FunctionPass *llvm::createJumpThreadingPass() { return new JumpThreading(); } @@ -125,7 +137,7 @@ FunctionPass *llvm::createJumpThreadingPass() { return new JumpThreading(); } bool JumpThreading::runOnFunction(Function &F) { DEBUG(dbgs() << "Jump threading on function '" << F.getName() << "'\n"); TD = getAnalysisIfAvailable<TargetData>(); - LVI = EnableLVI ? &getAnalysis<LazyValueInfo>() : 0; + LVI = &getAnalysis<LazyValueInfo>(); FindLoopHeaders(F); @@ -147,7 +159,7 @@ bool JumpThreading::runOnFunction(Function &F) { DEBUG(dbgs() << " JT: Deleting dead block '" << BB->getName() << "' with terminator: " << *BB->getTerminator() << '\n'); LoopHeaders.erase(BB); - if (LVI) LVI->eraseBlock(BB); + LVI->eraseBlock(BB); DeleteDeadBlock(BB); Changed = true; } else if (BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator())) { @@ -172,7 +184,7 @@ bool JumpThreading::runOnFunction(Function &F) { // for a block even if it doesn't get erased. This isn't totally // awesome, but it allows us to use AssertingVH to prevent nasty // dangling pointer issues within LazyValueInfo. - if (LVI) LVI->eraseBlock(BB); + LVI->eraseBlock(BB); if (TryToSimplifyUncondBranchFromEmptyBlock(BB)) { Changed = true; // If we deleted BB and BB was the header of a loop, then the @@ -260,6 +272,17 @@ void JumpThreading::FindLoopHeaders(Function &F) { LoopHeaders.insert(const_cast<BasicBlock*>(Edges[i].second)); } +// Helper method for ComputeValueKnownInPredecessors. If Value is a +// ConstantInt, push it. If it's an undef, push 0. Otherwise, do nothing. +static void PushConstantIntOrUndef(SmallVectorImpl<std::pair<ConstantInt*, + BasicBlock*> > &Result, + Constant *Value, BasicBlock* BB){ + if (ConstantInt *FoldedCInt = dyn_cast<ConstantInt>(Value)) + Result.push_back(std::make_pair(FoldedCInt, BB)); + else if (isa<UndefValue>(Value)) + Result.push_back(std::make_pair((ConstantInt*)0, BB)); +} + /// ComputeValueKnownInPredecessors - Given a basic block BB and a value V, see /// if we can infer that the value is a known ConstantInt in any of our /// predecessors. If so, return the known list of value and pred BB in the @@ -269,12 +292,24 @@ void JumpThreading::FindLoopHeaders(Function &F) { /// bool JumpThreading:: ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ + // This method walks up use-def chains recursively. Because of this, we could + // get into an infinite loop going around loops in the use-def chain. To + // prevent this, keep track of what (value, block) pairs we've already visited + // and terminate the search if we loop back to them + if (!RecursionSet.insert(std::make_pair(V, BB)).second) + return false; + + // An RAII help to remove this pair from the recursion set once the recursion + // stack pops back out again. + RecursionSetRemover remover(RecursionSet, std::make_pair(V, BB)); + // If V is a constantint, then it is known in all predecessors. if (isa<ConstantInt>(V) || isa<UndefValue>(V)) { ConstantInt *CI = dyn_cast<ConstantInt>(V); for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) Result.push_back(std::make_pair(CI, *PI)); + return true; } @@ -290,29 +325,25 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ /// TODO: Per PR2563, we could infer value range information about a /// predecessor based on its terminator. // - if (LVI) { - // FIXME: change this to use the more-rich 'getPredicateOnEdge' method if - // "I" is a non-local compare-with-a-constant instruction. This would be - // able to handle value inequalities better, for example if the compare is - // "X < 4" and "X < 3" is known true but "X < 4" itself is not available. - // Perhaps getConstantOnEdge should be smart enough to do this? - - for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { - BasicBlock *P = *PI; - // If the value is known by LazyValueInfo to be a constant in a - // predecessor, use that information to try to thread this block. - Constant *PredCst = LVI->getConstantOnEdge(V, P, BB); - if (PredCst == 0 || - (!isa<ConstantInt>(PredCst) && !isa<UndefValue>(PredCst))) - continue; + // FIXME: change this to use the more-rich 'getPredicateOnEdge' method if + // "I" is a non-local compare-with-a-constant instruction. This would be + // able to handle value inequalities better, for example if the compare is + // "X < 4" and "X < 3" is known true but "X < 4" itself is not available. + // Perhaps getConstantOnEdge should be smart enough to do this? + + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { + BasicBlock *P = *PI; + // If the value is known by LazyValueInfo to be a constant in a + // predecessor, use that information to try to thread this block. + Constant *PredCst = LVI->getConstantOnEdge(V, P, BB); + if (PredCst == 0 || + (!isa<ConstantInt>(PredCst) && !isa<UndefValue>(PredCst))) + continue; - Result.push_back(std::make_pair(dyn_cast<ConstantInt>(PredCst), P)); - } - - return !Result.empty(); + Result.push_back(std::make_pair(dyn_cast<ConstantInt>(PredCst), P)); } - - return false; + + return !Result.empty(); } /// If I is a PHI node, then we know the incoming values for any constants. @@ -322,14 +353,15 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ if (isa<ConstantInt>(InVal) || isa<UndefValue>(InVal)) { ConstantInt *CI = dyn_cast<ConstantInt>(InVal); Result.push_back(std::make_pair(CI, PN->getIncomingBlock(i))); - } else if (LVI) { + } else { Constant *CI = LVI->getConstantOnEdge(InVal, PN->getIncomingBlock(i), BB); - ConstantInt *CInt = dyn_cast_or_null<ConstantInt>(CI); - if (CInt) - Result.push_back(std::make_pair(CInt, PN->getIncomingBlock(i))); + // LVI returns null is no value could be determined. + if (!CI) continue; + PushConstantIntOrUndef(Result, CI, PN->getIncomingBlock(i)); } } + return !Result.empty(); } @@ -372,11 +404,8 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ Result.back().first = InterestingVal; } } - return !Result.empty(); - - // Try to process a few other binary operator patterns. - } else if (isa<BinaryOperator>(I)) { + return !Result.empty(); } // Handle the NOT form of XOR. @@ -392,23 +421,27 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ if (Result[i].first) Result[i].first = cast<ConstantInt>(ConstantExpr::getNot(Result[i].first)); + return true; } // Try to simplify some other binary operator values. } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) { - // AND or OR of a value with itself is that value. - ConstantInt *CI = dyn_cast<ConstantInt>(BO->getOperand(1)); - if (CI && (BO->getOpcode() == Instruction::And || - BO->getOpcode() == Instruction::Or)) { + if (ConstantInt *CI = dyn_cast<ConstantInt>(BO->getOperand(1))) { SmallVector<std::pair<ConstantInt*, BasicBlock*>, 8> LHSVals; ComputeValueKnownInPredecessors(BO->getOperand(0), BB, LHSVals); - for (unsigned i = 0, e = LHSVals.size(); i != e; ++i) - if (LHSVals[i].first == CI) - Result.push_back(std::make_pair(CI, LHSVals[i].second)); - - return !Result.empty(); + + // Try to use constant folding to simplify the binary operator. + for (unsigned i = 0, e = LHSVals.size(); i != e; ++i) { + Constant *V = LHSVals[i].first; + if (V == 0) V = UndefValue::get(BO->getType()); + Constant *Folded = ConstantExpr::get(BO->getOpcode(), V, CI); + + PushConstantIntOrUndef(Result, Folded, LHSVals[i].second); + } } + + return !Result.empty(); } // Handle compare with phi operand, where the PHI is defined in this block. @@ -424,7 +457,7 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ Value *Res = SimplifyCmpInst(Cmp->getPredicate(), LHS, RHS, TD); if (Res == 0) { - if (!LVI || !isa<Constant>(RHS)) + if (!isa<Constant>(RHS)) continue; LazyValueInfo::Tristate @@ -435,10 +468,8 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ Res = ConstantInt::get(Type::getInt1Ty(LHS->getContext()), ResT); } - if (isa<UndefValue>(Res)) - Result.push_back(std::make_pair((ConstantInt*)0, PredBB)); - else if (ConstantInt *CI = dyn_cast<ConstantInt>(Res)) - Result.push_back(std::make_pair(CI, PredBB)); + if (Constant *ConstRes = dyn_cast<Constant>(Res)) + PushConstantIntOrUndef(Result, ConstRes, PredBB); } return !Result.empty(); @@ -447,10 +478,9 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ // If comparing a live-in value against a constant, see if we know the // live-in value on any predecessors. - if (LVI && isa<Constant>(Cmp->getOperand(1)) && - Cmp->getType()->isIntegerTy()) { + if (isa<Constant>(Cmp->getOperand(1)) && Cmp->getType()->isIntegerTy()) { if (!isa<Instruction>(Cmp->getOperand(0)) || - cast<Instruction>(Cmp->getOperand(0))->getParent() != BB) { + cast<Instruction>(Cmp->getOperand(0))->getParent() != BB) { Constant *RHSCst = cast<Constant>(Cmp->getOperand(1)); for (pred_iterator PI = pred_begin(BB), E = pred_end(BB);PI != E; ++PI){ @@ -470,22 +500,18 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ return !Result.empty(); } - // Try to find a constant value for the LHS of an equality comparison, + // Try to find a constant value for the LHS of a comparison, // and evaluate it statically if we can. - if (Cmp->getPredicate() == CmpInst::ICMP_EQ || - Cmp->getPredicate() == CmpInst::ICMP_NE) { + if (Constant *CmpConst = dyn_cast<Constant>(Cmp->getOperand(1))) { SmallVector<std::pair<ConstantInt*, BasicBlock*>, 8> LHSVals; ComputeValueKnownInPredecessors(I->getOperand(0), BB, LHSVals); - ConstantInt *True = ConstantInt::getTrue(I->getContext()); - ConstantInt *False = ConstantInt::getFalse(I->getContext()); - if (Cmp->getPredicate() == CmpInst::ICMP_NE) std::swap(True, False); - for (unsigned i = 0, e = LHSVals.size(); i != e; ++i) { - if (LHSVals[i].first == Cmp->getOperand(1)) - Result.push_back(std::make_pair(True, LHSVals[i].second)); - else - Result.push_back(std::make_pair(False, LHSVals[i].second)); + Constant *V = LHSVals[i].first; + if (V == 0) V = UndefValue::get(CmpConst->getType()); + Constant *Folded = ConstantExpr::getCompare(Cmp->getPredicate(), + V, CmpConst); + PushConstantIntOrUndef(Result, Folded, LHSVals[i].second); } return !Result.empty(); @@ -493,19 +519,15 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ } } - if (LVI) { - // If all else fails, see if LVI can figure out a constant value for us. - Constant *CI = LVI->getConstant(V, BB); - ConstantInt *CInt = dyn_cast_or_null<ConstantInt>(CI); - if (CInt) { - for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) - Result.push_back(std::make_pair(CInt, *PI)); - } - - return !Result.empty(); + // If all else fails, see if LVI can figure out a constant value for us. + Constant *CI = LVI->getConstant(V, BB); + ConstantInt *CInt = dyn_cast_or_null<ConstantInt>(CI); + if (CInt) { + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) + Result.push_back(std::make_pair(CInt, *PI)); } - - return false; + + return !Result.empty(); } @@ -555,7 +577,7 @@ bool JumpThreading::ProcessBlock(BasicBlock *BB) { // Remember if SinglePred was the entry block of the function. If so, we // will need to move BB back to the entry position. bool isEntry = SinglePred == &SinglePred->getParent()->getEntryBlock(); - if (LVI) LVI->eraseBlock(SinglePred); + LVI->eraseBlock(SinglePred); MergeBasicBlockIntoOnlyPred(BB); if (isEntry && BB != &BB->getParent()->getEntryBlock()) @@ -596,7 +618,7 @@ bool JumpThreading::ProcessBlock(BasicBlock *BB) { TerminatorInst *BBTerm = BB->getTerminator(); for (unsigned i = 0, e = BBTerm->getNumSuccessors(); i != e; ++i) { if (i == BestSucc) continue; - RemovePredecessorAndSimplify(BBTerm->getSuccessor(i), BB, TD); + BBTerm->getSuccessor(i)->removePredecessor(BB, true); } DEBUG(dbgs() << " In block '" << BB->getName() @@ -608,104 +630,50 @@ bool JumpThreading::ProcessBlock(BasicBlock *BB) { Instruction *CondInst = dyn_cast<Instruction>(Condition); - // If the condition is an instruction defined in another block, see if a - // predecessor has the same condition: - // br COND, BBX, BBY - // BBX: - // br COND, BBZ, BBW - if (!LVI && - !Condition->hasOneUse() && // Multiple uses. - (CondInst == 0 || CondInst->getParent() != BB)) { // Non-local definition. - pred_iterator PI = pred_begin(BB), E = pred_end(BB); - if (isa<BranchInst>(BB->getTerminator())) { - for (; PI != E; ++PI) { - BasicBlock *P = *PI; - if (BranchInst *PBI = dyn_cast<BranchInst>(P->getTerminator())) - if (PBI->isConditional() && PBI->getCondition() == Condition && - ProcessBranchOnDuplicateCond(P, BB)) - return true; - } - } else { - assert(isa<SwitchInst>(BB->getTerminator()) && "Unknown jump terminator"); - for (; PI != E; ++PI) { - BasicBlock *P = *PI; - if (SwitchInst *PSI = dyn_cast<SwitchInst>(P->getTerminator())) - if (PSI->getCondition() == Condition && - ProcessSwitchOnDuplicateCond(P, BB)) - return true; - } - } - } - // All the rest of our checks depend on the condition being an instruction. if (CondInst == 0) { // FIXME: Unify this with code below. - if (LVI && ProcessThreadableEdges(Condition, BB)) + if (ProcessThreadableEdges(Condition, BB)) return true; return false; } if (CmpInst *CondCmp = dyn_cast<CmpInst>(CondInst)) { - if (!LVI && - (!isa<PHINode>(CondCmp->getOperand(0)) || - cast<PHINode>(CondCmp->getOperand(0))->getParent() != BB)) { - // If we have a comparison, loop over the predecessors to see if there is - // a condition with a lexically identical value. - pred_iterator PI = pred_begin(BB), E = pred_end(BB); - for (; PI != E; ++PI) { - BasicBlock *P = *PI; - if (BranchInst *PBI = dyn_cast<BranchInst>(P->getTerminator())) - if (PBI->isConditional() && P != BB) { - if (CmpInst *CI = dyn_cast<CmpInst>(PBI->getCondition())) { - if (CI->getOperand(0) == CondCmp->getOperand(0) && - CI->getOperand(1) == CondCmp->getOperand(1) && - CI->getPredicate() == CondCmp->getPredicate()) { - // TODO: Could handle things like (x != 4) --> (x == 17) - if (ProcessBranchOnDuplicateCond(P, BB)) - return true; - } - } - } - } - } - // For a comparison where the LHS is outside this block, it's possible // that we've branched on it before. Used LVI to see if we can simplify // the branch based on that. BranchInst *CondBr = dyn_cast<BranchInst>(BB->getTerminator()); Constant *CondConst = dyn_cast<Constant>(CondCmp->getOperand(1)); - if (LVI && CondBr && CondConst && CondBr->isConditional() && + pred_iterator PI = pred_begin(BB), PE = pred_end(BB); + if (CondBr && CondConst && CondBr->isConditional() && PI != PE && (!isa<Instruction>(CondCmp->getOperand(0)) || cast<Instruction>(CondCmp->getOperand(0))->getParent() != BB)) { // For predecessor edge, determine if the comparison is true or false // on that edge. If they're all true or all false, we can simplify the // branch. // FIXME: We could handle mixed true/false by duplicating code. - unsigned Trues = 0, Falses = 0, predcount = 0; - for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);PI != PE; ++PI){ - ++predcount; - LazyValueInfo::Tristate Ret = - LVI->getPredicateOnEdge(CondCmp->getPredicate(), - CondCmp->getOperand(0), CondConst, *PI, BB); - if (Ret == LazyValueInfo::True) - ++Trues; - else if (Ret == LazyValueInfo::False) - ++Falses; - } - - // If we can determine the branch direction statically, convert - // the conditional branch to an unconditional one. - if (Trues && Trues == predcount) { - RemovePredecessorAndSimplify(CondBr->getSuccessor(1), BB, TD); - BranchInst::Create(CondBr->getSuccessor(0), CondBr); - CondBr->eraseFromParent(); - return true; - } else if (Falses && Falses == predcount) { - RemovePredecessorAndSimplify(CondBr->getSuccessor(0), BB, TD); - BranchInst::Create(CondBr->getSuccessor(1), CondBr); - CondBr->eraseFromParent(); - return true; + LazyValueInfo::Tristate Baseline = + LVI->getPredicateOnEdge(CondCmp->getPredicate(), CondCmp->getOperand(0), + CondConst, *PI, BB); + if (Baseline != LazyValueInfo::Unknown) { + // Check that all remaining incoming values match the first one. + while (++PI != PE) { + LazyValueInfo::Tristate Ret = + LVI->getPredicateOnEdge(CondCmp->getPredicate(), + CondCmp->getOperand(0), CondConst, *PI, BB); + if (Ret != Baseline) break; + } + + // If we terminated early, then one of the values didn't match. + if (PI == PE) { + unsigned ToRemove = Baseline == LazyValueInfo::True ? 1 : 0; + unsigned ToKeep = Baseline == LazyValueInfo::True ? 0 : 1; + CondBr->getSuccessor(ToRemove)->removePredecessor(BB, true); + BranchInst::Create(CondBr->getSuccessor(ToKeep), CondBr); + CondBr->eraseFromParent(); + return true; + } } } } @@ -1125,6 +1093,7 @@ bool JumpThreading::ProcessThreadableEdges(Value *Cond, BasicBlock *BB) { SmallVector<std::pair<ConstantInt*, BasicBlock*>, 8> PredValues; if (!ComputeValueKnownInPredecessors(Cond, BB, PredValues)) return false; + assert(!PredValues.empty() && "ComputeValueKnownInPredecessors returned true with no values"); @@ -1419,8 +1388,7 @@ bool JumpThreading::ThreadEdge(BasicBlock *BB, << ", across block:\n " << *BB << "\n"); - if (LVI) - LVI->threadEdge(PredBB, BB, SuccBB); + LVI->threadEdge(PredBB, BB, SuccBB); // We are going to have to map operands from the original BB block to the new // copy of the block 'NewBB'. If there are PHI nodes in BB, evaluate them to @@ -1491,7 +1459,7 @@ bool JumpThreading::ThreadEdge(BasicBlock *BB, // We found a use of I outside of BB. Rename all uses of I that are outside // its block to be uses of the appropriate PHI node etc. See ValuesInBlocks // with the two values we know. - SSAUpdate.Initialize(I); + SSAUpdate.Initialize(I->getType(), I->getName()); SSAUpdate.AddAvailableValue(BB, I); SSAUpdate.AddAvailableValue(NewBB, ValueMapping[I]); @@ -1507,7 +1475,7 @@ bool JumpThreading::ThreadEdge(BasicBlock *BB, TerminatorInst *PredTerm = PredBB->getTerminator(); for (unsigned i = 0, e = PredTerm->getNumSuccessors(); i != e; ++i) if (PredTerm->getSuccessor(i) == BB) { - RemovePredecessorAndSimplify(BB, PredBB, TD); + BB->removePredecessor(PredBB, true); PredTerm->setSuccessor(i, NewBB); } @@ -1646,7 +1614,7 @@ bool JumpThreading::DuplicateCondBranchOnPHIIntoPred(BasicBlock *BB, // We found a use of I outside of BB. Rename all uses of I that are outside // its block to be uses of the appropriate PHI node etc. See ValuesInBlocks // with the two values we know. - SSAUpdate.Initialize(I); + SSAUpdate.Initialize(I->getType(), I->getName()); SSAUpdate.AddAvailableValue(BB, I); SSAUpdate.AddAvailableValue(PredBB, ValueMapping[I]); @@ -1657,7 +1625,7 @@ bool JumpThreading::DuplicateCondBranchOnPHIIntoPred(BasicBlock *BB, // PredBB no longer jumps to BB, remove entries in the PHI node for the edge // that we nuked. - RemovePredecessorAndSimplify(BB, PredBB, TD); + BB->removePredecessor(PredBB, true); // Remove the unconditional branch at the end of the PredBB block. OldPredBranch->eraseFromParent(); |