Skip to content

Commit bfd2230

Browse files
committed
[Runtime] Eliminate ProtocolConformanceFlags.
Eliminate the separate flags field in protocol conformance records, now that all of the information is stored in spare bits elsewhere. Reserve this 32-bit value for future use to describe conditional requirements.
1 parent aee0c68 commit bfd2230

File tree

5 files changed

+37
-40
lines changed

5 files changed

+37
-40
lines changed

docs/ABI/TypeMetadata.rst

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -418,22 +418,23 @@ a `swift_conformsToProtocol()` query). Each protocol conformance record
418418
contains:
419419

420420
- The `protocol descriptor`_ describing the protocol of the conformance,
421-
represented as an indirect 32-bit offset relative to the field.
422-
- A reference to the metadata for the **conforming type**, represented as
423-
an indirect 32-bit offset relative to the field, whose form is
424-
determined by the **protocol conformance flags** described below.
421+
represented as an (possibly indirect) 32-bit offset relative to the field.
422+
The low bit indicates whether it is an indirect offset; the second lowest
423+
bit is reserved for future use.
424+
- A reference to the **conforming type**, represented as a 32-bit offset
425+
relative to the field. The lower two bits indicate how the conforming
426+
type is represented:
427+
0. A direct reference to a nominal type descriptor.
428+
1. An indirect reference to a nominal type descriptor.
429+
2. A reference to nonunique, foreign type metadata.
430+
3. A reference to a pointer to an Objective-C class object.
425431
- The **witness table field** that provides access to the witness table
426-
describing the conformance itself; the form of this field is determined by
427-
the lower two bits, and can be one of:
432+
describing the conformance itself, represented as a direct 32-bit relative
433+
offset. The lower two bits indicate how the witness table is represented:
428434
0. The **witness table field** is a reference to a witness table.
429435
1. The **witness table field** is a reference to a **witness table
430436
accessor** function for an unconditional conformance.
431437
2. The **witness table field** is a reference to a **witness table
432438
accessor** function for a conditional conformance.
433439
3. Reserved for future use.
434-
All references are direct 32-bit offsets relative to the field.
435-
- The **protocol conformance flags** is a 32-bit field comprised of:
436-
437-
* **Bits 0-3** contain the type metadata record kind, which indicates how
438-
the **conforming type** field is encoded.
439-
440+
- A 32-bit value reserved for future use.

include/swift/Runtime/Metadata.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2566,9 +2566,9 @@ struct TargetProtocolConformanceRecord {
25662566
ProtocolConformanceReferenceKind>
25672567
WitnessTableAccessor;
25682568
};
2569-
2570-
/// Flags describing the protocol conformance.
2571-
ProtocolConformanceFlags UnusedFlags;
2569+
2570+
/// Reserved word.
2571+
unsigned Reserved;
25722572

25732573
public:
25742574
const ProtocolDescriptor *getProtocol() const {

lib/IRGen/GenDecl.cpp

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,19 +2189,16 @@ IRGenModule::getAddrOfLLVMVariableOrGOTEquivalent(LinkEntity entity,
21892189

21902190
namespace {
21912191
struct TypeEntityInfo {
2192-
ProtocolConformanceFlags flags;
2192+
TypeMetadataRecordKind typeKind;
21932193
LinkEntity entity;
21942194
llvm::Type *defaultTy, *defaultPtrTy;
21952195

21962196
/// Adjust the flags once we know whether the reference to this entity
21972197
/// will be indirect.
21982198
void adjustForKnownRef(ConstantReference &ref) {
21992199
if (ref.isIndirect() &&
2200-
flags.getTypeKind()
2201-
== TypeMetadataRecordKind::DirectNominalTypeDescriptor) {
2202-
flags = flags.withTypeKind(
2203-
TypeMetadataRecordKind::IndirectNominalTypeDescriptor);
2204-
}
2200+
typeKind == TypeMetadataRecordKind::DirectNominalTypeDescriptor)
2201+
typeKind = TypeMetadataRecordKind::IndirectNominalTypeDescriptor;
22052202
}
22062203
};
22072204
} // end anonymous namespace
@@ -2243,9 +2240,7 @@ getTypeEntityInfo(IRGenModule &IGM, CanType conformingType) {
22432240
defaultPtrTy = IGM.TypeMetadataPtrTy;
22442241
}
22452242

2246-
auto flags = ProtocolConformanceFlags().withTypeKind(typeKind);
2247-
2248-
return {flags, *entity, defaultTy, defaultPtrTy};
2243+
return {typeKind, *entity, defaultTy, defaultPtrTy};
22492244
}
22502245

22512246
/// Form an LLVM constant for the relative distance between a reference
@@ -2334,10 +2329,9 @@ llvm::Constant *IRGenModule::emitProtocolConformances() {
23342329
typeEntity.adjustForKnownRef(typeRef);
23352330
record.addTaggedRelativeOffset(RelativeAddressTy,
23362331
typeRef.getValue(),
2337-
typeEntity.flags.getValue());
2332+
static_cast<unsigned>(typeEntity.typeKind));
23382333

23392334
// Figure out what kind of witness table we have.
2340-
auto flags = typeEntity.flags;
23412335
llvm::Constant *witnessTableVar;
23422336
ProtocolConformanceReferenceKind conformanceKind;
23432337

