[llvm] r184368 - DebugInfo: PR14763/r183329 correct the location of indirect parameters

David Blaikie dblaikie at gmail.com
Wed Jun 19 14:55:14 PDT 2013


Author: dblaikie
Date: Wed Jun 19 16:55:13 2013
New Revision: 184368

URL: http://llvm.org/viewvc/llvm-project?rev=184368&view=rev
Log:
DebugInfo: PR14763/r183329 correct the location of indirect parameters

We had been papering over a problem with location info for non-trivial
types passed by value by emitting their type as references (this caused
the debugger to interpret the location information correctly, but broke
the type of the function). r183329 corrected the type information but
lead to the debugger interpreting the pointer parameter as the value -
the debug info describing the location needed an extra dereference.

Use a new flag in DIVariable to add the extra indirection (either by
promoting an existing DW_OP_reg (parameter passed in a register) to
DW_OP_breg + 0 or by adding DW_OP_deref to an existing DW_OP_breg + n
(parameter passed on the stack).

Added:
    llvm/trunk/test/DebugInfo/X86/parameters.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/AsmPrinter.h
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
    llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h

Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AsmPrinter.h?rev=184368&r1=184367&r2=184368&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original)
+++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Wed Jun 19 16:55:13 2013
@@ -407,7 +407,8 @@ namespace llvm {
     virtual unsigned getISAEncoding() { return 0; }
 
     /// EmitDwarfRegOp - Emit dwarf register operation.
-    virtual void EmitDwarfRegOp(const MachineLocation &MLoc) const;
+    virtual void EmitDwarfRegOp(const MachineLocation &MLoc,
+                                bool Indirect) const;
 
     //===------------------------------------------------------------------===//
     // Dwarf Lowering Routines

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=184368&r1=184367&r2=184368&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Wed Jun 19 16:55:13 2013
@@ -812,7 +812,8 @@ void AsmPrinter::EmitFunctionBody() {
 }
 
 /// EmitDwarfRegOp - Emit dwarf register operation.
-void AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const {
+void AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc,
+                                bool Indirect) const {
   const TargetRegisterInfo *TRI = TM.getRegisterInfo();
   int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);
 
@@ -830,7 +831,7 @@ void AsmPrinter::EmitDwarfRegOp(const Ma
   // caller might be in the middle of an dwarf expression. We should
   // probably assert that Reg >= 0 once debug info generation is more mature.
 
-  if (MLoc.isIndirect()) {
+  if (MLoc.isIndirect() || Indirect) {
     if (Reg < 32) {
       OutStreamer.AddComment(
         dwarf::OperationEncodingString(dwarf::DW_OP_breg0 + Reg));
@@ -841,7 +842,9 @@ void AsmPrinter::EmitDwarfRegOp(const Ma
       OutStreamer.AddComment(Twine(Reg));
       EmitULEB128(Reg);
     }
-    EmitSLEB128(MLoc.getOffset());
+    EmitSLEB128(!MLoc.isIndirect() ? 0 : MLoc.getOffset());
+    if (MLoc.isIndirect() && Indirect)
+      EmitInt8(dwarf::DW_OP_deref);
   } else {
     if (Reg < 32) {
       OutStreamer.AddComment(

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=184368&r1=184367&r2=184368&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed Jun 19 16:55:13 2013
@@ -2443,7 +2443,7 @@ void DwarfDebug::emitDebugLoc() {
       } else if (Entry.isLocation()) {
         if (!DV.hasComplexAddress())
           // Regular entry.
-          Asm->EmitDwarfRegOp(Entry.Loc);
+          Asm->EmitDwarfRegOp(Entry.Loc, DV.isIndirect());
         else {
           // Complex address entry.
           unsigned N = DV.getNumAddrElements();
@@ -2451,7 +2451,7 @@ void DwarfDebug::emitDebugLoc() {
           if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) {
             if (Entry.Loc.getOffset()) {
               i = 2;
-              Asm->EmitDwarfRegOp(Entry.Loc);
+              Asm->EmitDwarfRegOp(Entry.Loc, DV.isIndirect());
               Asm->OutStreamer.AddComment("DW_OP_deref");
               Asm->EmitInt8(dwarf::DW_OP_deref);
               Asm->OutStreamer.AddComment("DW_OP_plus_uconst");
@@ -2461,11 +2461,11 @@ void DwarfDebug::emitDebugLoc() {
               // If first address element is OpPlus then emit
               // DW_OP_breg + Offset instead of DW_OP_reg + Offset.
               MachineLocation Loc(Entry.Loc.getReg(), DV.getAddrElement(1));
-              Asm->EmitDwarfRegOp(Loc);
+              Asm->EmitDwarfRegOp(Loc, DV.isIndirect());
               i = 2;
             }
           } else {
-            Asm->EmitDwarfRegOp(Entry.Loc);
+            Asm->EmitDwarfRegOp(Entry.Loc, DV.isIndirect());
           }
 
           // Emit remaining complex address elements.

Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=184368&r1=184367&r2=184368&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Wed Jun 19 16:55:13 2013
@@ -214,13 +214,14 @@ namespace {
 } // end of anonymous namespace
 
 /// EmitDwarfRegOp - Emit dwarf register operation.
-void ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const {
+void ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc,
+                                   bool Indirect) const {
   const TargetRegisterInfo *RI = TM.getRegisterInfo();
   if (RI->getDwarfRegNum(MLoc.getReg(), false) != -1) {
-    AsmPrinter::EmitDwarfRegOp(MLoc);
+    AsmPrinter::EmitDwarfRegOp(MLoc, Indirect);
     return;
   }
-  assert(MLoc.isReg() &&
+  assert(MLoc.isReg() && !Indirect &&
          "This doesn't support offset/indirection - implement it if needed");
   unsigned Reg = MLoc.getReg();
   if (Reg >= ARM::S0 && Reg <= ARM::S31) {

Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h?rev=184368&r1=184367&r2=184368&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h Wed Jun 19 16:55:13 2013
@@ -98,7 +98,8 @@ private:
 
 public:
   /// EmitDwarfRegOp - Emit dwarf register operation.
-  virtual void EmitDwarfRegOp(const MachineLocation &MLoc) const LLVM_OVERRIDE;
+  virtual void EmitDwarfRegOp(const MachineLocation &MLoc, bool Indirect) const
+      LLVM_OVERRIDE;
 
   virtual unsigned getISAEncoding() LLVM_OVERRIDE {
     // ARM/Darwin adds ISA to the DWARF info for each function.

Added: llvm/trunk/test/DebugInfo/X86/parameters.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/parameters.ll?rev=184368&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/parameters.ll (added)
+++ llvm/trunk/test/DebugInfo/X86/parameters.ll Wed Jun 19 16:55:13 2013
@@ -0,0 +1,70 @@
+; REQUIRES: object-emission
+;
+; RUN: llc -O0 -filetype=obj < %s > %t
+; RUN: llvm-dwarfdump %t | FileCheck %s
+
+; Test case derived from compiling the following source with clang -g:
+;
+; namespace pr14763 {
+; struct foo {
+;   foo(const foo&);
+; };
+;
+; foo func(foo f) {
+;   return f; // reference 'f' for now because otherwise we hit another bug
+; }
+; }
+
+; CHECK: debug_info contents
+; CHECK: DW_AT_name{{.*}} = "f"
+; CHECK: DW_AT_location{{.*}}([[LOC:0x[0-9]*]])
+; CHECK: debug_loc contents
+; CHECK-NEXT: [[LOC]]: Begining
+; CHECK-NEXT:            Ending
+; 0x74 is DW_OP_breg0 + 4, showing that the parameter is accessed indirectly
+; (with a zero offset) from the register parameter
+; CHECK-NEXT: Location description: 74 00
+
+%"struct.pr14763::foo" = type { i8 }
+
+; Function Attrs: uwtable
+define void @_ZN7pr147634funcENS_3fooE(%"struct.pr14763::foo"* noalias sret %agg.result, %"struct.pr14763::foo"* %f) #0 {
+entry:
+  call void @llvm.dbg.declare(metadata !{%"struct.pr14763::foo"* %f}, metadata !17), !dbg !20
+  call void @_ZN7pr147633fooC1ERKS0_(%"struct.pr14763::foo"* %agg.result, %"struct.pr14763::foo"* %f), !dbg !21
+  ret void, !dbg !21
+}
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.declare(metadata, metadata) #1
+
+declare void @_ZN7pr147633fooC1ERKS0_(%"struct.pr14763::foo"*, %"struct.pr14763::foo"*) #2
+
+attributes #0 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind readnone }
+attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.dbg.cu = !{!0}
+
+!0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version 3.4 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/tmp/pass.cpp] [DW_LANG_C_plus_plus]
+!1 = metadata !{metadata !"pass.cpp", metadata !"/tmp"}
+!2 = metadata !{i32 0}
+!3 = metadata !{metadata !4}
+!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"func", metadata !"func", metadata !"_ZN7pr147634funcENS_3fooE", i32 6, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (%"struct.pr14763::foo"*, %"struct.pr14763::foo"*)* @_ZN7pr147634funcENS_3fooE, null, null, metadata !2, i32 6} ; [ DW_TAG_subprogram ] [line 6] [def] [func]
+!5 = metadata !{i32 786489, metadata !1, null, metadata !"pr14763", i32 1} ; [ DW_TAG_namespace ] [pr14763] [line 1]
+!6 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = metadata !{metadata !8, metadata !8}
+!8 = metadata !{i32 786451, metadata !1, metadata !5, metadata !"foo", i32 2, i64 8, i64 8, i32 0, i32 0, null, metadata !9, i32 0, null, null} ; [ DW_TAG_structure_type ] [foo] [line 2, size 8, align 8, offset 0] [from ]
+!9 = metadata !{metadata !10}
+!10 = metadata !{i32 786478, metadata !1, metadata !8, metadata !"foo", metadata !"foo", metadata !"", i32 3, metadata !11, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !16, i32 3} ; [ DW_TAG_subprogram ] [line 3] [foo]
+!11 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !12, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!12 = metadata !{null, metadata !13, metadata !14}
+!13 = metadata !{i32 786447, i32 0, i32 0, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 1088, metadata !8} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from foo]
+!14 = metadata !{i32 786448, null, null, null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !15} ; [ DW_TAG_reference_type ] [line 0, size 0, align 0, offset 0] [from ]
+!15 = metadata !{i32 786470, null, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, metadata !8} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from foo]
+!16 = metadata !{i32 786468}
+!17 = metadata !{i32 786689, metadata !4, metadata !"f", metadata !18, i32 16777222, metadata !19, i32 8192, i32 0} ; [ DW_TAG_arg_variable ] [f] [line 6]
+!18 = metadata !{i32 786473, metadata !1}         ; [ DW_TAG_file_type ] [/tmp/pass.cpp]
+!19 = metadata !{i32 786448, null, null, null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !8} ; [ DW_TAG_reference_type ] [line 0, size 0, align 0, offset 0] [from foo]
+!20 = metadata !{i32 6, i32 0, metadata !4, null}
+!21 = metadata !{i32 7, i32 0, metadata !4, null}





More information about the llvm-commits mailing list