Skip to content

Commit cf8a9de

Browse files
committed
Additional comments about the different orders of deserialization and
bugfixes
1 parent 384877f commit cf8a9de

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

lib/Serialization/DeserializeSIL.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,8 @@ llvm::Expected<SILFunction *> SILDeserializer::readSILFunctionChecked(
609609
// We can't deserialize function bodies after IRGen lowering passes have
610610
// happened since other definitions in the module will no longer be in
611611
// canonical SIL form.
612+
assert(!forDebugScope || declarationOnly); // debug scopes must always be read
613+
// declaration only
612614
switch (SILMod.getStage()) {
613615
case SILStage::Raw:
614616
case SILStage::Canonical:
@@ -628,12 +630,29 @@ llvm::Expected<SILFunction *> SILDeserializer::readSILFunctionChecked(
628630
auto &cacheEntry = Funcs[FID - 1];
629631

630632
if (cacheEntry.isFullyDeserialized() ||
631-
(cacheEntry.isDeserialized() && (declarationOnly || forDebugScope))) {
633+
(cacheEntry.isDeserialized() && declarationOnly)) {
632634
auto fn = cacheEntry.get();
633635

634-
if (fn->isZombie() && !forDebugScope)
635-
return nullptr;
636-
return fn;
636+
// Functions onlyReferencedByDebugInfo (A) are a subset of functions
637+
// referred to by debug scopes forDebugScope=true (B)
638+
639+
// I) Functions in A U B only ever get deserialized as zombies
640+
641+
// II) For rest of functions (B - A), there are two orders of
642+
// deserialization:
643+
// i) Deserialized for debugging -> deserialized by linker/optimizer:
644+
// a) Deserialize as zombie. When referenced by linker/optimizer,
645+
// createDeclaration would resurrect function as normal
646+
// ii) Deserialized by linker/optimizer -> deserialized for debugging ->
647+
// no zombie created
648+
649+
if (fn->isZombie() && !forDebugScope) {
650+
if (cacheEntry.isFullyDeserialized())
651+
return nullptr;
652+
// else function resurrected below by createDeclaration
653+
} else {
654+
return fn;
655+
}
637656
}
638657

639658
BCOffsetRAII restoreOffset(SILCursor);
@@ -836,7 +855,7 @@ llvm::Expected<SILFunction *> SILDeserializer::readSILFunctionChecked(
836855

837856
// TODO: for functions deserialized for debug scopes, set linkage to private
838857
// as public symbols make into the final binary even when zombies?
839-
fn->setLinkage(onlyReferencedByDebugInfo ? SILLinkage::Private : linkage);
858+
fn->setLinkage(forDebugScope ? SILLinkage::Private : linkage);
840859
fn->setTransparent(IsTransparent_t(isTransparent == 1));
841860
fn->setSerializedKind(SerializedKind_t(serializedKind));
842861
fn->setThunk(IsThunk_t(isThunk));
@@ -873,10 +892,9 @@ llvm::Expected<SILFunction *> SILDeserializer::readSILFunctionChecked(
873892
for (auto ID : SemanticsIDs) {
874893
fn->addSemanticsAttr(MF->getIdentifierText(ID));
875894
}
876-
if (onlyReferencedByDebugInfo) {
895+
if (forDebugScope)
877896
SILMod.eraseFunction(fn);
878-
}
879-
if (Callback && !onlyReferencedByDebugInfo)
897+
if (Callback && !forDebugScope)
880898
Callback->didDeserialize(MF->getAssociatedModule(), fn);
881899
}
882900

@@ -1013,7 +1031,7 @@ llvm::Expected<SILFunction *> SILDeserializer::readSILFunctionChecked(
10131031
// Remember this in our cache in case it's a recursive function.
10141032
// Increase the reference count to keep it alive.
10151033
bool isFullyDeserialized =
1016-
(isEmptyFunction || !declarationOnly) && !onlyReferencedByDebugInfo;
1034+
(isEmptyFunction || !declarationOnly || onlyReferencedByDebugInfo);
10171035
if (cacheEntry.isDeserialized()) {
10181036
assert(fn == cacheEntry.get() && "changing SIL function during deserialization!");
10191037
} else {

0 commit comments

Comments
 (0)