Skip to content

Commit 83bf9dd

Browse files
authored
Merge pull request #20040 from DougGregor/remove-witness-table-accessor
[ABI] Eliminate witness table accessors.
2 parents dfb01b6 + 6abc848 commit 83bf9dd

36 files changed

+194
-578
lines changed

docs/ABI/Mangling.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ Globals
128128

129129
global ::= protocol-conformance 'Mc' // protocol conformance descriptor
130130
global ::= protocol-conformance 'WP' // protocol witness table
131-
global ::= protocol-conformance 'Wa' // protocol witness table accessor
131+
global ::= protocol-conformance 'Wa' // protocol witness table accessor (HISTORICAL)
132132

133133
global ::= protocol-conformance 'WG' // generic protocol witness table (HISTORICAL)
134134
global ::= protocol-conformance 'Wp' // protocol witness table pattern

include/swift/ABI/Metadata.h

+20-53
Original file line numberDiff line numberDiff line change
@@ -2013,13 +2013,10 @@ struct TargetGenericWitnessTable {
20132013
/// to require instantiation.
20142014
uint16_t WitnessTablePrivateSizeInWordsAndRequiresInstantiation;
20152015

2016-
/// The pattern.
2017-
RelativeDirectPointer<const TargetWitnessTable<Runtime>> Pattern;
2018-
20192016
/// The instantiation function, which is called after the template is copied.
20202017
RelativeDirectPointer<void(TargetWitnessTable<Runtime> *instantiatedTable,
20212018
const TargetMetadata<Runtime> *type,
2022-
void ** const *instantiationArgs),
2019+
const void * const *instantiationArgs),
20232020
/*nullable*/ true> Instantiator;
20242021

20252022
using PrivateDataType = void *[swift::NumGenericMetadataPrivateDataWords];
@@ -2036,18 +2033,6 @@ struct TargetGenericWitnessTable {
20362033
uint16_t requiresInstantiation() const {
20372034
return WitnessTablePrivateSizeInWordsAndRequiresInstantiation & 0x01;
20382035
}
2039-
2040-
/// Retrieve the protocol conformance descriptor.
2041-
ConstTargetPointer<Runtime, TargetProtocolConformanceDescriptor<Runtime>>
2042-
getConformance() const {
2043-
return Pattern->Description;
2044-
}
2045-
2046-
/// Retrieve the protocol.
2047-
ConstTargetPointer<Runtime, TargetProtocolDescriptor<Runtime>>
2048-
getProtocol() const {
2049-
return Pattern->Description->getProtocol();
2050-
}
20512036
};
20522037
using GenericWitnessTable = TargetGenericWitnessTable<InProcess>;
20532038

@@ -2279,15 +2264,8 @@ struct TargetProtocolConformanceDescriptor final
22792264
// Some description of the type that conforms to the protocol.
22802265
TargetTypeReference<Runtime> TypeRef;
22812266

2282-
// The conformance, or a generator function for the conformance.
2283-
union {
2284-
/// A direct reference to the witness table for the conformance.
2285-
RelativeDirectPointer<const TargetWitnessTable<Runtime>> WitnessTable;
2286-
2287-
/// A function that produces the witness table given an instance of the
2288-
/// type.
2289-
RelativeDirectPointer<WitnessTableAccessorFn> WitnessTableAccessor;
2290-
};
2267+
/// The witness table pattern, which may also serve as the witness table.
2268+
RelativeDirectPointer<const TargetWitnessTable<Runtime>> WitnessTablePattern;
22912269

22922270
/// Various flags, including the kind of conformance.
22932271
ConformanceFlags Flags;
@@ -2302,10 +2280,6 @@ struct TargetProtocolConformanceDescriptor final
23022280
return Flags.getTypeReferenceKind();
23032281
}
23042282

2305-
typename ConformanceFlags::ConformanceKind getConformanceKind() const {
2306-
return Flags.getConformanceKind();
2307-
}
2308-
23092283
const char *getDirectObjCClassName() const {
23102284
return TypeRef.getDirectObjCClassName(getTypeKind());
23112285
}
@@ -2325,6 +2299,18 @@ struct TargetProtocolConformanceDescriptor final
23252299
return this->template getTrailingObjects<RelativeContextPointer<Runtime>>();
23262300
}
23272301

