[llvm] [RemoveDIs][DebugInfo][IR] Add parsing for non-intrinsic debug values (PR #79818)

Stephen Tozer via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 29 08:03:09 PST 2024


https://github.com/SLTozer updated https://github.com/llvm/llvm-project/pull/79818

>From 149417b60970dd70024b93cd599406a13c9793be Mon Sep 17 00:00:00 2001
From: Stephen Tozer <Stephen.Tozer at Sony.com>
Date: Mon, 29 Jan 2024 11:04:24 +0000
Subject: [PATCH 1/2] Add parsing for non-intrinsic debug values

---
 llvm/include/llvm/AsmParser/LLParser.h        |   4 +
 llvm/include/llvm/AsmParser/LLToken.h         |   3 +
 .../include/llvm/IR/DebugProgramInstruction.h |  24 +++
 llvm/lib/AsmParser/LLLexer.cpp                |  18 ++-
 llvm/lib/AsmParser/LLParser.cpp               | 144 +++++++++++++++++-
 llvm/lib/IR/DebugProgramInstruction.cpp       |  17 +++
 .../roundtrip-non-instruction-debug-info.ll   |  87 +++++++++++
 7 files changed, 295 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll

diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index cf358c384f52033..6e3facbfcea573c 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -177,6 +177,9 @@ namespace llvm {
     /// UpgradeDebuginfo so it can generate broken bitcode.
     bool UpgradeDebugInfo;
 
+    bool SeenNewDbgInfoFormat = false;
+    bool SeenOldDbgInfoFormat = false;
+
     std::string SourceFileName;
 
   public:
@@ -585,6 +588,7 @@ namespace llvm {
     bool parseMDNodeTail(MDNode *&N);
     bool parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts);
     bool parseMetadataAttachment(unsigned &Kind, MDNode *&MD);
+    bool parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS);
     bool parseInstructionMetadata(Instruction &Inst);
     bool parseGlobalObjectMetadataAttachment(GlobalObject &GO);
     bool parseOptionalFunctionMetadata(Function &F);
diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h
index 147cf56c821aa1f..4ce97041ca309ea 100644
--- a/llvm/include/llvm/AsmParser/LLToken.h
+++ b/llvm/include/llvm/AsmParser/LLToken.h
@@ -36,6 +36,7 @@ enum Kind {
   exclaim, // !
   bar,     // |
   colon,   // :
+  hash,    // #
 
   kw_vscale,
   kw_x,
@@ -482,6 +483,8 @@ enum Kind {
   // Type valued tokens (TyVal).
   Type,
 
+  DbgRecordType,
+
   APFloat, // APFloatVal
   APSInt   // APSInt
 };
diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h
index 737417fb9b9a542..284bfdd18db94ff 100644
--- a/llvm/include/llvm/IR/DebugProgramInstruction.h
+++ b/llvm/include/llvm/IR/DebugProgramInstruction.h
@@ -129,6 +129,30 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
           DIAssignID *AssignID, Metadata *Address,
           DIExpression *AddressExpression, const DILocation *DI);
 
+private:
+  /// Private constructor for creating new instances during parsing only. Only
+  /// called through `createUnresolvedDPValue` below, which makes clear that
+  /// this is used for parsing only, and will later return a subclass depending
+  /// on which Type is passed.
+  DPValue(LocationType Type, Metadata *Val, MDNode *Variable,
+          DIExpression *Expression, MDNode *AssignID, Metadata *Address,
+          DIExpression *AddressExpression, MDNode *DI);
+
+public:
+  /// Used to create DPValues during parsing, where some metadata references may
+  /// still be unresolved. Although for some fields a generic `Metadata*`
+  /// argument is accepted for forward type-references, the verifier and
+  /// accessors will reject incorrect types later on. The function is used for
+  /// all types of DPValues for simplicity while parsing, but asserts if any
+  /// necessary fields are empty or unused fields are not empty, i.e. if the
+  /// #dbg_assign fields are used for a non-dbg-assign type.
+  static DPValue *createUnresolvedDPValue(LocationType Type, Metadata *Val,
+                                          MDNode *Variable,
+                                          DIExpression *Expression,
+                                          MDNode *AssignID, Metadata *Address,
+                                          DIExpression *AddressExpression,
+                                          MDNode *DI);
+
   static DPValue *createDPVAssign(Value *Val, DILocalVariable *Variable,
                                   DIExpression *Expression,
                                   DIAssignID *AssignID, Value *Address,
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index c8da3efbb68aff7..4daf8a484da63e0 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -440,7 +440,9 @@ lltok::Kind LLLexer::LexCaret() {
 ///    AttrGrpID ::= #[0-9]+
 lltok::Kind LLLexer::LexHash() {
   // Handle AttrGrpID: #[0-9]+
-  return LexUIntID(lltok::AttrGrpID);
+  if (isdigit(static_cast<unsigned char>(CurPtr[0])))
+    return LexUIntID(lltok::AttrGrpID);
+  return lltok::hash;
 }
 
 /// Lex a label, integer type, keyword, or hexadecimal integer constant.
@@ -922,6 +924,20 @@ lltok::Kind LLLexer::LexIdentifier() {
 
 #undef DWKEYWORD
 
+// Keywords for debug record types.
+#define DBGRECORDTYPEKEYWORD(STR)                                              \
+  do {                                                                         \
+    if (Keyword == "dbg_" #STR) {                                              \
+      StrVal = #STR;                                                           \
+      return lltok::DbgRecordType;                                             \
+    }                                                                          \
+  } while (false)
+
+  DBGRECORDTYPEKEYWORD(value);
+  DBGRECORDTYPEKEYWORD(declare);
+  DBGRECORDTYPEKEYWORD(assign);
+#undef DBGRECORDTYPEKEYWORD
+
   if (Keyword.starts_with("DIFlag")) {
     StrVal.assign(Keyword.begin(), Keyword.end());
     return lltok::DIFlag;
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index d6c5993797de111..b22d21f94a26ab9 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -62,6 +62,8 @@ static cl::opt<bool> AllowIncompleteIR(
         "Allow incomplete IR on a best effort basis (references to unknown "
         "metadata will be dropped)"));
 
+extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
+
 static std::string getTypeString(Type *T) {
   std::string Result;
   raw_string_ostream Tmp(Result);
@@ -6012,6 +6014,17 @@ bool LLParser::parseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc,
   return false;
 }
 
+bool isOldDbgFormatIntrinsic(StringRef Name) {
+  // Exit early for the common (non-debug-intrinsic) case.
+  // We can make this the only check when we begin supporting all "llvm.dbg"
+  // intrinsics in the new debug info format.
+  if (!Name.starts_with("llvm.dbg."))
+    return false;
+  Intrinsic::ID FnID = Function::lookupIntrinsicID(Name);
+  return FnID == Intrinsic::dbg_declare || FnID == Intrinsic::dbg_value ||
+         FnID == Intrinsic::dbg_assign;
+}
+
 /// FunctionHeader
 ///   ::= OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility
 ///       OptionalCallingConv OptRetAttrs OptUnnamedAddr Type GlobalName
@@ -6194,6 +6207,13 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine,
     }
   }
 
+  if (isOldDbgFormatIntrinsic(FunctionName)) {
+    if (SeenNewDbgInfoFormat)
+      return error(NameLoc, "llvm.dbg intrinsic should not appear in a module "
+                            "using non-intrinsic debug info");
+    SeenOldDbgInfoFormat = true;
+  }
+
   Fn = Function::Create(FT, GlobalValue::ExternalLinkage, AddrSpace,
                         FunctionName, M);
 
@@ -6359,9 +6379,29 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
 
   std::string NameStr;
 
-  // parse the instructions in this block until we get a terminator.
+  // parse the instructions and debug values in this block until we get a
+  // terminator.
   Instruction *Inst;
+  DPValue *DPV;
+  SmallVector<std::unique_ptr<DPValue>> TrailingDPValues;
   do {
+    // Handle debug records first - there should always be an instruction
+    // following the debug records, i.e. they cannot appear after the block
+    // terminator.
+    while (Lex.getKind() == lltok::hash) {
+      if (SeenOldDbgInfoFormat)
+        return error(Lex.getLoc(), "debug record should not appear in a module "
+                                   "containing debug info intrinsics");
+      SeenNewDbgInfoFormat = true;
+      Lex.Lex();
+      if (!BB->getModule()->IsNewDbgInfoFormat)
+        BB->getModule()->convertToNewDbgValues();
+
+      if (parseDebugProgramValue(DPV, PFS))
+        return true;
+      TrailingDPValues.emplace_back(DPV);
+    }
+
     // This instruction may have three possibilities for a name: a) none
     // specified, b) name specified "%foo =", c) number specified: "%4 =".
     LocTy NameLoc = Lex.getLoc();
@@ -6406,11 +6446,103 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
     // Set the name on the instruction.
     if (PFS.setInstName(NameID, NameStr, NameLoc, Inst))
       return true;
+
+    // Attach any preceding debug values to this instruction.
+    for (std::unique_ptr<DPValue> &DPV : TrailingDPValues) {
+      BB->insertDPValueBefore(DPV.release(), Inst->getIterator());
+    }
+    TrailingDPValues.clear();
   } while (!Inst->isTerminator());
 
+  assert(TrailingDPValues.empty() &&
+         "All debug values should have been attached to an instruction.");
+
   return false;
 }
 
+/// parseDebugProgramValue
+///   ::= #dbg_Type { (ValueAsMetadata|DIArgList|MDNode), MetadataID,
+///   DIExpression, DILocation }
+bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
+  using LocType = DPValue::LocationType;
+  LocTy DPVLoc = Lex.getLoc();
+  if (Lex.getKind() != lltok::DbgRecordType) {
+    return error(DPVLoc, "expected debug record type here");
+  }
+  auto Type = StringSwitch<LocType>(Lex.getStrVal())
+                  .Case("declare", LocType::Declare)
+                  .Case("value", LocType::Value)
+                  .Case("assign", LocType::Assign)
+                  .Default(LocType::End);
+  if (Type == LocType::End)
+    return error(DPVLoc, "expected valid #dbg record here");
+  Lex.Lex();
+  if (parseToken(lltok::lbrace, "Expected '{' here"))
+    return true;
+
+  // Parse Value field...
+  Metadata *ValLocMD;
+  if (parseMetadata(ValLocMD, &PFS))
+    return true;
+  if (parseToken(lltok::comma, "Expected ',' here"))
+    return true;
+
+  // Parse Variable field...
+  MDNode *Variable;
+  if (parseMDNode(Variable))
+    return true;
+  if (parseToken(lltok::comma, "Expected ',' here"))
+    return true;
+
+  // Parse Expression field...
+  LocTy ExprLoc = Lex.getLoc();
+  Metadata *Expression;
+  if (parseMetadata(Expression, &PFS))
+    return true;
+  if (!isa<DIExpression>(Expression))
+    return error(ExprLoc, "expected valid DIExpression here");
+  if (parseToken(lltok::comma, "Expected ',' here"))
+    return true;
+
+  // Parse additional fields for #dbg_assign.
+  MDNode *AssignID = nullptr;
+  Metadata *AddressLocation = nullptr;
+  Metadata *AddressExpression = nullptr;
+  if (Type == LocType::Assign) {
+    // Parse DIAssignID...
+    if (parseMDNode(AssignID))
+      return true;
+    if (parseToken(lltok::comma, "Expected ',' here"))
+      return true;
+
+    // Parse address ValueAsMetadata...
+    if (parseMetadata(AddressLocation, &PFS))
+      return true;
+    if (parseToken(lltok::comma, "Expected ',' here"))
+      return true;
+
+    // Parse address DIExpression...
+    LocTy AddressExprLoc = Lex.getLoc();
+    if (parseMetadata(AddressExpression, &PFS))
+      return true;
+    if (!isa<DIExpression>(Expression))
+      return error(AddressExprLoc, "expected valid DIExpression here");
+    if (parseToken(lltok::comma, "Expected ',' here"))
+      return true;
+  }
+
+  /// Parse DILocation...
+  MDNode *DebugLoc;
+  if (parseMDNode(DebugLoc))
+    return true;
+
+  if (parseToken(lltok::rbrace, "Expected '}' here"))
+    return true;
+  DPV = DPValue::createUnresolvedDPValue(
+      Type, ValLocMD, Variable, cast<DIExpression>(Expression), AssignID,
+      AddressLocation, cast_or_null<DIExpression>(AddressExpression), DebugLoc);
+  return false;
+}
 //===----------------------------------------------------------------------===//
 // Instruction Parsing.
 //===----------------------------------------------------------------------===//
