summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorKeno Fischer <kfischer@college.harvard.edu>2016-02-13 02:04:29 +0000
committerKeno Fischer <kfischer@college.harvard.edu>2016-02-13 02:04:29 +0000
commit7c7c3e35911f7f7c1709cac05b1d27ce19db5ab5 (patch)
treedfa4b1aa108c91e53e2c5822d5037de8da5fce06 /llvm
parent5e845e54f59930b86c1aca689345bcbaf4311c95 (diff)
downloadbcm5719-llvm-7c7c3e35911f7f7c1709cac05b1d27ce19db5ab5.tar.gz
bcm5719-llvm-7c7c3e35911f7f7c1709cac05b1d27ce19db5ab5.zip
[Cloning] Clone every Function's Debug Info
Summary: Export the CloneDebugInfoMetadata utility, which clones all debug info associated with a function into the first module. Also use this function in CloneModule on each function we clone (the CloneFunction entrypoint already does this). Without this, cloning a module will lead to DI quality regressions, especially since r252219 reversed the Function <-> DISubprogram edge (before we could get lucky and have this edge preserved if the DISubprogram itself was, e.g. due to location metadata). This was verified to fix missing debug information in julia and a unittest to verify the new behavior is included. Patch by Yichao Yu! Thanks! Reviewers: loladiro, pcc Differential Revision: http://reviews.llvm.org/D17165 llvm-svn: 260791
Diffstat (limited to 'llvm')
-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