Skip to content

Commit

Permalink
Merging r309928:
Browse files Browse the repository at this point in the history
------------------------------------------------------------------------
r309928 | ewancrawford | 2017-08-03 02:23:03 -0700 (Thu, 03 Aug 2017) | 56 lines

[Cloning] Move distinct GlobalVariable debug info metadata in CloneModule

Duplicating the distinct Subprogram and CU metadata nodes seems like the incorrect thing to do in CloneModule for GlobalVariable debug info. As it results in the scope of the GlobalVariable DI no longer being consistent with the rest of the module, and the new CU is absent from llvm.dbg.cu.

Fixed by adding RF_MoveDistinctMDs to MapMetadata flags for GlobalVariables.

Current unit test IR after clone:
```
@gv = global i32 1, comdat($comdat), !dbg !0, !type !5

define private void @f() comdat($comdat) personality void ()* @persfn !dbg !14 {

!llvm.dbg.cu = !{!10}

!0 = !DIGlobalVariableExpression(var: !1)
!1 = distinct !DIGlobalVariable(name: "gv", linkageName: "gv", scope: !2, file: !3, line: 1, type: !9, isLocal: false, isDefinition: true)
!2 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !3, line: 4, type: !4, isLocal: true, isDefinition: true, scopeLine: 3, isOptimized: false, unit: !6, variables: !5)
!3 = !DIFile(filename: "filename.c", directory: "/file/dir/")
!4 = !DISubroutineType(types: !5)
!5 = !{}
!6 = distinct !DICompileUnit(language: DW_LANG_C99, file: !7, producer: "CloneModule", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !5, globals: !8)
!7 = !DIFile(filename: "filename.c", directory: "/file/dir")
!8 = !{!0}
!9 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "decltype(nullptr)")
!10 = distinct !DICompileUnit(language: DW_LANG_C99, file: !7, producer: "CloneModule", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !5, globals: !11)
!11 = !{!12}
!12 = !DIGlobalVariableExpression(var: !13)
!13 = distinct !DIGlobalVariable(name: "gv", linkageName: "gv", scope: !14, file: !3, line: 1, type: !9, isLocal: false, isDefinition: true)
!14 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !3, line: 4, type: !4, isLocal: true, isDefinition: true, scopeLine: 3, isOptimized: false, unit: !10, variables: !5)
```

Patched IR after clone:
```
@gv = global i32 1, comdat($comdat), !dbg !0, !type !5

define private void @f() comdat($comdat) personality void ()* @persfn !dbg !2 {

!llvm.dbg.cu = !{!6}

!0 = !DIGlobalVariableExpression(var: !1)
!1 = distinct !DIGlobalVariable(name: "gv", linkageName: "gv", scope: !2, file: !3, line: 1, type: !9, isLocal: false, isDefinition: true)
!2 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !3, line: 4, type: !4, isLocal: true, isDefinition: true, scopeLine: 3, isOptimized: false, unit: !6, variables: !5)
!3 = !DIFile(filename: "filename.c", directory: "/file/dir/")
!4 = !DISubroutineType(types: !5)
!5 = !{}
!6 = distinct !DICompileUnit(language: DW_LANG_C99, file: !7, producer: "CloneModule", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !5, globals: !8)
!7 = !DIFile(filename: "filename.c", directory: "/file/dir")
!8 = !{!0}
!9 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "decltype(nullptr)")
```

Reviewers: aprantl, probinson, dblaikie, echristo, loladiro
Reviewed By: aprantl
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D36082

------------------------------------------------------------------------

llvm-svn: 309965
  • Loading branch information
