[SILGen] Consolidate emission of SILDeclRef definitions

Fill in the missing SILDeclRef cases in
`emitDelayedFunction`, and rename it to
`emitFunctionDefinition`. This will allow SIL to
be emitted only for a specific set of symbols.
This commit is contained in:
Hamish Knight
2020-09-02 21:09:09 -07:00
parent 789659e0d7
commit ac63abc8c2
2 changed files with 103 additions and 85 deletions

View File

@@ -676,17 +676,15 @@ bool SILGenModule::hasFunction(SILDeclRef constant) {
void SILGenModule::visitFuncDecl(FuncDecl *fd) { emitFunction(fd); }
static void emitDelayedFunction(SILGenModule &SGM,
SILDeclRef constant,
SILFunction *f) {
void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) {
switch (constant.kind) {
case SILDeclRef::Kind::Func: {
auto *fd = cast<FuncDecl>(constant.getDecl());
SGM.preEmitFunction(constant, fd, f, fd);
preEmitFunction(constant, fd, f, fd);
PrettyStackTraceSILFunction X("silgen emitFunction", f);
SILGenFunction(SGM, *f, fd).emitFunction(fd);
SGM.postEmitFunction(constant, f);
SILGenFunction(*this, *f, fd).emitFunction(fd);
postEmitFunction(constant, f);
break;
}
@@ -696,16 +694,16 @@ static void emitDelayedFunction(SILGenModule &SGM,
if (decl->getDeclContext()->getSelfClassDecl() &&
(decl->isDesignatedInit() ||
decl->isObjC())) {
SGM.preEmitFunction(constant, decl, f, decl);
preEmitFunction(constant, decl, f, decl);
PrettyStackTraceSILFunction X("silgen emitConstructor", f);
SILGenFunction(SGM, *f, decl).emitClassConstructorAllocator(decl);
SGM.postEmitFunction(constant, f);
SILGenFunction(*this, *f, decl).emitClassConstructorAllocator(decl);
postEmitFunction(constant, f);
} else {
SGM.preEmitFunction(constant, decl, f, decl);
preEmitFunction(constant, decl, f, decl);
PrettyStackTraceSILFunction X("silgen emitConstructor", f);
f->createProfiler(decl, constant, ForDefinition);
SILGenFunction(SGM, *f, decl).emitValueConstructor(decl);
SGM.postEmitFunction(constant, f);
SILGenFunction(*this, *f, decl).emitValueConstructor(decl);
postEmitFunction(constant, f);
}
break;
}
@@ -714,11 +712,11 @@ static void emitDelayedFunction(SILGenModule &SGM,
auto *decl = cast<ConstructorDecl>(constant.getDecl());
assert(decl->getDeclContext()->getSelfClassDecl());
SGM.preEmitFunction(constant, decl, f, decl);
preEmitFunction(constant, decl, f, decl);
PrettyStackTraceSILFunction X("silgen constructor initializer", f);
f->createProfiler(decl, constant, ForDefinition);
SILGenFunction(SGM, *f, decl).emitClassConstructorInitializer(decl);
SGM.postEmitFunction(constant, f);
SILGenFunction(*this, *f, decl).emitClassConstructorInitializer(decl);
postEmitFunction(constant, f);
break;
}
@@ -731,22 +729,22 @@ static void emitDelayedFunction(SILGenModule &SGM,
case DefaultArgumentKind::Normal: {
auto arg = param->getTypeCheckedDefaultExpr();
auto loc = RegularLocation::getAutoGeneratedLocation(arg);
SGM.preEmitFunction(constant, arg, f, loc);
preEmitFunction(constant, arg, f, loc);
PrettyStackTraceSILFunction X("silgen emitDefaultArgGenerator ", f);
SILGenFunction SGF(SGM, *f, initDC);
SILGenFunction SGF(*this, *f, initDC);
SGF.emitGeneratorFunction(constant, arg);
SGM.postEmitFunction(constant, f);
postEmitFunction(constant, f);
break;
}
case DefaultArgumentKind::StoredProperty: {
auto arg = param->getStoredProperty();
auto loc = RegularLocation::getAutoGeneratedLocation(arg);
SGM.preEmitFunction(constant, arg, f, loc);
preEmitFunction(constant, arg, f, loc);
PrettyStackTraceSILFunction X("silgen emitDefaultArgGenerator ", f);
SILGenFunction SGF(SGM, *f, initDC);
SILGenFunction SGF(*this, *f, initDC);
SGF.emitGeneratorFunction(constant, arg);
SGM.postEmitFunction(constant, f);
postEmitFunction(constant, f);
break;
}
@@ -780,23 +778,23 @@ static void emitDelayedFunction(SILGenModule &SGM,
}
auto loc = RegularLocation::getAutoGeneratedLocation(init);
SGM.preEmitFunction(constant, init, f, loc);
preEmitFunction(constant, init, f, loc);
PrettyStackTraceSILFunction X("silgen emitStoredPropertyInitialization", f);
f->createProfiler(init, constant, ForDefinition);
SILGenFunction SGF(SGM, *f, initDC);
SILGenFunction SGF(*this, *f, initDC);
// If this is a stored property initializer inside a type at global scope,
// it may close over a global variable. If we're emitting top-level code,
// then emit a "mark_function_escape" that lists the captured global
// variables so that definite initialization can reason about this
// escape point.
if (!var->getDeclContext()->isLocalContext() &&
SGM.TopLevelSGF && SGM.TopLevelSGF->B.hasValidInsertionPoint()) {
SGM.emitMarkFunctionEscapeForTopLevelCodeGlobals(var, captureInfo);
if (!var->getDeclContext()->isLocalContext() && TopLevelSGF &&
TopLevelSGF->B.hasValidInsertionPoint()) {
emitMarkFunctionEscapeForTopLevelCodeGlobals(var, captureInfo);
}
SGF.emitGeneratorFunction(constant, init, /*EmitProfilerIncrement=*/true);
SGM.postEmitFunction(constant, f);
postEmitFunction(constant, f);
break;
}
@@ -804,7 +802,7 @@ static void emitDelayedFunction(SILGenModule &SGM,
auto *var = cast<VarDecl>(constant.getDecl());
auto loc = RegularLocation::getAutoGeneratedLocation(var);
SGM.preEmitFunction(constant, var, f, loc);
preEmitFunction(constant, var, f, loc);
PrettyStackTraceSILFunction X(
"silgen emitPropertyWrapperBackingInitializer", f);
auto wrapperInfo = var->getPropertyWrapperBackingPropertyInfo();
@@ -812,26 +810,26 @@ static void emitDelayedFunction(SILGenModule &SGM,
f->createProfiler(wrapperInfo.initializeFromOriginal, constant,
ForDefinition);
auto varDC = var->getInnermostDeclContext();
SILGenFunction SGF(SGM, *f, varDC);
SILGenFunction SGF(*this, *f, varDC);
SGF.emitGeneratorFunction(constant, wrapperInfo.initializeFromOriginal);
SGM.postEmitFunction(constant, f);
postEmitFunction(constant, f);
break;
}
case SILDeclRef::Kind::GlobalAccessor: {
auto *global = cast<VarDecl>(constant.getDecl());
auto found = SGM.delayedGlobals.find(global);
assert(found != SGM.delayedGlobals.end());
auto found = delayedGlobals.find(global);
assert(found != delayedGlobals.end());
auto *onceToken = found->second.first;
auto *onceFunc = found->second.second;
auto loc = RegularLocation::getAutoGeneratedLocation(global);
SGM.preEmitFunction(constant, global, f, loc);
preEmitFunction(constant, global, f, loc);
PrettyStackTraceSILFunction X("silgen emitGlobalAccessor", f);
SILGenFunction(SGM, *f, global->getDeclContext())
SILGenFunction(*this, *f, global->getDeclContext())
.emitGlobalAccessor(global, onceToken, onceFunc);
SGM.postEmitFunction(constant, f);
postEmitFunction(constant, f);
break;
}
@@ -839,19 +837,63 @@ static void emitDelayedFunction(SILGenModule &SGM,
auto *decl = cast<EnumElementDecl>(constant.getDecl());
auto loc = RegularLocation::getAutoGeneratedLocation(decl);
SGM.preEmitFunction(constant, decl, f, loc);
preEmitFunction(constant, decl, f, loc);
PrettyStackTraceSILFunction X("silgen enum constructor", f);
SILGenFunction(SGM, *f, decl->getDeclContext()).emitEnumConstructor(decl);
SGM.postEmitFunction(constant, f);
SILGenFunction(*this, *f, decl->getDeclContext()).emitEnumConstructor(decl);
postEmitFunction(constant, f);
break;
}
case SILDeclRef::Kind::Destroyer:
case SILDeclRef::Kind::Deallocator:
case SILDeclRef::Kind::IVarInitializer:
case SILDeclRef::Kind::IVarDestroyer:
llvm_unreachable("Cannot emit as a delayed function");
break;
case SILDeclRef::Kind::Destroyer: {
auto *dd = cast<DestructorDecl>(constant.getDecl());
preEmitFunction(constant, dd, f, dd);
PrettyStackTraceSILFunction X("silgen emitDestroyingDestructor", f);
SILGenFunction(*this, *f, dd).emitDestroyingDestructor(dd);
postEmitFunction(constant, f);
return;
}
case SILDeclRef::Kind::Deallocator: {
auto *dd = cast<DestructorDecl>(constant.getDecl());
auto *cd = cast<ClassDecl>(dd->getDeclContext());
if (usesObjCAllocator(cd)) {
preEmitFunction(constant, dd, f, dd);
PrettyStackTraceSILFunction X("silgen emitDestructor -dealloc", f);
f->createProfiler(dd, constant, ForDefinition);
SILGenFunction(*this, *f, dd).emitObjCDestructor(constant);
postEmitFunction(constant, f);
return;
}
auto loc = RegularLocation::getAutoGeneratedLocation(dd);
preEmitFunction(constant, dd, f, loc);
PrettyStackTraceSILFunction X("silgen emitDeallocatingDestructor", f);
f->createProfiler(dd, constant, ForDefinition);
SILGenFunction(*this, *f, dd).emitDeallocatingDestructor(dd);
postEmitFunction(constant, f);
return;
}
case SILDeclRef::Kind::IVarInitializer: {
auto *cd = cast<ClassDecl>(constant.getDecl());
auto loc = RegularLocation::getAutoGeneratedLocation(cd);
preEmitFunction(constant, cd, f, loc);
PrettyStackTraceSILFunction X("silgen emitDestructor ivar initializer", f);
SILGenFunction(*this, *f, cd).emitIVarInitializer(constant);
postEmitFunction(constant, f);
return;
}
case SILDeclRef::Kind::IVarDestroyer: {
auto *cd = cast<ClassDecl>(constant.getDecl());
auto loc = RegularLocation::getAutoGeneratedLocation(cd);
preEmitFunction(constant, cd, f, loc);
PrettyStackTraceSILFunction X("silgen emitDestructor ivar destroyer", f);
SILGenFunction(*this, *f, cd).emitIVarDestroyer(constant);
postEmitFunction(constant, f);
return;
}
}
}
@@ -889,7 +931,7 @@ static void emitOrDelayFunction(SILGenModule &SGM,
return;
}
emitDelayedFunction(SGM, constant, f);
SGM.emitFunctionDefinition(constant, f);
}
void SILGenModule::preEmitFunction(SILDeclRef constant,
@@ -1232,12 +1274,7 @@ void SILGenModule::emitObjCAllocatorDestructor(ClassDecl *cd,
// Destructors are a necessary part of class metadata, so can't be delayed.
if (dd->hasBody()) {
SILDeclRef dealloc(dd, SILDeclRef::Kind::Deallocator);
SILFunction *f = getFunction(dealloc, ForDefinition);
preEmitFunction(dealloc, dd, f, dd);
PrettyStackTraceSILFunction X("silgen emitDestructor -dealloc", f);
f->createProfiler(dd, dealloc, ForDefinition);
SILGenFunction(*this, *f, dd).emitObjCDestructor(dealloc);
postEmitFunction(dealloc, f);
emitFunctionDefinition(dealloc, getFunction(dealloc, ForDefinition));
}
// Emit the Objective-C -dealloc entry point if it has
@@ -1249,24 +1286,16 @@ void SILGenModule::emitObjCAllocatorDestructor(ClassDecl *cd,
if (requiresIVarInitialization(*this, cd)) {
auto ivarInitializer = SILDeclRef(cd, SILDeclRef::Kind::IVarInitializer)
.asForeign();
SILFunction *f = getFunction(ivarInitializer, ForDefinition);
auto loc = RegularLocation::getAutoGeneratedLocation(dd);
preEmitFunction(ivarInitializer, dd, f, loc);
PrettyStackTraceSILFunction X("silgen emitDestructor ivar initializer", f);
SILGenFunction(*this, *f, cd).emitIVarInitializer(ivarInitializer);
postEmitFunction(ivarInitializer, f);
emitFunctionDefinition(ivarInitializer,
getFunction(ivarInitializer, ForDefinition));
}
// Emit the ivar destroyer, if needed.
if (hasNonTrivialIVars(cd)) {
auto ivarDestroyer = SILDeclRef(cd, SILDeclRef::Kind::IVarDestroyer)
.asForeign();
SILFunction *f = getFunction(ivarDestroyer, ForDefinition);
auto loc = RegularLocation::getAutoGeneratedLocation(dd);
preEmitFunction(ivarDestroyer, dd, f, loc);
PrettyStackTraceSILFunction X("silgen emitDestructor ivar destroyer", f);
SILGenFunction(*this, *f, cd).emitIVarDestroyer(ivarDestroyer);
postEmitFunction(ivarDestroyer, f);
emitFunctionDefinition(ivarDestroyer,
getFunction(ivarDestroyer, ForDefinition));
}
}
@@ -1276,12 +1305,8 @@ void SILGenModule::emitDestructor(ClassDecl *cd, DestructorDecl *dd) {
// Emit the ivar destroyer, if needed.
if (requiresIVarDestroyer(cd)) {
SILDeclRef ivarDestroyer(cd, SILDeclRef::Kind::IVarDestroyer);
SILFunction *f = getFunction(ivarDestroyer, ForDefinition);
auto loc = RegularLocation::getAutoGeneratedLocation(dd);
preEmitFunction(ivarDestroyer, dd, f, loc);
PrettyStackTraceSILFunction X("silgen emitDestructor ivar destroyer", f);
SILGenFunction(*this, *f, dd).emitIVarDestroyer(ivarDestroyer);
postEmitFunction(ivarDestroyer, f);
emitFunctionDefinition(ivarDestroyer,
getFunction(ivarDestroyer, ForDefinition));
}
// If the class would use the Objective-C allocator, only emit -dealloc.
@@ -1294,24 +1319,14 @@ void SILGenModule::emitDestructor(ClassDecl *cd, DestructorDecl *dd) {
// Destructors are a necessary part of class metadata, so can't be delayed.
if (dd->hasBody()) {
SILDeclRef destroyer(dd, SILDeclRef::Kind::Destroyer);
SILFunction *f = getFunction(destroyer, ForDefinition);
RegularLocation loc(dd);
preEmitFunction(destroyer, dd, f, loc);
PrettyStackTraceSILFunction X("silgen emitDestroyingDestructor", f);
SILGenFunction(*this, *f, dd).emitDestroyingDestructor(dd);
postEmitFunction(destroyer, f);
emitFunctionDefinition(destroyer, getFunction(destroyer, ForDefinition));
}
// Emit the deallocating destructor.
{
SILDeclRef deallocator(dd, SILDeclRef::Kind::Deallocator);
SILFunction *f = getFunction(deallocator, ForDefinition);
auto loc = RegularLocation::getAutoGeneratedLocation(dd);
preEmitFunction(deallocator, dd, f, loc);
PrettyStackTraceSILFunction X("silgen emitDeallocatingDestructor", f);
f->createProfiler(dd, deallocator, ForDefinition);
SILGenFunction(*this, *f, dd).emitDeallocatingDestructor(dd);
postEmitFunction(deallocator, f);
emitFunctionDefinition(deallocator,
getFunction(deallocator, ForDefinition));
}
}
@@ -1910,8 +1925,8 @@ public:
|| !SGM.pendingConformances.empty()) {
while (!SGM.forcedFunctions.empty()) {
auto &front = SGM.forcedFunctions.front();
emitDelayedFunction(SGM, front,
SGM.getEmittedFunction(front, ForDefinition));
SGM.emitFunctionDefinition(
front, SGM.getEmittedFunction(front, ForDefinition));
SGM.forcedFunctions.pop_front();
}
while (!SGM.pendingConformances.empty()) {