Skip to content

Commit e5a1d61

Browse files
authored
Merge pull request #73145 from augusto2112/keep-for-deb-def
Fix functions not being kept for debugger
2 parents 857cc38 + 5298450 commit e5a1d61

11 files changed

+85
-17
lines changed

include/swift/SIL/SILGlobalVariable.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ class SILGlobalVariable
147147
/// might be referenced from outside the current compilation unit.
148148
bool isPossiblyUsedExternally() const;
149149

150+
/// Returns true if this global variable should be preserved so it can
151+
/// potentially be inspected by the debugger.
152+
bool shouldBePreservedForDebugger() const;
153+
150154
/// Get this global variable's serialized attribute.
151155
IsSerialized_t isSerialized() const;
152156
void setSerialized(IsSerialized_t isSerialized);

lib/IRGen/GenDecl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2841,6 +2841,8 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
28412841
// Mark as llvm.used if @_used, set section if @_section
28422842
if (var->markedAsUsed())
28432843
addUsedGlobal(gvar);
2844+
else if (var->shouldBePreservedForDebugger() && forDefinition)
2845+
addUsedGlobal(gvar);
28442846
if (auto *sectionAttr = var->getSectionAttr())
28452847
gvar->setSection(sectionAttr->Name);
28462848
}
@@ -3710,7 +3712,7 @@ llvm::Function *IRGenModule::getAddrOfSILFunction(
37103712

37113713
// Also mark as llvm.used any functions that should be kept for the debugger.
37123714
// Only definitions should be kept.
3713-
if (f->shouldBePreservedForDebugger() && !fn->isDeclaration())
3715+
if (f->shouldBePreservedForDebugger() && forDefinition)
37143716
addUsedGlobal(fn);
37153717

37163718
// If `hasCReferences` is true, then the function is either marked with

lib/SIL/IR/SILFunction.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "swift/AST/Availability.h"
1717
#include "swift/AST/Expr.h"
1818
#include "swift/AST/GenericEnvironment.h"
19+
#include "swift/AST/IRGenOptions.h"
1920
#include "swift/AST/Module.h"
2021
#include "swift/AST/Stmt.h"
2122
#include "swift/Basic/OptimizationMode.h"
@@ -970,6 +971,17 @@ bool SILFunction::shouldBePreservedForDebugger() const {
970971
if (getEffectiveOptimizationMode() != OptimizationMode::NoOptimization)
971972
return false;
972973

974+
if (getModule().getASTContext().LangOpts.hasFeature(Feature::Embedded))
975+
return false;
976+
977+
if (const IRGenOptions *options = getModule().getIRGenOptionsOrNull()) {
978+
if (options->WitnessMethodElimination ||
979+
options->VirtualFunctionElimination ||
980+
options->LLVMLTOKind != IRGenLLVMLTOKind::None) {
981+
return false;
982+
}
983+
}
984+
973985
if (isAvailableExternally())
974986
return false;
975987

lib/SIL/IR/SILGlobalVariable.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,20 @@ SILGlobalVariable::~SILGlobalVariable() {
6161
}
6262

6363
bool SILGlobalVariable::isPossiblyUsedExternally() const {
64+
if (shouldBePreservedForDebugger())
65+
return true;
66+
6467
SILLinkage linkage = getLinkage();
6568
return swift::isPossiblyUsedExternally(linkage, getModule().isWholeModule());
6669
}
6770

71+
bool SILGlobalVariable::shouldBePreservedForDebugger() const {
72+
if (getModule().getOptions().OptMode != OptimizationMode::NoOptimization)
73+
return false;
74+
// Keep any language-level global variables for the debugger.
75+
return VDecl != nullptr;
76+
}
77+
6878
/// Get this global variable's fragile attribute.
6979
IsSerialized_t SILGlobalVariable::isSerialized() const {
7080
return Serialized ? IsSerialized : IsNotSerialized;

test/IRGen/conditional-dead-strip-exec.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
@inline(never) func func1_used() { print("func1_used") }
2626

2727
// (2) unused
28+
@_semantics("no.preserve.debugger")
2829
@inline(never) func func2_dead() { print("func2_dead") }
2930

3031
// (3) completely unused
@@ -35,6 +36,7 @@ protocol TheProtocol { }
3536

3637
// (5) unused class
3738
class MyClass: TheProtocol {
39+
@_semantics("no.preserve.debugger")
3840
func unused_method() {}
3941
}
4042

test/IRGen/objc_pointers.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import Foundation
2020
}
2121

2222
// CHECK-LABEL: s13objc_pointers14returnNSObject3objSo0D0CAE_tF
23+
@_semantics("no.preserve.debugger")
2324
func returnNSObject(obj: NSObject) -> NSObject {
2425
// CHECK-NOT: return
2526
// CHECK: @llvm.objc.retain

test/IRGen/preserve_for_debugger.swift

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
// RUN: %target-swiftc_driver %s -g -Onone -emit-ir | %FileCheck %s
22

3+
4+
// Check that unused globals are preserved at Onone.
5+
6+
private let number = 42
7+
// CHECK: distinct !DIGlobalVariable(name: "number",
8+
39
// Check that unused functions are preserved at Onone.
410
func unused() {
511
}
12+
// CHECK: !DISubprogram(name: "unused", linkageName: "$s21preserve_for_debugger6unusedyyF"
613

714
// Property wrappers generate transparent getters, which we would like to check still exist at Onone.
815
@propertyWrapper
@@ -24,5 +31,36 @@ public class User {
2431
let c = User()
2532
c.f()
2633

27-
// CHECK: !DISubprogram(name: "unused", linkageName: "$s21preserve_for_debugger6unusedyyF"
2834
// CHECK: !DISubprogram(name: "number.get"
35+
36+
protocol Foo {}
37+
38+
@propertyWrapper
39+
struct Bar<ObjectType: Foo> {
40+
var storage: ObjectType
41+
42+
public init(wrappedValue: ObjectType) {
43+
storage = wrappedValue
44+
}
45+
46+
public var wrappedValue: ObjectType {
47+
return storage
48+
}
49+
50+
}
51+
52+
class Baz: Foo {
53+
let x = 42
54+
}
55+
56+
struct Qux {
57+
@Bar(wrappedValue: Baz()) private var baz: Baz
58+
59+
func f() {
60+
print(self.baz) // break here
61+
}
62+
}
63+
let qux = Qux()
64+
qux.f()
65+
66+
// CHECK: !DISubprogram(name: "baz.get"

test/IRGen/section.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
@_section("__DATA,__mysection") public var g3: Bool = true
1010
@_section("__DATA,__mysection") var g4: UnsafeMutablePointer<Int>? = nil
1111
@_section("__DATA,__mysection") var g5: UnsafeMutablePointer<Int>? = UnsafeMutablePointer(bitPattern: 0x42424242)
12-
@_section("__TEXT,__mysection") func foo() {}
12+
@_section("__TEXT,__mysection") @_used func foo() {}
1313

1414
struct MyStruct {
1515
@_section("__DATA,__mysection") static var static0: Int = 1
16-
@_section("__TEXT,__mysection") func foo() {}
16+
@_section("__TEXT,__mysection") @_used func foo() {}
1717
}
1818

1919
// SIL: @_section("__DATA,__mysection") @_hasStorage @_hasInitialValue var g0: Int { get set }
@@ -22,10 +22,10 @@ struct MyStruct {
2222
// SIL: @_section("__DATA,__mysection") @_hasStorage @_hasInitialValue public var g3: Bool { get set }
2323
// SIL: @_section("__DATA,__mysection") @_hasStorage @_hasInitialValue var g4: UnsafeMutablePointer<Int>? { get set }
2424
// SIL: @_section("__DATA,__mysection") @_hasStorage @_hasInitialValue var g5: UnsafeMutablePointer<Int>? { get set }
25-
// SIL: @_section("__TEXT,__mysection") func foo()
25+
// SIL: @_section("__TEXT,__mysection") @_used func foo()
2626
// SIL: struct MyStruct {
2727
// SIL: @_section("__DATA,__mysection") @_hasStorage @_hasInitialValue static var static0: Int { get set }
28-
// SIL: @_section("__TEXT,__mysection") func foo()
28+
// SIL: @_section("__TEXT,__mysection") @_used func foo()
2929

3030
// SIL: sil private [global_init_once_fn] [perf_constraint] @$s7section2g0_WZ : $@convention(c)
3131
// SIL: sil hidden [global_init] @$s7section2g0Sivau : $@convention(thin)
@@ -39,10 +39,10 @@ struct MyStruct {
3939
// SIL: sil hidden [global_init] @$s7section2g4SpySiGSgvau : $@convention(thin)
4040
// SIL: sil private [global_init_once_fn] [perf_constraint] @$s7section2g5_WZ : $@convention(c)
4141
// SIL: sil hidden [global_init] @$s7section2g5SpySiGSgvau : $@convention(thin)
42-
// SIL: sil hidden [section "__TEXT,__mysection"] @$s7section3fooyyF : $@convention(thin)
42+
// SIL: sil hidden [used] [section "__TEXT,__mysection"] @$s7section3fooyyF : $@convention(thin)
4343
// SIL: sil private [global_init_once_fn] [perf_constraint] @$s7section8MyStructV7static0_WZ : $@convention(c)
4444
// SIL: sil hidden [global_init] @$s7section8MyStructV7static0Sivau : $@convention(thin)
45-
// SIL: sil hidden [section "__TEXT,__mysection"] @$s7section8MyStructV3fooyyF : $@convention(method)
45+
// SIL: sil hidden [used] [section "__TEXT,__mysection"] @$s7section8MyStructV3fooyyF : $@convention(method)
4646

4747
// IR: @"$s7section2g0Sivp" = hidden global %TSi <{ {{(i64|i32)}} 1 }>, section "__DATA,__mysection"
4848
// IR: @"$s7section2g1Si_Sitvp" = hidden global <{ %TSi, %TSi }> <{ %TSi <{ {{(i64|i32)}} 42 }>, %TSi <{ {{(i64|i32)}} 43 }> }>, section "__DATA,__mysection"

test/IRGen/section_asm.swift

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,22 @@
2727
// CHECK-NOT: .section
2828
// CHECK: $s7section8MyStructV7static0SivpZ:
2929

30-
// CHECKELF: .section{{.*}}"__TEXT,__mysection","ax"
30+
// CHECKELF: .section{{.*}}"__TEXT,__mysection","axR"
3131
// CHECKELF-NOT: .section
3232
// CHECKELF: $s7section3fooyyF:
3333

34-
// CHECKELF: .section{{.*}}"__TEXT,__mysection","ax"
34+
// CHECKELF: .section{{.*}}"__TEXT,__mysection","axR"
3535
// CHECKELF-NOT: .section
3636
// CHECKELF: $s7section8MyStructV3fooyyF:
3737

38-
// CHECKELF: .section{{.*}}"__DATA,__mysection","aw"
38+
// CHECKELF: .section{{.*}}"__DATA,__mysection","awR"
3939
// CHECKELF-NOT: .section
4040
// CHECKELF: $s7section2g0Sivp:
41-
// CHECKELF-NOT: .section
4241
// CHECKELF: $s7section2g1Si_Sitvp:
43-
// CHECKELF-NOT: .section
4442
// CHECKELF: $s7section2g2Sbvp:
4543
// CHECKELF: .section{{.*}}"__DATA,__mysection","awR"
4644
// CHECKELF: $s7section2g3Sbvp:
47-
// CHECKELF: .section{{.*}}"__DATA,__mysection","aw"
45+
// CHECKELF: .section{{.*}}"__DATA,__mysection","awR"
4846
// CHECKELF: $s7section2g4SpySiGSgvp:
49-
// CHECKELF-NOT: .section
5047
// CHECKELF: $s7section2g5SpySiGSgvp:
51-
// CHECKELF-NOT: .section
5248
// CHECKELF: $s7section8MyStructV7static0SivpZ:

test/embedded/accessor-unavailable.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,8 @@ struct Foo {
1515
}
1616
}
1717

18+
let foo = Foo()
19+
let _ = foo[5]
20+
1821
// CHECK: $s4main3FooVyS2icig
1922
// CHECK-NOT: $s4main3FooVyS2icis

0 commit comments

Comments
 (0)