@@ -7638,6 +7770,16 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS,
     }
     CI->setFastMathFlags(FMF);
   }
+
+  if (CalleeID.Kind == ValID::t_GlobalName &&
+      isOldDbgFormatIntrinsic(CalleeID.StrVal)) {
+    if (SeenNewDbgInfoFormat) {
+      CI->deleteValue();
+      return error(CallLoc, "llvm.dbg intrinsic should not appear in a module "
+                            "using non-intrinsic debug info");
+    }
+    SeenOldDbgInfoFormat = true;
+  }
   CI->setAttributes(PAL);
   ForwardRefAttrGroups[CI] = FwdRefAttrGrps;
   Inst = CI;
diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp
index fd234685d5fd4bd..560ace9a84d70c1 100644
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ b/llvm/lib/IR/DebugProgramInstruction.cpp
@@ -59,6 +59,23 @@ DPValue::DPValue(Metadata *Value, DILocalVariable *Variable,
 
 void DPValue::deleteInstr() { delete this; }
 
+DPValue::DPValue(DPValue::LocationType Type, Metadata *Val, MDNode *Variable,
+                 DIExpression *Expression, MDNode *AssignID, Metadata *Address,
+                 DIExpression *AddressExpression, MDNode *DI)
+    : DebugValueUser({Val, Address, AssignID}), Variable(Variable),
+      Expression(Expression), DbgLoc(DI), AddressExpression(AddressExpression),
+      Type(Type) {}
+
+DPValue *DPValue::createUnresolvedDPValue(DPValue::LocationType Type,
+                                          Metadata *Val, MDNode *Variable,
+                                          DIExpression *Expression,
+                                          MDNode *AssignID, Metadata *Address,
+                                          DIExpression *AddressExpression,
+                                          MDNode *DI) {
+  return new DPValue(Type, Val, Variable, Expression, AssignID, Address,
+                     AddressExpression, DI);
+}
+
 DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV,
                                 DIExpression *Expr, const DILocation *DI) {
   return new DPValue(ValueAsMetadata::get(Location), DV, Expr, DI,
diff --git a/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll b/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll
new file mode 100644
index 000000000000000..f8c0024977bc226
--- /dev/null
+++ b/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll
@@ -0,0 +1,87 @@
+;; Test that we can write in the old debug info format.
+; RUN: opt --passes=verify -S --write-experimental-debuginfo=false < %s \
+; RUN:   | FileCheck %s --check-prefixes=CHECK,OLDDBG --implicit-check-not=llvm.dbg
+
+;; Test that we can write in the new debug info format...
+; RUN: opt --passes=verify -S --write-experimental-debuginfo=true < %s \
+; RUN:   | FileCheck %s --check-prefixes=CHECK,NEWDBG --implicit-check-not=llvm.dbg
+
+;; ...and then read the new format and write the old format.
+; RUN: opt --passes=verify -S --write-experimental-debuginfo=true < %s \
+; RUN:   | opt --passes=verify -S --write-experimental-debuginfo=false \
+; RUN:   | FileCheck %s --check-prefixes=CHECK,OLDDBG  --implicit-check-not=llvm.dbg
+
+;; Test also that the new flag is independent of the flag that enables use of
+;; these non-instruction debug info during LLVM passes.
+; RUN: opt --passes=verify -S --try-experimental-debuginfo-iterators --write-experimental-debuginfo=false < %s \
+; RUN:   | FileCheck %s --check-prefixes=CHECK,OLDDBG --implicit-check-not=llvm.dbg
+; 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
+
+; 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]+]]
+; NEWDBG-NEXT: {{^}}    #dbg_value { i32 %[[VAL_A]], ![[VAR_A:[0-9]+]], !DIExpression(), ![[LOC_1:[0-9]+]] }
+; CHECK-NEXT: {{^}}  %[[VAL_B:[0-9a-zA-Z]+]] = alloca
+; OLDDBG-NEXT: call void @llvm.dbg.declare(metadata ptr %[[VAL_B]], metadata ![[VAR_B:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC_2:[0-9]+]]
+; NEWDBG-NEXT: {{^}}    #dbg_declare { ptr %[[VAL_B]], ![[VAR_B:[0-9]+]], !DIExpression(), ![[LOC_2:[0-9]+]] }
+; CHECK-NEXT: {{^}}  %[[VAL_ADD:[0-9a-zA-Z]+]] = add i32 %[[VAL_A]], 5
+; OLDDBG-NEXT: call void @llvm.dbg.value(metadata !DIArgList(i32 %[[VAL_A]], i32 %[[VAL_ADD]]), metadata ![[VAR_A]], metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)), !dbg ![[LOC_3:[0-9]+]]
+; NEWDBG-NEXT: {{^}}    #dbg_value { !DIArgList(i32 %[[VAL_A]], i32 %[[VAL_ADD]]), ![[VAR_A]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), ![[LOC_3:[0-9]+]] }
+; CHECK-NEXT: {{^}}  store i32 %[[VAL_ADD]]{{.+}}, !DIAssignID ![[ASSIGNID:[0-9]+]]
+; OLDDBG-NEXT: call void @llvm.dbg.assign(metadata i32 %[[VAL_ADD]], metadata ![[VAR_B]], metadata !DIExpression(), metadata ![[ASSIGNID]], metadata ptr %[[VAL_B]], metadata !DIExpression()), !dbg ![[LOC_4:[0-9]+]]
+; NEWDBG-NEXT: {{^}}    #dbg_assign { i32 %[[VAL_ADD]], ![[VAR_B]], !DIExpression(), ![[ASSIGNID]], ptr %[[VAL_B]], !DIExpression(), ![[LOC_4:[0-9]+]] }
+; CHECK-NEXT: {{^}}  ret i32
+
+; OLDDBG-DAG: declare void @llvm.dbg.value
+; OLDDBG-DAG: declare void @llvm.dbg.declare
+; OLDDBG-DAG: declare void @llvm.dbg.assign
+
+; CHECK-DAG: llvm.dbg.cu
+; CHECK-DAG: ![[VAR_A]] = !DILocalVariable(name: "a"
+; CHECK-DAG: ![[VAR_B]] = !DILocalVariable(name: "b"
+; CHECK-DAG: ![[LOC_1]] = !DILocation(line: 3, column: 15
+; CHECK-DAG: ![[LOC_2]] = !DILocation(line: 3, column: 20
+; CHECK-DAG: ![[LOC_3]] = !DILocation(line: 3, column: 25
+; CHECK-DAG: ![[LOC_4]] = !DILocation(line: 3, column: 30
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+  call void @llvm.dbg.value(metadata i32 %a, metadata !20, metadata !DIExpression()), !dbg !30
+  %b = alloca i32, !dbg !30, !DIAssignID !40
+  call void @llvm.dbg.declare(metadata ptr %b, metadata !21, metadata !DIExpression()), !dbg !31
+  %add = add i32 %a, 5, !dbg !31
+  call void @llvm.dbg.value(metadata !DIArgList(i32 %a, i32 %add), metadata !20, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)), !dbg !32
+  store i32 %add, ptr %b, !dbg !32, !DIAssignID !40
+  call void @llvm.dbg.assign(metadata i32 %add, metadata !21, metadata !DIExpression(), metadata !40, metadata ptr %b, metadata !DIExpression()), !dbg !33
+  ret i32 %add, !dbg !33
+
+}
+
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+declare void @llvm.dbg.declare(metadata, metadata, metadata)
+declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !13)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!12, !12}
+!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!13 = !{!20, !21}
+!20 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !12)
+!21 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !12)
+!30 = !DILocation(line: 3, column: 15, scope: !7)
+!31 = !DILocation(line: 3, column: 20, scope: !7)
+!32 = !DILocation(line: 3, column: 25, scope: !7)
+!33 = !DILocation(line: 3, column: 30, scope: !7)
+!40 = distinct !DIAssignID()
\ No newline at end of file

