Skip to content

[ownership] Change ReturnInst to have its ValueOwnershipKind stored within it rather than always recomputing from the function type. #34644

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
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
2 changes: 1 addition & 1 deletion include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1969,7 +1969,7 @@ class SILBuilder {

ReturnInst *createReturn(SILLocation Loc, SILValue ReturnValue) {
return insertTerminator(new (getModule()) ReturnInst(
getSILDebugLocation(Loc), ReturnValue));
getFunction(), getSILDebugLocation(Loc), ReturnValue));
}

ThrowInst *createThrow(SILLocation Loc, SILValue errorValue) {
Expand Down
21 changes: 15 additions & 6 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -7360,16 +7360,25 @@ class ReturnInst
{
friend SILBuilder;

/// We store the ownership kind in the return inst, but we do not consider the
/// underlying return inst to be forwarding. This is because its ownership is
/// tied to the function signature and thus should be static.
ValueOwnershipKind ownershipKind;

/// Constructs a ReturnInst representing a return.
///
/// \param DebugLoc The backing AST location.
///
/// \param ReturnValue The value to be returned.
///
ReturnInst(SILDebugLocation DebugLoc, SILValue ReturnValue)
: UnaryInstructionBase(DebugLoc, ReturnValue) {}
/// \param func The function we are returning from. Used to compute the
/// preferred ownership kind.
/// \param debugLoc The backing AST location.
/// \param returnValue The value to be returned.
ReturnInst(SILFunction &func, SILDebugLocation debugLoc,
SILValue returnValue);

public:
/// Return the ownership kind for this instruction if we had any direct
/// results.
ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }

SuccessorListTy getSuccessors() {
// No Successors.
return SuccessorListTy();
Expand Down
31 changes: 3 additions & 28 deletions lib/SIL/IR/OperandOwnership.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,36 +485,11 @@ OperandOwnershipKindClassifier::visitCheckedCastBranchInst(
return map.getValue();
}

//// FIX THIS HERE
OperandOwnershipKindMap
OperandOwnershipKindClassifier::visitReturnInst(ReturnInst *ri) {
auto *f =ri->getFunction();

// If we have a trivial value, return allLive().
bool isTrivial = ri->getOperand()->getType().isTrivial(*f);
if (isTrivial) {
return Map::allLive();
}

SILFunctionConventions fnConv = f->getConventions();

auto results = fnConv.getDirectSILResults();
if (results.empty())
return Map();

auto ownershipKindRange = makeTransformRange(results,
[&](const SILResultInfo &info) {
return info.getOwnershipKind(*f, f->getLoweredFunctionType());
});

// Then merge all of our ownership kinds. If we fail to merge, return an empty
// map so we fail on all operands.
auto mergedBase = ValueOwnershipKind::merge(ownershipKindRange);
if (!mergedBase)
return Map();

auto base = *mergedBase;
return Map::compatibilityMap(base, base.getForwardingLifetimeConstraint());
auto kind = ri->getOwnershipKind();
auto lifetimeConstraint = kind.getForwardingLifetimeConstraint();
return Map::compatibilityMap(kind, lifetimeConstraint);
}

OperandOwnershipKindMap
Expand Down
25 changes: 25 additions & 0 deletions lib/SIL/IR/SILInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2863,3 +2863,28 @@ bool GetAsyncContinuationInstBase::throws() const {
return getType().castTo<BoundGenericType>()->getDecl()
== getFunction()->getASTContext().getUnsafeThrowingContinuationDecl();
}

ReturnInst::ReturnInst(SILFunction &func, SILDebugLocation debugLoc,
SILValue returnValue)
: UnaryInstructionBase(debugLoc, returnValue),
ownershipKind(ValueOwnershipKind::None) {
// If we have a trivial value, leave our ownership kind as none.
if (returnValue->getType().isTrivial(func))
return;

SILFunctionConventions fnConv = func.getConventions();

// If we do not have any direct SIL results, we should accept a tuple
// argument, meaning that we should have a none ownership kind.
auto results = fnConv.getDirectSILResults();
if (results.empty())
return;

auto ownershipKindRange =
makeTransformRange(results, [&](const SILResultInfo &info) {
return info.getOwnershipKind(func, func.getLoweredFunctionType());
});

// Then merge all of our ownership kinds. Assert if we fail to merge.
ownershipKind = *ValueOwnershipKind::merge(ownershipKindRange);
}