Skip to content

Commit c29e3a5

Browse files
authored
Merge pull request #2035 from medismailben/apple/stable/20200714
[llvm/DebugInfo] Emit DW_OP_implicit_value when tuning for LLDB
2 parents a03e563 + 233a7a2 commit c29e3a5

File tree

7 files changed

+200
-8
lines changed

7 files changed

+200
-8
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2513,8 +2513,22 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
25132513
// encoding is supported.
25142514
DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));
25152515
} else if (Value.isConstantFP()) {
2516-
APInt RawBytes = Value.getConstantFP()->getValueAPF().bitcastToAPInt();
2517-
DwarfExpr.addUnsignedConstant(RawBytes);
2516+
if (AP.getDwarfVersion() >= 4 && (AP.getDwarfDebug()->tuneForGDB() ||
2517+
AP.getDwarfDebug()->tuneForLLDB())) {
2518+
DwarfExpr.addConstantFP(Value.getConstantFP()->getValueAPF(), AP);
2519+
return;
2520+
} else if (Value.getConstantFP()
2521+
->getValueAPF()
2522+
.bitcastToAPInt()
2523+
.getBitWidth() <= 64 /*bits*/)
2524+
DwarfExpr.addUnsignedConstant(
2525+
Value.getConstantFP()->getValueAPF().bitcastToAPInt());
2526+
else
2527+
LLVM_DEBUG(
2528+
dbgs()
2529+
<< "Skipped DwarfExpression creation for ConstantFP of size"
2530+
<< Value.getConstantFP()->getValueAPF().bitcastToAPInt().getBitWidth()
2531+
<< " bits\n");
25182532
}
25192533
DwarfExpr.addExpression(std::move(ExprCursor));
25202534
}

llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/BinaryFormat/Dwarf.h"
1818
#include "llvm/CodeGen/Register.h"
1919
#include "llvm/CodeGen/TargetRegisterInfo.h"
20+
#include "llvm/IR/DataLayout.h"
2021
#include "llvm/IR/DebugInfoMetadata.h"
2122
#include "llvm/Support/ErrorHandling.h"
2223
#include <algorithm>
@@ -25,6 +26,8 @@
2526

2627
using namespace llvm;
2728

29+
#define DEBUG_TYPE "dwarfdebug"
30+
2831
void DwarfExpression::emitConstu(uint64_t Value) {
2932
if (Value < 32)
3033
emitOp(dwarf::DW_OP_lit0 + Value);
@@ -219,6 +222,31 @@ void DwarfExpression::addUnsignedConstant(const APInt &Value) {
219222
}
220223
}
221224

225+
void DwarfExpression::addConstantFP(const APFloat &APF, const AsmPrinter &AP) {
226+
assert(isImplicitLocation() || isUnknownLocation());
227+
APInt API = APF.bitcastToAPInt();
228+
int NumBytes = API.getBitWidth() / 8;
229+
if (NumBytes == 4 /*float*/ || NumBytes == 8 /*double*/) {
230+
// FIXME: Add support for `long double`.
231+
emitOp(dwarf::DW_OP_implicit_value);
232+
emitUnsigned(NumBytes /*Size of the block in bytes*/);
233+
234+
const uint64_t *Value = API.getRawData();
235+
const bool IsLittleEndian = AP.getDataLayout().isLittleEndian();
236+
uint64_t Swapped = support::endian::byte_swap(
237+
*Value, IsLittleEndian ? support::little : support::big);
238+
239+
const char *SwappedBytes = reinterpret_cast<const char *>(&Swapped);
240+
for (int i = 0; i < NumBytes; ++i)
241+
emitData1(SwappedBytes[i]);
242+
243+
return;
244+
}
245+
LLVM_DEBUG(
246+
dbgs() << "Skipped DW_OP_implicit_value creation for ConstantFP of size: "
247+
<< API.getBitWidth() << " bits\n");
248+
}
249+
222250
bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
223251
DIExpressionCursor &ExprCursor,
224252
unsigned MachineReg,

llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,9 @@ class DwarfExpression {
299299
/// Emit an unsigned constant.
300300
void addUnsignedConstant(const APInt &Value);
301301

302+
/// Emit an floating point constant.
303+
void addConstantFP(const APFloat &Value, const AsmPrinter &AP);
304+
302305
/// Lock this down to become a memory location description.
303306
void setMemoryLocationKind() {
304307
assert(isUnknownLocation());

llvm/test/DebugInfo/X86/float_const_loclist.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,10 @@
2020
;
2121
; CHECK: .debug_info contents:
2222
; CHECK: DW_TAG_variable
23-
; CHECK-NEXT: DW_AT_location {{.*}} (
24-
; CHECK-NEXT: [0x[[START:.*]], 0x[[END:.*]]): DW_OP_constu 0xc8f5c28f5c28f800, DW_OP_piece 0x8, DW_OP_constu 0x4000, DW_OP_bit_piece 0x10 0x40)
2523
; CHECK-NEXT: DW_AT_name {{.*}}"ld"
2624
; CHECK: DW_TAG_variable
2725
; CHECK-NEXT: DW_AT_location {{.*}} (
28-
; CHECK-NEXT: [0x[[START]], 0x[[END]]): DW_OP_constu 0x4048f5c3)
26+
; CHECK-NEXT: [0x{{.*}}, 0x{{.*}}): DW_OP_constu 0x4048f5c3)
2927
; CHECK-NEXT: DW_AT_name {{.*}}"f"
3028

3129
source_filename = "test.c"
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
;; This test checks for emission of DW_OP_implicit_value operation
2+
;; for double type.
3+
4+
; RUN: llc -debugger-tune=gdb -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s
5+
; RUN: llc -debugger-tune=lldb -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s
6+
7+
; CHECK: .debug_info contents:
8+
; CHECK: DW_TAG_variable
9+
; CHECK-NEXT: DW_AT_location ({{.*}}
10+
; CHECK-NEXT: [{{.*}}): DW_OP_implicit_value 0x8 0x1f 0x85 0xeb 0x51 0xb8 0x1e 0x09 0x40)
11+
; CHECK-NEXT: DW_AT_name ("d")
12+
13+
; RUN: llc -debugger-tune=sce -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s -check-prefix=SCE-CHECK
14+
15+
; SCE-CHECK: .debug_info contents:
16+
; SCE-CHECK: DW_TAG_variable
17+
; SCE-CHECK-NEXT: DW_AT_location ({{.*}}
18+
; SCE-CHECK-NEXT: [{{.*}}): DW_OP_constu 0x40091eb851eb851f, DW_OP_stack_value)
19+
; SCE-CHECK-NEXT: DW_AT_name ("d")
20+
21+
;; Generated from: clang -ggdb -O1
22+
;;int main() {
23+
;; double d = 3.14;
24+
;; printf("dummy\n");
25+
;; d *= d;
26+
;; return 0;
27+
;;}
28+
29+
; ModuleID = 'implicit_value-double.c'
30+
source_filename = "implicit_value-double.c"
31+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
32+
target triple = "x86_64-unknown-linux-gnu"
33+
34+
@str = private unnamed_addr constant [6 x i8] c"dummy\00", align 1
35+
36+
; Function Attrs: nofree nounwind uwtable
37+
define dso_local i32 @main() local_unnamed_addr #0 !dbg !7 {
38+
entry:
39+
call void @llvm.dbg.value(metadata double 3.140000e+00, metadata !12, metadata !DIExpression()), !dbg !14
40+
%puts = call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([6 x i8], [6 x i8]* @str, i64 0, i64 0)), !dbg !15
41+
call void @llvm.dbg.value(metadata double undef, metadata !12, metadata !DIExpression()), !dbg !14
42+
ret i32 0, !dbg !16
43+
}
44+
45+
; Function Attrs: nounwind readnone speculatable willreturn
46+
declare void @llvm.dbg.value(metadata, metadata, metadata) #1
47+
48+
; Function Attrs: nofree nounwind
49+
declare i32 @puts(i8* nocapture readonly) local_unnamed_addr #2
50+
51+
attributes #0 = { nofree nounwind uwtable }
52+
attributes #1 = { nounwind readnone speculatable willreturn }
53+
attributes #2 = { nofree nounwind }
54+
55+
!llvm.dbg.cu = !{!0}
56+
!llvm.module.flags = !{!3, !4, !5}
57+
!llvm.ident = !{!6}
58+
59+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
60+
!1 = !DIFile(filename: "implicit_value-double.c", directory: "/home/")
61+
!2 = !{}
62+
!3 = !{i32 7, !"Dwarf Version", i32 4}
63+
!4 = !{i32 2, !"Debug Info Version", i32 3}
64+
!5 = !{i32 1, !"wchar_size", i32 4}
65+
!6 = !{!"clang version 11.0.0"}
66+
!7 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
67+
!8 = !DISubroutineType(types: !9)
68+
!9 = !{!10}
69+
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
70+
!11 = !{!12}
71+
!12 = !DILocalVariable(name: "d", scope: !7, file: !1, line: 2, type: !13)
72+
!13 = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float)
73+
!14 = !DILocation(line: 0, scope: !7)
74+
!15 = !DILocation(line: 3, column: 2, scope: !7)
75+
!16 = !DILocation(line: 5, column: 2, scope: !7)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
;; This test checks for emission of DW_OP_implicit_value operation
2+
;; for float type.
3+
4+
; RUN: llc -debugger-tune=gdb -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s
5+
; RUN: llc -debugger-tune=lldb -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s
6+
7+
; CHECK: .debug_info contents:
8+
; CHECK: DW_TAG_variable
9+
; CHECK-NEXT: DW_AT_location ({{.*}}
10+
; CHECK-NEXT: [{{.*}}): DW_OP_implicit_value 0x4 0xc3 0xf5 0x48 0x40)
11+
; CHECK-NEXT: DW_AT_name ("f")
12+
13+
; RUN: llc -debugger-tune=sce -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s -check-prefix=SCE-CHECK
14+
15+
; SCE-CHECK: .debug_info contents:
16+
; SCE-CHECK: DW_TAG_variable
17+
; SCE-CHECK-NEXT: DW_AT_location ({{.*}}
18+
; SCE-CHECK-NEXT: [{{.*}}): DW_OP_constu 0x4048f5c3, DW_OP_stack_value)
19+
; SCE-CHECK-NEXT: DW_AT_name ("f")
20+
21+
;; Generated from: clang -ggdb -O1
22+
;;int main() {
23+
;; float f = 3.14f;
24+
;; printf("dummy\n");
25+
;; f *= f;
26+
;; return 0;
27+
;;}
28+
; ModuleID = 'implicit_value-float.c'
29+
source_filename = "implicit_value-float.c"
30+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
31+
target triple = "x86_64-unknown-linux-gnu"
32+
33+
@str = private unnamed_addr constant [6 x i8] c"dummy\00", align 1
34+
35+
; Function Attrs: nofree nounwind uwtable
36+
define dso_local i32 @main() local_unnamed_addr #0 !dbg !7 {
37+
entry:
38+
call void @llvm.dbg.value(metadata float 0x40091EB860000000, metadata !12, metadata !DIExpression()), !dbg !14
39+
%puts = call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([6 x i8], [6 x i8]* @str, i64 0, i64 0)), !dbg !15
40+
call void @llvm.dbg.value(metadata float undef, metadata !12, metadata !DIExpression()), !dbg !14
41+
ret i32 0, !dbg !16
42+
}
43+
44+
; Function Attrs: nounwind readnone speculatable willreturn
45+
declare void @llvm.dbg.value(metadata, metadata, metadata) #1
46+
47+
; Function Attrs: nofree nounwind
48+
declare i32 @puts(i8* nocapture readonly) local_unnamed_addr #2
49+
50+
attributes #0 = { nofree nounwind uwtable }
51+
attributes #1 = { nounwind readnone speculatable willreturn }
52+
attributes #2 = { nofree nounwind }
53+
54+
!llvm.dbg.cu = !{!0}
55+
!llvm.module.flags = !{!3, !4, !5}
56+
!llvm.ident = !{!6}
57+
58+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
59+
!1 = !DIFile(filename: "implicit_value-float.c", directory: "/home/")
60+
!2 = !{}
61+
!3 = !{i32 7, !"Dwarf Version", i32 4}
62+
!4 = !{i32 2, !"Debug Info Version", i32 3}
63+
!5 = !{i32 1, !"wchar_size", i32 4}
64+
!6 = !{!"clang version 11.0.0"}
65+
!7 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
66+
!8 = !DISubroutineType(types: !9)
67+
!9 = !{!10}
68+
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
69+
!11 = !{!12}
70+
!12 = !DILocalVariable(name: "f", scope: !7, file: !1, line: 2, type: !13)
71+
!13 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
72+
!14 = !DILocation(line: 0, scope: !7)
73+
!15 = !DILocation(line: 3, column: 2, scope: !7)
74+
!16 = !DILocation(line: 5, column: 2, scope: !7)

