[llvm] 6e39379 - [DwarfExpression] Support entry values for indirect parameters

Vedant Kumar via llvm-commits llvm-commits at lists.llvm.org
Tue May 26 14:35:21 PDT 2020


Author: Vedant Kumar
Date: 2020-05-26T14:22:28-07:00
New Revision: 6e39379bbbe1d8aba658f638dfc42f0ba0cbb926

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

LOG: [DwarfExpression] Support entry values for indirect parameters

Summary:
A struct argument can be passed-by-value to a callee via a pointer to a
temporary stack copy. Add support for emitting an entry value DBG_VALUE
when an indirect parameter DBG_VALUE becomes unavailable. This is done
by omitting DW_OP_stack_value from the entry value expression, to make
the expression describe the location of an object.

rdar://63373691

Reviewers: djtodoro, aprantl, dstenb

Subscribers: hiraditya, lldb-commits, llvm-commits

Tags: #lldb, #llvm

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

Added: 
    llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-indirect-param-with-offset.mir
    llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-indirect-param.mir

Modified: 
    lldb/test/API/functionalities/param_entry_vals/basic_entry_values/main.cpp
    llvm/docs/LangRef.rst
    llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
    llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
    llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
    llvm/lib/CodeGen/LiveDebugValues.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/test/API/functionalities/param_entry_vals/basic_entry_values/main.cpp b/lldb/test/API/functionalities/param_entry_vals/basic_entry_values/main.cpp
index c739a05f421e..83f622cadf14 100644
--- a/lldb/test/API/functionalities/param_entry_vals/basic_entry_values/main.cpp
+++ b/lldb/test/API/functionalities/param_entry_vals/basic_entry_values/main.cpp
@@ -137,6 +137,30 @@ func14(int &sink, void (*target_no_tailcall)(int &, int)) {
   target_no_tailcall(sink, 123);
 }
 
