diff options
-rw-r--r-- | llvm/include/llvm/Transforms/Utils/Cloning.h | 27 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUAlwaysInlinePass.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/PartialInlining.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/CloneFunction.cpp | 40 | ||||
-rw-r--r-- | llvm/unittests/Transforms/Utils/Cloning.cpp | 14 |
5 files changed, 32 insertions, 56 deletions
diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h index 6adc58e2e98..2ff9b84d3ff 100644 --- a/llvm/include/llvm/Transforms/Utils/Cloning.h +++ b/llvm/include/llvm/Transforms/Utils/Cloning.h @@ -114,20 +114,19 @@ BasicBlock *CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, 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 diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAlwaysInlinePass.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAlwaysInlinePass.cpp index ad267d35085..63f5fb3cdf0 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUAlwaysInlinePass.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUAlwaysInlinePass.cpp @@ -45,9 +45,8 @@ bool AMDGPUAlwaysInline::runOnModule(Module &M) { 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); } diff --git a/llvm/lib/Transforms/IPO/PartialInlining.cpp b/llvm/lib/Transforms/IPO/PartialInlining.cpp index 7b1b0985043..b602cf4fb58 100644 --- a/llvm/lib/Transforms/IPO/PartialInlining.cpp +++ b/llvm/lib/Transforms/IPO/PartialInlining.cpp @@ -71,10 +71,8 @@ Function* PartialInliner::unswitchFunction(Function* F) { // 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<BasicBlock>(VMap[entryBlock]); BasicBlock* newReturnBlock = cast<BasicBlock>(VMap[returnBlock]); BasicBlock* newNonReturnBlock = cast<BasicBlock>(VMap[nonReturnBlock]); diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index c8d12129861..24f7d69293e 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -172,30 +172,14 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, TypeMapper, Materializer); } -// 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) { - if (const DISubprogram *OldSP = OldFunc->getSubprogram()) { - auto *NewSP = cast<DISubprogram>(MapMetadata(OldSP, VMap)); - // FIXME: There ought to be a better way to do this: ValueMapper - // will clone the distinct DICompileUnit. Use the original one - // instead. - NewSP->replaceUnit(OldSP->getUnit()); - NewFunc->setSubprogram(NewSP); - } -} - -/// 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; @@ -211,7 +195,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(); @@ -221,11 +206,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; } diff --git a/llvm/unittests/Transforms/Utils/Cloning.cpp b/llvm/unittests/Transforms/Utils/Cloning.cpp index 44804107738..f53e0a95e94 100644 --- a/llvm/unittests/Transforms/Utils/Cloning.cpp +++ b/llvm/unittests/Transforms/Utils/Cloning.cpp @@ -274,8 +274,7 @@ protected: void CreateNewFunc() { ValueToValueMapTy VMap; - NewFunc = CloneFunction(OldFunc, VMap, true, nullptr); - M->getFunctionList().push_back(NewFunc); + NewFunc = CloneFunction(OldFunc, VMap, nullptr); } void SetupFinder() { @@ -301,16 +300,13 @@ TEST_F(CloneFunc, Subprogram) { 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<DISubprogram>(*Iter); - Iter++; - auto *Sub2 = cast<DISubprogram>(*Iter); + auto *Sub = cast<DISubprogram>(*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 instructions in the old function still belong to it in the |