zmodem committed Aug 3, 2017
1 parent add6d42 commit 335fe85
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
3 changes: 2 additions & 1 deletion llvm/lib/Transforms/Utils/CloneModule.cpp
Expand Up @@ -132,7 +132,8 @@ std::unique_ptr<Module> llvm::CloneModule(
SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
I->getAllMetadata(MDs);
for (auto MD : MDs)
GV->addMetadata(MD.first, *MapMetadata(MD.second, VMap));
GV->addMetadata(MD.first,
*MapMetadata(MD.second, VMap, RF_MoveDistinctMDs));

copyComdat(GV, &*I);
}
Expand Down
59 changes: 59 additions & 0 deletions llvm/unittests/Transforms/Utils/Cloning.cpp
Expand Up @@ -507,6 +507,19 @@ class CloneModule : public ::testing::Test {
DINode::FlagZero, false);
F->setSubprogram(Subprogram);

// Create and assign DIGlobalVariableExpression to gv
auto GVExpression = DBuilder.createGlobalVariableExpression(
Subprogram, "gv", "gv", File, 1, DBuilder.createNullPtrType(), false);
GV->addDebugInfo(GVExpression);

// DIGlobalVariableExpression not attached to any global variable
auto Expr = DBuilder.createExpression(
ArrayRef<uint64_t>{dwarf::DW_OP_constu, 42U, dwarf::DW_OP_stack_value});

DBuilder.createGlobalVariableExpression(
Subprogram, "unattached", "unattached", File, 1,
DBuilder.createNullPtrType(), false, Expr);

auto *Entry = BasicBlock::Create(C, "", F);
IBuilder.SetInsertPoint(Entry);
IBuilder.CreateRetVoid();
Expand Down Expand Up @@ -546,6 +559,52 @@ TEST_F(CloneModule, GlobalMetadata) {
EXPECT_NE(nullptr, NewGV->getMetadata(LLVMContext::MD_type));
}

TEST_F(CloneModule, GlobalDebugInfo) {
GlobalVariable *NewGV = NewM->getGlobalVariable("gv");
EXPECT_TRUE(NewGV != nullptr);

// Find debug info expression assigned to global
SmallVector<DIGlobalVariableExpression *, 1> GVs;
NewGV->getDebugInfo(GVs);
EXPECT_EQ(GVs.size(), 1U);

DIGlobalVariableExpression *GVExpr = GVs[0];
DIGlobalVariable *GV = GVExpr->getVariable();
EXPECT_TRUE(GV != nullptr);

EXPECT_EQ(GV->getName(), "gv");
EXPECT_EQ(GV->getLine(), 1U);

// Assert that the scope of the debug info attached to
// global variable matches the cloned function.
DISubprogram *SP = NewM->getFunction("f")->getSubprogram();
EXPECT_TRUE(SP != nullptr);
EXPECT_EQ(GV->getScope(), SP);
}

TEST_F(CloneModule, CompileUnit) {
// Find DICompileUnit listed in llvm.dbg.cu
auto *NMD = NewM->getNamedMetadata("llvm.dbg.cu");
EXPECT_TRUE(NMD != nullptr);
EXPECT_EQ(NMD->getNumOperands(), 1U);

DICompileUnit *CU = dyn_cast<llvm::DICompileUnit>(NMD->getOperand(0));
EXPECT_TRUE(CU != nullptr);

// Assert this CU is consistent with the cloned function debug info
DISubprogram *SP = NewM->getFunction("f")->getSubprogram();
EXPECT_TRUE(SP != nullptr);
EXPECT_EQ(SP->getUnit(), CU);

// Check globals listed in CU have the correct scope
DIGlobalVariableExpressionArray GlobalArray = CU->getGlobalVariables();
EXPECT_EQ(GlobalArray.size(), 2U);
for (DIGlobalVariableExpression *GVExpr : GlobalArray) {
DIGlobalVariable *GV = GVExpr->getVariable();
EXPECT_EQ(GV->getScope(), SP);
}
}

TEST_F(CloneModule, Comdat) {
GlobalVariable *NewGV = NewM->getGlobalVariable("gv");
auto *CD = NewGV->getComdat();
Expand Down

0 comments on commit 335fe85

Please sign in to comment.