>From 7619fa2d7f93242555e15f9930037a55e026e89b Mon Sep 17 00:00:00 2001
From: Stephen Tozer <Stephen.Tozer at Sony.com>
Date: Mon, 29 Jan 2024 16:02:50 +0000
Subject: [PATCH 2/2] Address review nits

---
 llvm/lib/AsmParser/LLParser.cpp | 45 ++++++++++++++++++++-------------
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index b22d21f94a26ab9..910d3fed04a5715 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -71,6 +71,15 @@ 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)
+    M->setIsNewDbgInfoFormat(false);
+  return false;
+}
+
 /// Run: module ::= toplevelentity*
 bool LLParser::Run(bool UpgradeDebugInfo,
                    DataLayoutCallbackTy DataLayoutCallback) {
@@ -88,7 +97,7 @@ bool LLParser::Run(bool UpgradeDebugInfo,
   }
 
   return parseTopLevelEntities() || validateEndOfModule(UpgradeDebugInfo) ||
-         validateEndOfIndex();
+         validateEndOfIndex() || finalizeDebugInfoFormat(M);
 }
 
 bool LLParser::parseStandaloneConstantValue(Constant *&C,
@@ -6379,10 +6388,9 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
 
   std::string NameStr;
 
-  // parse the instructions and debug values in this block until we get a
+  // Parse the instructions and debug values in this block until we get a
   // terminator.
   Instruction *Inst;
-  DPValue *DPV;
   SmallVector<std::unique_ptr<DPValue>> TrailingDPValues;
   do {
     // Handle debug records first - there should always be an instruction
@@ -6394,9 +6402,10 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
                                    "containing debug info intrinsics");
       SeenNewDbgInfoFormat = true;
       Lex.Lex();
-      if (!BB->getModule()->IsNewDbgInfoFormat)
-        BB->getModule()->convertToNewDbgValues();
+      if (!M->IsNewDbgInfoFormat)
+        M->convertToNewDbgValues();
 
+      DPValue *DPV;
       if (parseDebugProgramValue(DPV, PFS))
         return true;
       TrailingDPValues.emplace_back(DPV);
@@ -6448,9 +6457,8 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
       return true;
 
     // Attach any preceding debug values to this instruction.
-    for (std::unique_ptr<DPValue> &DPV : TrailingDPValues) {
+    for (std::unique_ptr<DPValue> &DPV : TrailingDPValues)
       BB->insertDPValueBefore(DPV.release(), Inst->getIterator());
-    }
     TrailingDPValues.clear();
   } while (!Inst->isTerminator());
 