+/// A structure that is guaranteed -- when passed to a callee by value -- to be
+/// passed via a pointer to a temporary copy in the caller. On x86_64 & aarch64
+/// only.
+struct StructPassedViaPointerToTemporaryCopy {
+  // Under the 64-bit AAPCS, a struct larger than 16 bytes is not SROA'd, and
+  // is instead passed via pointer to a temporary copy.
+  long a, b, c;
+  StructPassedViaPointerToTemporaryCopy() : a(1), b(2), c(3) {}
+
+  // Failing that, a virtual method forces passing via pointer to a temporary
+  // copy under the common calling conventions (e.g. 32/64-bit x86, Linux/Win,
+  // according to https://www.agner.org/optimize/calling_conventions.pdf).
+  virtual void add_vtable() {}
+};
+
+__attribute__((noinline)) void func15(StructPassedViaPointerToTemporaryCopy S) {
+  use<StructPassedViaPointerToTemporaryCopy &>(S);
+  use<int &>(dummy);
+
+  ++global;
+  //% self.filecheck("expr S", "main.cpp", "-check-prefix=FUNC15-EXPR")
+  // FUNC15-EXPR: (a = 1, b = 2, c = 3)
+}
+
 __attribute__((disable_tail_calls)) int main() {
   int sink = 0;
   S1 s1;
@@ -169,5 +193,9 @@ __attribute__((disable_tail_calls)) int main() {
   // Test that evaluation can "see through" an indirect tail call.
   func14(sink, func13);
 
+  // Test evaluation of an entry value that dereferences a temporary stack
+  // slot set up by the caller for a StructPassedViaPointerToTemporaryCopy.
+  func15(StructPassedViaPointerToTemporaryCopy());
+
   return 0;
 }

diff  --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 01f41a7ea3f1..0891392b1e61 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -5104,9 +5104,11 @@ The current supported opcode vocabulary is limited:
 
   ``DW_OP_LLVM_entry_value`` is only legal in MIR. The operation is introduced
   by the ``LiveDebugValues`` pass; currently only for function parameters that
-  are unmodified throughout a function and that are described as simple
-  register location descriptions. The operation is also introduced by the
-  ``AsmPrinter`` pass when a call site parameter value
+  are unmodified throughout a function. Support is limited to function
+  parameter that are described as simple register location descriptions, or as
+  indirect locations (e.g. when a struct is passed-by-value to a callee via a
+  pointer to a temporary copy made in the caller). The entry value op is also
+  introduced by the ``AsmPrinter`` pass when a call site parameter value
   (``DW_AT_call_site_parameter_value``) is represented as entry value of the
   parameter.
 - ``DW_OP_breg`` (or ``DW_OP_bregx``) represents a content on the provided

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 93bf9d6c2f71..dce90b3c17c0 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -1285,15 +1285,12 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
   DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
   const DIExpression *DIExpr = DV.getSingleExpression();
   DwarfExpr.addFragmentOffset(DIExpr);
-  if (Location.isIndirect())
-    DwarfExpr.setMemoryLocationKind();
+  DwarfExpr.setLocation(Location, DIExpr);
 
   DIExpressionCursor Cursor(DIExpr);
 
-  if (DIExpr->isEntryValue()) {
-    DwarfExpr.setEntryValueFlag();
+  if (DIExpr->isEntryValue())
     DwarfExpr.beginEntryValueExpression(Cursor);
-  }
 
   const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
   if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 17fcf692d913..953154f0b10b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -2399,14 +2399,11 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
       DwarfExpr.addUnsignedConstant(Value.getInt());
   } else if (Value.isLocation()) {
     MachineLocation Location = Value.getLoc();
-    if (Location.isIndirect())
-      DwarfExpr.setMemoryLocationKind();
+    DwarfExpr.setLocation(Location, DIExpr);
     DIExpressionCursor Cursor(DIExpr);
 
-    if (DIExpr->isEntryValue()) {
-      DwarfExpr.setEntryValueFlag();
+    if (DIExpr->isEntryValue())
       DwarfExpr.beginEntryValueExpression(Cursor);
-    }
 
     const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
     if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index 69bc06cb9467..7b64c2238bd6 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -259,7 +259,8 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
     if (isEntryValue())
       finalizeEntryValue();
 
-    if (isEntryValue() && !isParameterValue() && DwarfVersion >= 4)
+    if (isEntryValue() && !isIndirect() && !isParameterValue() &&
+        DwarfVersion >= 4)
       emitOp(dwarf::DW_OP_stack_value);
 
     DwarfRegs.clear();
@@ -318,6 +319,25 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
   return true;
 }
 
