diff --git a/llvm/include/llvm/Transforms/Scalar/JumpThreading.h b/llvm/include/llvm/Transforms/Scalar/JumpThreading.h --- a/llvm/include/llvm/Transforms/Scalar/JumpThreading.h +++ b/llvm/include/llvm/Transforms/Scalar/JumpThreading.h @@ -112,6 +112,8 @@ bool MaybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB); void UpdateSSA(BasicBlock *BB, BasicBlock *NewBB, DenseMap &ValueMapping); + std::pair> + CloneBasicBlock(BasicBlock *BB, BasicBlock* PredBB); bool ThreadEdge(BasicBlock *BB, const SmallVectorImpl &PredBBs, BasicBlock *SuccBB); bool DuplicateCondBranchOnPHIIntoPred( diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -1973,6 +1973,58 @@ } } +/// Clone basic block BB except its terminator just for predecessor PredBB. +/// Return the newly created basic block and the map from the variables in BB to +/// the variables in the newly created basic block. +std::pair> +JumpThreadingPass::CloneBasicBlock(BasicBlock *BB, BasicBlock* PredBB) { + // 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 + // account for entry from PredBB. + DenseMap ValueMapping; + + BasicBlock *NewBB = BasicBlock::Create(BB->getContext(), + BB->getName()+".thread", + BB->getParent(), BB); + NewBB->moveAfter(PredBB); + + // Set the block frequency of NewBB. + if (HasProfileData) { + auto NewBBFreq = + BFI->getBlockFreq(PredBB) * BPI->getEdgeProbability(PredBB, BB); + BFI->setBlockFreq(NewBB, NewBBFreq.getFrequency()); + } + + BasicBlock::iterator BI = BB->begin(); + // Clone the phi nodes of BB into NewBB. The resulting phi nodes are trivial, + // since NewBB only has one predecessor, but SSAUpdater might need to rewrite + // the operand of the cloned phi. + for (; PHINode *PN = dyn_cast(BI); ++BI) { + PHINode *NewPN = PHINode::Create(PN->getType(), 1, PN->getName(), NewBB); + NewPN->addIncoming(PN->getIncomingValueForBlock(PredBB), PredBB); + ValueMapping[PN] = NewPN; + } + + // Clone the non-phi instructions of BB into NewBB, keeping track of the + // mapping and using it to remap operands in the cloned instructions. + for (; !BI->isTerminator(); ++BI) { + Instruction *New = BI->clone(); + New->setName(BI->getName()); + NewBB->getInstList().push_back(New); + ValueMapping[&*BI] = New; + + // Remap operands to patch up intra-block references. + for (unsigned i = 0, e = New->getNumOperands(); i != e; ++i) + if (Instruction *Inst = dyn_cast(New->getOperand(i))) { + DenseMap::iterator I = ValueMapping.find(Inst); + if (I != ValueMapping.end()) + New->setOperand(i, I->second); + } + } + + return {NewBB, ValueMapping}; +} + /// ThreadEdge - We have decided that it is safe and profitable to factor the /// blocks in PredBBs to one predecessor, then thread an edge from it to SuccBB /// across BB. Transform the IR to reflect this change. @@ -2030,49 +2082,9 @@ LVI->enableDT(); 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 - // account for entry from PredBB. DenseMap ValueMapping; - - BasicBlock *NewBB = BasicBlock::Create(BB->getContext(), - BB->getName()+".thread", - BB->getParent(), BB); - NewBB->moveAfter(PredBB); - - // Set the block frequency of NewBB. - if (HasProfileData) { - auto NewBBFreq = - BFI->getBlockFreq(PredBB) * BPI->getEdgeProbability(PredBB, BB); - BFI->setBlockFreq(NewBB, NewBBFreq.getFrequency()); - } - - BasicBlock::iterator BI = BB->begin(); - // Clone the phi nodes of BB into NewBB. The resulting phi nodes are trivial, - // since NewBB only has one predecessor, but SSAUpdater might need to rewrite - // the operand of the cloned phi. - for (; PHINode *PN = dyn_cast(BI); ++BI) { - PHINode *NewPN = PHINode::Create(PN->getType(), 1, PN->getName(), NewBB); - NewPN->addIncoming(PN->getIncomingValueForBlock(PredBB), PredBB); - ValueMapping[PN] = NewPN; - } - - // Clone the non-phi instructions of BB into NewBB, keeping track of the - // mapping and using it to remap operands in the cloned instructions. - for (; !BI->isTerminator(); ++BI) { - Instruction *New = BI->clone(); - New->setName(BI->getName()); - NewBB->getInstList().push_back(New); - ValueMapping[&*BI] = New; - - // Remap operands to patch up intra-block references. - for (unsigned i = 0, e = New->getNumOperands(); i != e; ++i) - if (Instruction *Inst = dyn_cast(New->getOperand(i))) { - DenseMap::iterator I = ValueMapping.find(Inst); - if (I != ValueMapping.end()) - New->setOperand(i, I->second); - } - } + BasicBlock *NewBB; + std::tie(NewBB, ValueMapping) = CloneBasicBlock(BB, PredBB); // We didn't copy the terminator from BB over to NewBB, because there is now // an unconditional jump to SuccBB. Insert the unconditional jump.