Skip to content

Commit 49ee148

Browse files
committed
[DebugInfo] Add support for chained fragments in salvageDebugInfo
1 parent 0faa055 commit 49ee148

File tree

2 files changed

+87
-6
lines changed

2 files changed

+87
-6
lines changed

lib/SILOptimizer/Utils/InstOptUtils.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,12 +1854,6 @@ void swift::salvageDebugInfo(SILInstruction *I) {
18541854
auto VarInfo = DbgInst->getVarInfo();
18551855
if (!VarInfo)
18561856
continue;
1857-
if (VarInfo->DIExpr.hasFragment())
1858-
// Since we can't merge two different op_fragment
1859-
// now, we're simply bailing out if there is an
1860-
// existing op_fragment in DIExpression.
1861-
// TODO: Try to merge two op_fragment expressions here.
1862-
continue;
18631857
for (VarDecl *FD : FieldDecls) {
18641858
SILDebugVariable NewVarInfo = *VarInfo;
18651859
auto FieldVal = STI->getFieldValue(FD);
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// RUN: %target-sil-opt %s -performance-constant-propagation | %FileCheck %s
2+
3+
sil_stage canonical
4+
5+
import Builtin
6+
import Swift
7+
8+
struct Wrapper {
9+
let bytes: UInt64
10+
private func pop(numBits: UInt64) -> Wrapper
11+
public static func maker(bits: UInt64) -> Wrapper
12+
}
13+
14+
sil_scope 3 { loc "e.swift":6:16 parent @pop : $@convention(method) (UInt64, Wrapper) -> Wrapper }
15+
sil_scope 4 { loc "e.swift":8:12 parent 3 }
16+
17+
// Wrapper.pop(numBits:), scope 3
18+
sil private @pop : $@convention(method) (UInt64, Wrapper) -> Wrapper {
19+
[global: ]
20+
bb0(%0 : $UInt64, %1 : $Wrapper):
21+
debug_value %0 : $UInt64, let, name "numBits", argno 1, scope 3
22+
debug_value %1 : $Wrapper, let, name "self", argno 2, implicit, scope 3
23+
%4 = struct_extract %1 : $Wrapper, #Wrapper.bytes, scope 3
24+
%5 = struct_extract %4 : $UInt64, #UInt64._value, scope 3
25+
%6 = struct_extract %0 : $UInt64, #UInt64._value, scope 3
26+
%7 = integer_literal $Builtin.Int1, -1, scope 3
27+
%8 = builtin "usub_with_overflow_Int64"(%5 : $Builtin.Int64, %6 : $Builtin.Int64, %7 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1), scope 3
28+
%9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 0, scope 3
29+
%10 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 1, scope 3
30+
cond_fail %10 : $Builtin.Int1, "arithmetic overflow", scope 3
31+
%12 = struct $UInt64 (%9 : $Builtin.Int64), scope 3
32+
%13 = struct $Wrapper (%12 : $UInt64), loc * "e.swift":3:8
33+
return %13 : $Wrapper, scope 3
34+
} // end sil function 'pop'
35+
36+
sil_scope 7 { loc "e.swift":12:22 parent @maker : $@convention(method) (UInt64, @thin Wrapper.Type) -> Wrapper }
37+
sil_scope 8 { loc "e.swift":17:12 parent 7 }
38+
sil_scope 10 { loc "e.swift":17:39 parent 7 }
39+
sil_scope 11 { loc "e.swift":6:16 parent @pop : $@convention(method) (UInt64, Wrapper) -> Wrapper inlined_at 10 }
40+
sil_scope 12 { loc "e.swift":8:12 parent 11 inlined_at 10 }
41+
42+
// static Wrapper.maker(bits:), scope 7
43+
// CHECK-LABEL: sil {{.*}} @maker
44+
sil hidden @maker : $@convention(method) (UInt64, @thin Wrapper.Type) -> Wrapper {
45+
[global: ]
46+
bb0(%0 : $UInt64, %1 : $@thin Wrapper.Type):
47+
// CHECK: debug_value %0 : $UInt64, let, name "bits", argno 1
48+
debug_value %0 : $UInt64, let, name "bits", argno 1, scope 7
49+
// CHECK: debug_value %1 : $@thin Wrapper.Type, let, name "self", argno 2, implicit
50+
debug_value %1 : $@thin Wrapper.Type, let, name "self", argno 2, implicit, scope 7
51+
%4 = integer_literal $Builtin.Int64, 3735928559, scope 7
52+
%5 = struct $UInt64 (%4 : $Builtin.Int64), scope 7
53+
%6 = struct $Wrapper (%5 : $UInt64), loc * "e.swift":3:8
54+
// CHECK-DAG: debug_value %0 : $UInt64, let, name "numBits", argno 1
55+
debug_value %0 : $UInt64, let, name "numBits", argno 1, scope 11
56+
// CHECK-DAG: debug_value %{{.*}} : $Builtin.Int64, let, name "self", {{.*}}, implicit, type $Wrapper, expr op_fragment:#Wrapper.bytes:op_fragment:#UInt64._value
57+
debug_value %6 : $Wrapper, let, name "self", argno 2, implicit, scope 11
58+
%9 = struct_extract %6 : $Wrapper, #Wrapper.bytes, scope 11
59+
%10 = struct_extract %9 : $UInt64, #UInt64._value, scope 11
60+
%11 = struct_extract %0 : $UInt64, #UInt64._value, scope 11
61+
%12 = integer_literal $Builtin.Int1, -1, scope 11
62+
%13 = builtin "usub_with_overflow_Int64"(%10 : $Builtin.Int64, %11 : $Builtin.Int64, %12 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1), scope 11
63+
%14 = tuple_extract %13 : $(Builtin.Int64, Builtin.Int1), 0, scope 11
64+
%15 = tuple_extract %13 : $(Builtin.Int64, Builtin.Int1), 1, scope 11
65+
cond_fail %15 : $Builtin.Int1, "arithmetic overflow", scope 11
66+
%17 = struct $UInt64 (%14 : $Builtin.Int64), scope 11
67+
%18 = struct $Wrapper (%17 : $UInt64), loc * "e.swift":3:8
68+
return %18 : $Wrapper, scope 7
69+
} // end sil function 'maker'
70+
71+
72+
// Generated and adapted from this Swift source code:
73+
// ```swift
74+
// struct Wrapper {
75+
// let bytes: UInt64
76+
//
77+
// private func pop(numBits: UInt64) -> Wrapper {
78+
// // `self` in here is a nested fragment. It should be salvaged, when inlined in `maker(bits:)`
79+
// return Self(bytes: bytes - numBits)
80+
// }
81+
//
82+
// public static func maker(bits: UInt64) -> Wrapper {
83+
// // This function is static, but `pop`'s self should be inlined in here
84+
// return Wrapper(bytes: 0xDEADBEEF).pop(numBits: bits)
85+
// }
86+
// }
87+
// ```

0 commit comments

Comments
 (0)