Skip to content

Commit c7051d2

Browse files
committed
[ownership] Change ReturnInst to have its ValueOwnershipKind stored within it rather than always recomputing from the function type.
This allows us to hoist the error case of having a function signature with conflicting ownership requirements into the creation of the return inst instead of at the time of computing Operand Constraints. This is the last part of the Operand Constraint computation that can fail that once removed will let me use fail to mean any constriant is allowed.
1 parent 4aa1ef3 commit c7051d2

File tree

4 files changed

+44
-35
lines changed

4 files changed

+44
-35
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1969,7 +1969,7 @@ class SILBuilder {
19691969

19701970
ReturnInst *createReturn(SILLocation Loc, SILValue ReturnValue) {
19711971
return insertTerminator(new (getModule()) ReturnInst(
1972-
getSILDebugLocation(Loc), ReturnValue));
1972+
getFunction(), getSILDebugLocation(Loc), ReturnValue));
19731973
}
19741974

19751975
ThrowInst *createThrow(SILLocation Loc, SILValue errorValue) {

include/swift/SIL/SILInstruction.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7360,16 +7360,25 @@ class ReturnInst
73607360
{
73617361
friend SILBuilder;
73627362

7363+
/// We store the ownership kind in the return inst, but we do not consider the
7364+
/// underlying return inst to be forwarding. This is because its ownership is
7365+
/// tied to the function signature and thus should be static.
7366+
ValueOwnershipKind ownershipKind;
7367+
73637368
/// Constructs a ReturnInst representing a return.
73647369
///
7365-
/// \param DebugLoc The backing AST location.
7366-
///
7367-
/// \param ReturnValue The value to be returned.
7368-
///
7369-
ReturnInst(SILDebugLocation DebugLoc, SILValue ReturnValue)
7370-
: UnaryInstructionBase(DebugLoc, ReturnValue) {}
7370+
/// \param func The function we are returning from. Used to compute the
7371+
/// preferred ownership kind.
7372+
/// \param debugLoc The backing AST location.
7373+
/// \param returnValue The value to be returned.
7374+
ReturnInst(SILFunction &func, SILDebugLocation debugLoc,
7375+
SILValue returnValue);
73717376

73727377
public:
7378+
/// Return the ownership kind for this instruction if we had any direct
7379+
/// results.
7380+
ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }
7381+
73737382
SuccessorListTy getSuccessors() {
73747383
// No Successors.
73757384
return SuccessorListTy();

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -485,36 +485,11 @@ OperandOwnershipKindClassifier::visitCheckedCastBranchInst(
485485
return map.getValue();
486486
}
487487

488-
//// FIX THIS HERE
489488
OperandOwnershipKindMap
490489
OperandOwnershipKindClassifier::visitReturnInst(ReturnInst *ri) {
491-
auto *f =ri->getFunction();
492-
493-
// If we have a trivial value, return allLive().
494-
bool isTrivial = ri->getOperand()->getType().isTrivial(*f);
495-
if (isTrivial) {
496-
return Map::allLive();
497-
}
498-
499-
SILFunctionConventions fnConv = f->getConventions();
500-
501-
auto results = fnConv.getDirectSILResults();
502-
if (results.empty())
503-
return Map();
504-
505-
auto ownershipKindRange = makeTransformRange(results,
506-
[&](const SILResultInfo &info) {
507-
return info.getOwnershipKind(*f, f->getLoweredFunctionType());
508-
});
509-
510-
// Then merge all of our ownership kinds. If we fail to merge, return an empty
511-
// map so we fail on all operands.
512-
auto mergedBase = ValueOwnershipKind::merge(ownershipKindRange);
513-
if (!mergedBase)
514-
return Map();
515-
516-
auto base = *mergedBase;
517-
return Map::compatibilityMap(base, base.getForwardingLifetimeConstraint());
490+
auto kind = ri->getOwnershipKind();
491+
auto lifetimeConstraint = kind.getForwardingLifetimeConstraint();
492+
return Map::compatibilityMap(kind, lifetimeConstraint);
518493
}
519494

520495
OperandOwnershipKindMap

lib/SIL/IR/SILInstructions.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2863,3 +2863,28 @@ bool GetAsyncContinuationInstBase::throws() const {
28632863
return getType().castTo<BoundGenericType>()->getDecl()
28642864
== getFunction()->getASTContext().getUnsafeThrowingContinuationDecl();
28652865
}
2866+
2867+
ReturnInst::ReturnInst(SILFunction &func, SILDebugLocation debugLoc,
2868+
SILValue returnValue)
2869+
: UnaryInstructionBase(debugLoc, returnValue),
2870+
ownershipKind(ValueOwnershipKind::None) {
2871+
// If we have a trivial value, leave our ownership kind as none.
2872+
if (returnValue->getType().isTrivial(func))
2873+
return;
2874+
2875+
SILFunctionConventions fnConv = func.getConventions();
2876+
2877+
// If we do not have any direct SIL results, we should accept a tuple
2878+
// argument, meaning that we should have a none ownership kind.
2879+
auto results = fnConv.getDirectSILResults();
2880+
if (results.empty())
2881+
return;
2882+
2883+
auto ownershipKindRange =
2884+
makeTransformRange(results, [&](const SILResultInfo &info) {
2885+
return info.getOwnershipKind(func, func.getLoweredFunctionType());
2886+
});
2887+
2888+
// Then merge all of our ownership kinds. Assert if we fail to merge.
2889+
ownershipKind = *ValueOwnershipKind::merge(ownershipKindRange);
2890+
}

0 commit comments

Comments
 (0)