2302+
/// Whether this conformance is non-unique because it has been synthesized
2303+
/// for a foreign type.
2304+
bool isSynthesizedNonUnique() const {
2305+
return Flags.isSynthesizedNonUnique();
2306+
}
2307+
2308+
/// Whether this conformance has any conditional requirements that need to
2309+
/// be evaluated.
2310+
bool hasConditionalRequirements() const {
2311+
return Flags.getNumConditionalRequirements() > 0;
2312+
}
2313+
23282314
/// Retrieve the conditional requirements that must also be
23292315
/// satisfied
23302316
llvm::ArrayRef<GenericRequirementDescriptor>
@@ -2333,31 +2319,12 @@ struct TargetProtocolConformanceDescriptor final
23332319
Flags.getNumConditionalRequirements()};
23342320
}
23352321

2336-
/// Get the directly-referenced static witness table.
2337-
const swift::TargetWitnessTable<Runtime> *getStaticWitnessTable() const {
2338-
switch (getConformanceKind()) {
2339-
case ConformanceFlags::ConformanceKind::WitnessTable:
2340-
break;
2341-
2342-
case ConformanceFlags::ConformanceKind::WitnessTableAccessor:
2343-
case ConformanceFlags::ConformanceKind::ConditionalWitnessTableAccessor:
2344-
assert(false && "not witness table");
2345-
}
2346-
return WitnessTable;
2322+
/// Get the directly-referenced witness table pattern, which may also
2323+
/// serve as the witness table.
2324+
const swift::TargetWitnessTable<Runtime> *getWitnessTablePattern() const {
2325+
return WitnessTablePattern;
23472326
}
2348-
2349-
WitnessTableAccessorFn *getWitnessTableAccessor() const {
2350-
switch (getConformanceKind()) {
2351-
case ConformanceFlags::ConformanceKind::WitnessTableAccessor:
2352-
case ConformanceFlags::ConformanceKind::ConditionalWitnessTableAccessor:
2353-
break;
2354-
2355-
case ConformanceFlags::ConformanceKind::WitnessTable:
2356-
assert(false && "not witness table accessor");
2357-
}
2358-
return WitnessTableAccessor;
2359-
}
2360-
2327+
23612328
/// Get the canonical metadata for the type referenced by this record, or
23622329
/// return null if the record references a generic or universal type.
23632330
const TargetMetadata<Runtime> *getCanonicalTypeMetadata() const;

include/swift/ABI/MetadataValues.h

+1-25
Original file line numberDiff line numberDiff line change
@@ -600,24 +600,9 @@ class ConformanceFlags {
600600
public:
601601
typedef uint32_t int_type;
602602

603-
enum class ConformanceKind {
604-
/// A direct reference to a protocol witness table.
605-
WitnessTable,
606-
/// A function pointer that can be called to access the protocol witness
607-
/// table.
608-
WitnessTableAccessor,
609-
/// A function pointer that can be called to access the protocol witness
610-
/// table whose conformance is conditional on additional requirements that
611-
/// must first be evaluated and then provided to the accessor function.
612-
ConditionalWitnessTableAccessor,
613-
614-
First_Kind = WitnessTable,
615-
Last_Kind = ConditionalWitnessTableAccessor,
616-
};
617-
618603
private:
619604
enum : int_type {
620-
ConformanceKindMask = 0x07, // 8 conformance kinds
605+
UnusedLowBits = 0x07, // historical conformance kind
621606

622607
TypeMetadataKindMask = 0x7 << 3, // 8 type reference kinds
623608
TypeMetadataKindShift = 3,
@@ -637,10 +622,6 @@ class ConformanceFlags {
637622
public:
638623
ConformanceFlags(int_type value = 0) : Value(value) {}
639624

640-
ConformanceFlags withConformanceKind(ConformanceKind kind) const {
641-
return ConformanceFlags((Value & ~ConformanceKindMask) | int_type(kind));
642-
}
643-
644625
ConformanceFlags withTypeReferenceKind(TypeReferenceKind kind) const {
645626
return ConformanceFlags((Value & ~TypeMetadataKindMask)
646627
| (int_type(kind) << TypeMetadataKindShift));
@@ -677,11 +658,6 @@ class ConformanceFlags {
677658
: 0));
678659
}
679660

680-
/// Retrieve the conformance kind.
681-
ConformanceKind getConformanceKind() const {
682-
return ConformanceKind(Value & ConformanceKindMask);
683-
}
684-
685661
/// Retrieve the type reference kind kind.
686662
TypeReferenceKind getTypeReferenceKind() const {
687663
return TypeReferenceKind(

include/swift/AST/ProtocolConformance.h

-4
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,6 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance {
258258
/// Get the substitutions associated with this conformance.
259259
SubstitutionMap getSubstitutions(ModuleDecl *M) const;
260260

261-
/// Determine whether the witness table access function for this conformance
262-
/// needs to be passed information when called, or if it stands alone.
263-
bool witnessTableAccessorRequiresArguments() const;
264-
265261
/// Get the underlying normal conformance.
266262
const NormalProtocolConformance *getRootNormalConformance() const;
267263

include/swift/IRGen/Linking.h

-12
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,6 @@ class LinkEntity {
244244
/// ProtocolConformance*.
245245
ProtocolWitnessTablePattern,
246246

247-
/// A witness accessor function. The secondary pointer is a
248-
/// ProtocolConformance*.
249-
ProtocolWitnessTableAccessFunction,
250-
251247
/// The instantiation function for a generic protocol witness table.
252248
/// The secondary pointer is a ProtocolConformance*.
253249
GenericProtocolWitnessTableInstantiationFunction,
@@ -727,14 +723,6 @@ class LinkEntity {
727723
return entity;
728724
}
729725

730-
static LinkEntity
731-
forProtocolWitnessTableAccessFunction(const ProtocolConformance *C) {
732-
LinkEntity entity;
733-
entity.setForProtocolConformance(Kind::ProtocolWitnessTableAccessFunction,
734-
C);
735-
return entity;
736-
}
737-
738726
static LinkEntity
739727
forGenericProtocolWitnessTableInstantiationFunction(
740728
const ProtocolConformance *C) {

include/swift/Runtime/Metadata.h

+6-18
Original file line numberDiff line numberDiff line change
@@ -385,18 +385,13 @@ SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
385385
MetadataResponse swift_checkMetadataState(MetadataRequest request,
386386
const Metadata *type);
387387

388-
/// Instantiate a resilient or generic protocol witness table.
388+
/// Retrieve a witness table based on a given conformance.
389389
///
390390
/// \param conformance - The protocol conformance descriptor, which
391-
/// contains the generic witness table record. It may either have fields
392-
/// that require runtime initialization, or be missing requirements at the
393-
/// end for which default witnesses are available.
391+
/// contains any information required to form the witness table.
394392
///
395393
/// \param type - The conforming type, used to form a uniquing key
396-
/// for the conformance. If the witness table is not dependent on
397-
/// the substituted type of the conformance, this can be set to
398-
/// nullptr, in which case there will only be one instantiated
399-
/// witness table per witness table template.
394+
/// for the conformance.
400395
///
401396
/// \param instantiationArgs - An opaque pointer that's forwarded to
402397
/// the instantiation function, used for conditional conformances.
@@ -406,9 +401,9 @@ MetadataResponse swift_checkMetadataState(MetadataRequest request,
406401
/// conformances.
407402
SWIFT_RUNTIME_EXPORT
408403
const WitnessTable *
409-
swift_instantiateWitnessTable(ProtocolConformanceDescriptor *conformance,
410-
const Metadata *type,
411-
void **const *instantiationArgs);
404+
swift_getWitnessTable(const ProtocolConformanceDescriptor *conformance,
405+
const Metadata *type,
406+
const void * const *instantiationArgs);
412407

413408
/// Retrieve an associated type witness from the given witness table.
414409
///
@@ -490,13 +485,6 @@ MetadataResponse
490485
swift_getForeignTypeMetadata(MetadataRequest request,
491486
ForeignTypeMetadata *nonUnique);
492487

493-
/// \brief Fetch a unique witness table for a foreign witness table.
494-
SWIFT_RUNTIME_EXPORT
495-
const WitnessTable *
496-
swift_getForeignWitnessTable(const WitnessTable *nonUniqueWitnessCandidate,
497-
const TypeContextDescriptor *forForeignType,
498-
const ProtocolDescriptor *forProtocol);
499-
500488
/// \brief Fetch a uniqued metadata for a tuple type.
501489
///
502490
/// The labels argument is null if and only if there are no element

include/swift/Runtime/RuntimeFunctions.def

+4-14
Original file line numberDiff line numberDiff line change
@@ -585,16 +585,6 @@ FUNCTION(GetForeignTypeMetadata, swift_getForeignTypeMetadata, SwiftCC,
585585
ARGS(SizeTy, TypeMetadataPtrTy),
586586
ATTRS(NoUnwind, ReadNone)) // only writes to runtime-private fields
587587

588-
// WitnessTable *swift_getForeignWitnessTable(
589-
// const WitnessTable *candidate,
590-
// const TypeContextDescriptor *forType,
591-
// const ProtocolDescriptor *forProtocol);
592-
FUNCTION(GetForeignWitnessTable, swift_getForeignWitnessTable, C_CC,
593-
RETURNS(WitnessTablePtrTy),
594-
ARGS(WitnessTablePtrTy, TypeContextDescriptorPtrTy,
595-
ProtocolDescriptorPtrTy),
596-
ATTRS(NoUnwind, ReadNone))
597-
598588
// MetadataResponse swift_getSingletonMetadata(MetadataRequest request,
599589
// TypeContextDescriptor *type);
600590
FUNCTION(GetSingletonMetadata, swift_getSingletonMetadata, SwiftCC,
@@ -635,10 +625,10 @@ FUNCTION(CheckMetadataState, swift_checkMetadataState, SwiftCC,
635625
ATTRS(NoUnwind, ReadOnly))
636626

637627
// const ProtocolWitnessTable *
638-
// swift_instantiateWitnessTable(const ProtocolConformanceDescriptor *conf,
639-
// const Metadata *type,
640-
// void ** const *instantiationArgs);
641-
FUNCTION(InstantiateWitnessTable, swift_instantiateWitnessTable, C_CC,
628+
// swift_getWitnessTable(const ProtocolConformanceDescriptor *conf,
629+
// const Metadata *type,
630+
// const void * const *instantiationArgs);
631+
FUNCTION(GetWitnessTable, swift_getWitnessTable, C_CC,
642632
RETURNS(WitnessTablePtrTy),
643633
ARGS(ProtocolConformanceDescriptorPtrTy,
644634
TypeMetadataPtrTy,

lib/AST/ProtocolConformance.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -1079,10 +1079,6 @@ ProtocolConformance::getRootNormalConformance() const {
10791079
return cast<NormalProtocolConformance>(C);
10801080
}
10811081

1082-
bool ProtocolConformance::witnessTableAccessorRequiresArguments() const {
1083-
return getRootNormalConformance()->getDeclContext()->isGenericContext();
1084-
}
1085-
10861082
bool ProtocolConformance::isVisibleFrom(const DeclContext *dc) const {
10871083
// FIXME: Implement me!
10881084
return true;

lib/IRGen/GenDecl.cpp

-30
Original file line numberDiff line numberDiff line change
@@ -3643,36 +3643,6 @@ IRGenModule::getAddrOfGenericWitnessTableInstantiationFunction(
36433643
return entry;
36443644
}
36453645

3646-
/// Fetch the witness table access function for a protocol conformance.
3647-
llvm::Function *
3648-
IRGenModule::getAddrOfWitnessTableAccessFunction(
3649-
const NormalProtocolConformance *conf,
3650-
ForDefinition_t forDefinition) {
3651-
IRGen.addLazyWitnessTable(conf);
3652-
3653-
LinkEntity entity = LinkEntity::forProtocolWitnessTableAccessFunction(conf);
3654-
llvm::Function *&entry = GlobalFuncs[entity];
3655-
if (entry) {
3656-
if (forDefinition) updateLinkageForDefinition(*this, entry, entity);
3657-
return entry;
3658-
}
3659-
3660-
llvm::FunctionType *fnType;
3661-
if (conf->witnessTableAccessorRequiresArguments()) {
3662-
// conditional requirements are passed indirectly, as an array of witness
3663-
// tables.
3664-
fnType = llvm::FunctionType::get(
3665-
WitnessTablePtrTy, {TypeMetadataPtrTy, WitnessTablePtrPtrTy}, false);
3666-
} else {
3667-
fnType = llvm::FunctionType::get(WitnessTablePtrTy, false);
3668-
}
3669-
3670-
Signature signature(fnType, llvm::AttributeList(), DefaultCC);
3671-
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
3672-
entry = createFunction(*this, link, signature);
3673-
return entry;
3674-
}
3675-
36763646
/// Fetch the lazy witness table access function for a protocol conformance.
36773647
llvm::Function *
36783648
IRGenModule::getAddrOfWitnessTableLazyAccessFunction(

0 commit comments

Comments
 (0)