mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[ABI] Use mangled names for associated type witnesses.
Rather than storing associated type metadata access functions in witness tables, initially store a pointer to a mangled type name. On first access, demangle that type name and replace the witness table entry with the resulting type metadata. This reduces the code size of protocol conformances, because we no longer need to create associated type metadata access functions for every associated type, and the mangled names are much smaller (and sharable). The same code size improvements apply to defaulted associated types for resilient protocols, although those are more rare. Witness tables themselves are slightly smaller, because we don’t need separate private entries in them to act as caches. On the caller side, associated type metadata is always produced via a call to swift_getAssociatedTypeWitness(), which handles the demangling and caching behavior. In all, this reduces the size of the standard library by ~70k. There are additional code-size wins that are possible with follow-on work: * We can stop emitting type metadata access functions for non-resilient types that have constant metadata (like `Int`), because they’re only currently used as associated type metadata access functions. * We can stop emitting separate associated type reflection metadata, because the reflection infrastructure can use these mangled names directly.
This commit is contained in:
@@ -222,7 +222,8 @@ llvm::Constant *IRGenModule::getAddrOfStringForTypeRef(StringRef str) {
|
||||
}
|
||||
|
||||
llvm::Constant *IRGenModule::getAddrOfStringForTypeRef(
|
||||
const SymbolicMangling &mangling) {
|
||||
const SymbolicMangling &mangling,
|
||||
unsigned alignment) {
|
||||
// Create a symbol name for the symbolic mangling. This is used as the
|
||||
// uniquing key both for ODR coalescing and within this TU.
|
||||
IRGenMangler mangler;
|
||||
@@ -230,9 +231,12 @@ llvm::Constant *IRGenModule::getAddrOfStringForTypeRef(
|
||||
mangler.mangleSymbolNameForSymbolicMangling(mangling);
|
||||
|
||||
// See if we emitted the constant already.
|
||||
// FIXME: Make sure the existing variable has enough alignment. Otherwise,
|
||||
// replace it.
|
||||
auto &entry = StringsForTypeRef[symbolName];
|
||||
if (entry.second)
|
||||
if (entry.second && entry.first->getAlignment() >= alignment) {
|
||||
return entry.second;
|
||||
}
|
||||
|
||||
ConstantInitBuilder B(*this);
|
||||
auto S = B.beginStruct();
|
||||
@@ -284,7 +288,7 @@ llvm::Constant *IRGenModule::getAddrOfStringForTypeRef(
|
||||
nullptr,
|
||||
symbolName);
|
||||
var->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
||||
var->setAlignment(1);
|
||||
var->setAlignment(alignment);
|
||||
setTrueConstGlobal(var);
|
||||
var->setSection(getReflectionTypeRefSectionName());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user