Skip to content

Commit

Permalink
[RemoveDIs] Load into new debug info format by default in LLVM (#89799)
Browse files Browse the repository at this point in the history
This patch enables parsing and creating modules directly into the new
debug info format. Prior to this patch, all modules were constructed
with the old debug info format by default, and would be converted into
the new format just before running LLVM passes. This is an important
milestone, in that this means that every tool will now be exposed to
debug records, rather than those that run LLVM passes. As far as I've
tested, all LLVM tools/projects now either handle debug records, or
convert them to the old intrinsic format.

There are a few unit tests that need updating for this patch; these are
either cases of tests that previously needed to set the debug info
format to function, or tests that depend on the old debug info format in
some way. There should be no visible change in the output of any LLVM
tool as a result of this patch, although the likelihood of this patch
breaking downstream code means an NFC tag might be a little misleading,
if not technically incorrect:

This will probably break some downstream tools that don't already handle
debug records. If your downstream code breaks as a result of this
change, the simplest fix is to convert the module in question to the old
debug format before you process it, using
`Module::convertFromNewDbgValues()`. For more information about how to
handle debug records or about what has changed, see the migration
document:
  https://llvm.org/docs/RemoveDIsDebugInfo.html
  • Loading branch information
SLTozer authored May 1, 2024
1 parent 167427f commit 2f01fd9
Show file tree
Hide file tree
Showing 16 changed files with 143 additions and 61 deletions.
7 changes: 7 additions & 0 deletions llvm/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@ Changes to the Metadata Info
Changes to the Debug Info
---------------------------------

* LLVM has switched from using debug intrinsics internally to using debug
records by default. This should happen transparently when using the DIBuilder
to construct debug variable information, but will require changes for any code
that interacts with debug intrinsics directly. Debug intrinsics will only be
supported on a best-effort basis from here onwards; for more information, see
the `migration docs <https://llvm.org/docs/RemoveDIsDebugInfo.html>`_.

Changes to the LLVM tools
---------------------------------
* llvm-nm and llvm-objdump can now print symbol information from linked
Expand Down
1 change: 0 additions & 1 deletion llvm/include/llvm/AsmParser/LLParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,6 @@ namespace llvm {

// Top-Level Entities
bool parseTopLevelEntities();
bool finalizeDebugInfoFormat(Module *M);
void dropUnknownMetadataReferences();
bool validateEndOfModule(bool UpgradeDebugInfo);
bool validateEndOfIndex();
Expand Down
34 changes: 16 additions & 18 deletions llvm/lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,23 +74,6 @@ static std::string getTypeString(Type *T) {
return Tmp.str();
}

// Whatever debug info format we parsed, we should convert to the expected debug
// info format immediately afterwards.
bool LLParser::finalizeDebugInfoFormat(Module *M) {
// We should have already returned an error if we observed both intrinsics and
// records in this IR.
assert(!(SeenNewDbgInfoFormat && SeenOldDbgInfoFormat) &&
"Mixed debug intrinsics/records seen without a parsing error?");
if (PreserveInputDbgFormat == cl::boolOrDefault::BOU_TRUE) {
UseNewDbgInfoFormat = SeenNewDbgInfoFormat;
WriteNewDbgInfoFormatToBitcode = SeenNewDbgInfoFormat;
WriteNewDbgInfoFormat = SeenNewDbgInfoFormat;
} else if (M) {
M->setIsNewDbgInfoFormat(false);
}
return false;
}

/// Run: module ::= toplevelentity*
bool LLParser::Run(bool UpgradeDebugInfo,
DataLayoutCallbackTy DataLayoutCallback) {
Expand All @@ -108,7 +91,7 @@ bool LLParser::Run(bool UpgradeDebugInfo,
}

return parseTopLevelEntities() || validateEndOfModule(UpgradeDebugInfo) ||
validateEndOfIndex() || finalizeDebugInfoFormat(M);
validateEndOfIndex();
}

bool LLParser::parseStandaloneConstantValue(Constant *&C,
Expand Down Expand Up @@ -207,6 +190,18 @@ void LLParser::dropUnknownMetadataReferences() {
bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
if (!M)
return false;

// We should have already returned an error if we observed both intrinsics and
// records in this IR.
assert(!(SeenNewDbgInfoFormat && SeenOldDbgInfoFormat) &&
"Mixed debug intrinsics/records seen without a parsing error?");
if (PreserveInputDbgFormat == cl::boolOrDefault::BOU_TRUE) {
UseNewDbgInfoFormat = SeenNewDbgInfoFormat;
WriteNewDbgInfoFormatToBitcode = SeenNewDbgInfoFormat;
WriteNewDbgInfoFormat = SeenNewDbgInfoFormat;
M->setNewDbgInfoFormatFlag(SeenNewDbgInfoFormat);
}

// Handle any function attribute group forward references.
for (const auto &RAG : ForwardRefAttrGroups) {
Value *V = RAG.first;
Expand Down Expand Up @@ -439,6 +434,9 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
UpgradeModuleFlags(*M);
UpgradeSectionAttributes(*M);

if (PreserveInputDbgFormat != cl::boolOrDefault::BOU_TRUE)
M->setIsNewDbgInfoFormat(UseNewDbgInfoFormat);

if (!Slots)
return false;
// Initialize the slot mapping.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4319,7 +4319,7 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
if (PreserveInputDbgFormat != cl::boolOrDefault::BOU_TRUE) {
TheModule->IsNewDbgInfoFormat =
UseNewDbgInfoFormat &&
LoadBitcodeIntoNewDbgInfoFormat == cl::boolOrDefault::BOU_TRUE;
LoadBitcodeIntoNewDbgInfoFormat != cl::boolOrDefault::BOU_FALSE;
}

this->ValueTypeCallback = std::move(Callbacks.ValueType);
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/IR/BasicBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ template class llvm::SymbolTableListTraits<Instruction,
BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
BasicBlock *InsertBefore)
: Value(Type::getLabelTy(C), Value::BasicBlockVal),
IsNewDbgInfoFormat(false), Parent(nullptr) {
IsNewDbgInfoFormat(UseNewDbgInfoFormat), Parent(nullptr) {

if (NewParent)
insertInto(NewParent, InsertBefore);
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/IR/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ static cl::opt<unsigned> NonGlobalValueMaxNameSize(
"non-global-value-max-name-size", cl::Hidden, cl::init(1024),
cl::desc("Maximum size for the name of non-global values."));

extern cl::opt<bool> UseNewDbgInfoFormat;

void Function::convertToNewDbgValues() {
IsNewDbgInfoFormat = true;
for (auto &BB : *this) {
Expand Down Expand Up @@ -438,7 +440,7 @@ Function::Function(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace,
: GlobalObject(Ty, Value::FunctionVal,
OperandTraits<Function>::op_begin(this), 0, Linkage, name,
computeAddrSpace(AddrSpace, ParentModule)),
NumArgs(Ty->getNumParams()), IsNewDbgInfoFormat(false) {
NumArgs(Ty->getNumParams()), IsNewDbgInfoFormat(UseNewDbgInfoFormat) {
assert(FunctionType::isValidReturnType(getReturnType()) &&
"invalid return type");
setGlobalObjectSubClassData(0);
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/IR/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@

using namespace llvm;

extern cl::opt<bool> UseNewDbgInfoFormat;

//===----------------------------------------------------------------------===//
// Methods to implement the globals and functions lists.
//
Expand All @@ -72,7 +74,7 @@ template class llvm::SymbolTableListTraits<GlobalIFunc>;
Module::Module(StringRef MID, LLVMContext &C)
: Context(C), ValSymTab(std::make_unique<ValueSymbolTable>(-1)),
ModuleID(std::string(MID)), SourceFileName(std::string(MID)), DL(""),
IsNewDbgInfoFormat(false) {
IsNewDbgInfoFormat(UseNewDbgInfoFormat) {
Context.addModule(this);
}

Expand Down
7 changes: 3 additions & 4 deletions llvm/tools/llvm-as/llvm-as.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,10 @@ int main(int argc, char **argv) {
}

// Convert to new debug format if requested.
assert(!M->IsNewDbgInfoFormat && "Unexpectedly in new debug mode");
if (UseNewDbgInfoFormat && WriteNewDbgInfoFormatToBitcode) {
M->convertToNewDbgValues();
M->setIsNewDbgInfoFormat(UseNewDbgInfoFormat &&
WriteNewDbgInfoFormatToBitcode);
if (M->IsNewDbgInfoFormat)
M->removeDebugIntrinsicDeclarations();
}

std::unique_ptr<ModuleSummaryIndex> Index = std::move(ModuleAndIndex.Index);

Expand Down
2 changes: 1 addition & 1 deletion llvm/tools/llvm-dis/llvm-dis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ int main(int argc, char **argv) {
// All that llvm-dis does is write the assembly to a file.
if (!DontPrint) {
if (M) {
ScopedDbgInfoFormatSetter FormatSetter(*M, WriteNewDbgInfoFormat);
M->setIsNewDbgInfoFormat(WriteNewDbgInfoFormat);
if (WriteNewDbgInfoFormat)
M->removeDebugIntrinsicDeclarations();
M->print(Out->os(), Annotator.get(), PreserveAssemblyUseListOrder);
Expand Down
8 changes: 1 addition & 7 deletions llvm/tools/llvm-link/llvm-link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,12 +489,6 @@ int main(int argc, char **argv) {
if (LoadBitcodeIntoNewDbgInfoFormat == cl::boolOrDefault::BOU_UNSET)
LoadBitcodeIntoNewDbgInfoFormat = cl::boolOrDefault::BOU_TRUE;

// RemoveDIs debug-info transition: tests may request that we /try/ to use the
// new debug-info format.
if (TryUseNewDbgInfoFormat) {
// Turn the new debug-info format on.
UseNewDbgInfoFormat = true;
}
// Since llvm-link collects multiple IR modules together, for simplicity's
// sake we disable the "PreserveInputDbgFormat" flag to enforce a single
// debug info format.
Expand Down Expand Up @@ -556,7 +550,7 @@ int main(int argc, char **argv) {
SetFormat(WriteNewDbgInfoFormat);
Composite->print(Out.os(), nullptr, PreserveAssemblyUseListOrder);
} else if (Force || !CheckBitcodeOutputToConsole(Out.os())) {
SetFormat(WriteNewDbgInfoFormatToBitcode);
SetFormat(UseNewDbgInfoFormat && WriteNewDbgInfoFormatToBitcode);
WriteBitcodeToFile(*Composite, Out.os(), PreserveBitcodeUseListOrder);
}

Expand Down
32 changes: 32 additions & 0 deletions llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/IRSimilarityIdentifier.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
Expand All @@ -22,6 +23,27 @@
using namespace llvm;
using namespace IRSimilarity;

extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
extern cl::opt<cl::boolOrDefault> PreserveInputDbgFormat;
extern bool WriteNewDbgInfoFormatToBitcode;
extern cl::opt<bool> WriteNewDbgInfoFormat;

// Backup all of the existing settings that may be modified when
// PreserveInputDbgFormat=true, so that when the test is finished we return them
// (and the "preserve" setting) to their original values.
static auto SaveDbgInfoFormat() {
return make_scope_exit(
[OldPreserveInputDbgFormat = PreserveInputDbgFormat.getValue(),
OldUseNewDbgInfoFormat = UseNewDbgInfoFormat.getValue(),
OldWriteNewDbgInfoFormatToBitcode = WriteNewDbgInfoFormatToBitcode,
OldWriteNewDbgInfoFormat = WriteNewDbgInfoFormat.getValue()] {
PreserveInputDbgFormat = OldPreserveInputDbgFormat;
UseNewDbgInfoFormat = OldUseNewDbgInfoFormat;
WriteNewDbgInfoFormatToBitcode = OldWriteNewDbgInfoFormatToBitcode;
WriteNewDbgInfoFormat = OldWriteNewDbgInfoFormat;
});
}

static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
StringRef ModuleStr) {
SMDiagnostic Err;
Expand Down Expand Up @@ -1308,6 +1330,9 @@ TEST(IRInstructionMapper, CallBrInstIllegal) {

// Checks that an debuginfo intrinsics are mapped to be invisible. Since they
// do not semantically change the program, they can be recognized as similar.
// FIXME: PreserveInputDbgFormat is set to true because this test contains
// malformed debug info that cannot be converted to the new debug info format;
// this test should be updated later to use valid debug info.
TEST(IRInstructionMapper, DebugInfoInvisible) {
StringRef ModuleString = R"(
define i32 @f(i32 %a, i32 %b) {
Expand All @@ -1320,6 +1345,8 @@ TEST(IRInstructionMapper, DebugInfoInvisible) {
declare void @llvm.dbg.value(metadata)
!0 = distinct !{!"test\00", i32 10})";
auto SettingGuard = SaveDbgInfoFormat();
PreserveInputDbgFormat = cl::boolOrDefault::BOU_TRUE;
LLVMContext Context;
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

Expand Down Expand Up @@ -1916,6 +1943,9 @@ TEST(IRSimilarityCandidate, CheckRegionsDifferentTypes) {

// Check that debug instructions do not impact similarity. They are marked as
// invisible.
// FIXME: PreserveInputDbgFormat is set to true because this test contains
// malformed debug info that cannot be converted to the new debug info format;
// this test should be updated later to use valid debug info.
TEST(IRSimilarityCandidate, IdenticalWithDebug) {
StringRef ModuleString = R"(
define i32 @f(i32 %a, i32 %b) {
Expand All @@ -1938,6 +1968,8 @@ TEST(IRSimilarityCandidate, IdenticalWithDebug) {
declare void @llvm.dbg.value(metadata)
!0 = distinct !{!"test\00", i32 10}
!1 = distinct !{!"test\00", i32 11})";
auto SettingGuard = SaveDbgInfoFormat();
PreserveInputDbgFormat = cl::boolOrDefault::BOU_TRUE;
LLVMContext Context;
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

Expand Down
17 changes: 0 additions & 17 deletions llvm/unittests/IR/BasicBlockDbgInfoTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ TEST(BasicBlockDbgInfoTest, InsertAfterSelf) {
!11 = !DILocation(line: 1, column: 1, scope: !6)
)");

// Convert the module to "new" form debug-info.
M->convertToNewDbgValues();
// Fetch the entry block.
BasicBlock &BB = M->getFunction("f")->getEntryBlock();

Expand Down Expand Up @@ -104,8 +102,6 @@ TEST(BasicBlockDbgInfoTest, InsertAfterSelf) {
auto Range2 = RetInst->getDbgRecordRange();
EXPECT_EQ(std::distance(Range2.begin(), Range2.end()), 1u);

M->convertFromNewDbgValues();

UseNewDbgInfoFormat = false;
}

Expand Down Expand Up @@ -196,8 +192,6 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) {

// Fetch the entry block,
BasicBlock &BB = M->getFunction("f")->getEntryBlock();
// Convert the module to "new" form debug-info.
M->convertToNewDbgValues();
EXPECT_EQ(BB.size(), 2u);

// Fetch out our two markers,
Expand Down Expand Up @@ -332,8 +326,6 @@ TEST(BasicBlockDbgInfoTest, HeadBitOperations) {
// Test that the movement of debug-data when using moveBefore etc and
// insertBefore etc are governed by the "head" bit of iterators.
BasicBlock &BB = M->getFunction("f")->getEntryBlock();
// Convert the module to "new" form debug-info.
M->convertToNewDbgValues();

// Test that the head bit behaves as expected: it should be set when the
// code wants the _start_ of the block, but not otherwise.
Expand Down Expand Up @@ -441,8 +433,6 @@ TEST(BasicBlockDbgInfoTest, InstrDbgAccess) {
// Check that DbgVariableRecords can be accessed from Instructions without
// digging into the depths of DbgMarkers.
BasicBlock &BB = M->getFunction("f")->getEntryBlock();
// Convert the module to "new" form debug-info.
M->convertToNewDbgValues();

Instruction *BInst = &*BB.begin();
Instruction *CInst = BInst->getNextNode();
Expand Down Expand Up @@ -579,7 +569,6 @@ class DbgSpliceTest : public ::testing::Test {
void SetUp() override {
UseNewDbgInfoFormat = true;
M = parseIR(C, SpliceTestIR.c_str());
M->convertToNewDbgValues();

BBEntry = &M->getFunction("f")->getEntryBlock();
BBExit = BBEntry->getNextNode();
Expand Down Expand Up @@ -1219,7 +1208,6 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceTrailing) {

BasicBlock &Entry = M->getFunction("f")->getEntryBlock();
BasicBlock &Exit = *Entry.getNextNode();
M->convertToNewDbgValues();

// Begin by forcing entry block to have dangling DbgVariableRecord.
Entry.getTerminator()->eraseFromParent();
Expand Down Expand Up @@ -1273,7 +1261,6 @@ TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsert) {
)");

BasicBlock &Entry = M->getFunction("f")->getEntryBlock();
M->convertToNewDbgValues();

// Fetch the relevant instructions from the converted function.
Instruction *SubInst = &*Entry.begin();
Expand Down Expand Up @@ -1352,7 +1339,6 @@ TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsertForOneDbgVariableRecord) {
)");

BasicBlock &Entry = M->getFunction("f")->getEntryBlock();
M->convertToNewDbgValues();

// Fetch the relevant instructions from the converted function.
Instruction *SubInst = &*Entry.begin();
Expand Down Expand Up @@ -1436,7 +1422,6 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty1) {
Function &F = *M->getFunction("f");
BasicBlock &Entry = F.getEntryBlock();
BasicBlock &Exit = *Entry.getNextNode();
M->convertToNewDbgValues();

// Begin by forcing entry block to have dangling DbgVariableRecord.
Entry.getTerminator()->eraseFromParent();
Expand Down Expand Up @@ -1506,7 +1491,6 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty2) {
Function &F = *M->getFunction("f");
BasicBlock &Entry = F.getEntryBlock();
BasicBlock &Exit = *Entry.getNextNode();
M->convertToNewDbgValues();

// Begin by forcing entry block to have dangling DbgVariableRecord.
Entry.getTerminator()->eraseFromParent();
Expand Down Expand Up @@ -1576,7 +1560,6 @@ TEST(BasicBlockDbgInfoTest, DbgMoveToEnd) {
Function &F = *M->getFunction("f");
BasicBlock &Entry = F.getEntryBlock();
BasicBlock &Exit = *Entry.getNextNode();
M->convertToNewDbgValues();

// Move the return to the end of the entry block.
Instruction *Br = Entry.getTerminator();
Expand Down
Loading

0 comments on commit 2f01fd9

Please sign in to comment.