[Runtime+IRGen] Instantiate layout strings for generic multi payload enum (#66621)

Instantiating layout strings for generic types reduces code size and is expected to improve performance of generic value witnesses.
This commit is contained in:
Dario Rexin
2023-06-14 09:31:11 -07:00
committed by GitHub
parent d06e8c9ec7
commit 8b48a0d3e0
11 changed files with 354 additions and 68 deletions

View File

@@ -126,6 +126,11 @@ inline static bool handleNextRefCount(const Metadata *metadata,
Handler::handleMultiPayloadEnumFN(metadata, typeLayout, offset, true,
addrOffset,
std::forward<Params>(params)...);
} else if (SWIFT_UNLIKELY(tag ==
RefCountingKind::MultiPayloadEnumGeneric)) {
Handler::handleMultiPayloadEnumGeneric(metadata, typeLayout, offset,
addrOffset,
std::forward<Params>(params)...);
} else {
Handler::handleReference(tag, addrOffset, std::forward<Params>(params)...);
}
@@ -263,16 +268,16 @@ static void handleMultiPayloadEnumFN(const Metadata *metadata,
getEnumTag = readRelativeFunctionPointer<GetEnumTagFn>(typeLayout, offset);
}
size_t numCases = readBytes<size_t>(typeLayout, offset);
size_t numPayloads = readBytes<size_t>(typeLayout, offset);
size_t refCountBytes = readBytes<size_t>(typeLayout, offset);
size_t enumSize = readBytes<size_t>(typeLayout, offset);
unsigned enumTag = getEnumTag(addr + addrOffset);
if (enumTag < numCases) {
if (enumTag < numPayloads) {
size_t nestedOffset = offset + (enumTag * sizeof(size_t));
size_t refCountOffset = readBytes<size_t>(typeLayout, nestedOffset);
nestedOffset = offset + (numCases * sizeof(size_t)) + refCountOffset;
nestedOffset = offset + (numPayloads * sizeof(size_t)) + refCountOffset;
uintptr_t nestedAddrOffset = addrOffset;
handleRefCounts<0, Handler>(metadata, typeLayout, nestedOffset,
@@ -280,7 +285,37 @@ static void handleMultiPayloadEnumFN(const Metadata *metadata,
std::forward<Params>(params)...);
}
offset += refCountBytes + (numCases * sizeof(size_t));
offset += refCountBytes + (numPayloads * sizeof(size_t));
addrOffset += enumSize;
}
template <typename Handler, typename... Params>
static void handleMultiPayloadEnumGeneric(const Metadata *metadata,
const uint8_t *typeLayout,
size_t &offset,
uintptr_t &addrOffset,
uint8_t *addr,
Params... params) {
auto tagBytes = readBytes<size_t>(typeLayout, offset);
auto numPayloads = readBytes<size_t>(typeLayout, offset);
auto refCountBytes = readBytes<size_t>(typeLayout, offset);
auto enumSize = readBytes<size_t>(typeLayout, offset);
auto tagBytesOffset = enumSize - tagBytes;
auto enumTag = readTagBytes(addr + addrOffset + tagBytesOffset, tagBytes);
if (enumTag < numPayloads) {
size_t nestedOffset = offset + (enumTag * sizeof(size_t));
size_t refCountOffset = readBytes<size_t>(typeLayout, nestedOffset);
nestedOffset = offset + (numPayloads * sizeof(size_t)) + refCountOffset;
uintptr_t nestedAddrOffset = addrOffset;
handleRefCounts<0, Handler>(metadata, typeLayout, nestedOffset,
nestedAddrOffset, addr,
std::forward<Params>(params)...);
}
offset += refCountBytes + (numPayloads * sizeof(size_t));
addrOffset += enumSize;
}
@@ -337,6 +372,15 @@ struct DestroyHandler {
resolved, addrOffset, addr);
}
static inline void handleMultiPayloadEnumGeneric(const Metadata *metadata,
const uint8_t *typeLayout,
size_t &offset,
uintptr_t &addrOffset,
uint8_t *addr) {
::handleMultiPayloadEnumGeneric<DestroyHandler>(metadata, typeLayout, offset,
addrOffset, addr);
}
static inline void handleReference(RefCountingKind tag, uintptr_t addrOffset,
uint8_t *addr) {
const auto &destroyFunc = destroyTable[static_cast<uint8_t>(tag)];
@@ -431,6 +475,16 @@ struct CopyHandler {
resolved, addrOffset, dest, src);
}
static inline void handleMultiPayloadEnumGeneric(const Metadata *metadata,
const uint8_t *typeLayout,
size_t &offset,
uintptr_t &addrOffset,
uint8_t *dest,
uint8_t *src) {
::handleMultiPayloadEnumGeneric<CopyHandler>(metadata, typeLayout, offset,
addrOffset, dest, src);
}
static inline void handleReference(RefCountingKind tag, uintptr_t addrOffset,
uint8_t *dest, uint8_t *src) {
const auto &retainFunc = retainTable[static_cast<uint8_t>(tag)];
@@ -488,6 +542,16 @@ struct TakeHandler {
resolved, addrOffset, dest, src);
}
static inline void handleMultiPayloadEnumGeneric(const Metadata *metadata,
const uint8_t *typeLayout,
size_t &offset,
uintptr_t &addrOffset,
uint8_t *dest,
uint8_t *src) {
::handleMultiPayloadEnumGeneric<TakeHandler>(metadata, typeLayout, offset,
addrOffset, dest, src);
}
static inline void handleReference(RefCountingKind tag, uintptr_t addrOffset,
uint8_t *dest, uint8_t *src) {
if (tag == RefCountingKind::UnknownWeak) {