Skip to content

[ownership] When deserializing a SILFunction, match the ownership of … #26605

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
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
10 changes: 7 additions & 3 deletions include/swift/SIL/SILFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,12 @@ class SILFunction
SILFunction *InsertBefore = nullptr,
const SILDebugScope *DebugScope = nullptr);

/// Set has ownership to the given value. True means that the function has
/// ownership, false means it does not.
///
/// Only for use by FunctionBuilders!
void setHasOwnership(bool newValue) { HasOwnership = newValue; }

public:
~SILFunction();

Expand Down Expand Up @@ -444,9 +450,7 @@ class SILFunction

/// Sets the HasOwnership flag to false. This signals to SIL that no
/// ownership instructions should be in this function any more.
void setOwnershipEliminated() {
HasOwnership = false;
}
void setOwnershipEliminated() { setHasOwnership(false); }

/// Returns true if this function was deserialized from canonical
/// SIL. (.swiftmodule files contain canonical SIL; .sib files may be 'raw'
Expand Down
8 changes: 8 additions & 0 deletions include/swift/SIL/SILFunctionBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,15 @@ class SILFunctionBuilder {

void addFunctionAttributes(SILFunction *F, DeclAttributes &Attrs,
SILModule &M, SILDeclRef constant = SILDeclRef());

/// We do not expose this to everyone, instead we allow for our users to opt
/// into this if they need to. Please do not do this in general! We only want
/// to use this when deserializing a function body.
static void setHasOwnership(SILFunction *F, bool newValue) {
F->setHasOwnership(newValue);
}
};

} // namespace swift

#endif
19 changes: 10 additions & 9 deletions lib/Serialization/DeserializeSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,8 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn,
if (SILMod.isSerialized())
isSerialized = IsNotSerialized;

SILSerializationFunctionBuilder builder(SILMod);

// If we have an existing function, verify that the types match up.
if (fn) {
if (fn->getLoweredType() != ty) {
Expand Down Expand Up @@ -576,7 +578,6 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn,

} else {
// Otherwise, create a new function.
SILSerializationFunctionBuilder builder(SILMod);
fn = builder.createDeclaration(name, ty, loc);
fn->setLinkage(linkage.getValue());
fn->setTransparent(IsTransparent_t(isTransparent == 1));
Expand All @@ -599,19 +600,22 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn,
for (auto ID : SemanticsIDs) {
fn->addSemanticsAttr(MF->getIdentifierText(ID));
}
if (!hasQualifiedOwnership)
fn->setOwnershipEliminated();
if (Callback) Callback->didDeserialize(MF->getAssociatedModule(), fn);
}

// First before we do /anything/ validate that our function is truly empty.
assert(fn->empty() && "SILFunction to be deserialized starts being empty.");

// Given that our original function was empty, just match the deserialized
// function. Ownership doesn't really have a meaning without a body.
builder.setHasOwnership(fn, hasQualifiedOwnership);

// Mark this function as deserialized. This avoids rerunning diagnostic
// passes. Certain passes in the madatory pipeline may not work as expected
// after arbitrary optimization and lowering.
if (!MF->IsSIB)
fn->setWasDeserializedCanonical();

assert(fn->empty() &&
"SILFunction to be deserialized starts being empty.");

fn->setBare(IsBare);
const SILDebugScope *DS = fn->getDebugScope();
if (!DS) {
Expand Down Expand Up @@ -675,9 +679,6 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn,
&& "function already has context generic params?!");
if (genericEnv)
fn->setGenericEnvironment(genericEnv);
if (!hasQualifiedOwnership) {
fn->setOwnershipEliminated();
}

scratch.clear();
kind = SILCursor.readRecord(entry.ID, scratch);
Expand Down
4 changes: 4 additions & 0 deletions lib/Serialization/SILSerializationFunctionBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ class LLVM_LIBRARY_VISIBILITY SILSerializationFunctionBuilder {
IsNotSerialized, IsNotDynamic, ProfileCounter(), IsNotThunk,
SubclassScope::NotApplicable);
}

void setHasOwnership(SILFunction *f, bool newValue) {
builder.setHasOwnership(f, newValue);
}
};

} // namespace swift
Expand Down