[llvm] adf7a0a - [WebAssembly] Use TargetIndex operands in DbgValue to track WebAssembly operands locations

Derek Schuff via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 20 14:45:22 PST 2019


Author: Yury Delendik
Date: 2019-12-20T14:39:05-08:00
New Revision: adf7a0a558a51f275bf8906b6a010c397560b7ff

URL: https://github.com/llvm/llvm-project/commit/adf7a0a558a51f275bf8906b6a010c397560b7ff
DIFF: https://github.com/llvm/llvm-project/commit/adf7a0a558a51f275bf8906b6a010c397560b7ff.diff

LOG: [WebAssembly] Use TargetIndex operands in DbgValue to track WebAssembly operands locations

Extends DWARF expression language to express locals/globals locations. (via
target-index operands atm) (possible variants are: non-virtual registers
or address spaces)

The WebAssemblyExplicitLocals can replace virtual registers to targertindex
operand type at the time when WebAssembly backend introduces
{get,set,tee}_local instead of corresponding virtual registers.

Reviewed By: aprantl, dschuff

Tags: #debug-info, #llvm

Differential Revision: https://reviews.llvm.org/D52634

Added: 
    llvm/test/DebugInfo/WebAssembly/dbg-value-dwarfdump.ll
    llvm/test/DebugInfo/WebAssembly/dbg-value-ti.ll

Modified: 
    llvm/include/llvm/BinaryFormat/Dwarf.def
    llvm/include/llvm/BinaryFormat/Dwarf.h
    llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
    llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
    llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
    llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
    llvm/lib/Target/WebAssembly/WebAssembly.h
    llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp
    llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h
    llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
    llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
    llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.h

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def
index cf3eaf433e5d..3faf3be65032 100644
--- a/llvm/include/llvm/BinaryFormat/Dwarf.def
+++ b/llvm/include/llvm/BinaryFormat/Dwarf.def
@@ -648,6 +648,8 @@ HANDLE_DW_OP(0xa9, reinterpret, 5, DWARF)
 // Vendor extensions:
 // Extensions for GNU-style thread-local storage.
 HANDLE_DW_OP(0xe0, GNU_push_tls_address, 0, GNU)
+// Extensions for WebAssembly.
+HANDLE_DW_OP(0xed, WASM_location, 0, WASM)
 // The GNU entry value extension.
 HANDLE_DW_OP(0xf3, GNU_entry_value, 0, GNU)
 // Extensions for Fission proposal.

diff  --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h
index 93eaf368033a..2ad201831d2b 100644
--- a/llvm/include/llvm/BinaryFormat/Dwarf.h
+++ b/llvm/include/llvm/BinaryFormat/Dwarf.h
@@ -63,7 +63,8 @@ enum LLVMConstants : uint32_t {
   DWARF_VENDOR_GNU = 3,
   DWARF_VENDOR_GOOGLE = 4,
   DWARF_VENDOR_LLVM = 5,
-  DWARF_VENDOR_MIPS = 6
+  DWARF_VENDOR_MIPS = 6,
+  DWARF_VENDOR_WASM = 7
 };
 
 /// Constants that define the DWARF format as 32 or 64 bit.

diff  --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index a8e8d3f813db..9f68b07b76c3 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -879,6 +879,10 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
     OS << MI->getOperand(0).getImm();
   } else if (MI->getOperand(0).isCImm()) {
     MI->getOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/);
