Skip to content

Commit e231ae1

Browse files
authored
Merge pull request #21240 from rjmccall/remove-xi-witnesses-5.0
[5.0] Remove the extra-inhabitant value witnesses
2 parents c786ca4 + 405e659 commit e231ae1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1750
-1447
lines changed

docs/Runtime.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,7 @@ optimization.
260260
0000000000023a40 T _swift_assignExistentialWithCopy
261261
000000000001dbf0 T _swift_copyPOD
262262
000000000001c560 T _swift_getEnumCaseMultiPayload
263-
000000000001be60 T _swift_getEnumCaseSinglePayload
264263
000000000001c400 T _swift_storeEnumTagMultiPayload
265-
000000000001bf90 T _swift_storeEnumTagSinglePayload
266264
```
267265

268266
## Type metadata lookup

include/swift/ABI/Metadata.h

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -295,10 +295,9 @@ class TargetValueWitnessTypes {
295295
// Handle the data witnesses explicitly so we can use more specific
296296
// types for the flags enums.
297297
typedef size_t size;
298-
typedef ValueWitnessFlags flags;
299298
typedef size_t stride;
300-
typedef ExtraInhabitantFlags extraInhabitantFlags;
301-
299+
typedef ValueWitnessFlags flags;
300+
typedef uint32_t extraInhabitantCount;
302301
};
303302

304303
struct TypeLayout;
@@ -376,16 +375,9 @@ template <typename Runtime> struct TargetValueWitnessTable {
376375

377376
/// The number of extra inhabitants, that is, bit patterns that do not form
378377
/// valid values of the type, in this type's binary representation.
379-
unsigned getNumExtraInhabitants() const;
380-
381-
/// Assert that this value witness table is an extra-inhabitants
382-
/// value witness table and return it as such.
383-
///
384-
/// This has an awful name because it's supposed to be internal to
385-
/// this file. Code outside this file should use LLVM's cast/dyn_cast.
386-
/// We don't want to use those here because we need to avoid accidentally
387-
/// introducing ABI dependencies on LLVM structures.
388-
const struct ExtraInhabitantsValueWitnessTable *_asXIVWT() const;
378+
unsigned getNumExtraInhabitants() const {
379+
return extraInhabitantCount;
380+
}
389381

390382
/// Assert that this value witness table is an enum value witness table
391383
/// and return it as such.
@@ -608,13 +600,6 @@ struct TargetMetadata {
608600
#define DATA_VALUE_WITNESS(LOWER, UPPER, TYPE)
609601
#include "swift/ABI/ValueWitness.def"
610602

611-
int vw_getExtraInhabitantIndex(const OpaqueValue *value) const {
612-
return getValueWitnesses()->_asXIVWT()->getExtraInhabitantIndex(value, this);
613-
}
614-
void vw_storeExtraInhabitant(OpaqueValue *value, int index) const {
615-
getValueWitnesses()->_asXIVWT()->storeExtraInhabitant(value, index, this);
616-
}
617-
618603
unsigned vw_getEnumTag(const OpaqueValue *value) const {
619604
return getValueWitnesses()->_asEVWT()->getEnumTag(const_cast<OpaqueValue*>(value), this);
620605
}
@@ -637,6 +622,10 @@ struct TargetMetadata {
637622
return getValueWitnesses()->getStride();
638623
}
639624

625+
unsigned vw_getNumExtraInhabitants() const {
626+
return getValueWitnesses()->getNumExtraInhabitants();
627+
}
628+
640629
/// Allocate an out-of-line buffer if values of this type don't fit in the
641630
/// ValueBuffer.
642631
/// NOTE: This is not a box for copy-on-write existentials.

include/swift/ABI/MetadataValues.h

Lines changed: 12 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -121,24 +121,27 @@ class TargetValueWitnessFlags {
121121
// flags of the field types can be mostly bitwise-or'ed together to derive the
122122
// flags for the struct. (The "non-inline" and "has-extra-inhabitants" bits
123123
// still require additional fixup.)
124-
enum : int_type {
124+
enum : uint32_t {
125125
AlignmentMask = 0x000000FF,
126+
// unused 0x0000FF00,
126127
IsNonPOD = 0x00010000,
127128
IsNonInline = 0x00020000,
128-
HasExtraInhabitants = 0x00040000,
129+
// unused 0x00040000,
129130
HasSpareBits = 0x00080000,
130131
IsNonBitwiseTakable = 0x00100000,
131132
HasEnumWitnesses = 0x00200000,
132133
Incomplete = 0x00400000,
133-
134-
// Everything else is reserved.
134+
// unused 0xFF800000,
135135
};
136136

137+
static constexpr const uint32_t MaxNumExtraInhabitants = 0x7FFFFFFF;
138+
137139
private:
138-
int_type Data;
140+
uint32_t Data;
141+
142+
explicit constexpr TargetValueWitnessFlags(uint32_t data) : Data(data) {}
139143

140144
public:
141-
explicit constexpr TargetValueWitnessFlags(int_type data) : Data(data) {}
142145
constexpr TargetValueWitnessFlags() : Data(0) {}
143146

144147
/// The required alignment of the first byte of an object of this
@@ -192,22 +195,12 @@ class TargetValueWitnessFlags {
192195
return TargetValueWitnessFlags((Data & ~IsNonBitwiseTakable) |
193196
(isBT ? 0 : IsNonBitwiseTakable));
194197
}
195-
/// True if this type's binary representation has extra inhabitants, that is,
196-
/// bit patterns that do not form valid values of the type.
197-
///
198-
/// If true, then the extra inhabitant value witness table entries are
199-
/// available in this type's value witness table.
200-
bool hasExtraInhabitants() const { return Data & HasExtraInhabitants; }
198+
201199
/// True if this type's binary representation is that of an enum, and the
202200
/// enum value witness table entries are available in this type's value
203201
/// witness table.
204202
bool hasEnumWitnesses() const { return Data & HasEnumWitnesses; }
205203
constexpr TargetValueWitnessFlags
206-
withExtraInhabitants(bool hasExtraInhabitants) const {
207-
return TargetValueWitnessFlags((Data & ~HasExtraInhabitants) |
208-
(hasExtraInhabitants ? HasExtraInhabitants : 0));
209-
}
210-
constexpr TargetValueWitnessFlags
211204
withEnumWitnesses(bool hasEnumWitnesses) const {
212205
return TargetValueWitnessFlags((Data & ~HasEnumWitnesses) |
213206
(hasEnumWitnesses ? HasEnumWitnesses : 0));
@@ -223,44 +216,12 @@ class TargetValueWitnessFlags {
223216
(isIncomplete ? Incomplete : 0));
224217
}
225218

226-
constexpr int_type getOpaqueValue() const { return Data; }
227-
static constexpr TargetValueWitnessFlags getFromOpaqueValue(int_type data) {
228-
return TargetValueWitnessFlags(data);
219+
constexpr uint32_t getOpaqueValue() const {
220+
return Data;
229221
}
230222
};
231223
using ValueWitnessFlags = TargetValueWitnessFlags<size_t>;
232224

233-
/// Flags stored in a value-witness table with extra inhabitants.
234-
template <typename int_type>
235-
class TargetExtraInhabitantFlags {
236-
public:
237-
enum : int_type {
238-
NumExtraInhabitantsMask = 0x7FFFFFFFU,
239-
ExtraInhabitantFlags
240-
};
241-
int_type Data;
242-
243-
constexpr TargetExtraInhabitantFlags(int_type data) : Data(data) {}
244-
245-
public:
246-
constexpr TargetExtraInhabitantFlags() : Data(0) {}
247-
/// The number of extra inhabitants in the type's representation.
248-
int getNumExtraInhabitants() const { return Data & NumExtraInhabitantsMask; }
249-
250-
constexpr TargetExtraInhabitantFlags
251-
withNumExtraInhabitants(unsigned numExtraInhabitants) const {
252-
return TargetExtraInhabitantFlags((Data & ~NumExtraInhabitantsMask) |
253-
numExtraInhabitants);
254-
}
255-
256-
constexpr int_type getOpaqueValue() const { return Data; }
257-
static constexpr TargetExtraInhabitantFlags getFromOpaqueValue(int_type data){
258-
return TargetExtraInhabitantFlags(data);
259-
}
260-
};
261-
using ExtraInhabitantFlags =
262-
TargetExtraInhabitantFlags<size_t>;
263-
264225
/// Flags for dynamic-cast operations.
265226
enum class DynamicCastFlags : size_t {
266227
/// All flags clear.

include/swift/ABI/ValueWitness.def

Lines changed: 24 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -23,39 +23,27 @@
2323
#if defined(WANT_ALL_VALUE_WITNESSES)
2424
#undef WANT_ALL_VALUE_WITNESSES
2525
#define WANT_REQUIRED_VALUE_WITNESSES 1
26-
#define WANT_EXTRA_INHABITANT_VALUE_WITNESSES 1
2726
#define WANT_ENUM_VALUE_WITNESSES 1
2827

2928
/// WANT_ONLY_REQUIRED_VALUE_WITNESSES
3029
/// Define this to expand only the required value witnesses.
3130
#elif defined(WANT_ONLY_REQUIRED_VALUE_WITNESSES)
3231
#undef WANT_ONLY_REQUIRED_VALUE_WITNESSES
3332
#define WANT_REQUIRED_VALUE_WITNESSES 1
34-
#define WANT_EXTRA_INHABITANT_VALUE_WITNESSES 0
35-
#define WANT_ENUM_VALUE_WITNESSES 0
36-
37-
/// WANT_ONLY_EXTRA_INHABITANT_VALUE_WITNESSES
38-
/// Define this to expand only the extra-inhabitant value witnesses.
39-
#elif defined(WANT_ONLY_EXTRA_INHABITANT_VALUE_WITNESSES)
40-
#undef WANT_ONLY_EXTRA_INHABITANT_VALUE_WITNESSES
41-
#define WANT_REQUIRED_VALUE_WITNESSES 0
42-
#define WANT_EXTRA_INHABITANT_VALUE_WITNESSES 1
4333
#define WANT_ENUM_VALUE_WITNESSES 0
4434

4535
/// WANT_ONLY_ENUM_VALUE_WITNESSES
4636
/// Define this to expand only the enum value witnesses.
4737
#elif defined(WANT_ONLY_ENUM_VALUE_WITNESSES)
4838
#undef WANT_ONLY_ENUM_VALUE_WITNESSES
4939
#define WANT_REQUIRED_VALUE_WITNESSES 0
50-
#define WANT_EXTRA_INHABITANT_VALUE_WITNESSES 0
5140
#define WANT_ENUM_VALUE_WITNESSES 1
5241

5342
/// WANT_REQUIRED_VALUE_WITNESSES
54-
/// WANT_EXTRA_INHABITANT_VALUE_WITNESSES
5543
/// WANT_ENUM_VALUE_WITNESSES
5644
/// Define all of these to control exactly what to expand.
5745
#else
58-
#if !defined(WANT_REQUIRED_VALUE_WITNESSES) || !defined(WANT_EXTRA_INHABITANT_VALUE_WITNESSES) || !defined(WANT_ENUM_VALUE_WITNESSES)
46+
#if !defined(WANT_REQUIRED_VALUE_WITNESSES) || !defined(WANT_ENUM_VALUE_WITNESSES)
5947
#error failed to define a WANT macro; possible typo?
6048
#endif
6149
#endif
@@ -206,7 +194,16 @@ BEGIN_VALUE_WITNESS_RANGE(TypeLayoutWitness,
206194
BEGIN_VALUE_WITNESS_RANGE(RequiredTypeLayoutWitness,
207195
Size)
208196

209-
/// SIZE_TYPE flags;
197+
/// SIZE_TYPE stride;
198+
///
199+
/// The required size per element of an array of this type. It is at least
200+
/// one, even for zero-sized types, like the empty tuple.
201+
DATA_VALUE_WITNESS(stride,
202+
Stride,
203+
SIZE_TYPE)
204+
205+
206+
/// UINT_TYPE flags;
210207
///
211208
/// The ValueWitnessAlignmentMask bits represent the required
212209
/// alignment of the first byte of an object of this type, expressed
@@ -222,97 +219,35 @@ BEGIN_VALUE_WITNESS_RANGE(RequiredTypeLayoutWitness,
222219
/// The ValueWitnessIsNonInline bit is set if the type cannot be
223220
/// represented in a fixed-size buffer or if it is not bitwise takable.
224221
///
225-
/// The Enum_HasExtraInhabitants bit is set if the type's binary
226-
/// representation has "extra inhabitants" that do not form valid values of
227-
/// the type, and the value witness table contains the ExtraInhabitantWitness
228-
/// entries.
222+
/// The ExtraInhabitantsMask bits represent the number of "extra inhabitants"
223+
/// of the bit representation of the value that do not form valid values of
224+
/// the type.
229225
///
230226
/// The Enum_HasSpareBits bit is set if the type's binary representation
231227
/// has unused bits.
232228
///
233229
/// The HasEnumWitnesses bit is set if the type is an enum type.
234230
DATA_VALUE_WITNESS(flags,
235231
Flags,
236-
SIZE_TYPE)
232+
UINT_TYPE)
237233

238-
/// SIZE_TYPE stride;
234+
/// UINT_TYPE extraInhabitantCount;
239235
///
240-
/// The required size per element of an array of this type. It is at least
241-
/// one, even for zero-sized types, like the empty tuple.
242-
DATA_VALUE_WITNESS(stride,
243-
Stride,
244-
SIZE_TYPE)
236+
/// The number of extra inhabitants in the type.
237+
DATA_VALUE_WITNESS(extraInhabitantCount,
238+
ExtraInhabitantCount,
239+
UINT_TYPE)
245240

246241
END_VALUE_WITNESS_RANGE(RequiredTypeLayoutWitness,
247-
Stride)
242+
ExtraInhabitantCount)
248243

249244
END_VALUE_WITNESS_RANGE(RequiredValueWitness,
250-
Stride)
251-
252-
#endif /* WANT_REQUIRED_VALUE_WITNESSES */
253-
254-
#if WANT_EXTRA_INHABITANT_VALUE_WITNESSES
255-
256-
// The following value witnesses are conditionally present based on
257-
// the Enum_HasExtraInhabitants bit of the flags.
258-
259-
/// SIZE_TYPE extraInhabitantFlags;
260-
///
261-
/// These bits are always present if the extra inhabitants witnesses are:
262-
///
263-
/// - The NumExtraInhabitantsMask bits contain the number of extra
264-
/// inhabitants of the type representation.
265-
///
266-
/// If the Enum_HasSpareBits flag is set in the value witness flags, these
267-
/// additional flags are available:
268-
///
269-
/// - The NumSpareBitsMask bits contain the number of (host-endian) contiguous
270-
/// spare bits in the type representation.
271-
/// - The SpareBitsShiftMask bits contain the (host-endian) bit offset of the
272-
/// lowest spare bit.
273-
DATA_VALUE_WITNESS(extraInhabitantFlags,
274-
ExtraInhabitantFlags,
275-
SIZE_TYPE)
276-
277-
BEGIN_VALUE_WITNESS_RANGE(ExtraInhabitantValueWitness,
278-
ExtraInhabitantFlags)
245+
ExtraInhabitantCount)
279246

280247
END_VALUE_WITNESS_RANGE(TypeLayoutWitness,
281-
ExtraInhabitantFlags)
282-
283-
/// void (*storeExtraInhabitant)(T *obj, int index, M *self);
284-
///
285-
/// Given an invalid object of this type, store the representation of an
286-
/// extra inhabitant of the type. The object will remain invalid, because
287-
/// an extra inhabitant is by definition an invalid representation of the
288-
/// type. index must be less than numExtraInhabitants.
289-
FUNCTION_VALUE_WITNESS(storeExtraInhabitant,
290-
StoreExtraInhabitant,
291-
VOID_TYPE,
292-
(MUTABLE_VALUE_TYPE, INT_TYPE, TYPE_TYPE))
293-
294-
BEGIN_VALUE_WITNESS_RANGE(ExtraInhabitantValueWitnessFunction,
295-
StoreExtraInhabitant)
296-
297-
/// int (*getExtraInhabitantIndex)(T *obj, M *self);
298-
///
299-
/// Given an invalid object of this type with an extra inhabitant
300-
/// representation, returns the index of the extra inhabitant representation.
301-
/// Returns -1 if the object is a valid value of the type. If non-negative,
302-
/// the return value is the same index that can be passed to
303-
/// storeExtraInhabitant to reproduce the representation.
304-
FUNCTION_VALUE_WITNESS(getExtraInhabitantIndex,
305-
GetExtraInhabitantIndex,
306-
INT_TYPE,
307-
(IMMUTABLE_VALUE_TYPE, TYPE_TYPE))
308-
309-
END_VALUE_WITNESS_RANGE(ExtraInhabitantValueWitnessFunction,
310-
GetExtraInhabitantIndex)
248+
ExtraInhabitantCount)
311249

312-
END_VALUE_WITNESS_RANGE(ExtraInhabitantValueWitness,
313-
GetExtraInhabitantIndex)
314-
315-
#endif /* WANT_EXTRA_INHABITANT_VALUE_WITNESSES */
250+
#endif /* WANT_REQUIRED_VALUE_WITNESSES */
316251

317252
#if WANT_ENUM_VALUE_WITNESSES
318253

@@ -372,9 +307,7 @@ END_VALUE_WITNESS_RANGE(ValueWitness,
372307
#undef FUNCTION_VALUE_WITNESS
373308
#undef VALUE_WITNESS
374309
#undef ENUM_VALUE_WITNESS
375-
#undef EXTRA_INHABITANT_VALUE_WITNESS
376310
#undef NON_REQUIRED_VALUE_WITNESS
377311
#undef REQUIRED_VALUE_WITNESS
378312
#undef WANT_ENUM_VALUE_WITNESSES
379-
#undef WANT_EXTRA_INHABITANT_VALUE_WITNESSES
380313
#undef WANT_REQUIRED_VALUE_WITNESSES

0 commit comments

Comments
 (0)