SILGen: Only emit implicit and Clang importer decls by need.

If a SILDeclRef references a decl that isn't explicit in the source code and can't be referenced externally, then we only need to emit it if it's referenced in the current TU. Partially addresses rdar://problem/21444126, though we still eagerly generate witness tables for generated conformances, which still pull in a bunch of noise.

Swift SVN r29536
This commit is contained in:
Joe Groff
2015-06-20 22:35:39 +00:00
parent 77f6228542
commit f58ce3e5e1
13 changed files with 324 additions and 91 deletions

View File

@@ -190,6 +190,29 @@ static SILLinkage getLinkageForLocalContext(DeclContext *dc) {
return SILLinkage::Shared;
}
bool SILDeclRef::isThunk() const {
return isCurried || isForeignToNativeThunk() || isNativeToForeignThunk();
}
bool SILDeclRef::isClangImported() const {
if (!hasDecl())
return false;
ValueDecl *d = getDecl();
DeclContext *moduleContext = d->getDeclContext()->getModuleScopeContext();
if (isa<ClangModuleUnit>(moduleContext)) {
if (isa<ConstructorDecl>(d) || isa<EnumElementDecl>(d))
return true;
if (auto *FD = dyn_cast<FuncDecl>(d))
if (FD->isAccessor() ||
isa<NominalTypeDecl>(d->getDeclContext()))
return true;
}
return false;
}
SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
// Anonymous functions have local linkage.
if (auto closure = getAbstractClosureExpr())
@@ -207,22 +230,16 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
}
// Currying and calling convention thunks have shared linkage.
if (isCurried || isForeignToNativeThunk() || isNativeToForeignThunk())
if (isThunk())
return SILLinkage::Shared;
// Declarations imported from Clang modules have shared linkage.
// FIXME: They shouldn't.
const SILLinkage ClangLinkage = SILLinkage::Shared;
if (isa<ClangModuleUnit>(moduleContext)) {
if (isa<ConstructorDecl>(d) || isa<EnumElementDecl>(d))
return ClangLinkage;
if (auto *FD = dyn_cast<FuncDecl>(d))
if (FD->isAccessor() ||
isa<NominalTypeDecl>(d->getDeclContext()))
return ClangLinkage;
}
if (isClangImported())
return ClangLinkage;
// Declarations that were derived on behalf of types in Clang modules get
// shared linkage.
if (auto *FD = dyn_cast<FuncDecl>(d)) {