llvm/test/DebugInfo/X86/stack-value-piece.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@
2626
; CHECK: DW_AT_name ("f")
2727
; CHECK: DW_TAG_variable
2828
; CHECK-NEXT: DW_AT_location ([[F:0x[0-9a-f]+]]
29-
; CHECK-NEXT: [{{.*}}, {{.*}}): DW_OP_reg17 XMM0, DW_OP_piece 0x4, DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x4
30-
; CHECK-NEXT: [{{.*}}, {{.*}}): DW_OP_piece 0x4, DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x4)
29+
; CHECK-NEXT: [{{.*}}, {{.*}}): DW_OP_reg17 XMM0, DW_OP_piece 0x4, {{(DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x4|DW_OP_implicit_value 0x4 0x00 0x00 0x00 0x00)}}
30+
; CHECK-NEXT: [{{.*}}, {{.*}}): DW_OP_piece 0x4, {{(DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x4|DW_OP_implicit_value 0x4 0x00 0x00 0x00 0x00)}})
3131
; CHECK-NEXT: DW_AT_name ("r")
3232
;
3333
; CHECK: .debug_loc contents:
3434
; CHECK: [[I]]:
3535
; CHECK-NEXT: ({{.*}}, {{.*}}): DW_OP_reg5 RDI, DW_OP_piece 0x4, DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x4
3636
; CHECK: [[F]]:
37-
; CHECK-NEXT: ({{.*}}, {{.*}}): DW_OP_reg17 XMM0, DW_OP_piece 0x4, DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x4
37+
; CHECK-NEXT: ({{.*}}, {{.*}}): DW_OP_reg17 XMM0, DW_OP_piece 0x4, {{DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x4|DW_OP_implicit_value 0x4 0x00 0x00 0x00 0x00}}
3838

3939
source_filename = "stack-value-piece.c"
4040
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"

0 commit comments

Comments
 (0)