@@ -2367,8 +2361,8 @@ llvm::Constant *IRGenModule::emitProtocolConformances() {
23672361
record.addTaggedRelativeOffset(RelativeAddressTy, witnessTableVar,
23682362
static_cast<unsigned>(conformanceKind));
23692363

2370-
// Flags.
2371-
record.addInt(Int32Ty, flags.getValue());
2364+
// Reserved.
2365+
record.addInt(Int32Ty, 0);
23722366

23732367
record.finishAndAddTo(recordsArray);
23742368
}
@@ -2377,7 +2371,7 @@ llvm::Constant *IRGenModule::emitProtocolConformances() {
23772371
// resolve relocations relative to it.
23782372

23792373
auto var = recordsArray.finishAndCreateGlobal("\x01l_protocol_conformances",
2380-
getPointerAlignment(),
2374+
Alignment(4),
23812375
/*isConstant*/ true,
23822376
llvm::GlobalValue::PrivateLinkage);
23832377

@@ -2447,7 +2441,8 @@ llvm::Constant *IRGenModule::emitTypeMetadataRecords() {
24472441
unsigned arrayIdx = elts.size();
24482442
llvm::Constant *recordFields[] = {
24492443
emitRelativeReference(typeRef, var, { arrayIdx, 0 }),
2450-
llvm::ConstantInt::get(Int32Ty, typeEntity.flags.getValue()),
2444+
llvm::ConstantInt::get(Int32Ty,
2445+
static_cast<unsigned>(typeEntity.typeKind)),
24512446
};
24522447

24532448
auto record = llvm::ConstantStruct::get(TypeMetadataRecordTy,

test/IRGen/protocol_conformance_records.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public protocol Runcible {
1616
// CHECK-SAME: @_T028protocol_conformance_records15NativeValueTypeVMn
1717
// -- witness table
1818
// CHECK-SAME: @_T028protocol_conformance_records15NativeValueTypeVAA8RuncibleAAWP
19-
// -- flags 0x00: direct nominal type descriptor
19+
// -- reserved
2020
// CHECK-SAME: i32 0
2121
// CHECK-SAME: },
2222
public struct NativeValueType: Runcible {
@@ -30,7 +30,7 @@ public struct NativeValueType: Runcible {
3030
// CHECK-SAME: @_T028protocol_conformance_records15NativeClassTypeCMn
3131
// -- witness table
3232
// CHECK-SAME: @_T028protocol_conformance_records15NativeClassTypeCAA8RuncibleAAWP
33-
// -- flags 0x00: direct nominal type descriptor
33+
// -- reserved
3434
// CHECK-SAME: i32 0
3535
// CHECK-SAME: },
3636
public class NativeClassType: Runcible {
@@ -44,7 +44,7 @@ public class NativeClassType: Runcible {
4444
// CHECK-SAME: @_T028protocol_conformance_records17NativeGenericTypeVMn
4545
// -- witness table
4646
// CHECK-SAME: @_T028protocol_conformance_records17NativeGenericTypeVyxGAA8RuncibleAAWP
47-
// -- flags 0x00: direct nominal type descriptor
47+
// -- reserved
4848
// CHECK-SAME: i32 0
4949
// CHECK-SAME: },
5050
public struct NativeGenericType<T>: Runcible {
@@ -58,7 +58,7 @@ public struct NativeGenericType<T>: Runcible {
5858
// CHECK-SAME: @got._T0SiMn
5959
// -- witness table
6060
// CHECK-SAME: @_T0Si28protocol_conformance_records8RuncibleAAWP
61-
// -- flags 0x00: direct nominal type descriptor
61+
// -- reserved
6262
// CHECK-SAME: i32 0
6363
// CHECK-SAME: }
6464
extension Int: Runcible {
@@ -74,7 +74,7 @@ extension Int: Runcible {
7474
// CHECK-SAME: @got._T016resilient_struct4SizeVMn
7575
// -- witness table
7676
// CHECK-SAME: @_T016resilient_struct4SizeV28protocol_conformance_records8RuncibleADWP
77-
// -- flags 0x00: direct nominal type descriptor
77+
// -- reserved
7878
// CHECK-SAME: i32 0
7979
// CHECK-SAME: }
8080

@@ -93,7 +93,7 @@ public protocol Spoon { }
9393
// CHECK-SAME: @_T028protocol_conformance_records17NativeGenericTypeVMn
9494
// -- witness table accessor
9595
// CHECK-SAME: i32 add{{.*}}@_T028protocol_conformance_records17NativeGenericTypeVyxGAA5SpoonA2aERzlWa{{.*}}i32 2),
96-
// -- flags 0x00: direct nominal type descriptor
96+
// -- reserved
9797
// CHECK-SAME: i32 0
9898
// CHECK-SAME: }
9999
extension NativeGenericType : Spoon where T: Spoon {

test/IRGen/protocol_conformance_records_objc.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ public protocol Runcible {
2323
// CHECK: i32 2
2424
// -- witness table
2525
// CHECK: @_T0SC6NSRectV33protocol_conformance_records_objc8RuncibleACWP
26-
// -- flags 0x02: nonunique type metadata
27-
// CHECK: i32 2 },
26+
// -- reserved
27+
// CHECK: i32 0
28+
// CHECK: },
2829
extension NSRect: Runcible {
2930
public func runce() {}
3031
}
@@ -38,8 +39,8 @@ extension NSRect: Runcible {
3839
// CHECK: i32 3
3940
// -- witness table
4041
// CHECK: @_T0So5GizmoC33protocol_conformance_records_objc8RuncibleACWP
41-
// -- flags 0x03: indirect class object
42-
// CHECK: i32 3
42+
// -- reserved
43+
// CHECK: i32 0
4344
// CHECK: }
4445
extension Gizmo: Runcible {
4546
public func runce() {}

0 commit comments

Comments
 (0)