Skip to content

Commit 8a38738

Browse files
committedJan 18, 2023
IRGen: Initial support for relative protocol witness table emission
1 parent 9e4f9f7 commit 8a38738

12 files changed

+662
-29
lines changed
 

‎include/swift/AST/IRGenOptions.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,9 @@ class IRGenOptions {
422422
/// Collocate metadata functions in their own section.
423423
unsigned CollocatedMetadataFunctions : 1;
424424

425+
/// Use relative (and constant) protocol witness tables.
426+
unsigned UseRelativeProtocolWitnessTables : 1;
427+
425428
/// The number of threads for multi-threaded code generation.
426429
unsigned NumThreads = 0;
427430

@@ -493,7 +496,8 @@ class IRGenOptions {
493496
InternalizeAtLink(false), InternalizeSymbols(false),
494497
EmitGenericRODatas(false), NoPreallocatedInstantiationCaches(false),
495498
DisableReadonlyStaticObjects(false),
496-
CollocatedMetadataFunctions(false), CmdArgs(),
499+
CollocatedMetadataFunctions(false),
500+
UseRelativeProtocolWitnessTables(false), CmdArgs(),
497501
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
498502
TypeInfoFilter(TypeInfoDumpFilter::All) {
499503
#ifndef NDEBUG

‎include/swift/Option/FrontendOptions.td

+7
Original file line numberDiff line numberDiff line change
@@ -1119,6 +1119,13 @@ def disable_collocate_metadata_functions :
11191119
Flag<["-"], "disable-collocate-metadata-functions">,
11201120
HelpText<"Disable collocate metadata functions">;
11211121

1122+
def enable_relative_protocol_witness_tables :
1123+
Flag<["-"], "enable-relative-protocol-witness-tables">,
1124+
HelpText<"Enable relative protocol witness tables">;
1125+
def disable_relative_protocol_witness_tables :
1126+
Flag<["-"], "disable-relative-protocol-witness-tables">,
1127+
HelpText<"Disable relative protocol witness tables">;
1128+
11221129
def enable_new_llvm_pass_manager :
11231130
Flag<["-"], "enable-new-llvm-pass-manager">,
11241131
HelpText<"Enable the new llvm pass manager">;

‎include/swift/Runtime/Metadata.h

+20
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,11 @@ swift_getWitnessTable(const ProtocolConformanceDescriptor *conformance,
354354
const Metadata *type,
355355
const void * const *instantiationArgs);
356356

357+
const WitnessTable *
358+
swift_getWitnessTableRelative(const ProtocolConformanceDescriptor *conformance,
359+
const Metadata *type,
360+
const void * const *instantiationArgs);
361+
357362
/// Retrieve an associated type witness from the given witness table.
358363
///
359364
/// \param wtable The witness table.
@@ -369,6 +374,13 @@ MetadataResponse swift_getAssociatedTypeWitness(
369374
const Metadata *conformingType,
370375
const ProtocolRequirement *reqBase,
371376
const ProtocolRequirement *assocType);
377+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
378+
MetadataResponse swift_getAssociatedTypeWitnessRelative(
379+
MetadataRequest request,
380+
WitnessTable *wtable,
381+
const Metadata *conformingType,
382+
const ProtocolRequirement *reqBase,
383+
const ProtocolRequirement *assocType);
372384

373385
/// Retrieve an associated conformance witness table from the given witness
374386
/// table.
@@ -388,6 +400,14 @@ const WitnessTable *swift_getAssociatedConformanceWitness(
388400
const ProtocolRequirement *reqBase,
389401
const ProtocolRequirement *assocConformance);
390402

403+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
404+
const WitnessTable *swift_getAssociatedConformanceWitnessRelative(
405+
WitnessTable *wtable,
406+
const Metadata *conformingType,
407+
const Metadata *assocType,
408+
const ProtocolRequirement *reqBase,
409+
const ProtocolRequirement *assocConformance);
410+
391411
/// Determine whether two protocol conformance descriptors describe the same
392412
/// conformance of a type to a protocol.
393413
///

‎include/swift/Runtime/RuntimeFunctions.def

+27
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,13 @@ FUNCTION(GetWitnessTable, swift_getWitnessTable, C_CC, AlwaysAvailable,
907907
WitnessTablePtrPtrTy),
908908
ATTRS(NoUnwind, ReadOnly),
909909
EFFECT(MetaData)) // ?
910+
FUNCTION(GetWitnessTableRelative, swift_getWitnessTableRelative, C_CC, AlwaysAvailable,
911+
RETURNS(WitnessTablePtrTy),
912+
ARGS(ProtocolConformanceDescriptorPtrTy,
913+
TypeMetadataPtrTy,
914+
WitnessTablePtrPtrTy),
915+
ATTRS(NoUnwind, ReadOnly),
916+
EFFECT(MetaData)) // ?
910917

911918
// MetadataResponse swift_getAssociatedTypeWitness(
912919
// MetadataRequest request,
@@ -924,6 +931,16 @@ FUNCTION(GetAssociatedTypeWitness, swift_getAssociatedTypeWitness,
924931
ProtocolRequirementStructTy->getPointerTo()),
925932
ATTRS(NoUnwind, ReadNone, WillReturn),
926933
EFFECT(MetaData)) // ?
934+
FUNCTION(GetAssociatedTypeWitnessRelative, swift_getAssociatedTypeWitnessRelative,
935+
SwiftCC, AlwaysAvailable,
936+
RETURNS(TypeMetadataResponseTy),
937+
ARGS(SizeTy,
938+
WitnessTablePtrTy,
939+
TypeMetadataPtrTy,
940+
ProtocolRequirementStructTy->getPointerTo(),
941+
ProtocolRequirementStructTy->getPointerTo()),
942+
ATTRS(NoUnwind, ReadNone, WillReturn),
943+
EFFECT(MetaData)) // ?
927944

928945
// SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
929946
// const WitnessTable *swift_getAssociatedConformanceWitness(
@@ -942,6 +959,16 @@ FUNCTION(GetAssociatedConformanceWitness,
942959
ProtocolRequirementStructTy->getPointerTo()),
943960
ATTRS(NoUnwind, ReadNone, WillReturn),
944961
EFFECT(MetaData)) // ?
962+
FUNCTION(GetAssociatedConformanceWitnessRelative,
963+
swift_getAssociatedConformanceWitnessRelative, SwiftCC, AlwaysAvailable,
964+
RETURNS(WitnessTablePtrTy),
965+
ARGS(WitnessTablePtrTy,
966+
TypeMetadataPtrTy,
967+
TypeMetadataPtrTy,
968+
ProtocolRequirementStructTy->getPointerTo(),
969+
ProtocolRequirementStructTy->getPointerTo()),
970+
ATTRS(NoUnwind, ReadNone, WillReturn),
971+
EFFECT(MetaData)) // ?
945972

