[llvm] r265760 - DwarfDebug: Support floating point constants in location lists.

Robinson, Paul via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 7 18:22:39 PDT 2016


Awesome--thanks!  (I thought there was a PR for this but I'm
not finding it. Good stuff anyway.)
--paulr

> -----Original Message-----
> From: llvm-commits [mailto:llvm-commits-bounces at lists.llvm.org] On Behalf
> Of Adrian Prantl via llvm-commits
> Sent: Thursday, April 07, 2016 5:39 PM
> To: llvm-commits at lists.llvm.org
> Subject: [llvm] r265760 - DwarfDebug: Support floating point constants in
> location lists.
> 
> Author: adrian
> Date: Thu Apr  7 19:38:37 2016
> New Revision: 265760
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=265760&view=rev
> Log:
> DwarfDebug: Support floating point constants in location lists.
> 
> This patch closes a gap in the DWARF backend that caused LLVM to drop
> debug info for floating point variables that were constant for part of
> their scope. Floating point constants are emitted as one or more
> DW_OP_constu joined via DW_OP_piece.
> 
> This fixes a regression caught by the LLDB testsuite that I introduced
> in r262247 when we stopped blindly expanding the range of singular
> DBG_VALUEs to span the entire scope and started to emit location lists
> with accurate ranges instead.
> 
> Also deletes a now-impossible testcase (debug-loc-empty-entries).
> 
> <rdar://problem/25448338>
> 
> Added:
>     llvm/trunk/test/DebugInfo/X86/float_const_loclist.ll
> Removed:
>     llvm/trunk/test/DebugInfo/X86/debug-loc-empty-entries.ll
> Modified:
>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h
> 
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=265760&r1=265
> 759&r2=265760&view=diff
> ==========================================================================
> ====
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu Apr  7 19:38:37
> 2016
> @@ -1438,10 +1438,10 @@ static void emitDebugLocValue(const AsmP
>          DwarfExpr.AddMachineRegExpression(Expr, Loc.getReg(),
>                                            PieceOffsetInBits);
>      }
> +  } else if (Value.isConstantFP()) {
> +    APInt RawBytes = Value.getConstantFP()-
> >getValueAPF().bitcastToAPInt();
> +    DwarfExpr.AddUnsignedConstant(RawBytes);
>    }
> -  // else ... ignore constant fp. There is not any good way to
> -  // to represent them here in dwarf.
> -  // FIXME: ^
>  }
> 
>  void DebugLocEntry::finalize(const AsmPrinter &AP,
> 
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp?rev=265760&r
> 1=265759&r2=265760&view=diff
> ==========================================================================
> ====
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp Thu Apr  7
> 19:38:37 2016
> @@ -159,29 +159,37 @@ bool DwarfExpression::AddMachineRegPiece
>    return CurPos > PieceOffsetInBits;
>  }
> 
> +void DwarfExpression::AddStackValue() {
> +  if (DwarfVersion >= 4)
> +    EmitOp(dwarf::DW_OP_stack_value);
> +}
> +
>  void DwarfExpression::AddSignedConstant(int Value) {
>    EmitOp(dwarf::DW_OP_consts);
>    EmitSigned(Value);
> -  // The proper way to describe a constant value is
> -  // DW_OP_constu <const>, DW_OP_stack_value.
> -  // Unfortunately, DW_OP_stack_value was not available until DWARF-4,
> -  // so we will continue to generate DW_OP_constu <const> for DWARF-2
> -  // and DWARF-3. Technically, this is incorrect since DW_OP_const
> <const>
> -  // actually describes a value at a constant addess, not a constant
> value.
> -  // However, in the past there was no better way  to describe a constant
> -  // value, so the producers and consumers started to rely on heuristics
> -  // to disambiguate the value vs. location status of the expression.
> -  // See PR21176 for more details.
> -  if (DwarfVersion >= 4)
> -    EmitOp(dwarf::DW_OP_stack_value);
> +  AddStackValue();
>  }
> 
>  void DwarfExpression::AddUnsignedConstant(unsigned Value) {
>    EmitOp(dwarf::DW_OP_constu);
>    EmitUnsigned(Value);
> -  // cf. comment in DwarfExpression::AddSignedConstant().
> -  if (DwarfVersion >= 4)
> -    EmitOp(dwarf::DW_OP_stack_value);
> +  AddStackValue();
> +}
> +
> +void DwarfExpression::AddUnsignedConstant(APInt Value) {
> +  unsigned Size = Value.getBitWidth();
> +  const uint64_t *Data = Value.getRawData();
> +
> +  // Chop it up into 64-bit pieces, because that's the maximum that
> +  // AddUnsignedConstant takes.
> +  unsigned Offset = 0;
> +  while (Offset < Size) {
> +    AddUnsignedConstant(*Data++);
> +    if (Offset == 0 && Size <= 64)
> +      break;
> +    AddOpPiece(std::min(Size-Offset, 64u), Offset);
> +    Offset += 64;
> +  }
>  }
> 
>  static unsigned getOffsetOrZero(unsigned OffsetInBits,
> 
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h?rev=265760&r1=
> 265759&r2=265760&view=diff
> ==========================================================================
> ====
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h Thu Apr  7
> 19:38:37 2016
> @@ -61,6 +61,19 @@ public:
>    void AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0);
>    /// Emit a shift-right dwarf expression.
>    void AddShr(unsigned ShiftBy);
> +  /// Emit a DW_OP_stack_value, if supported.
> +  ///
> +  /// The proper way to describe a constant value is
> +  /// DW_OP_constu <const>, DW_OP_stack_value.
> +  /// Unfortunately, DW_OP_stack_value was not available until DWARF-4,
> +  /// so we will continue to generate DW_OP_constu <const> for DWARF-2
> +  /// and DWARF-3. Technically, this is incorrect since DW_OP_const
> <const>
> +  /// actually describes a value at a constant addess, not a constant
> value.
> +  /// However, in the past there was no better way  to describe a
> constant
> +  /// value, so the producers and consumers started to rely on heuristics
> +  /// to disambiguate the value vs. location status of the expression.
> +  /// See PR21176 for more details.
> +  void AddStackValue();
> 
>    /// Emit an indirect dwarf register operation for the given machine
> register.
>    /// \return false if no DWARF register exists for MachineReg.
> @@ -87,6 +100,8 @@ public:
>    void AddSignedConstant(int Value);
>    /// Emit an unsigned constant.
>    void AddUnsignedConstant(unsigned Value);
> +  /// Emit an unsigned constant.
> +  void AddUnsignedConstant(APInt Value);
> 
>    /// \brief Emit an entire expression on top of a machine register
> location.
>    ///
> 
> Removed: llvm/trunk/test/DebugInfo/X86/debug-loc-empty-entries.ll
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/test/DebugInfo/X86/debug-loc-empty-
> entries.ll?rev=265759&view=auto
> ==========================================================================
> ====
> --- llvm/trunk/test/DebugInfo/X86/debug-loc-empty-entries.ll (original)
> +++ llvm/trunk/test/DebugInfo/X86/debug-loc-empty-entries.ll (removed)
> @@ -1,66 +0,0 @@
> -; RUN: llc -mtriple=x86_64-apple-macosx <%s | FileCheck %s
> -; Test that we don't generate empty .debug_loc entries.  Originally,
> there were
> -; two empty .debug_loc entries for 'a' in an otherwise empty .debug_loc
> list.
> -;
> -; CHECK:      .section __DWARF,__debug_loc,regular,debug
> -; CHECK-NEXT: Lsection_debug_loc:
> -; CHECK-NEXT: .section __DWARF,__debug_abbrev,regular,debug
> -;
> -; Test that the variable stuck around.
> -; CHECK:      .section __DWARF,__debug_info,regular,debug
> -; CHECK:      DW_TAG_variable
> -; CHECK-NOT:  DW_AT_location
> -
> -; Generated using clang -cc1 with the following args:
> -;
> -;   -triple x86_64-apple-macosx -emit-llvm -gdwarf-4 -O1
> -;
> -; From this testcase:
> -;
> -;;   void fn1() {
> -;;     float a = 1;
> -;;     for (;;)
> -;;       a = 0;
> -;;   }
> -
> -; Function Attrs: noreturn nounwind readnone
> -define void @_Z3fn1v() #0 !dbg !4 {
> -entry:
> -  tail call void @llvm.dbg.value(metadata float 1.000000e+00, i64 0,
> metadata !9, metadata !14), !dbg !15
> -  br label %for.cond, !dbg !16
> -
> -for.cond:                                         ; preds = %for.cond,
> %entry
> -  tail call void @llvm.dbg.value(metadata float 0.000000e+00, i64 0,
> metadata !9, metadata !14), !dbg !15
> -  br label %for.cond, !dbg !17
> -}
> -
> -; Function Attrs: nounwind readnone
> -declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
> -
> -attributes #0 = { noreturn nounwind readnone "less-precise-fpmad"="false"
> "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-
> math"="false" "no-realign-stack" "stack-protector-buffer-size"="8"
> "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-
> float"="false" }
> -attributes #1 = { nounwind readnone }
> -
> -!llvm.dbg.cu = !{!0}
> -!llvm.module.flags = !{!11, !12}
> -!llvm.ident = !{!13}
> -
> -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1,
> producer: "clang version 3.7.0 (trunk 238517) (llvm/trunk 238524)",
> isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2,
> retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
> -!1 = !DIFile(filename: "<stdin>", directory:
> "/Users/dexonsmith/data/llvm/bootstrap/play/delta2/testcase")
> -!2 = !{}
> -!3 = !{!4}
> -!4 = distinct !DISubprogram(name: "fn1", linkageName: "_Z3fn1v", scope:
> !5, file: !5, line: 1, type: !6, isLocal: false, isDefinition: true,
> scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, variables: !8)
> -!5 = !DIFile(filename: "t.cpp", directory:
> "/Users/dexonsmith/data/llvm/bootstrap/play/delta2/testcase")
> -!6 = !DISubroutineType(types: !7)
> -!7 = !{null}
> -!8 = !{!9}
> -!9 = !DILocalVariable(name: "a", scope: !4, file: !5, line: 2, type: !10)
> -!10 = !DIBasicType(name: "float", size: 32, align: 32, encoding:
> DW_ATE_float)
> -!11 = !{i32 2, !"Dwarf Version", i32 4}
> -!12 = !{i32 2, !"Debug Info Version", i32 3}
> -!13 = !{!"clang version 3.7.0 (trunk 238517) (llvm/trunk 238524)"}
> -!14 = !DIExpression()
> -!15 = !DILocation(line: 2, scope: !4)
> -!16 = !DILocation(line: 3, scope: !4)
> -!17 = !DILocation(line: 3, scope: !18)
> -!18 = distinct !DILexicalBlock(scope: !19, file: !5, line: 3)
> -!19 = distinct !DILexicalBlock(scope: !4, file: !5, line: 3)
> 
> Added: llvm/trunk/test/DebugInfo/X86/float_const_loclist.ll
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/test/DebugInfo/X86/float_const_loclist.ll?rev=265760&vi
> ew=auto
> ==========================================================================
> ====
> --- llvm/trunk/test/DebugInfo/X86/float_const_loclist.ll (added)
> +++ llvm/trunk/test/DebugInfo/X86/float_const_loclist.ll Thu Apr  7
> 19:38:37 2016
> @@ -0,0 +1,86 @@
> +; RUN: llc %s -stop-after=livedebugvalues -o %t 2>&1 | FileCheck --check-
> prefix=SANITY %s
> +; RUN: llc < %s -filetype=obj | llvm-dwarfdump - | FileCheck %s
> +; Test debug_loc support for floating point constants.
> +;
> +; Created from clang -O1:
> +;   void barrier();
> +;   void foo() {
> +;     float f;
> +;     long double ld;
> +;     barrier();
> +;     f = 3.14;
> +;     ld = 3.14;
> +;     barrier();
> +;   }
> +;
> +; SANITY: CALL{{.*}} @barrier
> +; SANITY: DBG_VALUE x86_fp80 0xK4000C8F5C28F5C28F800
> +; SANITY: DBG_VALUE float 0x40091EB860000000
> +; SANITY: TAILJMP{{.*}} @barrier
> +;
> +; CHECK: .debug_info contents:
> +; CHECK: DW_TAG_variable
> +; CHECK-NEXT:  DW_AT_location {{.*}} (0x00000000)
> +; CHECK-NEXT:  DW_AT_name {{.*}}"ld"
> +; CHECK: DW_TAG_variable
> +; CHECK-NEXT:  DW_AT_location {{.*}} (0x00000031)
> +; CHECK-NEXT:  DW_AT_name {{.*}}"f"
> +;
> +; CHECK: .debug_loc contents:
> +; CHECK: 0x00000000: Beginning address offset: [[START:.*]]
> +; CHECK:                Ending address offset: [[END:.*]]
> +; CHECK:                 Location description: 10 80 f0 a3 e1 05 93 08 10
> 80 80 01 9d 10 40
> +;                        constu ..., piece 8, constu ..., bit-piece 16 64
> +; CHECK: 0x00000031: Beginning address offset: [[START]]
> +; CHECK:                Ending address offset: [[END]]
> +; CHECK:                 Location description: 10 c3 eb a3 82 04
> +;                                              constu ...
> +source_filename = "test.c"
> +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
> +target triple = "x86_64-apple-macosx10.11.0"
> +
> +; Function Attrs: nounwind ssp uwtable
> +define void @foo() #0 !dbg !4 {
> +entry:
> +  tail call void (...) @barrier() #3, !dbg !16
> +  tail call void @llvm.dbg.value(metadata float 0x40091EB860000000, i64
> 0, metadata !8, metadata !17), !dbg !18
> +  tail call void @llvm.dbg.value(metadata x86_fp80
> 0xK4000C8F5C28F5C28F800, i64 0, metadata !10, metadata !17), !dbg !19
> +  tail call void (...) @barrier() #3, !dbg !20
> +  ret void, !dbg !21
> +}
> +
> +declare void @barrier(...)
> +
> +; Function Attrs: nounwind readnone
> +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2
> +
> +attributes #0 = { nounwind ssp uwtable }
> +attributes #2 = { nounwind readnone }
> +attributes #3 = { nounwind }
> +
> +!llvm.dbg.cu = !{!0}
> +!llvm.module.flags = !{!12, !13, !14}
> +!llvm.ident = !{!15}
> +
> +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer:
> "clang version 3.9.0 (trunk 265328) (llvm/trunk 265330)", isOptimized:
> true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, subprograms:
> !3)
> +!1 = !DIFile(filename: "test.c", directory:
> "/Volumes/Data/radar/25448338")
> +!2 = !{}
> +!3 = !{!4}
> +!4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3,
> type: !5, isLocal: false, isDefinition: true, scopeLine: 4, isOptimized:
> true, variables: !7)
> +!5 = !DISubroutineType(types: !6)
> +!6 = !{null}
> +!7 = !{!8, !10}
> +!8 = !DILocalVariable(name: "f", scope: !4, file: !1, line: 5, type: !9)
> +!9 = !DIBasicType(name: "float", size: 32, align: 32, encoding:
> DW_ATE_float)
> +!10 = !DILocalVariable(name: "ld", scope: !4, file: !1, line: 6, type:
> !11)
> +!11 = !DIBasicType(name: "long double", size: 128, align: 128, encoding:
> DW_ATE_float)
> +!12 = !{i32 2, !"Dwarf Version", i32 2}
> +!13 = !{i32 2, !"Debug Info Version", i32 3}
> +!14 = !{i32 1, !"PIC Level", i32 2}
> +!15 = !{!"clang version 3.9.0 (trunk 265328) (llvm/trunk 265330)"}
> +!16 = !DILocation(line: 7, column: 3, scope: !4)
> +!17 = !DIExpression()
> +!18 = !DILocation(line: 5, column: 9, scope: !4)
> +!19 = !DILocation(line: 6, column: 15, scope: !4)
> +!20 = !DILocation(line: 10, column: 3, scope: !4)
> +!21 = !DILocation(line: 11, column: 1, scope: !4)
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list