mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Always put SILFunctions into a zombie list, when they are erased.
This removes the function body, but preserves the SILFunction object, which may be still referenced by different kinds of meta-information e.g. debug info for inlined functions, generic specializations information, etc. Doing this unconditionally simplifies the code and makes it less error-prone to reference SILFunctions from any kind of meta-information. It just works. No need to set any special flags, etc.
This commit is contained in:
@@ -200,12 +200,6 @@ private:
|
||||
/// after the pass runs, we only see a semantic-arc world.
|
||||
bool HasQualifiedOwnership = true;
|
||||
|
||||
/// True if this function is referenced by any kind of meta-information. This
|
||||
/// is the case e.g. when a function is referenced by the specialization
|
||||
/// information. Setting this flag ensures that the functions becomes a zombie
|
||||
/// function later.
|
||||
bool ReferencedByMetainformation = false;
|
||||
|
||||
SILFunction(SILModule &module, SILLinkage linkage, StringRef mangledName,
|
||||
CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
|
||||
Optional<SILLocation> loc, IsBare_t isBareSILFunction,
|
||||
@@ -297,26 +291,13 @@ public:
|
||||
/// Mark this function as removed from the module's function list, but kept
|
||||
/// as "zombie" for debug info or vtable stub generation.
|
||||
void setZombie() {
|
||||
assert((isInlined() || isExternallyUsedSymbol() ||
|
||||
isReferencedByMetainformation()) &&
|
||||
"Function should be deleted instead of getting a zombie");
|
||||
assert(!isZombie() && "Function is a zombie function already");
|
||||
Zombie = true;
|
||||
}
|
||||
|
||||
/// Returns true if this function is dead, but kept in the module's zombie list.
|
||||
bool isZombie() const { return Zombie; }
|
||||
|
||||
/// Mark this function as referenced by meta-information.
|
||||
void setReferencedByMetainformation() {
|
||||
ReferencedByMetainformation = true;
|
||||
}
|
||||
|
||||
/// Returns true if this function is referenced by any kind of
|
||||
/// meta-information.
|
||||
bool isReferencedByMetainformation() const {
|
||||
return ReferencedByMetainformation;
|
||||
}
|
||||
|
||||
/// Returns true if this function has qualified ownership instructions in it.
|
||||
bool hasQualifiedOwnership() const { return HasQualifiedOwnership; }
|
||||
|
||||
|
||||
@@ -2231,13 +2231,7 @@ void KeyPathInst::dropReferencedPattern() {
|
||||
|
||||
GenericSpecializationInformation::GenericSpecializationInformation(
|
||||
SILFunction *Caller, SILFunction *Parent, SubstitutionList Subs)
|
||||
: Caller(Caller), Parent(Parent), Subs(Subs) {
|
||||
// Specialization information may reference these functions, even
|
||||
// if they are removed by means of e.g. dead function elimination.
|
||||
if (Caller)
|
||||
Caller->setReferencedByMetainformation();
|
||||
Parent->setReferencedByMetainformation();
|
||||
}
|
||||
: Caller(Caller), Parent(Parent), Subs(Subs) {}
|
||||
|
||||
const GenericSpecializationInformation *
|
||||
GenericSpecializationInformation::create(SILFunction *Caller,
|
||||
|
||||
@@ -555,32 +555,24 @@ void SILModule::removeFromZombieList(StringRef Name) {
|
||||
|
||||
/// Erase a function from the module.
|
||||
void SILModule::eraseFunction(SILFunction *F) {
|
||||
|
||||
assert(! F->isZombie() && "zombie function is in list of alive functions");
|
||||
if (F->isInlined() || F->isExternallyUsedSymbol() ||
|
||||
F->isReferencedByMetainformation()) {
|
||||
// The owner of the function's Name is the FunctionTable key. As we remove
|
||||
// the function from the table we have to store the name string elsewhere:
|
||||
// in zombieFunctionNames.
|
||||
StringRef copiedName = F->getName().copy(zombieFunctionNames);
|
||||
FunctionTable.erase(F->getName());
|
||||
F->Name = copiedName;
|
||||
|
||||
// The owner of the function's Name is the FunctionTable key. As we remove
|
||||
// the function from the table we have to store the name string elsewhere:
|
||||
// in zombieFunctionNames.
|
||||
StringRef copiedName = F->getName().copy(zombieFunctionNames);
|
||||
FunctionTable.erase(F->getName());
|
||||
F->Name = copiedName;
|
||||
// The function is dead, but we need it later (at IRGen) for debug info
|
||||
// or vtable stub generation. So we move it into the zombie list.
|
||||
getFunctionList().remove(F);
|
||||
zombieFunctions.push_back(F);
|
||||
ZombieFunctionTable[copiedName] = F;
|
||||
F->setZombie();
|
||||
|
||||
// The function is dead, but we need it later (at IRGen) for debug info
|
||||
// or vtable stub generation. So we move it into the zombie list.
|
||||
getFunctionList().remove(F);
|
||||
zombieFunctions.push_back(F);
|
||||
ZombieFunctionTable[copiedName] = F;
|
||||
F->setZombie();
|
||||
|
||||
// This opens dead-function-removal opportunities for called functions.
|
||||
// (References are not needed anymore.)
|
||||
F->dropAllReferences();
|
||||
} else {
|
||||
FunctionTable.erase(F->getName());
|
||||
getFunctionList().erase(F);
|
||||
}
|
||||
// This opens dead-function-removal opportunities for called functions.
|
||||
// (References are not needed anymore.)
|
||||
F->dropAllReferences();
|
||||
}
|
||||
|
||||
void SILModule::invalidateFunctionInSILCache(SILFunction *F) {
|
||||
|
||||
Reference in New Issue
Block a user