diff options
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 38 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h | 15 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/debug-loc-empty-entries.ll | 66 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/float_const_loclist.ll | 86 |
5 files changed, 127 insertions, 84 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 1043d0a1435..296a799d33c 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1438,10 +1438,10 @@ static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, 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, diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index 7b5b831da16..0608e05edd5 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -159,29 +159,37 @@ bool DwarfExpression::AddMachineRegPiece(unsigned MachineReg, 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, diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h index 78ec937a6b6..5de9131d5c4 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -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. /// diff --git a/llvm/test/DebugInfo/X86/debug-loc-empty-entries.ll b/llvm/test/DebugInfo/X86/debug-loc-empty-entries.ll deleted file mode 100644 index c26d8aea2d1..00000000000 --- a/llvm/test/DebugInfo/X86/debug-loc-empty-entries.ll +++ /dev/null @@ -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) diff --git a/llvm/test/DebugInfo/X86/float_const_loclist.ll b/llvm/test/DebugInfo/X86/float_const_loclist.ll new file mode 100644 index 00000000000..eb531178d21 --- /dev/null +++ b/llvm/test/DebugInfo/X86/float_const_loclist.ll @@ -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) |