Skip to content

Commit d6bc48a

Browse files
authored
Merge pull request #39313 from kubamracek/conditional
Implement conditional stripping of type descriptors, protocols and protocol conformances via !llvm.used.conditional
2 parents 814d583 + 2dfd232 commit d6bc48a

26 files changed

+647
-140
lines changed

docs/ABI/Mangling.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,13 @@ Globals
137137
global ::= type assoc-type-list 'MXA' // generic parameter ref (HISTORICAL)
138138
global ::= protocol 'Mp' // protocol descriptor
139139

140+
global ::= protocol 'Hr' // protocol descriptor runtime record
141+
global ::= nominal-type 'Hn' // nominal type descriptor runtime record
142+
#if SWIFT_RUNTIME_VERSION >= 5.1
143+
global ::= opaque-type 'Ho' // opaque type descriptor runtime record
144+
#endif
145+
global ::= protocol-conformance 'Hc' // protocol conformance runtime record
146+
140147
global ::= nominal-type 'Mo' // class metadata immediate member base offset
141148

142149
global ::= type 'MF' // metadata for remote mirrors: field descriptor

include/swift/AST/ASTMangler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ class ASTMangler : public Mangler {
252252
std::string mangleTypeForTypeName(Type type);
253253

254254
std::string mangleOpaqueTypeDescriptor(const OpaqueTypeDecl *decl);
255+
256+
std::string mangleOpaqueTypeDescriptorRecord(const OpaqueTypeDecl *decl);
255257

256258
std::string mangleDeclType(const ValueDecl *decl);
257259

include/swift/AST/IRGenOptions.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,8 @@ class IRGenOptions {
361361

362362
unsigned WitnessMethodElimination : 1;
363363

364+
unsigned ConditionalRuntimeRecords : 1;
365+
364366
unsigned InternalizeAtLink : 1;
365367

366368
/// The number of threads for multi-threaded code generation.
@@ -422,7 +424,8 @@ class IRGenOptions {
422424
DisableRoundTripDebugTypes(false), DisableDebuggerShadowCopies(false),
423425
DisableConcreteTypeMetadataMangledNameAccessors(false),
424426
EnableGlobalISel(false), VirtualFunctionElimination(false),
425-
WitnessMethodElimination(false), InternalizeAtLink(false),
427+
WitnessMethodElimination(false), ConditionalRuntimeRecords(false),
428+
InternalizeAtLink(false),
426429
CmdArgs(),
427430
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
428431
TypeInfoFilter(TypeInfoDumpFilter::All) {}

include/swift/Demangling/DemangleNodes.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ CONTEXT_NODE(NativeOwningMutableAddressor)
157157
CONTEXT_NODE(NativePinningAddressor)
158158
CONTEXT_NODE(NativePinningMutableAddressor)
159159
NODE(NominalTypeDescriptor)
160+
NODE(NominalTypeDescriptorRecord)
160161
NODE(NonObjCAttribute)
161162
NODE(Number)
162163
NODE(ObjCAsyncCompletionHandlerImpl)
@@ -182,7 +183,9 @@ NODE(ProtocolConformanceRefInTypeModule)
182183
NODE(ProtocolConformanceRefInProtocolModule)
183184
NODE(ProtocolConformanceRefInOtherModule)
184185
NODE(ProtocolDescriptor)
186+
NODE(ProtocolDescriptorRecord)
185187
NODE(ProtocolConformanceDescriptor)
188+
NODE(ProtocolConformanceDescriptorRecord)
186189
NODE(ProtocolList)
187190
NODE(ProtocolListWithClass)
188191
NODE(ProtocolListWithAnyObject)
@@ -289,6 +292,7 @@ NODE(AccessorFunctionReference)
289292
NODE(OpaqueType)
290293
NODE(OpaqueTypeDescriptorSymbolicReference)
291294
NODE(OpaqueTypeDescriptor)
295+
NODE(OpaqueTypeDescriptorRecord)
292296
NODE(OpaqueTypeDescriptorAccessor)
293297
NODE(OpaqueTypeDescriptorAccessorImpl)
294298
NODE(OpaqueTypeDescriptorAccessorKey)

include/swift/IRGen/Linking.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,18 @@ class LinkEntity {
222222
/// The pointer is a NominalTypeDecl*.
223223
NominalTypeDescriptor,
224224

225+
/// The nominal type descriptor runtime record for a nominal type.
226+
/// The pointer is a NominalTypeDecl*.
227+
NominalTypeDescriptorRecord,
228+
225229
/// The descriptor for an opaque type.
226230
/// The pointer is an OpaqueTypeDecl*.
227231
OpaqueTypeDescriptor,
228232

233+
/// The runtime record for a descriptor for an opaque type.
234+
/// The pointer is an OpaqueTypeDecl*.
235+
OpaqueTypeDescriptorRecord,
236+
229237
/// The descriptor accessor for an opaque type used for dynamic functions.
230238
/// The pointer is an OpaqueTypeDecl*.
231239
OpaqueTypeDescriptorAccessor,
@@ -272,6 +280,10 @@ class LinkEntity {
272280
/// The pointer is a ProtocolDecl*.
273281
ProtocolDescriptor,
274282

283+
/// The protocol descriptor runtime record for a protocol type.
284+
/// The pointer is a ProtocolDecl*.
285+
ProtocolDescriptorRecord,
286+
275287
/// The alias referring to the base of the requirements within the
276288
/// protocol descriptor, which is used to determine the offset of a
277289
/// particular requirement in the witness table.
@@ -372,6 +384,10 @@ class LinkEntity {
372384
/// The pointer is a RootProtocolConformance*.
373385
ProtocolConformanceDescriptor,
374386

387+
/// The protocol conformance descriptor runtime record for a conformance.
388+
/// The pointer is a RootProtocolConformance*.
389+
ProtocolConformanceDescriptorRecord,
390+
375391
// These are both type kinds and protocol-conformance kinds.
376392

377393
/// A lazy protocol witness accessor function. The pointer is a
@@ -481,6 +497,7 @@ class LinkEntity {
481497

482498
static bool isRootProtocolConformanceKind(Kind k) {
483499
return (k == Kind::ProtocolConformanceDescriptor ||
500+
k == Kind::ProtocolConformanceDescriptorRecord ||
484501
k == Kind::ProtocolWitnessTable);
485502
}
486503

@@ -834,12 +851,24 @@ class LinkEntity {
834851
return entity;
835852
}
836853

854+
static LinkEntity forNominalTypeDescriptorRecord(NominalTypeDecl *decl) {
855+
LinkEntity entity;
856+
entity.setForDecl(Kind::NominalTypeDescriptorRecord, decl);
857+
return entity;
858+
}
859+
837860
static LinkEntity forOpaqueTypeDescriptor(OpaqueTypeDecl *decl) {
838861
LinkEntity entity;
839862
entity.setForDecl(Kind::OpaqueTypeDescriptor, decl);
840863
return entity;
841864
}
842865

866+
static LinkEntity forOpaqueTypeDescriptorRecord(OpaqueTypeDecl *decl) {
867+
LinkEntity entity;
868+
entity.setForDecl(Kind::OpaqueTypeDescriptorRecord, decl);
869+
return entity;
870+
}
871+
843872
static LinkEntity forOpaqueTypeDescriptorAccessor(OpaqueTypeDecl *decl) {
844873
LinkEntity entity;
845874
entity.setForDecl(Kind::OpaqueTypeDescriptorAccessor, decl);
@@ -902,6 +931,12 @@ class LinkEntity {
902931
return entity;
903932
}
904933

934+
static LinkEntity forProtocolDescriptorRecord(ProtocolDecl *decl) {
935+
LinkEntity entity;
936+
entity.setForDecl(Kind::ProtocolDescriptorRecord, decl);
937+
return entity;
938+
}
939+
905940
static LinkEntity forProtocolRequirementsBaseDescriptor(ProtocolDecl *decl) {
906941
LinkEntity entity;
907942
entity.setForDecl(Kind::ProtocolRequirementsBaseDescriptor, decl);
@@ -1070,6 +1105,14 @@ class LinkEntity {
10701105
return entity;
10711106
}
10721107

1108+
static LinkEntity
1109+
forProtocolConformanceDescriptorRecord(const RootProtocolConformance *C) {
1110+
LinkEntity entity;
1111+
entity.setForProtocolConformance(Kind::ProtocolConformanceDescriptorRecord,
1112+
C);
1113+
return entity;
1114+
}
1115+
10731116
static LinkEntity forCoroutineContinuationPrototype(CanSILFunctionType type) {
10741117
LinkEntity entity;
10751118
entity.setForType(Kind::CoroutineContinuationPrototype, type);

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,10 @@ def internalize_at_link : Flag<["-"], "internalize-at-link">,
511511
" all client code of public types is part of the same link unit, or that"
512512
" external symbols are explicitly requested via -exported_symbols_list)">;
513513

514+
def conditional_runtime_records : Flag<["-"], "conditional-runtime-records">,
515+
Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>,
516+
HelpText<"Allow removal of runtime metadata records (public types, protocol conformances) based on whether they're used or unused">;
517+
514518
def disable_previous_implementation_calls_in_dynamic_replacements :
515519
Flag<["-"], "disable-previous-implementation-calls-in-dynamic-replacements">,
516520
Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>,

lib/AST/ASTMangler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3332,3 +3332,11 @@ std::string ASTMangler::mangleOpaqueTypeDescriptor(const OpaqueTypeDecl *decl) {
33323332
appendOperator("MQ");
33333333
return finalize();
33343334
}
3335+
3336+
std::string
3337+
ASTMangler::mangleOpaqueTypeDescriptorRecord(const OpaqueTypeDecl *decl) {
3338+
beginMangling();
3339+
appendOpaqueDeclName(decl);
3340+
appendOperator("Ho");
3341+
return finalize();
3342+
}

lib/Demangling/Demangler.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,18 @@ NodePointer Demangler::demangleOperator() {
793793
case 'p':
794794
return createWithChild(
795795
Node::Kind::ProtocolConformanceRefInProtocolModule, popProtocol());
796+
797+
// Runtime records (type/protocol/conformance)
798+
case 'c':
799+
return createWithChild(Node::Kind::ProtocolConformanceDescriptorRecord,
800+
popProtocolConformance());
801+
case 'n':
802+
return createWithPoppedType(Node::Kind::NominalTypeDescriptorRecord);
803+
case 'o': // XXX
804+
return createWithChild(Node::Kind::OpaqueTypeDescriptorRecord, popNode());
805+
case 'r':
806+
return createWithChild(Node::Kind::ProtocolDescriptorRecord, popProtocol());
807+
796808
default:
797809
pushBack();
798810
pushBack();

lib/Demangling/NodePrinter.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ class NodePrinter {
439439
case Node::Kind::NativePinningAddressor:
440440
case Node::Kind::NativePinningMutableAddressor:
441441
case Node::Kind::NominalTypeDescriptor:
442+
case Node::Kind::NominalTypeDescriptorRecord:
442443
case Node::Kind::NonObjCAttribute:
443444
case Node::Kind::Number:
444445
case Node::Kind::ObjCAsyncCompletionHandlerImpl:
@@ -447,6 +448,7 @@ class NodePrinter {
447448
case Node::Kind::ObjCMetadataUpdateFunction:
448449
case Node::Kind::ObjCResilientClassStub:
449450
case Node::Kind::OpaqueTypeDescriptor:
451+
case Node::Kind::OpaqueTypeDescriptorRecord:
450452
case Node::Kind::OpaqueTypeDescriptorAccessor:
451453
case Node::Kind::OpaqueTypeDescriptorAccessorImpl:
452454
case Node::Kind::OpaqueTypeDescriptorAccessorKey:
@@ -463,8 +465,10 @@ class NodePrinter {
463465
case Node::Kind::PropertyDescriptor:
464466
case Node::Kind::ProtocolConformance:
465467
case Node::Kind::ProtocolConformanceDescriptor:
468+
case Node::Kind::ProtocolConformanceDescriptorRecord:
466469
case Node::Kind::MetadataInstantiationCache:
467470
case Node::Kind::ProtocolDescriptor:
471+
case Node::Kind::ProtocolDescriptorRecord:
468472
case Node::Kind::ProtocolRequirementsBaseDescriptor:
469473
case Node::Kind::ProtocolSelfConformanceDescriptor:
470474
case Node::Kind::ProtocolSelfConformanceWitness:
@@ -2017,10 +2021,18 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
20172021
Printer << "protocol conformance descriptor for ";
20182022
print(Node->getChild(0), depth + 1);
20192023
return nullptr;
2024+
case Node::Kind::ProtocolConformanceDescriptorRecord:
2025+
Printer << "protocol conformance descriptor runtime record for ";
2026+
print(Node->getChild(0), depth + 1);
2027+
return nullptr;
20202028
case Node::Kind::ProtocolDescriptor:
20212029
Printer << "protocol descriptor for ";
20222030
print(Node->getChild(0), depth + 1);
20232031
return nullptr;
2032+
case Node::Kind::ProtocolDescriptorRecord:
2033+
Printer << "protocol descriptor runtime record for ";
2034+
print(Node->getChild(0), depth + 1);
2035+
return nullptr;
20242036
case Node::Kind::ProtocolRequirementsBaseDescriptor:
20252037
Printer << "protocol requirements base descriptor for ";
20262038
print(Node->getChild(0), depth + 1);
@@ -2123,10 +2135,18 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
21232135
Printer << "nominal type descriptor for ";
21242136
print(Node->getChild(0), depth + 1);
21252137
return nullptr;
2138+
case Node::Kind::NominalTypeDescriptorRecord:
2139+
Printer << "nominal type descriptor runtime record for ";
2140+
print(Node->getChild(0), depth + 1);
2141+
return nullptr;
21262142
case Node::Kind::OpaqueTypeDescriptor:
21272143
Printer << "opaque type descriptor for ";
21282144
print(Node->getChild(0), depth + 1);
21292145
return nullptr;
2146+
case Node::Kind::OpaqueTypeDescriptorRecord:
2147+
Printer << "opaque type descriptor runtime record for ";
2148+
print(Node->getChild(0), depth + 1);
2149+
return nullptr;
21302150
case Node::Kind::OpaqueTypeDescriptorAccessor:
21312151
Printer << "opaque type descriptor accessor for ";
21322152
print(Node->getChild(0), depth + 1);

lib/Demangling/OldRemangler.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,12 @@ ManglingError Remangler::mangleNominalTypeDescriptor(Node *node,
639639
return mangleSingleChildNode(node, depth + 1); // type
640640
}
641641

642+
ManglingError Remangler::mangleNominalTypeDescriptorRecord(Node *node,
643+
unsigned depth) {
644+
Buffer << "Hn";
645+
return mangleSingleChildNode(node, depth + 1); // type
646+
}
647+
642648
ManglingError Remangler::manglePropertyDescriptor(Node *node, unsigned depth) {
643649
// not supported
644650
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
@@ -659,6 +665,12 @@ ManglingError Remangler::mangleProtocolDescriptor(Node *node, unsigned depth) {
659665
return mangleProtocolWithoutPrefix(node->begin()[0], depth + 1);
660666
}
661667

668+
ManglingError Remangler::mangleProtocolDescriptorRecord(Node *node,
669+
unsigned depth) {
670+
Buffer << "Hr";
671+
return mangleProtocolWithoutPrefix(node->begin()[0], depth + 1);
672+
}
673+
662674
ManglingError
663675
Remangler::mangleProtocolRequirementsBaseDescriptor(Node *node,
664676
unsigned depth) {
@@ -679,6 +691,13 @@ ManglingError Remangler::mangleProtocolConformanceDescriptor(Node *node,
679691
return mangleProtocolConformance(node->begin()[0], depth + 1);
680692
}
681693

694+
ManglingError
695+
Remangler::mangleProtocolConformanceDescriptorRecord(Node *node,
696+
unsigned depth) {
697+
Buffer << "Hc";
698+
return mangleProtocolConformance(node->begin()[0], depth + 1);
699+
}
700+
682701
ManglingError
683702
Remangler::mangleProtocolSelfConformanceDescriptor(Node *node, unsigned depth) {
684703
Buffer << "MS";
@@ -2624,6 +2643,10 @@ ManglingError Remangler::mangleOpaqueTypeDescriptor(Node *node,
26242643
unsigned depth) {
26252644
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
26262645
}
2646+
ManglingError Remangler::mangleOpaqueTypeDescriptorRecord(Node *node,
2647+
unsigned depth) {
2648+
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
2649+
}
26272650
ManglingError Remangler::mangleOpaqueTypeDescriptorAccessor(Node *node,
26282651
unsigned depth) {
26292652
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);

lib/Demangling/Remangler.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,13 +2116,27 @@ ManglingError Remangler::mangleNominalTypeDescriptor(Node *node,
21162116
return ManglingError::Success;
21172117
}
21182118

2119+
ManglingError Remangler::mangleNominalTypeDescriptorRecord(Node *node,
2120+
unsigned depth) {
2121+
RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1));
2122+
Buffer << "Hn";
2123+
return ManglingError::Success;
2124+
}
2125+
21192126
ManglingError Remangler::mangleOpaqueTypeDescriptor(Node *node,
21202127
unsigned depth) {
21212128
RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1));
21222129
Buffer << "MQ";
21232130
return ManglingError::Success;
21242131
}
21252132

2133+
ManglingError Remangler::mangleOpaqueTypeDescriptorRecord(Node *node,
2134+
unsigned depth) {
2135+
RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1));
2136+
Buffer << "Ho";
2137+
return ManglingError::Success;
2138+
}
2139+
21262140
ManglingError Remangler::mangleOpaqueTypeDescriptorAccessor(Node *node,
21272141
unsigned depth) {
21282142
RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1));
@@ -2419,6 +2433,13 @@ ManglingError Remangler::mangleProtocolDescriptor(Node *node, unsigned depth) {
24192433
return ManglingError::Success;
24202434
}
24212435

2436+
ManglingError Remangler::mangleProtocolDescriptorRecord(Node *node,
2437+
unsigned depth) {
2438+
RETURN_IF_ERROR(manglePureProtocol(getSingleChild(node), depth + 1));
2439+
Buffer << "Hr";
2440+
return ManglingError::Success;
2441+
}
2442+
24222443
ManglingError
24232444
Remangler::mangleProtocolRequirementsBaseDescriptor(Node *node,
24242445
unsigned depth) {
@@ -2441,6 +2462,14 @@ ManglingError Remangler::mangleProtocolConformanceDescriptor(Node *node,
24412462
return ManglingError::Success;
24422463
}
24432464

2465+
ManglingError
2466+
Remangler::mangleProtocolConformanceDescriptorRecord(Node *node,
2467+
unsigned depth) {
2468+
RETURN_IF_ERROR(mangleProtocolConformance(node->getChild(0), depth + 1));
2469+
Buffer << "Hc";
2470+
return ManglingError::Success;
2471+
}
2472+
24442473
ManglingError Remangler::mangleProtocolList(Node *node, Node *superclass,
24452474
bool hasExplicitAnyObject,
24462475
unsigned depth) {

lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1931,6 +1931,10 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
19311931
Opts.WitnessMethodElimination = true;
19321932
}
19331933

1934+
if (Args.hasArg(OPT_conditional_runtime_records)) {
1935+
Opts.ConditionalRuntimeRecords = true;
1936+
}
1937+
19341938
if (Args.hasArg(OPT_internalize_at_link)) {
19351939
Opts.InternalizeAtLink = true;
19361940
}

0 commit comments

Comments
 (0)