mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Use the first element of structs and tuples as a source
for extra inhabitants. For structs in particular, this eliminates a major source of abstraction penatlies. For example, an optional struct containing an object pointer is now represented the same way as an optional object pointer, which is critical for correctly importing CF types as Unmanaged<T>!. In time, we should generalize this to consider all elements as sources for extra inhabitants, as well as exploiting spare bits in the representation, but getting the single-element case right really provides the bulk of the benefit. This commit restores r17242 and r17243 with a fix to use value witnesses that actually forward the right type metadata down. We were already generating these value witnesses in the dependent struct VWT pattern, but I was being too clever and trying to use the underlying value witness directly. Swift SVN r17267
This commit is contained in:
@@ -569,6 +569,15 @@ struct ValueWitnessTable {
|
||||
/// The number of extra inhabitants, that is, bit patterns that do not form
|
||||
/// valid values of the type, in this type's binary representation.
|
||||
unsigned getNumExtraInhabitants() const;
|
||||
|
||||
/// Assert that this value witness table is an extra-inhabitants
|
||||
/// value witness table and return it as such.
|
||||
///
|
||||
/// This has an awful name because it's supposed to be internal to
|
||||
/// this file. Code outside this file should use LLVM's cast/dyn_cast.
|
||||
/// We don't want to use those here because we need to avoid accidentally
|
||||
/// introducing ABI dependencies on LLVM structures.
|
||||
const struct ExtraInhabitantsValueWitnessTable *_asXIVWT() const;
|
||||
};
|
||||
|
||||
/// A value-witness table with extra inhabitants entry points.
|
||||
@@ -588,15 +597,23 @@ struct ExtraInhabitantsValueWitnessTable : ValueWitnessTable {
|
||||
value_witness_types::extraInhabitantFlags eif)
|
||||
: ValueWitnessTable(base), storeExtraInhabitant(sei),
|
||||
getExtraInhabitantIndex(geii), extraInhabitantFlags(eif) {}
|
||||
|
||||
static bool classof(const ValueWitnessTable *table) {
|
||||
return table->flags.hasExtraInhabitants();
|
||||
}
|
||||
};
|
||||
|
||||
inline const ExtraInhabitantsValueWitnessTable *
|
||||
ValueWitnessTable::_asXIVWT() const {
|
||||
assert(ExtraInhabitantsValueWitnessTable::classof(this));
|
||||
return static_cast<const ExtraInhabitantsValueWitnessTable *>(this);
|
||||
}
|
||||
|
||||
inline unsigned ValueWitnessTable::getNumExtraInhabitants() const {
|
||||
// If the table does not have extra inhabitant witnesses, then there are zero.
|
||||
if (!flags.hasExtraInhabitants())
|
||||
return 0;
|
||||
return static_cast<const ExtraInhabitantsValueWitnessTable &>(*this)
|
||||
.extraInhabitantFlags
|
||||
.getNumExtraInhabitants();
|
||||
return this->_asXIVWT()->extraInhabitantFlags.getNumExtraInhabitants();
|
||||
}
|
||||
|
||||
// Standard value-witness tables.
|
||||
@@ -794,6 +811,13 @@ public:
|
||||
}
|
||||
FOR_ALL_FUNCTION_VALUE_WITNESSES(FORWARD_WITNESS)
|
||||
#undef FORWARD_WITNESS
|
||||
|
||||
int vw_getExtraInhabitantIndex(const OpaqueValue *value) const {
|
||||
return getValueWitnesses()->_asXIVWT()->getExtraInhabitantIndex(value, this);
|
||||
}
|
||||
void vw_storeExtraInhabitant(OpaqueValue *value, int index) const {
|
||||
getValueWitnesses()->_asXIVWT()->storeExtraInhabitant(value, index, this);
|
||||
}
|
||||
|
||||
/// Get the nominal type descriptor if this metadata describes a nominal type,
|
||||
/// or return null if it does not.
|
||||
|
||||
Reference in New Issue
Block a user