+  } else if (MI->getOperand(0).isTargetIndex()) {
+    auto Op = MI->getOperand(0);
+    OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")";
+    return true;
   } else {
     unsigned Reg;
     if (MI->getOperand(0).isReg()) {

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index 17e39b3d3268..36278f2e9e2d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -20,13 +20,33 @@
 namespace llvm {
 class AsmPrinter;
 
+/// This struct describes target specific location.
+struct TargetIndexLocation {
+  int Index;
+  int Offset;
+
+  TargetIndexLocation() = default;
+  TargetIndexLocation(unsigned Idx, int64_t Offset)
+      : Index(Idx), Offset(Offset) {}
+
+  bool operator==(const TargetIndexLocation &Other) const {
+    return Index == Other.Index && Offset == Other.Offset;
+  }
+};
+
 /// A single location or constant.
 class DbgValueLoc {
   /// Any complex address location expression for this DbgValueLoc.
   const DIExpression *Expression;
 
   /// Type of entry that this represents.
-  enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt };
+  enum EntryType {
+    E_Location,
+    E_Integer,
+    E_ConstantFP,
+    E_ConstantInt,
+    E_TargetIndexLocation
+  };
   enum EntryType EntryKind;
 
   /// Either a constant,
@@ -36,8 +56,12 @@ class DbgValueLoc {
     const ConstantInt *CIP;
   } Constant;
 
-  /// Or a location in the machine frame.
-  MachineLocation Loc;
+  union {
+    /// Or a location in the machine frame.
+    MachineLocation Loc;
+    /// Or a location from target specific location.
+    TargetIndexLocation TIL;
+  };
 
 public:
   DbgValueLoc(const DIExpression *Expr, int64_t i)
@@ -56,8 +80,13 @@ class DbgValueLoc {
       : Expression(Expr), EntryKind(E_Location), Loc(Loc) {
     assert(cast<DIExpression>(Expr)->isValid());
   }
+  DbgValueLoc(const DIExpression *Expr, TargetIndexLocation Loc)
+      : Expression(Expr), EntryKind(E_TargetIndexLocation), TIL(Loc) {}
 
   bool isLocation() const { return EntryKind == E_Location; }
+  bool isTargetIndexLocation() const {
+    return EntryKind == E_TargetIndexLocation;
+  }
   bool isInt() const { return EntryKind == E_Integer; }
   bool isConstantFP() const { return EntryKind == E_ConstantFP; }
   bool isConstantInt() const { return EntryKind == E_ConstantInt; }
@@ -65,6 +94,7 @@ class DbgValueLoc {
   const ConstantFP *getConstantFP() const { return Constant.CFP; }
   const ConstantInt *getConstantInt() const { return Constant.CIP; }
   MachineLocation getLoc() const { return Loc; }
+  TargetIndexLocation getTargetIndexLocation() const { return TIL; }
   bool isFragment() const { return getExpression()->isFragment(); }
   bool isEntryVal() const { return getExpression()->isEntryValue(); }
   const DIExpression *getExpression() const { return Expression; }
@@ -162,6 +192,8 @@ inline bool operator==(const DbgValueLoc &A,
   switch (A.EntryKind) {
   case DbgValueLoc::E_Location:
     return A.Loc == B.Loc;
+  case DbgValueLoc::E_TargetIndexLocation:
+    return A.TIL == B.TIL;
   case DbgValueLoc::E_Integer:
     return A.Constant.Int == B.Constant.Int;
   case DbgValueLoc::E_ConstantFP:

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 0a0322f235ec..739cbaf694f5 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -241,6 +241,11 @@ static DbgValueLoc getDebugLocValue(const MachineInstr *MI) {
     MachineLocation MLoc(RegOp.getReg(), Op1.isImm());
     return DbgValueLoc(Expr, MLoc);
   }
+  if (MI->getOperand(0).isTargetIndex()) {
+    auto Op = MI->getOperand(0);
+    return DbgValueLoc(Expr,
+                       TargetIndexLocation(Op.getIndex(), Op.getOffset()));
+  }
   if (MI->getOperand(0).isImm())
     return DbgValueLoc(Expr, MI->getOperand(0).getImm());
   if (MI->getOperand(0).isFPImm())
@@ -2241,6 +2246,11 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
     if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
       return;
     return DwarfExpr.addExpression(std::move(Cursor));
+  } else if (Value.isTargetIndexLocation()) {
+    TargetIndexLocation Loc = Value.getTargetIndexLocation();
+    // TODO TargetIndexLocation is a target-independent. Currently only the WebAssembly-specific
+    // encoding is supported.
+    DwarfExpr.addWasmLocation(Loc.Index, Loc.Offset);
   } else if (Value.isConstantFP()) {
     APInt RawBytes = Value.getConstantFP()->getValueAPF().bitcastToAPInt();
     DwarfExpr.addUnsignedConstant(RawBytes);

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index df33a4faa85c..310647f15a5e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -572,3 +572,11 @@ void DwarfExpression::emitLegacyZExt(unsigned FromBits) {
   emitUnsigned((1ULL << FromBits) - 1);
   emitOp(dwarf::DW_OP_and);
 }
+
+void DwarfExpression::addWasmLocation(unsigned Index, int64_t Offset) {
+  assert(LocationKind == Implicit || LocationKind == Unknown);
+  LocationKind = Implicit;
+  emitOp(dwarf::DW_OP_WASM_location);
+  emitUnsigned(Index);
+  emitSigned(Offset);
+}

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 1ad46669f9b2..46c07b1d5b6b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -337,6 +337,10 @@ class DwarfExpression {
 
   void emitLegacySExt(unsigned FromBits);
   void emitLegacyZExt(unsigned FromBits);
+
+  /// Emit location information expressed via WebAssembly location + offset
+  /// The Index is an identifier for locals, globals or operand stack.
+  void addWasmLocation(unsigned Index, int64_t Offset);
 };
 
 /// DwarfExpression implementation for .debug_loc entries.

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
index 5009b1b7b412..7d817d8a9925 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
@@ -93,6 +93,8 @@ static DescVector getDescriptions() {
   Descriptions[DW_OP_implicit_value] =
       Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeBlock);
   Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf3);
+  Descriptions[DW_OP_WASM_location] =
+      Desc(Op::Dwarf4, Op::SizeLEB, Op::SignedSizeLEB);
   Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3);
   Descriptions[DW_OP_addrx] = Desc(Op::Dwarf4, Op::SizeLEB);
   Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB);

diff  --git a/llvm/lib/Target/WebAssembly/WebAssembly.h b/llvm/lib/Target/WebAssembly/WebAssembly.h
index fcbd0a5082ff..fcd48e0096b6 100644
--- a/llvm/lib/Target/WebAssembly/WebAssembly.h
+++ b/llvm/lib/Target/WebAssembly/WebAssembly.h
@@ -79,6 +79,10 @@ void initializeWebAssemblyRegNumberingPass(PassRegistry &);
 void initializeWebAssemblyPeepholePass(PassRegistry &);
 void initializeWebAssemblyCallIndirectFixupPass(PassRegistry &);
 
+namespace WebAssembly {
+enum TargetIndex { TI_LOCAL_START, TI_GLOBAL_START, TI_OPERAND_STACK_START };
+} // end namespace WebAssembly
+
 } // end namespace llvm
 
 #endif

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp
index 579377c9a5d7..114a50a3055d 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "WebAssemblyDebugValueManager.h"
+#include "WebAssembly.h"
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "llvm/CodeGen/MachineInstr.h"
 
@@ -43,3 +44,10 @@ void WebAssemblyDebugValueManager::clone(MachineInstr *Insert,
     MBB->insert(Insert, Clone);
   }
 }
+
+void WebAssemblyDebugValueManager::replaceWithLocal(unsigned LocalId) {
+  for (auto *DBI : DbgValues) {
+    MachineOperand &Op = DBI->getOperand(0);
+    Op.ChangeToTargetIndex(llvm::WebAssembly::TI_LOCAL_START, LocalId);
+  }
+}

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h
index 06e8805b5ad0..7eae3cb5febd 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h
@@ -30,6 +30,7 @@ class WebAssemblyDebugValueManager {
   void move(MachineInstr *Insert);
   void updateReg(unsigned Reg);
   void clone(MachineInstr *Insert, unsigned NewReg);
+  void replaceWithLocal(unsigned LocalId);
 };
 
 } // end namespace llvm

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
index ef75bb215317..acbd4c9921b0 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
@@ -17,6 +17,7 @@
 
 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
 #include "WebAssembly.h"
+#include "WebAssemblyDebugValueManager.h"
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "WebAssemblySubtarget.h"
 #include "WebAssemblyUtilities.h"
@@ -261,6 +262,8 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
             .addImm(LocalId)
             .addReg(MI.getOperand(2).getReg());
 
+        WebAssemblyDebugValueManager(&MI).replaceWithLocal(LocalId);
+
         MI.eraseFromParent();
         Changed = true;
         continue;
@@ -290,6 +293,9 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
           } else {
             unsigned LocalId = getLocalId(Reg2Local, CurLocal, OldReg);
             unsigned Opc = getLocalSetOpcode(RC);
+
+            WebAssemblyDebugValueManager(&MI).replaceWithLocal(LocalId);
+
             BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc))
                 .addImm(LocalId)
                 .addReg(NewReg);

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
index b60fd6f687fb..221dacaf821b 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
@@ -14,6 +14,7 @@
 
 #include "WebAssemblyInstrInfo.h"
 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