946973
// SWIFT_RUNTIME_EXPORT
947974
// SWIFT_CC(swift) bool swift_compareProtocolConformanceDescriptors(

‎lib/Frontend/CompilerInvocation.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -2482,6 +2482,10 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
24822482
Args.hasFlag(OPT_enable_collocate_metadata_functions,
24832483
OPT_disable_collocate_metadata_functions,
24842484
Opts.CollocatedMetadataFunctions);
2485+
Opts.UseRelativeProtocolWitnessTables =
2486+
Args.hasFlag(OPT_enable_relative_protocol_witness_tables,
2487+
OPT_disable_relative_protocol_witness_tables,
2488+
Opts.UseRelativeProtocolWitnessTables);
24852489
return false;
24862490
}
24872491

‎lib/IRGen/GenOpaque.cpp

+17-2
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,20 @@ llvm::PointerType *IRGenModule::getEnumValueWitnessTablePtrTy() {
308308

309309
Address irgen::slotForLoadOfOpaqueWitness(IRGenFunction &IGF,
310310
llvm::Value *table,
311-
WitnessIndex index) {
311+
WitnessIndex index,
312+
bool areEntriesRelative) {
312313
assert(table->getType() == IGF.IGM.WitnessTablePtrTy);
313314

315+
// Are we loading from a relative protocol witness table.
316+
if (areEntriesRelative) {
317+
llvm::Value *slot =
318+
IGF.Builder.CreateBitOrPointerCast(table, IGF.IGM.RelativeAddressPtrTy);
319+
if (index.getValue() != 0)
320+
slot = IGF.Builder.CreateConstInBoundsGEP1_32(IGF.IGM.RelativeAddressTy,
321+
slot, index.getValue());
322+
return Address(slot, IGF.IGM.RelativeAddressTy, Alignment(4));
323+
}
324+
314325
// GEP to the appropriate index, avoiding spurious IR in the trivial case.
315326
llvm::Value *slot = table;
316327
if (index.getValue() != 0)
@@ -326,8 +337,12 @@ llvm::Value *irgen::emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF,
326337
llvm::Value *table,
327338
WitnessIndex index,
328339
llvm::Value **slotPtr) {
329-
auto slot = slotForLoadOfOpaqueWitness(IGF, table, index);
340+
auto isRelativeTable = IGF.IGM.IRGen.Opts.UseRelativeProtocolWitnessTables;
341+
auto slot = slotForLoadOfOpaqueWitness(IGF, table, index, isRelativeTable);
330342
if (slotPtr) *slotPtr = slot.getAddress();
343+
if (isRelativeTable) {
344+
return IGF.emitLoadOfRelativePointer(slot, false, IGF.IGM.Int8Ty);
345+
}
331346
return IGF.emitInvariantLoad(slot);
332347
}
333348

‎lib/IRGen/GenOpaque.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,11 @@ namespace irgen {
4040

4141
/// Given a witness table (protocol or value), return the address of the slot
4242
/// for one of the witnesses.
43+
/// If \p areEntriesRelative is true we are emitting code for a relative
44+
/// protocol witness table.
4345
Address slotForLoadOfOpaqueWitness(IRGenFunction &IGF, llvm::Value *table,
44-
WitnessIndex index);
46+
WitnessIndex index,
47+
bool areEntriesRelative = false);
4548

4649
/// Given a witness table (protocol or value), load one of the
4750
/// witnesses.

0 commit comments

Comments
 (0)
Please sign in to comment.