Skip to content

Commit

Permalink
[RemoveDIs] Add flag to control loading into new debug mode from bitc…
Browse files Browse the repository at this point in the history
…ode (#85649)

--load-bitcode-into-experimental-debuginfo-iterators

      false: Convert to the old debug mode after reading.
      true: Upgrade to the new debug info format (*).
      unset: Same as false (for now).

(*) As of this patch it actually just means "don't convert to either
mode after loading". Auto-upgrading will be implemented in an upcoming
patch.

With this flag we can incrementally add support for RemoveDIs by
overriding the "unset" behaviour in individual tools. The flag can be
removed once all tools support the new debug info mode.
  • Loading branch information
OCHyams committed Mar 19, 2024
1 parent 4a6bc9f commit 4f909da
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 8 deletions.
24 changes: 18 additions & 6 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ static cl::opt<bool> ExpandConstantExprs(
cl::desc(
"Expand constant expressions to instructions for testing purposes"));

/// Load bitcode directly into RemoveDIs format (use debug records instead
/// of debug intrinsics). UNSET is treated as FALSE, so the default action
/// is to do nothing. Individual tools can override this to incrementally add
/// support for the RemoveDIs format.
cl::opt<cl::boolOrDefault> LoadBitcodeIntoNewDbgInforFormat(
"load-bitcode-into-experimental-debuginfo-iterators", cl::Hidden,
cl::desc("Load bitcode directly into the new debug info format (regardless "
"of input format)"));

namespace {

enum {
Expand Down Expand Up @@ -4276,9 +4285,11 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
Error BitcodeReader::parseModule(uint64_t ResumeBit,
bool ShouldLazyLoadMetadata,
ParserCallbacks Callbacks) {
// Force the debug-info mode into the old format for now.
// FIXME: Remove this once all tools support RemoveDIs.
TheModule->IsNewDbgInfoFormat = false;
// Load directly into RemoveDIs format if LoadBitcodeIntoNewDbgInforFormat
// has been set to true (default action: load into the old debug format).
TheModule->IsNewDbgInfoFormat =
UseNewDbgInfoFormat &&
LoadBitcodeIntoNewDbgInforFormat == cl::boolOrDefault::BOU_TRUE;

this->ValueTypeCallback = std::move(Callbacks.ValueType);
if (ResumeBit) {
Expand Down Expand Up @@ -6762,9 +6773,9 @@ Error BitcodeReader::materialize(GlobalValue *GV) {
if (Error JumpFailed = Stream.JumpToBit(DFII->second))
return JumpFailed;

// Set the debug info mode to "new", forcing a mismatch between
// 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.
// everything back to the old mode after parsing if needed.
// FIXME: Remove this once all tools support RemoveDIs.
F->IsNewDbgInfoFormat = true;

Expand All @@ -6774,7 +6785,8 @@ Error BitcodeReader::materialize(GlobalValue *GV) {

// Convert new debug info records into intrinsics.
// FIXME: Remove this once all tools support RemoveDIs.
F->convertFromNewDbgValues();
if (!F->getParent()->IsNewDbgInfoFormat)
F->convertFromNewDbgValues();

if (StripDebugInfo)
stripDebugInfo(*F);
Expand Down
31 changes: 30 additions & 1 deletion llvm/test/Bitcode/dbg-record-roundtrip.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
;; Roundtrip tests.
; RUN: llvm-as --write-experimental-debuginfo-iterators-to-bitcode=true %s -o - | llvm-dis | FileCheck %s

;; Load RemoveDIs mode in llvm-dis but write out debug intrinsics.
; RUN: llvm-as --write-experimental-debuginfo-iterators-to-bitcode=true %s -o - \
; RUN: | llvm-dis --load-bitcode-into-experimental-debuginfo-iterators=true --write-experimental-debuginfo=false \
; RUN: | FileCheck %s

;; Load and write RemoveDIs mode in llvm-dis.
; RUN: llvm-as --write-experimental-debuginfo-iterators-to-bitcode=true %s -o - \
; RUN: | llvm-dis --load-bitcode-into-experimental-debuginfo-iterators=true --write-experimental-debuginfo=true \
; RUN: | FileCheck %s --check-prefixes=RECORDS

;; 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
Expand Down Expand Up @@ -39,16 +49,24 @@ entry:
; CHECK-NEXT: dbg.value(metadata ![[empty:[0-9]+]], metadata ![[e]], metadata !DIExpression()), !dbg ![[dbg]]
; CHECK-NEXT: dbg.value(metadata i32 poison, metadata ![[e]], metadata !DIExpression()), !dbg ![[dbg]]
; CHECK-NEXT: dbg.value(metadata i32 1, metadata ![[f:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]]
; RECORDS: entry:
; RECORDS-NEXT: dbg_value(i32 %p, ![[e:[0-9]+]], !DIExpression(), ![[dbg:[0-9]+]])
; RECORDS-NEXT: dbg_value(![[empty:[0-9]+]], ![[e]], !DIExpression(), ![[dbg]])
; RECORDS-NEXT: dbg_value(i32 poison, ![[e]], !DIExpression(), ![[dbg]])
; RECORDS-NEXT: dbg_value(i32 1, ![[f:[0-9]+]], !DIExpression(), ![[dbg]])
tail call void @llvm.dbg.value(metadata i32 %p, metadata !32, metadata !DIExpression()), !dbg !19
tail call void @llvm.dbg.value(metadata !29, metadata !32, metadata !DIExpression()), !dbg !19
tail call void @llvm.dbg.value(metadata i32 poison, metadata !32, metadata !DIExpression()), !dbg !19
tail call void @llvm.dbg.value(metadata i32 1, metadata !33, metadata !DIExpression()), !dbg !19
;; Arglist with an argument, constant, local use before def, poison.
; CHECK-NEXT: dbg.value(metadata !DIArgList(i32 %p, i32 0, i32 %0, i32 poison), metadata ![[f]], metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_arg, 2, DW_OP_LLVM_arg, 3, DW_OP_plus, DW_OP_minus)), !dbg ![[dbg]]
; RECORDS-NEXT: dbg_value(!DIArgList(i32 %p, i32 0, i32 %0, i32 poison), ![[f]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_arg, 2, DW_OP_LLVM_arg, 3, DW_OP_plus, DW_OP_minus), ![[dbg]])
tail call void @llvm.dbg.value(metadata !DIArgList(i32 %p, i32 0, i32 %0, i32 poison), metadata !33, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_arg, 2, DW_OP_LLVM_arg, 3, DW_OP_plus, DW_OP_minus)), !dbg !19
;; Check dbg.assign use before def (value, addr and ID). Check expression order too.
; CHECK: dbg.assign(metadata i32 %0, metadata ![[i:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, 0),
; CHECK-SAME: metadata ![[ID:[0-9]+]], metadata ptr %a, metadata !DIExpression(DW_OP_plus_uconst, 1)), !dbg ![[dbg]]
; RECORDS: dbg_assign(i32 %0, ![[i:[0-9]+]], !DIExpression(DW_OP_plus_uconst, 0),
; RECORDS-SAME: ![[ID:[0-9]+]], ptr %a, !DIExpression(DW_OP_plus_uconst, 1), ![[dbg]])
tail call void @llvm.dbg.assign(metadata i32 %0, metadata !36, metadata !DIExpression(DW_OP_plus_uconst, 0), metadata !37, metadata ptr %a, metadata !DIExpression(DW_OP_plus_uconst, 1)), !dbg !19
%a = alloca i32, align 4, !DIAssignID !37
; CHECK: %a = alloca i32, align 4, !DIAssignID ![[ID]]
Expand All @@ -58,24 +76,35 @@ entry:
; CHECK-NEXT: dbg.declare(metadata ptr poison, metadata ![[c:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]]
; CHECK-NEXT: dbg.declare(metadata ptr null, metadata ![[d:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]]
; CHECK-NEXT: dbg.declare(metadata ptr @g, metadata ![[h:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]]
; RECORDS: %a = alloca i32, align 4, !DIAssignID ![[ID]]
;; Check dbg.declare configurations.
; RECORDS-NEXT: dbg_declare(ptr %a, ![[a:[0-9]+]], !DIExpression(), ![[dbg]])
; RECORDS-NEXT: dbg_declare(![[empty:[0-9]+]], ![[b:[0-9]+]], !DIExpression(), ![[dbg]])
; RECORDS-NEXT: dbg_declare(ptr poison, ![[c:[0-9]+]], !DIExpression(), ![[dbg]])
; RECORDS-NEXT: dbg_declare(ptr null, ![[d:[0-9]+]], !DIExpression(), ![[dbg]])
; RECORDS-NEXT: dbg_declare(ptr @g, ![[h:[0-9]+]], !DIExpression(), ![[dbg]])
tail call void @llvm.dbg.declare(metadata ptr %a, metadata !17, metadata !DIExpression()), !dbg !19
tail call void @llvm.dbg.declare(metadata !29, metadata !28, metadata !DIExpression()), !dbg !19
tail call void @llvm.dbg.declare(metadata ptr poison, metadata !30, metadata !DIExpression()), !dbg !19
tail call void @llvm.dbg.declare(metadata ptr null, metadata !31, metadata !DIExpression()), !dbg !19
tail call void @llvm.dbg.declare(metadata ptr @g, metadata !35, metadata !DIExpression()), !dbg !19
;; Argument value dbg.declare.
; CHECK: dbg.declare(metadata ptr %storage, metadata ![[g:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]]
; RECORDS: dbg_declare(ptr %storage, ![[g:[0-9]+]], !DIExpression(), ![[dbg]])
tail call void @llvm.dbg.declare(metadata ptr %storage, metadata !34, metadata !DIExpression()), !dbg !19
;; Use before def dbg.value.
; CHECK: dbg.value(metadata i32 %0, metadata ![[e]], metadata !DIExpression()), !dbg ![[dbg]]
; RECORDS: dbg_value(i32 %0, ![[e]], !DIExpression(), ![[dbg]])
tail call void @llvm.dbg.value(metadata i32 %0, metadata !32, metadata !DIExpression()), !dbg !19
%0 = load i32, ptr @g, align 4, !dbg !20
;; Non-argument local value dbg.value.
; CHECK: dbg.value(metadata i32 %0, metadata ![[e]], metadata !DIExpression()), !dbg ![[dbg]]
; RECORDS: dbg_value(i32 %0, ![[e]], !DIExpression(), ![[dbg]])
tail call void @llvm.dbg.value(metadata i32 %0, metadata !32, metadata !DIExpression()), !dbg !19
store i32 %0, ptr %a, align 4, !dbg !19
%1 = load i32, ptr %a, align 4, !dbg !25
; CHECK: dbg.label(metadata ![[label:[0-9]+]]), !dbg ![[dbg]]
; RECORDS: dbg_label(![[label:[0-9]+]], ![[dbg]])
tail call void @llvm.dbg.label(metadata !38), !dbg !19
ret i32 %1, !dbg !27
}
Expand Down
10 changes: 9 additions & 1 deletion llvm/tools/llvm-dis/llvm-dis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ static cl::opt<bool> PrintThinLTOIndexOnly(
cl::desc("Only read thinlto index and print the index as LLVM assembly."),
cl::init(false), cl::Hidden, cl::cat(DisCategory));

extern cl::opt<bool> WriteNewDbgInfoFormat;

namespace {

static void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) {
Expand Down Expand Up @@ -249,8 +251,14 @@ int main(int argc, char **argv) {

// All that llvm-dis does is write the assembly to a file.
if (!DontPrint) {
if (M)
if (M) {
bool ChangeDbgFormat = M->IsNewDbgInfoFormat != WriteNewDbgInfoFormat;
if (ChangeDbgFormat)
M->setIsNewDbgInfoFormat(WriteNewDbgInfoFormat);
M->print(Out->os(), Annotator.get(), PreserveAssemblyUseListOrder);
if (ChangeDbgFormat)
M->setIsNewDbgInfoFormat(!WriteNewDbgInfoFormat);
}
if (Index)
Index->print(Out->os());
}
Expand Down

0 comments on commit 4f909da

Please sign in to comment.