+#include "WebAssembly.h"
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "WebAssemblySubtarget.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
@@ -230,3 +231,12 @@ bool WebAssemblyInstrInfo::reverseBranchCondition(
   Cond.front() = MachineOperand::CreateImm(!Cond.front().getImm());
   return false;
 }
+
+ArrayRef<std::pair<int, const char *>>
+WebAssemblyInstrInfo::getSerializableTargetIndices() const {
+  static const std::pair<int, const char *> TargetIndices[] = {
+      {WebAssembly::TI_LOCAL_START, "wasm-local-start"},
+      {WebAssembly::TI_GLOBAL_START, "wasm-global-start"},
+      {WebAssembly::TI_OPERAND_STACK_START, "wasm-operator-stack-start"}};
+  return makeArrayRef(TargetIndices);
+}

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.h
index cca8b395b6f7..5762fd964c2a 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.h
@@ -16,6 +16,7 @@
 #define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYINSTRINFO_H
 
 #include "WebAssemblyRegisterInfo.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
 
 #define GET_INSTRINFO_HEADER
@@ -64,6 +65,9 @@ class WebAssemblyInstrInfo final : public WebAssemblyGenInstrInfo {
                         int *BytesAdded = nullptr) const override;
   bool
   reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
+
+  ArrayRef<std::pair<int, const char *>>
+  getSerializableTargetIndices() const override;
 };
 
 } // end namespace llvm

