diff options
-rw-r--r-- | llvm/include/llvm/AsmParser/LLParser.h | 1 | ||||
-rw-r--r-- | llvm/include/llvm/IR/BasicBlock.h | 1 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Function.h | 1 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Module.h | 6 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 27 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 72 | ||||
-rw-r--r-- | llvm/lib/IR/BasicBlock.cpp | 21 | ||||
-rw-r--r-- | llvm/lib/IR/Function.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/IR/IRPrintingPasses.cpp | 3 | ||||
-rw-r--r-- | llvm/test/Bitcode/dbg-record-roundtrip.ll | 10 | ||||
-rw-r--r-- | llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll | 8 | ||||
-rw-r--r-- | llvm/tools/llvm-link/llvm-link.cpp | 5 | ||||
-rw-r--r-- | llvm/tools/llvm-lto/llvm-lto.cpp | 5 | ||||
-rw-r--r-- | llvm/tools/llvm-lto2/llvm-lto2.cpp | 5 |
14 files changed, 145 insertions, 26 deletions
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h index 8ebd0d3..b4e971f 100644 --- a/llvm/include/llvm/AsmParser/LLParser.h +++ b/llvm/include/llvm/AsmParser/LLParser.h @@ -335,6 +335,7 @@ namespace llvm { // Top-Level Entities bool parseTopLevelEntities(); + bool finalizeDebugInfoFormat(Module *M); void dropUnknownMetadataReferences(); bool validateEndOfModule(bool UpgradeDebugInfo); bool validateEndOfIndex(); diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h index 0c5a07b..e122096 100644 --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -92,6 +92,7 @@ public: /// in the new format (\p NewFlag == true), converting to the desired format /// if necessary. void setIsNewDbgInfoFormat(bool NewFlag); + void setNewDbgInfoFormatFlag(bool NewFlag); /// Record that the collection of DbgRecords in \p M "trails" after the last /// instruction of this block. These are equivalent to dbg.value intrinsics diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index d96d506..60f41b3 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -120,6 +120,7 @@ public: void convertFromNewDbgValues(); void setIsNewDbgInfoFormat(bool NewVal); + void setNewDbgInfoFormatFlag(bool NewVal); private: friend class TargetLibraryInfoImpl; diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index bb2e667..6135e15 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -245,6 +245,12 @@ public: else if (!UseNewFormat && IsNewDbgInfoFormat) convertFromNewDbgValues(); } + void setNewDbgInfoFormatFlag(bool NewFlag) { + for (auto &F : *this) { + F.setNewDbgInfoFormatFlag(NewFlag); + } + IsNewDbgInfoFormat = NewFlag; + } /// The Module constructor. Note that there is no default constructor. You /// must provide a name for the module upon construction. diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index fe49e52..67ec4a7 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -63,6 +63,9 @@ static cl::opt<bool> AllowIncompleteIR( "metadata will be dropped)")); extern llvm::cl::opt<bool> UseNewDbgInfoFormat; +extern cl::opt<cl::boolOrDefault> PreserveInputDbgFormat; +extern bool WriteNewDbgInfoFormatToBitcode; +extern cl::opt<bool> WriteNewDbgInfoFormat; static std::string getTypeString(Type *T) { std::string Result; @@ -71,12 +74,20 @@ static std::string getTypeString(Type *T) { return Tmp.str(); } -// Currently, we should always process modules in the old debug info format by -// default regardless of the module's format in IR; convert it to the old format -// here. -bool finalizeDebugInfoFormat(Module *M) { - if (M) +// 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; } @@ -6511,10 +6522,10 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) { if (SeenOldDbgInfoFormat) return error(Lex.getLoc(), "debug record should not appear in a module " "containing debug info intrinsics"); + if (!SeenNewDbgInfoFormat) + M->setNewDbgInfoFormatFlag(true); SeenNewDbgInfoFormat = true; Lex.Lex(); - if (!M->IsNewDbgInfoFormat) - M->convertToNewDbgValues(); DbgRecord *DR; if (parseDebugRecord(DR, PFS)) @@ -7928,6 +7939,8 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS, return error(CallLoc, "llvm.dbg intrinsic should not appear in a module " "using non-intrinsic debug info"); } + if (!SeenOldDbgInfoFormat) + M->setNewDbgInfoFormatFlag(false); SeenOldDbgInfoFormat = true; } CI->setAttributes(PAL); diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index aa6c9c9..5ea6cc2 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -108,6 +108,9 @@ cl::opt<cl::boolOrDefault> LoadBitcodeIntoNewDbgInfoFormat( "load-bitcode-into-experimental-debuginfo-iterators", cl::Hidden, cl::desc("Load bitcode directly into the new debug info format (regardless " "of input format)")); +extern cl::opt<cl::boolOrDefault> PreserveInputDbgFormat; +extern bool WriteNewDbgInfoFormatToBitcode; +extern cl::opt<bool> WriteNewDbgInfoFormat; namespace { @@ -682,6 +685,11 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { /// (e.g.) blockaddress forward references. bool WillMaterializeAllForwardRefs = false; + /// Tracks whether we have seen debug intrinsics or records in this bitcode; + /// seeing both in a single module is currently a fatal error. + bool SeenDebugIntrinsic = false; + bool SeenDebugRecord = false; + bool StripDebugInfo = false; TBAAVerifier TBAAVerifyHelper; @@ -3774,7 +3782,11 @@ Error BitcodeReader::globalCleanup() { for (Function &F : *TheModule) { MDLoader->upgradeDebugIntrinsics(F); Function *NewFn; - if (UpgradeIntrinsicFunction(&F, NewFn)) + // If PreserveInputDbgFormat=true, then we don't know whether we want + // intrinsics or records, and we won't perform any conversions in either + // case, so don't upgrade intrinsics to records. + if (UpgradeIntrinsicFunction( + &F, NewFn, PreserveInputDbgFormat != cl::boolOrDefault::BOU_TRUE)) UpgradedIntrinsics[&F] = NewFn; // Look for functions that rely on old function attribute behavior. UpgradeFunctionAttributes(F); @@ -4301,10 +4313,13 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, bool ShouldLazyLoadMetadata, ParserCallbacks Callbacks) { // Load directly into RemoveDIs format if LoadBitcodeIntoNewDbgInfoFormat - // has been set to true (default action: load into the old debug format). - TheModule->IsNewDbgInfoFormat = - UseNewDbgInfoFormat && - LoadBitcodeIntoNewDbgInfoFormat == cl::boolOrDefault::BOU_TRUE; + // has been set to true and we aren't attempting to preserve the existing + // format in the bitcode (default action: load into the old debug format). + if (PreserveInputDbgFormat != cl::boolOrDefault::BOU_TRUE) { + TheModule->IsNewDbgInfoFormat = + UseNewDbgInfoFormat && + LoadBitcodeIntoNewDbgInfoFormat == cl::boolOrDefault::BOU_TRUE; + } this->ValueTypeCallback = std::move(Callbacks.ValueType); if (ResumeBit) { @@ -6453,6 +6468,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN: { // DbgVariableRecords are placed after the Instructions that they are // attached to. + SeenDebugRecord = true; Instruction *Inst = getLastInstruction(); if (!Inst) return error("Invalid dbg record: missing instruction"); @@ -6613,6 +6629,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { TCK = CallInst::TCK_NoTail; cast<CallInst>(I)->setTailCallKind(TCK); cast<CallInst>(I)->setAttributes(PAL); + if (isa<DbgInfoIntrinsic>(I)) + SeenDebugIntrinsic = true; if (Error Err = propagateAttributeTypes(cast<CallBase>(I), ArgTyIDs)) { I->deleteValue(); return Err; @@ -6801,20 +6819,48 @@ Error BitcodeReader::materialize(GlobalValue *GV) { if (Error JumpFailed = Stream.JumpToBit(DFII->second)) return JumpFailed; - // Set the debug info mode to "new", possibly creating a mismatch between - // module and function debug modes. This is okay because we'll convert - // everything back to the old mode after parsing if needed. - // FIXME: Remove this once all tools support RemoveDIs. + // Regardless of the debug info format we want to end up in, we need + // IsNewDbgInfoFormat=true to construct any debug records seen in the bitcode. F->IsNewDbgInfoFormat = true; if (Error Err = parseFunctionBody(F)) return Err; F->setIsMaterializable(false); - // Convert new debug info records into intrinsics. - // FIXME: Remove this once all tools support RemoveDIs. - if (!F->getParent()->IsNewDbgInfoFormat) - F->convertFromNewDbgValues(); + // All parsed Functions should load into the debug info format dictated by the + // Module, unless we're attempting to preserve the input debug info format. + if (SeenDebugIntrinsic && SeenDebugRecord) + return error("Mixed debug intrinsics and debug records in bitcode module!"); + if (PreserveInputDbgFormat == cl::boolOrDefault::BOU_TRUE) { + bool SeenAnyDebugInfo = SeenDebugIntrinsic || SeenDebugRecord; + bool NewDbgInfoFormatDesired = + SeenAnyDebugInfo ? SeenDebugRecord : F->getParent()->IsNewDbgInfoFormat; + if (SeenAnyDebugInfo) { + UseNewDbgInfoFormat = SeenDebugRecord; + WriteNewDbgInfoFormatToBitcode = SeenDebugRecord; + WriteNewDbgInfoFormat = SeenDebugRecord; + } + // If the module's debug info format doesn't match the observed input + // format, then set its format now; we don't need to call the conversion + // function because there must be no existing intrinsics to convert. + // Otherwise, just set the format on this function now. + if (NewDbgInfoFormatDesired != F->getParent()->IsNewDbgInfoFormat) + F->getParent()->setNewDbgInfoFormatFlag(NewDbgInfoFormatDesired); + else + F->setNewDbgInfoFormatFlag(NewDbgInfoFormatDesired); + } else { + // If we aren't preserving formats, we use the Module flag to get our + // desired format instead of reading flags, in case we are lazy-loading and + // the format of the module has been changed since it was set by the flags. + // We only need to convert debug info here if we have debug records but + // desire the intrinsic format; everything else is a no-op or handled by the + // autoupgrader. + bool ModuleIsNewDbgInfoFormat = F->getParent()->IsNewDbgInfoFormat; + if (ModuleIsNewDbgInfoFormat || !SeenDebugRecord) + F->setNewDbgInfoFormatFlag(ModuleIsNewDbgInfoFormat); + else + F->setIsNewDbgInfoFormat(ModuleIsNewDbgInfoFormat); + } if (StripDebugInfo) stripDebugInfo(*F); diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp index ae99267..6e62767 100644 --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -30,11 +30,19 @@ using namespace llvm; #define DEBUG_TYPE "ir" STATISTIC(NumInstrRenumberings, "Number of renumberings across all blocks"); -cl::opt<bool> - UseNewDbgInfoFormat("experimental-debuginfo-iterators", - cl::desc("Enable communicating debuginfo positions " - "through iterators, eliminating intrinsics"), - cl::init(true)); +cl::opt<bool> UseNewDbgInfoFormat( + "experimental-debuginfo-iterators", + cl::desc("Enable communicating debuginfo positions through iterators, " + "eliminating intrinsics. Has no effect if " + "--preserve-input-debuginfo-format=true."), + cl::init(true)); +cl::opt<cl::boolOrDefault> PreserveInputDbgFormat( + "preserve-input-debuginfo-format", cl::Hidden, + cl::desc("When set to true, IR files will be processed and printed in " + "their current debug info format, regardless of default behaviour " + "or other flags passed. Has no effect if input IR does not " + "contain debug records or intrinsics. Ignored in llvm-link, " + "llvm-lto, and llvm-lto2.")); bool WriteNewDbgInfoFormatToBitcode /*set default value in cl::init() below*/; cl::opt<bool, true> WriteNewDbgInfoFormatToBitcode2( @@ -147,6 +155,9 @@ void BasicBlock::setIsNewDbgInfoFormat(bool NewFlag) { else if (!NewFlag && IsNewDbgInfoFormat) convertFromNewDbgValues(); } +void BasicBlock::setNewDbgInfoFormatFlag(bool NewFlag) { + IsNewDbgInfoFormat = NewFlag; +} ValueSymbolTable *BasicBlock::getValueSymbolTable() { if (Function *F = getParent()) diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index eb126f1..b5fda9b 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -103,6 +103,12 @@ void Function::setIsNewDbgInfoFormat(bool NewFlag) { else if (!NewFlag && IsNewDbgInfoFormat) convertFromNewDbgValues(); } +void Function::setNewDbgInfoFormatFlag(bool NewFlag) { + for (auto &BB : *this) { + BB.setNewDbgInfoFormatFlag(NewFlag); + } + IsNewDbgInfoFormat = NewFlag; +} //===----------------------------------------------------------------------===// // Argument Implementation diff --git a/llvm/lib/IR/IRPrintingPasses.cpp b/llvm/lib/IR/IRPrintingPasses.cpp index 84fb8e6..43252c5 100644 --- a/llvm/lib/IR/IRPrintingPasses.cpp +++ b/llvm/lib/IR/IRPrintingPasses.cpp @@ -25,7 +25,8 @@ using namespace llvm; cl::opt<bool> WriteNewDbgInfoFormat( "write-experimental-debuginfo", - cl::desc("Write debug info in the new non-intrinsic format"), + cl::desc("Write debug info in the new non-intrinsic format. Has no effect " + "if --preserve-input-debuginfo-format=true."), cl::init(false)); namespace { diff --git a/llvm/test/Bitcode/dbg-record-roundtrip.ll b/llvm/test/Bitcode/dbg-record-roundtrip.ll index bd347ca..cc83fdd 100644 --- a/llvm/test/Bitcode/dbg-record-roundtrip.ll +++ b/llvm/test/Bitcode/dbg-record-roundtrip.ll @@ -15,6 +15,16 @@ ; RUN: | llvm-dis --load-bitcode-into-experimental-debuginfo-iterators=true --write-experimental-debuginfo=true \ ; RUN: | FileCheck %s --check-prefixes=RECORDS +;; When preserving, we should output the format the bitcode was written in +;; regardless of the value of the write flag. +; RUN: llvm-as --write-experimental-debuginfo-iterators-to-bitcode=true %s -o - \ +; RUN: | llvm-dis --preserve-input-debuginfo-format=true --write-experimental-debuginfo=false \ +; RUN: | FileCheck %s --check-prefixes=RECORDS + +; RUN: llvm-as --write-experimental-debuginfo-iterators-to-bitcode=false %s -o - \ +; RUN: | llvm-dis --preserve-input-debuginfo-format=true --write-experimental-debuginfo=true \ +; RUN: | FileCheck %s + ;; Check that verify-uselistorder passes regardless of input format. ; RUN: llvm-as %s --write-experimental-debuginfo-iterators-to-bitcode=true -o - | verify-uselistorder ; RUN: verify-uselistorder %s diff --git a/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll b/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll index b15b76d..b154a4f 100644 --- a/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll +++ b/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll @@ -18,6 +18,14 @@ ; RUN: opt --passes=verify -S --try-experimental-debuginfo-iterators --write-experimental-debuginfo=true < %s \ ; RUN: | FileCheck %s --check-prefixes=CHECK,NEWDBG --implicit-check-not=llvm.dbg --implicit-check-not=#dbg +;; Test that the preserving flag overrides the write flag. +; RUN: opt --passes=verify -S --preserve-input-debuginfo-format=true --write-experimental-debuginfo=true < %s \ +; RUN: | FileCheck %s --check-prefixes=CHECK,OLDDBG --implicit-check-not=llvm.dbg --implicit-check-not=#dbg + +; RUN: opt --passes=verify -S --write-experimental-debuginfo=true < %s \ +; RUN: | opt --passes=verify -S --preserve-input-debuginfo-format=true --write-experimental-debuginfo=false \ +; RUN: | FileCheck %s --check-prefixes=CHECK,NEWDBG --implicit-check-not=llvm.dbg --implicit-check-not=#dbg + ; CHECK: @f(i32 %[[VAL_A:[0-9a-zA-Z]+]]) ; CHECK-NEXT: entry: ; OLDDBG-NEXT: call void @llvm.dbg.value(metadata i32 %[[VAL_A]], metadata ![[VAR_A:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC_1:[0-9]+]] diff --git a/llvm/tools/llvm-link/llvm-link.cpp b/llvm/tools/llvm-link/llvm-link.cpp index 9049cb5e..8f80cc2 100644 --- a/llvm/tools/llvm-link/llvm-link.cpp +++ b/llvm/tools/llvm-link/llvm-link.cpp @@ -135,6 +135,7 @@ static cl::opt<bool> TryUseNewDbgInfoFormat( cl::init(false)); extern cl::opt<bool> UseNewDbgInfoFormat; +extern cl::opt<cl::boolOrDefault> PreserveInputDbgFormat; extern cl::opt<cl::boolOrDefault> LoadBitcodeIntoNewDbgInfoFormat; @@ -492,6 +493,10 @@ int main(int argc, char **argv) { // 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. + PreserveInputDbgFormat = cl::boolOrDefault::BOU_FALSE; LLVMContext Context; Context.setDiagnosticHandler(std::make_unique<LLVMLinkDiagnosticHandler>(), diff --git a/llvm/tools/llvm-lto/llvm-lto.cpp b/llvm/tools/llvm-lto/llvm-lto.cpp index 3c452b6..f310097 100644 --- a/llvm/tools/llvm-lto/llvm-lto.cpp +++ b/llvm/tools/llvm-lto/llvm-lto.cpp @@ -271,6 +271,7 @@ static cl::opt<bool> TryUseNewDbgInfoFormat( extern cl::opt<bool> UseNewDbgInfoFormat; extern cl::opt<cl::boolOrDefault> LoadBitcodeIntoNewDbgInfoFormat; +extern cl::opt<cl::boolOrDefault> PreserveInputDbgFormat; namespace { @@ -954,6 +955,10 @@ int main(int argc, char **argv) { // Turn the new debug-info format on. UseNewDbgInfoFormat = true; } + // Since llvm-lto collects multiple IR modules together, for simplicity's sake + // we disable the "PreserveInputDbgFormat" flag to enforce a single debug info + // format. + PreserveInputDbgFormat = cl::boolOrDefault::BOU_FALSE; if (OptLevel < '0' || OptLevel > '3') error("optimization level must be between 0 and 3"); diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp index f222d02..faed9ff9 100644 --- a/llvm/tools/llvm-lto2/llvm-lto2.cpp +++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp @@ -194,6 +194,7 @@ static cl::opt<bool> TryUseNewDbgInfoFormat( extern cl::opt<bool> UseNewDbgInfoFormat; extern cl::opt<cl::boolOrDefault> LoadBitcodeIntoNewDbgInfoFormat; +extern cl::opt<cl::boolOrDefault> PreserveInputDbgFormat; static void check(Error E, std::string Msg) { if (!E) @@ -239,6 +240,10 @@ static int run(int argc, char **argv) { // Turn the new debug-info format on. UseNewDbgInfoFormat = true; } + // Since llvm-lto2 collects multiple IR modules together, for simplicity's + // sake we disable the "PreserveInputDbgFormat" flag to enforce a single debug + // info format. + PreserveInputDbgFormat = cl::boolOrDefault::BOU_FALSE; // FIXME: Workaround PR30396 which means that a symbol can appear // more than once if it is defined in module-level assembly and |