aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/AsmParser/LLParser.h1
-rw-r--r--llvm/include/llvm/IR/BasicBlock.h1
-rw-r--r--llvm/include/llvm/IR/Function.h1
-rw-r--r--llvm/include/llvm/IR/Module.h6
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp27
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp72
-rw-r--r--llvm/lib/IR/BasicBlock.cpp21
-rw-r--r--llvm/lib/IR/Function.cpp6
-rw-r--r--llvm/lib/IR/IRPrintingPasses.cpp3
-rw-r--r--llvm/test/Bitcode/dbg-record-roundtrip.ll10
-rw-r--r--llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll8
-rw-r--r--llvm/tools/llvm-link/llvm-link.cpp5
-rw-r--r--llvm/tools/llvm-lto/llvm-lto.cpp5
-rw-r--r--llvm/tools/llvm-lto2/llvm-lto2.cpp5
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