diff  --git a/llvm/test/DebugInfo/WebAssembly/dbg-value-dwarfdump.ll b/llvm/test/DebugInfo/WebAssembly/dbg-value-dwarfdump.ll
new file mode 100644
index 000000000000..f15ebe8e8933
--- /dev/null
+++ b/llvm/test/DebugInfo/WebAssembly/dbg-value-dwarfdump.ll
@@ -0,0 +1,70 @@
+; RUN: llc < %s -filetype=obj -o - | llvm-dwarfdump - | FileCheck %s
+
+; Verify if dwarfdump contains DBG_VALUE associated with locals.
+; See also dgb-value-ti.ll test.
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown-wasm"
+
+define hidden i32 @fib(i32 %n) local_unnamed_addr #0 !dbg !7 {
+
+entry:
+; CHECK: DW_TAG_subprogram
+; CHECK: DW_TAG_variable
+
+  call void @llvm.dbg.value(metadata i32 1, metadata !16, metadata !DIExpression()), !dbg !19
+  %cmp8 = icmp sgt i32 %n, 0, !dbg !21
+  br i1 %cmp8, label %for.body, label %for.end, !dbg !24
+
+for.body:                                         ; preds = %entry, %for.body
+  %b.011 = phi i32 [ %add, %for.body ], [ 1, %entry ]
+  %a.010 = phi i32 [ %b.011, %for.body ], [ 0, %entry ]
+  %i.09 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
+
+; CHECK: DW_OP_WASM_location 0x0 +[[LOCAL_1:[0-9]+]]
+  call void @llvm.dbg.value(metadata i32 %b.011, metadata !16, metadata !DIExpression()), !dbg !19
+
+; CHECK-NOT: DW_OP_WASM_location 0x0 +[[LOCAL_1]]
+; CHECK: DW_OP_WASM_location 0x0 +[[LOCAL_2:[0-9]+]]
+  %add = add nsw i32 %b.011, %a.010, !dbg !26
+  %inc = add nuw nsw i32 %i.09, 1, !dbg !28
+  call void @llvm.dbg.value(metadata i32 %add, metadata !16, metadata !DIExpression()), !dbg !19
+  %exitcond = icmp eq i32 %inc, %n, !dbg !21
+  br i1 %exitcond, label %for.end, label %for.body, !dbg !24, !llvm.loop !29
+
+for.end:                                          ; preds = %for.body, %entry
+  %b.0.lcssa = phi i32 [ 1, %entry ], [ %add, %for.body ], !dbg !31
+  call void @llvm.dbg.value(metadata i32 %b.0.lcssa, metadata !16, metadata !DIExpression()), !dbg !19
+  ret i32 %b.0.lcssa, !dbg !32
+}
+
+declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!4}
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "<unknown>", directory: "")
+!2 = !{}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!7 = distinct !DISubprogram(name: "fib", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!16}
+!16 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 2, type: !10)
+!17 = !DILocation(line: 1, column: 13, scope: !7)
+!18 = !DILocation(line: 2, column: 13, scope: !7)
+!19 = !DILocation(line: 2, column: 20, scope: !7)
+!20 = !DILocation(line: 2, column: 7, scope: !7)
+!21 = !DILocation(line: 3, column: 17, scope: !22)
+!22 = distinct !DILexicalBlock(scope: !23, file: !1, line: 3, column: 3)
+!23 = distinct !DILexicalBlock(scope: !7, file: !1, line: 3, column: 3)
+!24 = !DILocation(line: 3, column: 3, scope: !23)
+!25 = !DILocation(line: 2, column: 10, scope: !7)
+!26 = !DILocation(line: 6, column: 7, scope: !27)
+!27 = distinct !DILexicalBlock(scope: !22, file: !1, line: 3, column: 27)
+!28 = !DILocation(line: 3, column: 23, scope: !22)
+!29 = distinct !{!29, !24, !30}
+!30 = !DILocation(line: 7, column: 3, scope: !23)
+!31 = !DILocation(line: 0, scope: !7)
+!32 = !DILocation(line: 8, column: 3, scope: !7)

