Index: include/llvm/Transforms/Utils/Cloning.h =================================================================== --- include/llvm/Transforms/Utils/Cloning.h +++ include/llvm/Transforms/Utils/Cloning.h @@ -114,20 +114,19 @@ const Twine &NameSuffix = "", Function *F = nullptr, ClonedCodeInfo *CodeInfo = nullptr); -/// CloneFunction - 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. The final argument captures -/// information about the cloned code if non-null. -/// -/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue -/// mappings, and debug info metadata will not be cloned. -/// -Function *CloneFunction(const Function *F, ValueToValueMapTy &VMap, - bool ModuleLevelChanges, +/// CloneFunction - 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. The final argument captures information about the cloned code if +/// non-null. +/// +/// VMap contains no non-identity GlobalValue mappings and debug info metadata +/// will not be cloned. +/// +Function *CloneFunction(Function *F, ValueToValueMapTy &VMap, ClonedCodeInfo *CodeInfo = nullptr); /// Clone OldFunc into NewFunc, transforming the old arguments into references Index: lib/Target/AMDGPU/AMDGPUAlwaysInlinePass.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUAlwaysInlinePass.cpp +++ lib/Target/AMDGPU/AMDGPUAlwaysInlinePass.cpp @@ -45,9 +45,8 @@ for (Function *F : FuncsToClone) { ValueToValueMapTy VMap; - Function *NewFunc = CloneFunction(F, VMap, false); + Function *NewFunc = CloneFunction(F, VMap); NewFunc->setLinkage(GlobalValue::InternalLinkage); - M.getFunctionList().push_back(NewFunc); F->replaceAllUsesWith(NewFunc); } Index: lib/Transforms/IPO/PartialInlining.cpp =================================================================== --- lib/Transforms/IPO/PartialInlining.cpp +++ lib/Transforms/IPO/PartialInlining.cpp @@ -71,10 +71,8 @@ // Clone the function, so that we can hack away on it. ValueToValueMapTy VMap; - Function* duplicateFunction = CloneFunction(F, VMap, - /*ModuleLevelChanges=*/false); + Function* duplicateFunction = CloneFunction(F, VMap); duplicateFunction->setLinkage(GlobalValue::InternalLinkage); - F->getParent()->getFunctionList().push_back(duplicateFunction); BasicBlock* newEntryBlock = cast(VMap[entryBlock]); BasicBlock* newReturnBlock = cast(VMap[returnBlock]); BasicBlock* newNonReturnBlock = cast(VMap[nonReturnBlock]); Index: lib/Transforms/Utils/CloneFunction.cpp =================================================================== --- lib/Transforms/Utils/CloneFunction.cpp +++ lib/Transforms/Utils/CloneFunction.cpp @@ -172,65 +172,14 @@ 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 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(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 ArgTypes; @@ -246,7 +195,8 @@ 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(); @@ -256,11 +206,10 @@ VMap[&I] = &*DestI++; // Add mapping to VMap } - if (ModuleLevelChanges) - CloneDebugInfoMetadata(NewF, F, VMap); - SmallVector Returns; // Ignore returns cloned. - CloneFunctionInto(NewF, F, VMap, ModuleLevelChanges, Returns, "", CodeInfo); + CloneFunctionInto(NewF, F, VMap, /*ModuleLevelChanges=*/false, Returns, "", + CodeInfo); + return NewF; } Index: unittests/Transforms/Utils/Cloning.cpp =================================================================== --- unittests/Transforms/Utils/Cloning.cpp +++ unittests/Transforms/Utils/Cloning.cpp @@ -275,8 +275,7 @@ void CreateNewFunc() { ValueToValueMapTy VMap; - NewFunc = CloneFunction(OldFunc, VMap, true, nullptr); - M->getFunctionList().push_back(NewFunc); + NewFunc = CloneFunction(OldFunc, VMap, nullptr); } void SetupFinder() { @@ -302,16 +301,13 @@ EXPECT_FALSE(verifyModule(*M)); unsigned SubprogramCount = Finder->subprogram_count(); - EXPECT_EQ(2U, SubprogramCount); + EXPECT_EQ(1U, SubprogramCount); auto Iter = Finder->subprograms().begin(); - auto *Sub1 = cast(*Iter); - Iter++; - auto *Sub2 = cast(*Iter); + auto *Sub = cast(*Iter); - EXPECT_TRUE( - (Sub1 == OldFunc->getSubprogram() && Sub2 == NewFunc->getSubprogram()) || - (Sub1 == NewFunc->getSubprogram() && Sub2 == OldFunc->getSubprogram())); + EXPECT_TRUE(Sub == OldFunc->getSubprogram()); + EXPECT_TRUE(Sub == NewFunc->getSubprogram()); } // Test that the new subprogram entry was not added to the CU which doesn't