Skip to content

Commit 315a763

Browse files
Merge pull request swiftlang#72218 from aschwaighofer/fragile_resilient_protocols
IRGen: Add code to support building fragile resilient protocol witnesses
2 parents b065540 + 9639e00 commit 315a763

19 files changed

+166
-4
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,8 @@ class IRGenOptions {
467467
/// Use relative (and constant) protocol witness tables.
468468
unsigned UseRelativeProtocolWitnessTables : 1;
469469

470+
unsigned UseFragileResilientProtocolWitnesses : 1;
471+
470472
/// The number of threads for multi-threaded code generation.
471473
unsigned NumThreads = 0;
472474

@@ -555,6 +557,7 @@ class IRGenOptions {
555557
EmitGenericRODatas(false), NoPreallocatedInstantiationCaches(false),
556558
DisableReadonlyStaticObjects(false), CollocatedMetadataFunctions(false),
557559
ColocateTypeDescriptors(true), UseRelativeProtocolWitnessTables(false),
560+
UseFragileResilientProtocolWitnesses(false),
558561
CmdArgs(), SanitizeCoverage(llvm::SanitizerCoverageOptions()),
559562
TypeInfoFilter(TypeInfoDumpFilter::All),
560563
PlatformCCallingConvention(llvm::CallingConv::C), UseCASBackend(false),

include/swift/IRGen/TBDGen.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ struct TBDGenOptions {
4747
/// Whether LLVM IR Witness Method Elimination is enabled.
4848
bool WitnessMethodElimination = false;
4949

50+
/// Whether resilient protocols should be emitted fragile.
51+
bool FragileResilientProtocols = false;
52+
5053
/// The install_name to use in the TBD file.
5154
std::string InstallName;
5255

@@ -78,6 +81,7 @@ struct TBDGenOptions {
7881
lhs.PublicOrPackageSymbolsOnly == rhs.PublicOrPackageSymbolsOnly &&
7982
lhs.VirtualFunctionElimination == rhs.VirtualFunctionElimination &&
8083
lhs.WitnessMethodElimination == rhs.WitnessMethodElimination &&
84+
lhs.FragileResilientProtocols == rhs.FragileResilientProtocols &&
8185
lhs.InstallName == rhs.InstallName &&
8286
lhs.ModuleLinkName == rhs.ModuleLinkName &&
8387
lhs.CurrentVersion == rhs.CurrentVersion &&
@@ -95,7 +99,7 @@ struct TBDGenOptions {
9599
return hash_combine(
96100
opts.HasMultipleIGMs, opts.IsInstallAPI, opts.LinkerDirectivesOnly,
97101
opts.PublicOrPackageSymbolsOnly, opts.VirtualFunctionElimination,
98-
opts.WitnessMethodElimination,
102+
opts.WitnessMethodElimination, opts.FragileResilientProtocols,
99103
opts.InstallName, opts.ModuleLinkName,
100104
opts.CurrentVersion, opts.CompatibilityVersion,
101105
opts.ModuleInstallNameMapPath,

include/swift/Option/FrontendOptions.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,6 +1259,12 @@ def enable_relative_protocol_witness_tables :
12591259
def disable_relative_protocol_witness_tables :
12601260
Flag<["-"], "disable-relative-protocol-witness-tables">,
12611261
HelpText<"Disable relative protocol witness tables">;
1262+
def enable_fragile_resilient_protocol_witnesses :
1263+
Flag<["-"], "enable-fragile-relative-protocol-tables">,
1264+
HelpText<"Enable relative protocol witness tables">;
1265+
def disable_fragile_resilient_protocol_witnesses :
1266+
Flag<["-"], "disable-fragile-relative-protocol-tables">,
1267+
HelpText<"Disable relative protocol witness tables">;
12621268

12631269
def enable_new_llvm_pass_manager :
12641270
Flag<["-"], "enable-new-llvm-pass-manager">,

include/swift/SIL/SILSymbolVisitor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ struct SILSymbolVisitorOptions {
3939

4040
/// Whether LLVM IR Witness Method Elimination is enabled.
4141
bool WitnessMethodElimination = false;
42+
43+
/// Whether resilient protocols should be emitted fragile.
44+
bool FragileResilientProtocols = false;
4245
};
4346

4447
/// Context for `SILSymbolVisitor` symbol enumeration.

lib/Frontend/CompilerInvocation.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2525,6 +2525,8 @@ static bool ParseTBDGenArgs(TBDGenOptions &Opts, ArgList &Args,
25252525

25262526
Opts.VirtualFunctionElimination = Args.hasArg(OPT_enable_llvm_vfe);
25272527
Opts.WitnessMethodElimination = Args.hasArg(OPT_enable_llvm_wme);
2528+
Opts.FragileResilientProtocols =
2529+
Args.hasArg(OPT_enable_fragile_resilient_protocol_witnesses);
25282530

25292531
if (const Arg *A = Args.getLastArg(OPT_tbd_compatibility_version)) {
25302532
Opts.CompatibilityVersion = A->getValue();
@@ -3046,6 +3048,10 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
30463048
Args.hasFlag(OPT_enable_relative_protocol_witness_tables,
30473049
OPT_disable_relative_protocol_witness_tables,
30483050
Opts.UseRelativeProtocolWitnessTables);
3051+
Opts.UseFragileResilientProtocolWitnesses =
3052+
Args.hasFlag(OPT_enable_fragile_resilient_protocol_witnesses,
3053+
OPT_disable_fragile_resilient_protocol_witnesses,
3054+
Opts.UseFragileResilientProtocolWitnesses);
30493055
Opts.EnableLargeLoadableTypesReg2Mem =
30503056
Args.hasFlag(OPT_enable_large_loadable_types_reg2mem,
30513057
OPT_disable_large_loadable_types_reg2mem,

lib/IRGen/GenDecl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6015,6 +6015,11 @@ bool IRGenModule::isResilient(NominalTypeDecl *D,
60156015
ClassDecl *asViewedFromRootClass) {
60166016
assert(!asViewedFromRootClass || isa<ClassDecl>(D));
60176017

6018+
// Ignore resilient protocols if requested.
6019+
if (isa<ProtocolDecl>(D) && IRGen.Opts.UseFragileResilientProtocolWitnesses) {
6020+
return false;
6021+
}
6022+
60186023
if (D->getModuleContext()->getBypassResilience())
60196024
return false;
60206025
if (expansion == ResilienceExpansion::Maximal &&

lib/IRGen/GenProto.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,10 @@ bool IRGenModule::isResilientConformance(
953953
const NormalProtocolConformance *conformance) {
954954
// If the protocol is not resilient, the conformance is not resilient
955955
// either.
956-
if (!conformance->getProtocol()->isResilient())
956+
bool shouldTreatProtocolNonResilient =
957+
IRGen.Opts.UseFragileResilientProtocolWitnesses;
958+
if (!conformance->getProtocol()->isResilient() ||
959+
shouldTreatProtocolNonResilient)
957960
return false;
958961

959962
auto *conformanceModule = conformance->getDeclContext()->getParentModule();
@@ -2167,6 +2170,7 @@ namespace {
21672170
void addResilientWitnesses() {
21682171
if (Description.resilientWitnesses.empty())
21692172
return;
2173+
assert(!IGM.IRGen.Opts.UseFragileResilientProtocolWitnesses);
21702174

21712175
Flags = Flags.withHasResilientWitnesses(true);
21722176

@@ -2540,6 +2544,17 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
25402544
bool isResilient = isResilientConformance(conf);
25412545
bool useRelativeProtocolWitnessTable =
25422546
IRGen.Opts.UseRelativeProtocolWitnessTables;
2547+
if (useRelativeProtocolWitnessTable &&
2548+
!conf->getConditionalRequirements().empty()) {
2549+
auto sig = conf->getGenericSignature();
2550+
sig->forEachParam([&](GenericTypeParamType *param, bool canonical) {
2551+
if (param->isParameterPack()) {
2552+
#ifndef NDEBUG
2553+
wt->dump();
2554+
#endif
2555+
llvm::report_fatal_error("use of relative protcol witness tables not supported");
2556+
}});
2557+
}
25432558
if (!isResilient) {
25442559
// Build the witness table.
25452560
ConstantInitBuilder builder(*this);

lib/IRGen/TBDGen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@ void TBDGenVisitor::visit(const TBDGenDescriptor &desc) {
511511
opts.PublicOrPackageSymbolsOnly = Opts.PublicOrPackageSymbolsOnly;
512512
opts.WitnessMethodElimination = Opts.WitnessMethodElimination;
513513
opts.VirtualFunctionElimination = Opts.VirtualFunctionElimination;
514+
opts.FragileResilientProtocols = Opts.FragileResilientProtocols;
514515

515516
auto silVisitorCtx = SILSymbolVisitorContext(SwiftModule, opts);
516517
auto visitorCtx = IRSymbolVisitorContext{UniversalLinkInfo, silVisitorCtx};

lib/SIL/IR/SILSymbolVisitor.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,8 @@ class SILSymbolVisitorImpl : public ASTVisitor<SILSymbolVisitorImpl> {
269269
// We cannot emit the witness table symbol if the protocol is imported
270270
// from another module and it's resilient, because initialization of that
271271
// protocol is necessary in this case
272-
if (!rootConformance->getProtocol()->isResilient(
272+
if (Ctx.getOpts().FragileResilientProtocols ||
273+
!rootConformance->getProtocol()->isResilient(
273274
IDC->getAsGenericContext()->getParentModule(),
274275
ResilienceExpansion::Maximal))
275276
Visitor.addProtocolWitnessTable(rootConformance);

stdlib/cmake/modules/AddSwiftStdlib.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,10 @@ function(_add_target_variant_c_compile_flags)
453453
list(APPEND result "-DSWIFT_STDLIB_USE_RELATIVE_PROTOCOL_WITNESS_TABLES")
454454
endif()
455455

456+
if(SWIFT_STDLIB_USE_FRAGILE_RESILIENT_PROTOCOL_WITNESS_TABLES)
457+
list(APPEND result "-DSWIFT_STDLIB_USE_FRAGILE_RESILIENT_PROTOCOL_WITNESS_TABLES")
458+
endif()
459+
456460
if(SWIFT_STDLIB_OVERRIDABLE_RETAIN_RELEASE)
457461
list(APPEND result "-DSWIFT_STDLIB_OVERRIDABLE_RETAIN_RELEASE")
458462
endif()

0 commit comments

Comments
 (0)