Skip to content

Commit

Permalink
[DebugInfo] Do not replace existing nodes from DICompileUnit
Browse files Browse the repository at this point in the history
When creating a new DIBuilder with an existing DICompileUnit, load the
DINodes from the current DICompileUnit so they don't get overwritten.
This is done in the MachineOutliner pass, but it didn't change the CU so
the bug never appeared. We need this if we ever want to add DINodes to
the CU after it has been created, e.g., DIGlobalVariables.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D114556
  • Loading branch information
ellishg authored and Kyungwoo Lee committed Nov 30, 2021
1 parent 5297cbf commit 0150645
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 1 deletion.
15 changes: 14 additions & 1 deletion llvm/lib/IR/DIBuilder.cpp
Expand Up @@ -34,7 +34,20 @@ static cl::opt<bool>
DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes, DICompileUnit *CU)
: M(m), VMContext(M.getContext()), CUNode(CU), DeclareFn(nullptr),
ValueFn(nullptr), LabelFn(nullptr),
AllowUnresolvedNodes(AllowUnresolvedNodes) {}
AllowUnresolvedNodes(AllowUnresolvedNodes) {
if (CUNode) {
if (const auto &ETs = CUNode->getEnumTypes())
AllEnumTypes.assign(ETs.begin(), ETs.end());
if (const auto &RTs = CUNode->getRetainedTypes())
AllRetainTypes.assign(RTs.begin(), RTs.end());
if (const auto &GVs = CUNode->getGlobalVariables())
AllGVs.assign(GVs.begin(), GVs.end());
if (const auto &IMs = CUNode->getImportedEntities())
AllImportedModules.assign(IMs.begin(), IMs.end());
if (const auto &MNs = CUNode->getMacros())
AllMacrosPerParent.insert({nullptr, {MNs.begin(), MNs.end()}});
}
}

void DIBuilder::trackIfUnresolved(MDNode *N) {
if (!N)
Expand Down
67 changes: 67 additions & 0 deletions llvm/unittests/IR/IRBuilderTest.cpp
Expand Up @@ -18,9 +18,11 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Verifier.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

using namespace llvm;
using ::testing::UnorderedElementsAre;

namespace {

Expand Down Expand Up @@ -891,6 +893,71 @@ TEST_F(IRBuilderTest, createArtificialSubprogram) {
EXPECT_TRUE(GSP->isArtificial());
}

// Check that we can add debug info to an existing DICompileUnit.
TEST_F(IRBuilderTest, appendDebugInfo) {
IRBuilder<> Builder(BB);
Builder.CreateRetVoid();
EXPECT_FALSE(verifyModule(*M));

auto GetNames = [](DICompileUnit *CU) {
SmallVector<StringRef> Names;
for (auto *ET : CU->getEnumTypes())
Names.push_back(ET->getName());
for (auto *RT : CU->getRetainedTypes())
Names.push_back(RT->getName());
for (auto *GV : CU->getGlobalVariables())
Names.push_back(GV->getVariable()->getName());
for (auto *IE : CU->getImportedEntities())
Names.push_back(IE->getName());
for (auto *Node : CU->getMacros())
if (auto *MN = dyn_cast_or_null<DIMacro>(Node))
Names.push_back(MN->getName());
return Names;
};

DICompileUnit *CU;
{
DIBuilder DIB(*M);
auto *File = DIB.createFile("main.c", "/");
CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "clang",
/*isOptimized=*/true, /*Flags=*/"",
/*Runtime Version=*/0);
auto *ByteTy = DIB.createBasicType("byte0", 8, dwarf::DW_ATE_signed);
DIB.createEnumerationType(CU, "ET0", File, /*LineNo=*/0, /*SizeInBits=*/8,
/*AlignInBits=*/8, /*Elements=*/{}, ByteTy);
DIB.retainType(ByteTy);
DIB.createGlobalVariableExpression(CU, "GV0", /*LinkageName=*/"", File,
/*LineNo=*/1, ByteTy,
/*IsLocalToUnit=*/true);
DIB.createImportedDeclaration(CU, nullptr, File, /*LineNo=*/2, "IM0");
DIB.createMacro(nullptr, /*LineNo=*/0, dwarf::DW_MACINFO_define, "M0");
DIB.finalize();
}
EXPECT_FALSE(verifyModule(*M));
EXPECT_THAT(GetNames(CU),
UnorderedElementsAre("ET0", "byte0", "GV0", "IM0", "M0"));

{
DIBuilder DIB(*M, true, CU);
auto *File = CU->getFile();
auto *ByteTy = DIB.createBasicType("byte1", 8, dwarf::DW_ATE_signed);
DIB.createEnumerationType(CU, "ET1", File, /*LineNo=*/0,
/*SizeInBits=*/8, /*AlignInBits=*/8,
/*Elements=*/{}, ByteTy);
DIB.retainType(ByteTy);
DIB.createGlobalVariableExpression(CU, "GV1", /*LinkageName=*/"", File,
/*LineNo=*/1, ByteTy,
/*IsLocalToUnit=*/true);
DIB.createImportedDeclaration(CU, nullptr, File, /*LineNo=*/2, "IM1");
DIB.createMacro(nullptr, /*LineNo=*/0, dwarf::DW_MACINFO_define, "M1");
DIB.finalize();
}
EXPECT_FALSE(verifyModule(*M));
EXPECT_THAT(GetNames(CU),
UnorderedElementsAre("ET0", "byte0", "GV0", "IM0", "M0", "ET1",
"byte1", "GV1", "IM1", "M1"));
}

TEST_F(IRBuilderTest, InsertExtractElement) {
IRBuilder<> Builder(BB);

Expand Down

0 comments on commit 0150645

Please sign in to comment.