@@ -6461,14 +6469,15 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
 }
 
 /// parseDebugProgramValue
-///   ::= #dbg_Type { (ValueAsMetadata|DIArgList|MDNode), MetadataID,
-///   DIExpression, DILocation }
+///   ::= #dbg_Type '{' (ValueAsMetadata|DIArgList|MDNode) ',' MetadataID ','
+///   DIExpression ','
+///   (DIAssignID',' (ValueAsMetadata|MDNode)',' DIExpression] ',')?
+///   DILocation '}'
 bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
   using LocType = DPValue::LocationType;
   LocTy DPVLoc = Lex.getLoc();
-  if (Lex.getKind() != lltok::DbgRecordType) {
+  if (Lex.getKind() != lltok::DbgRecordType)
     return error(DPVLoc, "expected debug record type here");
-  }
   auto Type = StringSwitch<LocType>(Lex.getStrVal())
                   .Case("declare", LocType::Declare)
                   .Case("value", LocType::Value)
@@ -6480,21 +6489,21 @@ bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
   if (parseToken(lltok::lbrace, "Expected '{' here"))
     return true;
 
-  // Parse Value field...
+  // Parse Value field.
   Metadata *ValLocMD;
   if (parseMetadata(ValLocMD, &PFS))
     return true;
   if (parseToken(lltok::comma, "Expected ',' here"))
     return true;
 
