Skip to content

Commit

Permalink
[Cloning] Clone every Function's Debug Info
Browse files Browse the repository at this point in the history
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260791 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Keno committed Feb 13, 2016
1 parent e31b74e commit 11adcc4
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 2 deletions.
5 changes: 5 additions & 0 deletions include/llvm/Transforms/Utils/Cloning.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions lib/Transforms/Utils/CloneFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand Down
1 change: 1 addition & 0 deletions lib/Transforms/Utils/CloneModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
25 changes: 25 additions & 0 deletions unittests/Transforms/Utils/Cloning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ class CloneModule : public ::testing::Test {
void SetupModule() { OldM = new Module("", C); }

void CreateOldModule() {
DIBuilder DBuilder(*OldM);
IRBuilder<> IBuilder(C);

auto *FuncType = FunctionType::get(Type::getVoidTy(C), false);
Expand All @@ -431,9 +432,25 @@ class CloneModule : public ::testing::Test {
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(); }
Expand All @@ -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);
}
}

0 comments on commit 11adcc4

Please sign in to comment.