summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Transforms/Utils/Cloning.h5
-rw-r--r--llvm/lib/Transforms/Utils/CloneFunction.cpp4
-rw-r--r--llvm/lib/Transforms/Utils/CloneModule.cpp1
-rw-r--r--llvm/unittests/Transforms/Utils/Cloning.cpp25
4 files changed, 33 insertions, 2 deletions
diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h
index 4f006f2adee..0bae2bd533c 100644
--- a/llvm/include/llvm/Transforms/Utils/Cloning.h
+++ b/llvm/include/llvm/Transforms/Utils/Cloning.h
@@ -130,6 +130,11 @@ Function *CloneFunction(const Function *F, ValueToValueMapTy &VMap,
bool ModuleLevelChanges,
ClonedCodeInfo *CodeInfo = nullptr);
+/// Clone the module-level debug info associated with OldFunc. The cloned data
+/// will point to NewFunc instead.
+void CloneDebugInfoMetadata(Function *NewFunc, const Function *OldFunc,
+ ValueToValueMapTy &VMap);
+
/// Clone OldFunc into NewFunc, transforming the old arguments into references
/// to VMap values. Note that if NewFunc already has basic blocks, the ones
/// cloned into it will be added to the end of the function. This function
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 6454afb8bc4..8b5692a78cc 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -187,8 +187,8 @@ static void AddOperand(DICompileUnit *CU, DISubprogramArray SPs,
// 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) {
+void llvm::CloneDebugInfoMetadata(Function *NewFunc, const Function *OldFunc,
+ ValueToValueMapTy &VMap) {
DebugInfoFinder Finder;
Finder.processModule(*OldFunc->getParent());
diff --git a/llvm/lib/Transforms/Utils/CloneModule.cpp b/llvm/lib/Transforms/Utils/CloneModule.cpp
index 53de62a28eb..b16a02adbd6 100644
--- a/llvm/lib/Transforms/Utils/CloneModule.cpp
+++ b/llvm/lib/Transforms/Utils/CloneModule.cpp
@@ -136,6 +136,7 @@ std::unique_ptr<Module> llvm::CloneModule(
VMap[&*J] = &*DestI++;
}
+ CloneDebugInfoMetadata(F, &*I, VMap);
SmallVector<ReturnInst*, 8> Returns; // Ignore returns cloned.
CloneFunctionInto(F, &*I, VMap, /*ModuleLevelChanges=*/true, Returns);
}
diff --git a/llvm/unittests/Transforms/Utils/Cloning.cpp b/llvm/unittests/Transforms/Utils/Cloning.cpp
index 25e322ee5a8..b761e4e220e 100644
--- a/llvm/unittests/Transforms/Utils/Cloning.cpp
+++ b/llvm/unittests/Transforms/Utils/Cloning.cpp
@@ -423,6 +423,7 @@ protected:
void SetupModule() { OldM = new Module("", C); }
void CreateOldModule() {
+ DIBuilder DBuilder(*OldM);
IRBuilder<> IBuilder(C);
auto *FuncType = FunctionType::get(Type::getVoidTy(C), false);
@@ -431,9 +432,25 @@ protected:
auto *F =
Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", OldM);
F->setPersonalityFn(PersFn);
+
+ // Create debug info
+ auto *File = DBuilder.createFile("filename.c", "/file/dir/");
+ DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
+ DISubroutineType *DFuncType = DBuilder.createSubroutineType(ParamTypes);
+ auto *CU =
+ DBuilder.createCompileUnit(dwarf::DW_LANG_C99, "filename.c",
+ "/file/dir", "CloneModule", false, "", 0);
+ // Function DI
+ auto *Subprogram = DBuilder.createFunction(CU, "f", "f", File, 4, DFuncType,
+ true, true, 3, 0, false);
+ F->setSubprogram(Subprogram);
+
auto *Entry = BasicBlock::Create(C, "", F);
IBuilder.SetInsertPoint(Entry);
IBuilder.CreateRetVoid();
+
+ // Finalize the debug info
+ DBuilder.finalize();
}
void CreateNewModule() { NewM = llvm::CloneModule(OldM).release(); }
@@ -447,4 +464,12 @@ TEST_F(CloneModule, Verify) {
EXPECT_FALSE(verifyModule(*NewM));
}
+TEST_F(CloneModule, Subprogram) {
+ Function *NewF = NewM->getFunction("f");
+ DISubprogram *SP = NewF->getSubprogram();
+ EXPECT_TRUE(SP != nullptr);
+ EXPECT_EQ(SP->getName(), "f");
+ EXPECT_EQ(SP->getFile()->getFilename(), "filename.c");
+ EXPECT_EQ(SP->getLine(), (unsigned)4);
+}
}
OpenPOWER on IntegriCloud