diff  --git a/llvm/test/DebugInfo/WebAssembly/dbg-value-ti.ll b/llvm/test/DebugInfo/WebAssembly/dbg-value-ti.ll
new file mode 100644
index 000000000000..a99ca2d43cb3
--- /dev/null
+++ b/llvm/test/DebugInfo/WebAssembly/dbg-value-ti.ll
@@ -0,0 +1,74 @@
+; RUN: llc < %s -stop-after=wasm-explicit-locals | FileCheck %s
+
+; Checks if DBG_VALUEs that correspond to new `local.{tee,set}` are
+; using `target-index(wasm-local-start)` operands.
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown-wasm"
+
+define hidden i32 @fib(i32 %n) local_unnamed_addr #0 !dbg !7 {
+; CHECK: body:
+entry:
+
+; CHECK: %[[REG1:.*]]:i32 = CONST_I32 1,
+; CHECK: LOCAL_SET_I32 [[LOOP_LOCAL:.*]], %[[REG1]],
+; CHECK: DBG_VALUE 1, $noreg,
+  call void @llvm.dbg.value(metadata i32 1, metadata !16, metadata !DIExpression()), !dbg !19
+  %cmp8 = icmp sgt i32 %n, 0, !dbg !21
+  br i1 %cmp8, label %for.body, label %for.end, !dbg !24
+
+for.body:                                         ; preds = %entry, %for.body
+  %b.011 = phi i32 [ %add, %for.body ], [ 1, %entry ]
+  %a.010 = phi i32 [ %b.011, %for.body ], [ 0, %entry ]
+  %i.09 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
+
+; CHECK: %[[REG2:.*]]:i32 = LOCAL_GET_I32 [[LOOP_LOCAL]],
+; CHECK: %[[REG3:.*]]:i32 = LOCAL_TEE_I32 [[TMP_LOCAL:.*]], %[[REG2]],
+; CHECK: DBG_VALUE target-index(wasm-local-start) + [[TMP_LOCAL]], $noreg,
+  call void @llvm.dbg.value(metadata i32 %b.011, metadata !16, metadata !DIExpression()), !dbg !19
+
+; CHECK: %[[REG4:.*]]:i32 = nsw ADD_I32
+; CHECK: LOCAL_SET_I32 [[LOOP_LOCAL]], %[[REG4]],
+; CHECK: DBG_VALUE target-index(wasm-local-start) + [[LOOP_LOCAL]], $noreg,
+  %add = add nsw i32 %b.011, %a.010, !dbg !26
+  %inc = add nuw nsw i32 %i.09, 1, !dbg !28
+  call void @llvm.dbg.value(metadata i32 %add, metadata !16, metadata !DIExpression()), !dbg !19
+  %exitcond = icmp eq i32 %inc, %n, !dbg !21
+  br i1 %exitcond, label %for.end, label %for.body, !dbg !24, !llvm.loop !29
+
+for.end:                                          ; preds = %for.body, %entry
+  %b.0.lcssa = phi i32 [ 1, %entry ], [ %add, %for.body ], !dbg !31
+  call void @llvm.dbg.value(metadata i32 %b.0.lcssa, metadata !16, metadata !DIExpression()), !dbg !19
+  ret i32 %b.0.lcssa, !dbg !32
+}
+
+declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!4}
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "<unknown>", directory: "")
+!2 = !{}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!7 = distinct !DISubprogram(name: "fib", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!16}
+!16 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 2, type: !10)
+!17 = !DILocation(line: 1, column: 13, scope: !7)
+!18 = !DILocation(line: 2, column: 13, scope: !7)
+!19 = !DILocation(line: 2, column: 20, scope: !7)
+!20 = !DILocation(line: 2, column: 7, scope: !7)
+!21 = !DILocation(line: 3, column: 17, scope: !22)
+!22 = distinct !DILexicalBlock(scope: !23, file: !1, line: 3, column: 3)
+!23 = distinct !DILexicalBlock(scope: !7, file: !1, line: 3, column: 3)
+!24 = !DILocation(line: 3, column: 3, scope: !23)
+!25 = !DILocation(line: 2, column: 10, scope: !7)
+!26 = !DILocation(line: 6, column: 7, scope: !27)
+!27 = distinct !DILexicalBlock(scope: !22, file: !1, line: 3, column: 27)
+!28 = !DILocation(line: 3, column: 23, scope: !22)
+!29 = distinct !{!29, !24, !30}
+!30 = !DILocation(line: 7, column: 3, scope: !23)
+!31 = !DILocation(line: 0, scope: !7)
+!32 = !DILocation(line: 8, column: 3, scope: !7)


        


More information about the llvm-commits mailing list