IRGen: emit type metadata and (value) witness tables lazily.

This gives big code size wins for unused types and also for types, which are never used in a generic context.
Also it reduces the amount of symbols in the symbol table.
The size wins heavily depend on the project. I have seen binary size reductions from 0 to 20% on real world projects.

rdar://problem/30119960
This commit is contained in:
Erik Eckstein
2017-03-10 12:46:07 -08:00
parent 555e52206a
commit 41c17a5b0c
19 changed files with 341 additions and 79 deletions

View File

@@ -726,6 +726,27 @@ llvm::Module *IRGenModule::releaseModule() {
return ClangCodeGen->ReleaseModule();
}
bool IRGenerator::canEmitWitnessTableLazily(SILWitnessTable *wt) {
bool isWholeModule = PrimaryIGM->getSILModule().isWholeModule();
if (isPossiblyUsedExternally(wt->getLinkage(), isWholeModule))
return false;
if (Opts.UseJIT)
return false;
return true;
}
void IRGenerator::addLazyWitnessTable(const ProtocolConformance *Conf) {
if (SILWitnessTable *wt = SIL.lookUpWitnessTable(Conf)) {
// Add it to the queue if it hasn't already been put there.
if (canEmitWitnessTableLazily(wt) &&
LazilyEmittedWitnessTables.insert(wt).second) {
LazyWitnessTables.push_back(wt);
}
}
}
llvm::AttributeSet IRGenModule::getAllocAttrs() {
if (AllocAttrs.isEmpty()) {
AllocAttrs = llvm::AttributeSet::get(LLVMContext,