-  // Parse Variable field...
+  // Parse Variable field.
   MDNode *Variable;
   if (parseMDNode(Variable))
     return true;
   if (parseToken(lltok::comma, "Expected ',' here"))
     return true;
 
-  // Parse Expression field...
+  // Parse Expression field.
   LocTy ExprLoc = Lex.getLoc();
   Metadata *Expression;
   if (parseMetadata(Expression, &PFS))
@@ -6509,19 +6518,19 @@ bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
   Metadata *AddressLocation = nullptr;
   Metadata *AddressExpression = nullptr;
   if (Type == LocType::Assign) {
-    // Parse DIAssignID...
+    // Parse DIAssignID.
     if (parseMDNode(AssignID))
       return true;
     if (parseToken(lltok::comma, "Expected ',' here"))
       return true;
 
-    // Parse address ValueAsMetadata...
+    // Parse address ValueAsMetadata.
     if (parseMetadata(AddressLocation, &PFS))
       return true;
     if (parseToken(lltok::comma, "Expected ',' here"))
       return true;
 
-    // Parse address DIExpression...
+    // Parse address DIExpression.
     LocTy AddressExprLoc = Lex.getLoc();
     if (parseMetadata(AddressExpression, &PFS))
       return true;
@@ -6531,7 +6540,7 @@ bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
       return true;
   }
 
-  /// Parse DILocation...
+  /// Parse DILocation.
   MDNode *DebugLoc;
   if (parseMDNode(DebugLoc))
     return true;



More information about the llvm-commits mailing list