Skip to content

[NFC] [SILGen] Refactor emitOrDelayFunction into a SILGenModule method #67095

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 18 additions & 20 deletions lib/SILGen/SILGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1158,42 +1158,40 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) {
}
}

/// Emit a function now, if it's externally usable or has been referenced in
/// the current TU, or remember how to emit it later if not.
static void emitOrDelayFunction(SILGenModule &SGM, SILDeclRef constant) {
void SILGenModule::emitOrDelayFunction(SILDeclRef constant) {
assert(!constant.isThunk());
assert(!constant.isClangImported());

auto emitAfter = SGM.lastEmittedFunction;
auto emitAfter = lastEmittedFunction;

// Implicit decls may be delayed if they can't be used externally.
auto linkage = constant.getLinkage(ForDefinition);
bool mayDelay = !constant.hasUserWrittenCode() &&
!constant.isDynamicallyReplaceable() &&
!isPossiblyUsedExternally(linkage, SGM.M.isWholeModule());
!isPossiblyUsedExternally(linkage, M.isWholeModule());

if (!mayDelay) {
SGM.emitFunctionDefinition(constant, SGM.getFunction(constant, ForDefinition));
emitFunctionDefinition(constant, getFunction(constant, ForDefinition));
return;
}

// If the function is already forced then it was previously delayed and then
// referenced. We don't need to emit or delay it again.
if (SGM.forcedFunctions.contains(constant))
if (forcedFunctions.contains(constant))
return;

if (auto *f = SGM.getEmittedFunction(constant, ForDefinition)) {
SGM.emitFunctionDefinition(constant, f);
if (auto *f = getEmittedFunction(constant, ForDefinition)) {
emitFunctionDefinition(constant, f);
return;
}

// This is a delayable function so remember how to emit it in case it gets
// referenced later.
SGM.delayedFunctions.insert({constant, emitAfter});
delayedFunctions.insert({constant, emitAfter});
// Even though we didn't emit the function now, update the
// lastEmittedFunction so that we preserve the original ordering that
// the symbols would have been emitted in.
SGM.lastEmittedFunction = constant;
lastEmittedFunction = constant;
}

void SILGenModule::preEmitFunction(SILDeclRef constant, SILFunction *F,
Expand Down Expand Up @@ -1432,7 +1430,7 @@ void SILGenModule::emitFunction(FuncDecl *fd) {
emitAbstractFuncDecl(fd);

if (fd->hasBody())
emitOrDelayFunction(*this, SILDeclRef(decl));
emitOrDelayFunction(SILDeclRef(decl));
}

void SILGenModule::addGlobalVariable(VarDecl *global) {
Expand All @@ -1457,11 +1455,11 @@ void SILGenModule::emitConstructor(ConstructorDecl *decl) {
// initializers, have separate entry points for allocation and
// initialization.
if (decl->isDesignatedInit() || decl->isObjC()) {
emitOrDelayFunction(*this, constant);
emitOrDelayFunction(constant);

if (decl->hasBody()) {
SILDeclRef initConstant(decl, SILDeclRef::Kind::Initializer);
emitOrDelayFunction(*this, initConstant);
emitOrDelayFunction(initConstant);
}

return;
Expand All @@ -1471,7 +1469,7 @@ void SILGenModule::emitConstructor(ConstructorDecl *decl) {
// Struct and enum constructors do everything in a single function, as do
// non-@objc convenience initializers for classes.
if (decl->hasBody()) {
emitOrDelayFunction(*this, constant);
emitOrDelayFunction(constant);
}
}

Expand Down Expand Up @@ -1620,7 +1618,7 @@ void SILGenModule::emitDefaultArgGenerator(SILDeclRef constant,

case DefaultArgumentKind::Normal:
case DefaultArgumentKind::StoredProperty:
emitOrDelayFunction(*this, constant);
emitOrDelayFunction(constant);
break;

case DefaultArgumentKind::Inherited:
Expand All @@ -1638,7 +1636,7 @@ void SILGenModule::
emitStoredPropertyInitialization(PatternBindingDecl *pbd, unsigned i) {
auto *var = pbd->getAnchoringVarDecl(i);
SILDeclRef constant(var, SILDeclRef::Kind::StoredPropertyInitializer);
emitOrDelayFunction(*this, constant);
emitOrDelayFunction(constant);
}

void SILGenModule::
Expand All @@ -1647,12 +1645,12 @@ emitPropertyWrapperBackingInitializer(VarDecl *var) {

if (initInfo.hasInitFromWrappedValue()) {
SILDeclRef constant(var, SILDeclRef::Kind::PropertyWrapperBackingInitializer);
emitOrDelayFunction(*this, constant);
emitOrDelayFunction(constant);
}

if (initInfo.hasInitFromProjectedValue()) {
SILDeclRef constant(var, SILDeclRef::Kind::PropertyWrapperInitFromProjectedValue);
emitOrDelayFunction(*this, constant);
emitOrDelayFunction(constant);
}
}

Expand Down Expand Up @@ -1687,7 +1685,7 @@ void SILGenModule::emitGlobalAccessor(VarDecl *global,
SILFunction *onceFunc) {
SILDeclRef accessor(global, SILDeclRef::Kind::GlobalAccessor);
delayedGlobals[global] = std::make_pair(onceToken, onceFunc);
emitOrDelayFunction(*this, accessor);
emitOrDelayFunction(accessor);
}

void SILGenModule::emitArgumentGenerators(SILDeclRef::Loc decl,
Expand Down
10 changes: 7 additions & 3 deletions lib/SILGen/SILGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,6 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
llvm::DenseMap<VarDecl *, std::pair<SILGlobalVariable *,
SILFunction *>> delayedGlobals;

/// The most recent declaration we considered for emission.
SILDeclRef lastEmittedFunction;

/// Bookkeeping to ensure that useConformancesFrom{ObjectiveC,}Type() is
/// only called once for each unique type, as an optimization.
llvm::DenseSet<TypeBase *> usedConformancesFromTypes;
Expand Down Expand Up @@ -310,6 +307,10 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
/// Emits the function definition for a given SILDeclRef.
void emitFunctionDefinition(SILDeclRef constant, SILFunction *f);

/// Emit a function now, if it's externally usable or has been referenced in
/// the current TU, or remember how to emit it later if not.
void emitOrDelayFunction(SILDeclRef constant);

/// Generates code for the given closure expression and adds the
/// SILFunction to the current SILModule under the name SILDeclRef(ce).
SILFunction *emitClosure(AbstractClosureExpr *ce);
Expand Down Expand Up @@ -613,6 +614,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
void tryEmitPropertyDescriptor(AbstractStorageDecl *decl);

private:
/// The most recent declaration we considered for emission.
SILDeclRef lastEmittedFunction;

/// Emit the deallocator for a class that uses the objc allocator.
void emitObjCAllocatorDestructor(ClassDecl *cd, DestructorDecl *dd);
};
Expand Down