Skip to content

Commit 78ca835

Browse files
authored
Merge pull request #16000 from slavapestov/fix-resilience-debugger-support
IRGen: New way of bypassing resilience for LLDB
2 parents d949c82 + 55633e8 commit 78ca835

File tree

8 files changed

+57
-26
lines changed

8 files changed

+57
-26
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ class IRGenOptions {
152152
/// Enables resilient class layout.
153153
unsigned EnableClassResilience : 1;
154154

155+
/// Bypass resilience when accessing resilient frameworks.
156+
unsigned EnableResilienceBypass : 1;
157+
155158
/// Should we try to build incrementally by not emitting an object file if it
156159
/// has the same IR hash as the module that we are preparing to emit?
157160
///
@@ -185,8 +188,8 @@ class IRGenOptions {
185188
EmbedMode(IRGenEmbedMode::None), HasValueNamesSetting(false),
186189
ValueNames(false), EnableReflectionMetadata(true),
187190
EnableReflectionNames(true), EnableClassResilience(false),
188-
UseIncrementalLLVMCodeGen(true), UseSwiftCall(false),
189-
GenerateProfile(false), CmdArgs(),
191+
EnableResilienceBypass(false), UseIncrementalLLVMCodeGen(true),
192+
UseSwiftCall(false), GenerateProfile(false), CmdArgs(),
190193
SanitizeCoverage(llvm::SanitizerCoverageOptions()) {}
191194

192195
// Get a hash of all options which influence the llvm compilation but are not

include/swift/Option/FrontendOptions.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,9 @@ def enable_resilience : Flag<["-"], "enable-resilience">,
450450
def enable_class_resilience : Flag<["-"], "enable-class-resilience">,
451451
HelpText<"Enable resilient layout for classes containing resilient value types">;
452452

453+
def enable_resilience_bypass : Flag<["-"], "enable-resilience-bypass">,
454+
HelpText<"Completely bypass resilience when accessing types in resilient frameworks">;
455+
453456
def group_info_path : Separate<["-"], "group-info-path">,
454457
HelpText<"The path to collect the group information of the compiled module">;
455458

lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,10 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
903903
Opts.EnableClassResilience = true;
904904
}
905905

906+
if (Args.hasArg(OPT_enable_resilience_bypass)) {
907+
Opts.EnableResilienceBypass = true;
908+
}
909+
906910
for (const auto &Lib : Args.getAllArgValues(options::OPT_autolink_library))
907911
Opts.LinkLibraries.push_back(LinkLibrary(Lib, LibraryKind::Library));
908912

lib/IRGen/GenType.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,15 @@ static ProtocolInfo *invalidProtocolInfo() { return (ProtocolInfo*) 1; }
10641064
TypeConverter::TypeConverter(IRGenModule &IGM)
10651065
: IGM(IGM),
10661066
FirstType(invalidTypeInfo()),
1067-
FirstProtocol(invalidProtocolInfo()) {}
1067+
FirstProtocol(invalidProtocolInfo()) {
1068+
// FIXME: In LLDB, everything is completely fragile, so that IRGen can query
1069+
// the size of resilient types. Of course this is not the right long term
1070+
// solution, because it won't work once the swiftmodule file is not in
1071+
// sync with the binary module. Once LLDB can calculate type layouts at
1072+
// runtime (using remote mirrors or some other mechanism), we can remove this.
1073+
if (IGM.IRGen.Opts.EnableResilienceBypass)
1074+
CompletelyFragile = true;
1075+
}
10681076

10691077
TypeConverter::~TypeConverter() {
10701078
// Delete all the converted type infos.

lib/IRGen/GenType.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,17 +222,21 @@ class GenericContextScope {
222222

223223
/// An RAII interface for forcing types to be lowered bypassing resilience.
224224
class CompletelyFragileScope {
225+
bool State;
225226
TypeConverter &TC;
226227
public:
227228
CompletelyFragileScope(TypeConverter &TC) : TC(TC) {
228-
TC.pushCompletelyFragile();
229+
State = TC.isCompletelyFragile();
230+
if (!State)
231+
TC.pushCompletelyFragile();
229232
}
230233

231234
CompletelyFragileScope(IRGenModule &IGM)
232235
: CompletelyFragileScope(IGM.Types) {}
233236

234237
~CompletelyFragileScope() {
235-
TC.popCompletelyFragile();
238+
if (!State)
239+
TC.popCompletelyFragile();
236240
}
237241
};
238242

lib/RemoteAST/RemoteAST.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,19 @@ struct IRGenContext {
6565

6666
private:
6767
IRGenContext(ASTContext &ctx, ModuleDecl *module)
68-
: SILMod(SILModule::createEmptyModule(module, SILOpts)),
68+
: IROpts(createIRGenOptions()),
69+
SILMod(SILModule::createEmptyModule(module, SILOpts)),
6970
IRGen(IROpts, *SILMod),
7071
IGM(IRGen, IRGen.createTargetMachine(), /*SourceFile*/ nullptr,
7172
LLVMContext, "<fake module name>", "<fake output filename>",
7273
"<fake main input filename>") {}
7374

75+
static IRGenOptions createIRGenOptions() {
76+
IRGenOptions IROpts;
77+
IROpts.EnableResilienceBypass = true;
78+
return IROpts;
79+
}
80+
7481
public:
7582
static std::unique_ptr<IRGenContext>
7683
create(ASTContext &ctx, DeclContext *nominalDC) {

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,7 @@ FileUnit *SerializedModuleLoader::loadAST(
200200
isFramework, loadedModuleFile,
201201
&extendedInfo);
202202
if (loadInfo.status == serialization::Status::Valid) {
203-
// In LLDB always use the default resilience strategy, so IRGen can query
204-
// the size of resilient types.
205-
if (!Ctx.LangOpts.DebuggerSupport)
206-
M.setResilienceStrategy(extendedInfo.getResilienceStrategy());
203+
M.setResilienceStrategy(extendedInfo.getResilienceStrategy());
207204

208205
// We've loaded the file. Now try to bring it into the AST.
209206
auto fileUnit = new (Ctx) SerializedASTFile(M, *loadedModuleFile,

test/DebugInfo/resilience.swift

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,36 @@
99
// RUN: %target-swift-frontend -g -I %t -emit-ir -enable-resilience %s -o - \
1010
// RUN: | %FileCheck %s
1111
//
12-
// RUN: %target-swift-frontend -g -I %t -emit-sil -enable-resilience %s -o - \
13-
// RUN: | %FileCheck %s --check-prefix=CHECK-SIL
14-
// RUN: %target-swift-frontend -g -I %t -emit-sil -enable-resilience %s -o - \
15-
// RUN: -debugger-support | %FileCheck %s --check-prefix=CHECK-LLDB
12+
// RUN: %target-swift-frontend -g -I %t -emit-ir -enable-resilience %s -o - \
13+
// RUN: -enable-resilience-bypass | %FileCheck %s --check-prefix=CHECK-LLDB
1614
import resilient_struct
1715

18-
func use<T>(_ t: T) {}
19-
16+
// CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S10resilience1fyyF"()
17+
// CHECK-LLDB-LABEL: define{{( protected)?}} swiftcc void @"$S10resilience1fyyF"()
2018
public func f() {
2119
let s1 = Size(w: 1, h: 2)
22-
use(s1)
20+
takesSize(s1)
2321
// CHECK: %[[ADDR:.*]] = alloca i8*
2422
// CHECK: call void @llvm.dbg.declare(metadata i8** %[[ADDR]],
2523
// CHECK-SAME: metadata ![[V1:[0-9]+]],
2624
// CHECK-SAME: metadata !DIExpression(DW_OP_deref))
2725
// CHECK: %[[S1:.*]] = alloca i8,
2826
// CHECK: store i8* %[[S1]], i8** %[[ADDR]]
29-
// CHECK: ![[V1]] = !DILocalVariable(name: "s1", {{.*}}type: ![[TY:[0-9]+]])
30-
// CHECK: ![[TY]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Size",
31-
// FIXME-NOT: size:
32-
// CHECK: =
27+
28+
// CHECK-LLDB: %[[ADDR:.*]] = alloca %T16resilient_struct4SizeV
29+
// CHECK-LLDB: call void @llvm.dbg.declare(metadata %T16resilient_struct4SizeV* %[[ADDR]],
30+
// CHECK-LLDB-SAME: metadata ![[V1:[0-9]+]],
31+
// CHECK-LLDB-SAME: metadata !DIExpression())
3332
}
3433

35-
// CHECK-SIL: // f()
36-
// CHECK-LLDB: // f()
37-
// CHECK-SIL: %0 = alloc_stack $Size, let, name "s1"
38-
// CHECK-LLDB: %0 = metatype $@thin Size.Type
39-
// CHECK-LLDB: debug_value %{{.*}} : $Size, let, name "s1"
34+
35+
// CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S10resilience9takesSizeyy16resilient_struct0C0VF"(%swift.opaque* noalias nocapture)
36+
// CHECK-LLDB-LABEL: define{{( protected)?}} swiftcc void @"$S10resilience9takesSizeyy16resilient_struct0C0VF"(%T16resilient_struct4SizeV* noalias nocapture dereferenceable({{8|16}}))
37+
public func takesSize(_ s: Size) {}
38+
39+
40+
// CHECK: ![[V1]] = !DILocalVariable(name: "s1", {{.*}}type: ![[TY:[0-9]+]])
41+
// CHECK: ![[TY]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Size",
42+
43+
// CHECK-LLDB: ![[V1]] = !DILocalVariable(name: "s1", {{.*}}type: ![[TY:[0-9]+]])
44+
// CHECK-LLDB: ![[TY]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Size",

0 commit comments

Comments
 (0)