+void DwarfExpression::setEntryValueFlags(const MachineLocation &Loc) {
+  LocationFlags |= EntryValue;
+  if (Loc.isIndirect())
+    LocationFlags |= Indirect;
+}
+
+void DwarfExpression::setLocation(const MachineLocation &Loc,
+                                  const DIExpression *DIExpr) {
+  if (Loc.isIndirect())
+    // Do not treat entry value descriptions of indirect parameters as memory
+    // locations. This allows DwarfExpression::addReg() to add DW_OP_regN to an
+    // entry value description.
+    if (!DIExpr->isEntryValue())
+      setMemoryLocationKind();
+
+  if (DIExpr->isEntryValue())
+    setEntryValueFlags(Loc);
+}
+
 void DwarfExpression::beginEntryValueExpression(
     DIExpressionCursor &ExprCursor) {
   auto Op = ExprCursor.take();

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 5d4386282787..42be827cd5a0 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -30,6 +30,7 @@ class APInt;
 class DwarfCompileUnit;
 class DIELoc;
 class TargetRegisterInfo;
+class MachineLocation;
 
 /// Holds a DIExpression and keeps track of how many operands have been consumed
 /// so far.
@@ -142,14 +143,18 @@ class DwarfExpression {
   /// The kind of location description being produced.
   enum { Unknown = 0, Register, Memory, Implicit };
 
-  /// The flags of location description being produced.
-  enum { EntryValue = 1, CallSiteParamValue };
+  /// Additional location flags which may be combined with any location kind.
+  /// Currently, entry values are not supported for the Memory location kind.
+  enum { EntryValue = 1 << 0, Indirect = 1 << 1, CallSiteParamValue = 1 << 2 };
 
   unsigned LocationKind : 3;
-  unsigned LocationFlags : 2;
+  unsigned LocationFlags : 3;
   unsigned DwarfVersion : 4;
 
 public:
+  /// Set the location (\p Loc) and \ref DIExpression (\p DIExpr) to describe.
+  void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr);
+
   bool isUnknownLocation() const { return LocationKind == Unknown; }
 
   bool isMemoryLocation() const { return LocationKind == Memory; }
@@ -160,6 +165,8 @@ class DwarfExpression {
 
   bool isEntryValue() const { return LocationFlags & EntryValue; }
 
+  bool isIndirect() const { return LocationFlags & Indirect; }
+
   bool isParameterValue() { return LocationFlags & CallSiteParamValue; }
 
   Optional<uint8_t> TagOffset;
@@ -296,7 +303,7 @@ class DwarfExpression {
   }
 
   /// Lock this down to become an entry value location.
-  void setEntryValueFlag() { LocationFlags |= EntryValue; }
+  void setEntryValueFlags(const MachineLocation &Loc);
 
   /// Lock this down to become a call site parameter location.
   void setCallSiteParamValueFlag() { LocationFlags |= CallSiteParamValue; }

diff  --git a/llvm/lib/CodeGen/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues.cpp
index 470cb227fe7c..00a6149a0540 100644
--- a/llvm/lib/CodeGen/LiveDebugValues.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues.cpp
@@ -1613,10 +1613,6 @@ bool LiveDebugValues::isEntryValueCandidate(
   if (MI.getDebugLoc()->getInlinedAt())
     return false;
 
-  // Do not consider indirect debug values (TODO: explain why).
-  if (MI.isIndirectDebugValue())
-    return false;
-
   // Only consider parameters that are described using registers. Parameters
   // that are passed on the stack are not yet supported, so ignore debug
   // values that are described by the frame or stack pointer.
@@ -1631,7 +1627,7 @@ bool LiveDebugValues::isEntryValueCandidate(
     return false;
 
   // TODO: Add support for parameters that have a pre-existing debug expressions
-  // (e.g. fragments, or indirect parameters using DW_OP_deref).
+  // (e.g. fragments).
   if (MI.getDebugExpression()->getNumElements() > 0)
     return false;
 

diff  --git a/llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-indirect-param-with-offset.mir b/llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-indirect-param-with-offset.mir
new file mode 100644
index 000000000000..ee3a8e8ae521
--- /dev/null
+++ b/llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-indirect-param-with-offset.mir
@@ -0,0 +1,102 @@
+# RUN: llc -emit-call-site-info -start-before=livedebugvalues -stop-after=machineverifier -o - %s \
+# RUN:   | FileCheck %s -check-prefix=MIR
+
+# Copied from dbgcall-site-indirect-param.mir, with hand modifications:
+# an offset is added to the indirect parameter DBG_VALUE.
+#
+# We do not support emitting an entry value in this case.
+
+# MIR:      renamable $w0 = LDRWui killed renamable $x8
+# MIR-NOT:  DBG_VALUE $x0, 0, {{.*}}, !DIExpression(DW_OP_LLVM_entry_value
+# MIR-NEXT: BL @baz
+# MIR-NEXT: frame-destroy LDPXpost
+# MIR-NEXT: TCRETURNdi @baz
+
+--- |
+  target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+  target triple = "arm64-apple-ios10.0.0"
+
+  %struct.fat_ptr = type { i32*, i32*, i32* }
+
+  define i32 @bar(%struct.fat_ptr* nocapture readonly %f) local_unnamed_addr !dbg !13 {
+  entry:
+    call void @llvm.dbg.declare(metadata %struct.fat_ptr* %f, metadata !23, metadata !DIExpression()), !dbg !24
+    %ptr2 = bitcast %struct.fat_ptr* %f to i32**, !dbg !25
+    %0 = load i32*, i32** %ptr2, align 8, !dbg !25
+    %1 = load i32, i32* %0, align 4, !dbg !31
+    %call = tail call i32 @baz(i32 %1), !dbg !34
+    %call1 = tail call i32 @baz(i32 %call), !dbg !35
+    ret i32 %call1, !dbg !36
+  }
+
+  declare void @llvm.dbg.declare(metadata, metadata, metadata)
+
+  declare !dbg !4 i32 @baz(i32) local_unnamed_addr optsize
+
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!8, !9, !10, !11}
+  !llvm.ident = !{!12}
+
+  !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None, sysroot: "/")
+  !1 = !DIFile(filename: "indirect.c", directory: "/tmp/fatptr")
+  !2 = !{}
+  !3 = !{!4}
+  !4 = !DISubprogram(name: "baz", scope: !1, file: !1, line: 4, type: !5, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
+  !5 = !DISubroutineType(types: !6)
+  !6 = !{!7, !7}
+  !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+  !8 = !{i32 7, !"Dwarf Version", i32 4}
+  !9 = !{i32 2, !"Debug Info Version", i32 3}
+  !10 = !{i32 1, !"wchar_size", i32 4}
+  !11 = !{i32 7, !"PIC Level", i32 2}
+  !12 = !{!"clang"}
+  !13 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 5, type: !14, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !22)
+  !14 = !DISubroutineType(types: !15)
+  !15 = !{!7, !16}
+  !16 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "fat_ptr", file: !1, line: 1, size: 192, elements: !17)
+  !17 = !{!18, !20, !21}
+  !18 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !16, file: !1, line: 2, baseType: !19, size: 64)
+  !19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64)
+  !20 = !DIDerivedType(tag: DW_TAG_member, name: "low", scope: !16, file: !1, line: 2, baseType: !19, size: 64, offset: 64)
+  !21 = !DIDerivedType(tag: DW_TAG_member, name: "high", scope: !16, file: !1, line: 2, baseType: !19, size: 64, offset: 128)
+  !22 = !{!23}
+  !23 = !DILocalVariable(name: "f", arg: 1, scope: !13, file: !1, line: 5, type: !16)
+  !24 = !DILocation(line: 5, column: 24, scope: !13)
+  !25 = !DILocation(line: 6, column: 23, scope: !13)
+  !31 = !DILocation(line: 6, column: 20, scope: !13)
+  !34 = !DILocation(line: 6, column: 16, scope: !13)
+  !35 = !DILocation(line: 6, column: 12, scope: !13)
+  !36 = !DILocation(line: 6, column: 5, scope: !13)
+
+...
+---
+name:            bar
+stack:
+  - { id: 0, name: '', type: spill-slot, offset: -8, size: 8, alignment: 8,
+      stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 1, name: '', type: spill-slot, offset: -16, size: 8, alignment: 8,
+      stack-id: default, callee-saved-register: '$fp', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+callSites:
+  - { bb: 0, offset: 8, fwdArgRegs:
+      - { arg: 0, reg: '$w0' } }
+  - { bb: 0, offset: 10, fwdArgRegs:
+      - { arg: 0, reg: '$w0' } }
+body:             |
+  bb.0.entry:
+    liveins: $x0, $lr
+
+    DBG_VALUE $x0, 0, !23, !DIExpression(DW_OP_plus_uconst, 12), debug-location !24
+    early-clobber $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2 :: (store 8 into %stack.1), (store 8 into %stack.0)
+    $fp = frame-setup ADDXri $sp, 0, 0
+    frame-setup CFI_INSTRUCTION def_cfa $w29, 16
+    frame-setup CFI_INSTRUCTION offset $w30, -8, debug-location !25
+    frame-setup CFI_INSTRUCTION offset $w29, -16, debug-location !25
+    renamable $x8 = LDRXui killed renamable $x0, 0, debug-location !25 :: (load 8 from %ir.ptr2)
+    renamable $w0 = LDRWui killed renamable $x8, 0, debug-location !31 :: (load 4 from %ir.0)
+    BL @baz, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $w0, implicit-def $sp, implicit-def $w0, debug-location !34
+    early-clobber $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2, debug-location !35 :: (load 8 from %stack.1), (load 8 from %stack.0)
+    TCRETURNdi @baz, 0, csr_aarch64_aapcs, implicit $sp, implicit $w0, debug-location !35
+
+...

diff  --git a/llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-indirect-param.mir b/llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-indirect-param.mir
new file mode 100644
index 000000000000..d7edd1c654ad
--- /dev/null
+++ b/llvm/test/DebugInfo/MIR/AArch64/dbgcall-site-indirect-param.mir
@@ -0,0 +1,117 @@
+# RUN: llc -emit-call-site-info -start-before=livedebugvalues -stop-after=machineverifier -o - %s \
+# RUN:   | FileCheck %s -check-prefix=MIR
+
+# RUN: llc -emit-call-site-info -start-before=livedebugvalues -filetype=obj -o - %s \
+# RUN:   | llvm-dwarfdump - | FileCheck %s -check-prefix=DWARF -implicit-check-not=DW_OP_entry_value
+
+# // Original Source
+# struct fat_ptr {
+#   int *ptr, *low, *high;
+# };
+# extern int baz(int x);
+# int bar(struct fat_ptr f) {
+#   return baz(baz(*f.ptr));
+# }
+
+# MIR:      renamable $w0 = LDRWui killed renamable $x8
+# MIR-NEXT: DBG_VALUE $x0, 0, {{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1)
+# MIR-NEXT: BL @baz
+# MIR-NEXT: frame-destroy LDPXpost
+# MIR-NEXT: TCRETURNdi @baz
+
+# After w0 is clobbered, we should get an indirect parameter entry value for "f".
+
+# DWARF-LABEL: DW_TAG_formal_parameter
+# DWARF-NEXT: DW_AT_location
+# DWARF-NEXT: [0x0000000000000000, 0x0000000000000010): DW_OP_breg0 W0+0
+# DWARF-NEXT: [0x0000000000000010, 0x000000000000001c): DW_OP_entry_value(DW_OP_reg0 W0))
+# DWARF-NEXT: DW_AT_name    ("f")
+
+--- |
+  target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+  target triple = "arm64-apple-ios10.0.0"
+
+  %struct.fat_ptr = type { i32*, i32*, i32* }
+
+  define i32 @bar(%struct.fat_ptr* nocapture readonly %f) local_unnamed_addr !dbg !13 {
+  entry:
+    call void @llvm.dbg.declare(metadata %struct.fat_ptr* %f, metadata !23, metadata !DIExpression()), !dbg !24
+    %ptr2 = bitcast %struct.fat_ptr* %f to i32**, !dbg !25
+    %0 = load i32*, i32** %ptr2, align 8, !dbg !25
+    %1 = load i32, i32* %0, align 4, !dbg !31
+    %call = tail call i32 @baz(i32 %1), !dbg !34
+    %call1 = tail call i32 @baz(i32 %call), !dbg !35
+    ret i32 %call1, !dbg !36
+  }
+
+  declare void @llvm.dbg.declare(metadata, metadata, metadata)
+
+  declare !dbg !4 i32 @baz(i32) local_unnamed_addr optsize
+
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!8, !9, !10, !11}
+  !llvm.ident = !{!12}
+
+  !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None, sysroot: "/")
+  !1 = !DIFile(filename: "indirect.c", directory: "/tmp/fatptr")
+  !2 = !{}
+  !3 = !{!4}
+  !4 = !DISubprogram(name: "baz", scope: !1, file: !1, line: 4, type: !5, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
+  !5 = !DISubroutineType(types: !6)
+  !6 = !{!7, !7}
+  !7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+  !8 = !{i32 7, !"Dwarf Version", i32 4}
+  !9 = !{i32 2, !"Debug Info Version", i32 3}
+  !10 = !{i32 1, !"wchar_size", i32 4}
+  !11 = !{i32 7, !"PIC Level", i32 2}
+  !12 = !{!"clang"}
+  !13 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 5, type: !14, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !22)
+  !14 = !DISubroutineType(types: !15)
+  !15 = !{!7, !16}
+  !16 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "fat_ptr", file: !1, line: 1, size: 192, elements: !17)
+  !17 = !{!18, !20, !21}
+  !18 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !16, file: !1, line: 2, baseType: !19, size: 64)
+  !19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64)
+  !20 = !DIDerivedType(tag: DW_TAG_member, name: "low", scope: !16, file: !1, line: 2, baseType: !19, size: 64, offset: 64)
+  !21 = !DIDerivedType(tag: DW_TAG_member, name: "high", scope: !16, file: !1, line: 2, baseType: !19, size: 64, offset: 128)
+  !22 = !{!23}
+  !23 = !DILocalVariable(name: "f", arg: 1, scope: !13, file: !1, line: 5, type: !16)
+  !24 = !DILocation(line: 5, column: 24, scope: !13)
+  !25 = !DILocation(line: 6, column: 23, scope: !13)
+  !31 = !DILocation(line: 6, column: 20, scope: !13)
+  !34 = !DILocation(line: 6, column: 16, scope: !13)
+  !35 = !DILocation(line: 6, column: 12, scope: !13)
+  !36 = !DILocation(line: 6, column: 5, scope: !13)
+
+...
+---
+name:            bar
+stack:
+  - { id: 0, name: '', type: spill-slot, offset: -8, size: 8, alignment: 8,
+      stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 1, name: '', type: spill-slot, offset: -16, size: 8, alignment: 8,
+      stack-id: default, callee-saved-register: '$fp', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+callSites:
+  - { bb: 0, offset: 8, fwdArgRegs:
+      - { arg: 0, reg: '$w0' } }
+  - { bb: 0, offset: 10, fwdArgRegs:
+      - { arg: 0, reg: '$w0' } }
+body:             |
+  bb.0.entry:
+    liveins: $x0, $lr
+
+    DBG_VALUE $x0, 0, !23, !DIExpression(), debug-location !24
+    early-clobber $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2 :: (store 8 into %stack.1), (store 8 into %stack.0)
+    $fp = frame-setup ADDXri $sp, 0, 0
+    frame-setup CFI_INSTRUCTION def_cfa $w29, 16
+    frame-setup CFI_INSTRUCTION offset $w30, -8, debug-location !25
+    frame-setup CFI_INSTRUCTION offset $w29, -16, debug-location !25
+    renamable $x8 = LDRXui killed renamable $x0, 0, debug-location !25 :: (load 8 from %ir.ptr2)
+    renamable $w0 = LDRWui killed renamable $x8, 0, debug-location !31 :: (load 4 from %ir.0)
+    BL @baz, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $w0, implicit-def $sp, implicit-def $w0, debug-location !34
+    early-clobber $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2, debug-location !35 :: (load 8 from %stack.1), (load 8 from %stack.0)
+    TCRETURNdi @baz, 0, csr_aarch64_aapcs, implicit $sp, implicit $w0, debug-location !35
+
+...


        


More information about the llvm-commits mailing list