diff options
Diffstat (limited to 'contrib/llvm/lib/Transforms/Utils/CloneFunction.cpp')
-rw-r--r-- | contrib/llvm/lib/Transforms/Utils/CloneFunction.cpp | 167 |
1 files changed, 86 insertions, 81 deletions
diff --git a/contrib/llvm/lib/Transforms/Utils/CloneFunction.cpp b/contrib/llvm/lib/Transforms/Utils/CloneFunction.cpp index 6454afb..4d33e22 100644 --- a/contrib/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/contrib/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/InstructionSimplify.h" @@ -119,6 +120,15 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, .addAttributes(NewFunc->getContext(), AttributeSet::FunctionIndex, OldAttrs.getFnAttributes())); + SmallVector<std::pair<unsigned, MDNode *>, 1> MDs; + OldFunc->getAllMetadata(MDs); + for (auto MD : MDs) + NewFunc->addMetadata( + MD.first, + *MapMetadata(MD.second, VMap, + ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges, + TypeMapper, Materializer)); + // Loop over all of the basic blocks in the function, cloning them as // appropriate. Note that we save BE this way in order to handle cloning of // recursive functions into themselves. @@ -163,65 +173,14 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, TypeMapper, Materializer); } -// Find the MDNode which corresponds to the subprogram data that described F. -static DISubprogram *FindSubprogram(const Function *F, - DebugInfoFinder &Finder) { - for (DISubprogram *Subprogram : Finder.subprograms()) { - if (Subprogram->describes(F)) - return Subprogram; - } - return nullptr; -} - -// Add an operand to an existing MDNode. The new operand will be added at the -// back of the operand list. -static void AddOperand(DICompileUnit *CU, DISubprogramArray SPs, - Metadata *NewSP) { - SmallVector<Metadata *, 16> NewSPs; - NewSPs.reserve(SPs.size() + 1); - for (auto *SP : SPs) - NewSPs.push_back(SP); - NewSPs.push_back(NewSP); - CU->replaceSubprograms(MDTuple::get(CU->getContext(), NewSPs)); -} - -// Clone the module-level debug info associated with OldFunc. The cloned data -// will point to NewFunc instead. -static void CloneDebugInfoMetadata(Function *NewFunc, const Function *OldFunc, - ValueToValueMapTy &VMap) { - DebugInfoFinder Finder; - Finder.processModule(*OldFunc->getParent()); - - const DISubprogram *OldSubprogramMDNode = FindSubprogram(OldFunc, Finder); - if (!OldSubprogramMDNode) return; - - auto *NewSubprogram = - cast<DISubprogram>(MapMetadata(OldSubprogramMDNode, VMap)); - NewFunc->setSubprogram(NewSubprogram); - - for (auto *CU : Finder.compile_units()) { - auto Subprograms = CU->getSubprograms(); - // If the compile unit's function list contains the old function, it should - // also contain the new one. - for (auto *SP : Subprograms) { - if (SP == OldSubprogramMDNode) { - AddOperand(CU, Subprograms, NewSubprogram); - break; - } - } - } -} - -/// Return a copy of the specified function, but without -/// embedding the function into another module. Also, any references specified -/// in the VMap are changed to refer to their mapped value instead of the -/// original one. If any of the arguments to the function are in the VMap, -/// the arguments are deleted from the resultant function. The VMap is -/// updated to include mappings from all of the instructions and basicblocks in -/// the function from their old to new values. +/// Return a copy of the specified function and add it to that function's +/// module. Also, any references specified in the VMap are changed to refer to +/// their mapped value instead of the original one. If any of the arguments to +/// the function are in the VMap, the arguments are deleted from the resultant +/// function. The VMap is updated to include mappings from all of the +/// instructions and basicblocks in the function from their old to new values. /// -Function *llvm::CloneFunction(const Function *F, ValueToValueMapTy &VMap, - bool ModuleLevelChanges, +Function *llvm::CloneFunction(Function *F, ValueToValueMapTy &VMap, ClonedCodeInfo *CodeInfo) { std::vector<Type*> ArgTypes; @@ -237,7 +196,8 @@ Function *llvm::CloneFunction(const Function *F, ValueToValueMapTy &VMap, ArgTypes, F->getFunctionType()->isVarArg()); // Create the new function... - Function *NewF = Function::Create(FTy, F->getLinkage(), F->getName()); + Function *NewF = + Function::Create(FTy, F->getLinkage(), F->getName(), F->getParent()); // Loop over the arguments, copying the names of the mapped arguments over... Function::arg_iterator DestI = NewF->arg_begin(); @@ -247,11 +207,10 @@ Function *llvm::CloneFunction(const Function *F, ValueToValueMapTy &VMap, VMap[&I] = &*DestI++; // Add mapping to VMap } - if (ModuleLevelChanges) - CloneDebugInfoMetadata(NewF, F, VMap); - SmallVector<ReturnInst*, 8> Returns; // Ignore returns cloned. - CloneFunctionInto(NewF, F, VMap, ModuleLevelChanges, Returns, "", CodeInfo); + CloneFunctionInto(NewF, F, VMap, /*ModuleLevelChanges=*/false, Returns, "", + CodeInfo); + return NewF; } @@ -338,9 +297,11 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB, if (Value *MappedV = VMap.lookup(V)) V = MappedV; - VMap[&*II] = V; - delete NewInst; - continue; + if (!NewInst->mayHaveSideEffects()) { + VMap[&*II] = V; + delete NewInst; + continue; + } } } @@ -372,7 +333,7 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB, ConstantInt *Cond = dyn_cast<ConstantInt>(BI->getCondition()); // Or is a known constant in the caller... if (!Cond) { - Value *V = VMap[BI->getCondition()]; + Value *V = VMap.lookup(BI->getCondition()); Cond = dyn_cast_or_null<ConstantInt>(V); } @@ -388,7 +349,7 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB, // If switching on a value known constant in the caller. ConstantInt *Cond = dyn_cast<ConstantInt>(SI->getCondition()); if (!Cond) { // Or known constant after constant prop in the callee... - Value *V = VMap[SI->getCondition()]; + Value *V = VMap.lookup(SI->getCondition()); Cond = dyn_cast_or_null<ConstantInt>(V); } if (Cond) { // Constant fold to uncond branch! @@ -475,7 +436,7 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc, // Defer PHI resolution until rest of function is resolved. SmallVector<const PHINode*, 16> PHIToResolve; for (const BasicBlock &BI : *OldFunc) { - Value *V = VMap[&BI]; + Value *V = VMap.lookup(&BI); BasicBlock *NewBB = cast_or_null<BasicBlock>(V); if (!NewBB) continue; // Dead block. @@ -519,7 +480,7 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc, OPN = PHIToResolve[phino]; PHINode *PN = cast<PHINode>(VMap[OPN]); for (unsigned pred = 0, e = NumPreds; pred != e; ++pred) { - Value *V = VMap[PN->getIncomingBlock(pred)]; + Value *V = VMap.lookup(PN->getIncomingBlock(pred)); if (BasicBlock *MappedBlock = cast_or_null<BasicBlock>(V)) { Value *InVal = MapValue(PN->getIncomingValue(pred), VMap, @@ -529,7 +490,8 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc, PN->setIncomingBlock(pred, MappedBlock); } else { PN->removeIncomingValue(pred, false); - --pred, --e; // Revisit the next entry. + --pred; // Revisit the next entry. + --e; } } } @@ -558,10 +520,9 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc, // entries. BasicBlock::iterator I = NewBB->begin(); for (; (PN = dyn_cast<PHINode>(I)); ++I) { - for (std::map<BasicBlock*, unsigned>::iterator PCI =PredCount.begin(), - E = PredCount.end(); PCI != E; ++PCI) { - BasicBlock *Pred = PCI->first; - for (unsigned NumToRemove = PCI->second; NumToRemove; --NumToRemove) + for (const auto &PCI : PredCount) { + BasicBlock *Pred = PCI.first; + for (unsigned NumToRemove = PCI.second; NumToRemove; --NumToRemove) PN->removeIncomingValue(Pred, false); } } @@ -592,9 +553,45 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc, // two PHINodes, the iteration over the old PHIs remains valid, and the // mapping will just map us to the new node (which may not even be a PHI // node). + const DataLayout &DL = NewFunc->getParent()->getDataLayout(); + SmallSetVector<const Value *, 8> Worklist; for (unsigned Idx = 0, Size = PHIToResolve.size(); Idx != Size; ++Idx) - if (PHINode *PN = dyn_cast<PHINode>(VMap[PHIToResolve[Idx]])) - recursivelySimplifyInstruction(PN); + if (isa<PHINode>(VMap[PHIToResolve[Idx]])) + Worklist.insert(PHIToResolve[Idx]); + + // Note that we must test the size on each iteration, the worklist can grow. + for (unsigned Idx = 0; Idx != Worklist.size(); ++Idx) { + const Value *OrigV = Worklist[Idx]; + auto *I = dyn_cast_or_null<Instruction>(VMap.lookup(OrigV)); + if (!I) + continue; + + // Skip over non-intrinsic callsites, we don't want to remove any nodes from + // the CGSCC. + CallSite CS = CallSite(I); + if (CS && CS.getCalledFunction() && !CS.getCalledFunction()->isIntrinsic()) + continue; + + // See if this instruction simplifies. + Value *SimpleV = SimplifyInstruction(I, DL); + if (!SimpleV) + continue; + + // Stash away all the uses of the old instruction so we can check them for + // recursive simplifications after a RAUW. This is cheaper than checking all + // uses of To on the recursive step in most cases. + for (const User *U : OrigV->users()) + Worklist.insert(cast<Instruction>(U)); + + // Replace the instruction with its simplified value. + I->replaceAllUsesWith(SimpleV); + + // If the original instruction had no side effects, remove it. + if (isInstructionTriviallyDead(I)) + I->eraseFromParent(); + else + VMap[OrigV] = I; + } // Now that the inlined function body has been fully constructed, go through // and zap unconditional fall-through branches. This happens all the time when @@ -684,7 +681,7 @@ void llvm::remapInstructionsInBlocks( for (auto *BB : Blocks) for (auto &Inst : *BB) RemapInstruction(&Inst, VMap, - RF_NoModuleLevelChanges | RF_IgnoreMissingEntries); + RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); } /// \brief Clones a loop \p OrigLoop. Returns the loop and the blocks in \p @@ -697,6 +694,8 @@ Loop *llvm::cloneLoopWithPreheader(BasicBlock *Before, BasicBlock *LoopDomBB, const Twine &NameSuffix, LoopInfo *LI, DominatorTree *DT, SmallVectorImpl<BasicBlock *> &Blocks) { + assert(OrigLoop->getSubLoops().empty() && + "Loop to be cloned cannot have inner loop"); Function *F = OrigLoop->getHeader()->getParent(); Loop *ParentLoop = OrigLoop->getParentLoop(); @@ -727,13 +726,19 @@ Loop *llvm::cloneLoopWithPreheader(BasicBlock *Before, BasicBlock *LoopDomBB, // Update LoopInfo. NewLoop->addBasicBlockToLoop(NewBB, *LI); - // Update DominatorTree. - BasicBlock *IDomBB = DT->getNode(BB)->getIDom()->getBlock(); - DT->addNewBlock(NewBB, cast<BasicBlock>(VMap[IDomBB])); + // Add DominatorTree node. After seeing all blocks, update to correct IDom. + DT->addNewBlock(NewBB, NewPH); Blocks.push_back(NewBB); } + for (BasicBlock *BB : OrigLoop->getBlocks()) { + // Update DominatorTree. + BasicBlock *IDomBB = DT->getNode(BB)->getIDom()->getBlock(); + DT->changeImmediateDominator(cast<BasicBlock>(VMap[BB]), + cast<BasicBlock>(VMap[IDomBB])); + } + // Move them physically from the end of the block list. F->getBasicBlockList().splice(Before->getIterator(), F->getBasicBlockList(), NewPH); |