Skip to content

Commit 1dc5c96

Browse files
committed
Intoduce unchecked_ownership instruction in raw SIL
This instruction can be used to disable ownership verification on it's result and will be allowed only in raw SIL. Sometimes SILGen can produce invalid ownership SSA, that cannot be resolved until mandatory passes run. We have a few ways to piecewise disable verification. With unchecked_ownership instruction we can provide a uniform way to disable ownership verification for a value.
1 parent a3aed17 commit 1dc5c96

File tree

17 files changed

+66
-2
lines changed

17 files changed

+66
-2
lines changed

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,6 +1447,8 @@ final public class CopyableToMoveOnlyWrapperAddrInst
14471447
final public class MoveOnlyWrapperToCopyableAddrInst
14481448
: SingleValueInstruction, UnaryInstruction {}
14491449

1450+
final public class UncheckedOwnershipInst: SingleValueInstruction, UnaryInstruction {}
1451+
14501452
final public class ObjectInst : SingleValueInstruction {
14511453
public var baseOperands: OperandArray {
14521454
operands[0..<bridged.ObjectInst_getNumBaseElements()]

SwiftCompilerSources/Sources/SIL/Registration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ private func registerSILClasses() {
120120
register(MoveOnlyWrapperToCopyableBoxInst.self)
121121
register(CopyableToMoveOnlyWrapperAddrInst.self)
122122
register(MoveOnlyWrapperToCopyableAddrInst.self)
123+
register(UncheckedOwnershipInst.self)
123124
register(ObjectInst.self)
124125
register(VectorInst.self)
125126
register(VectorBaseAddrInst.self)

include/swift/SIL/SILBuilder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,6 +1555,12 @@ class SILBuilder {
15551555
MoveOnlyWrapperToCopyableValueInst::Guaranteed));
15561556
}
15571557

1558+
UncheckedOwnershipInst *createUncheckedOwnership(SILLocation Loc,
1559+
SILValue Operand) {
1560+
return insert(new (getModule()) UncheckedOwnershipInst(
1561+
getSILDebugLocation(Loc), Operand, Operand->getOwnershipKind()));
1562+
}
1563+
15581564
UnconditionalCheckedCastInst *
15591565
createUnconditionalCheckedCast(SILLocation Loc,
15601566
CheckedCastInstOptions options,

include/swift/SIL/SILCloner.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2247,6 +2247,19 @@ void SILCloner<ImplClass>::visitCopyableToMoveOnlyWrapperValueInst(
22472247
recordClonedInstruction(inst, cvt);
22482248
}
22492249

2250+
template <typename ImplClass>
2251+
void SILCloner<ImplClass>::visitUncheckedOwnershipInst(
2252+
UncheckedOwnershipInst *uoi) {
2253+
getBuilder().setCurrentDebugScope(getOpScope(uoi->getDebugScope()));
2254+
if (!getBuilder().hasOwnership()) {
2255+
return recordFoldedValue(uoi, getOpValue(uoi->getOperand()));
2256+
}
2257+
2258+
recordClonedInstruction(
2259+
uoi, getBuilder().createUncheckedOwnership(
2260+
getOpLocation(uoi->getLoc()), getOpValue(uoi->getOperand())));
2261+
}
2262+
22502263
template <typename ImplClass>
22512264
void SILCloner<ImplClass>::visitReleaseValueInst(ReleaseValueInst *Inst) {
22522265
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));

include/swift/SIL/SILInstruction.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9553,6 +9553,17 @@ class MoveOnlyWrapperToCopyableAddrInst
95539553
}
95549554
};
95559555

9556+
class UncheckedOwnershipInst final
9557+
: public UnaryInstructionBase<SILInstructionKind::UncheckedOwnershipInst,
9558+
OwnershipForwardingSingleValueInstruction> {
9559+
friend class SILBuilder;
9560+
9561+
UncheckedOwnershipInst(SILDebugLocation DebugLoc, SILValue operand,
9562+
ValueOwnershipKind forwardingOwnershipKind)
9563+
: UnaryInstructionBase(DebugLoc, operand, operand->getType(),
9564+
forwardingOwnershipKind) {}
9565+
};
9566+
95569567
/// Given an object reference, return true iff it is non-nil and refers
95579568
/// to a native swift object with strong reference count of 1.
95589569
class IsUniqueInst
@@ -11696,6 +11707,7 @@ OwnershipForwardingSingleValueInstruction::classof(SILInstructionKind kind) {
1169611707
case SILInstructionKind::DropDeinitInst:
1169711708
case SILInstructionKind::BorrowedFromInst:
1169811709
case SILInstructionKind::ImplicitActorToOpaqueIsolationCastInst:
11710+
case SILInstructionKind::UncheckedOwnershipInst:
1169911711
return true;
1170011712
default:
1170111713
return false;

include/swift/SIL/SILNodes.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,8 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
469469
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
470470
#include "swift/AST/ReferenceStorage.def"
471471
SINGLE_VALUE_INST(UncheckedOwnershipConversionInst, unchecked_ownership_conversion,
472-
SingleValueInstruction, None, MayRelease)
472+
SingleValueInstruction, None, DoesNotRelease)
473+
473474
// A move_value is an OSSA only instruction. Its result does not have any side
474475
// effects relative to other OSSA values like copy_value.
475476
SINGLE_VALUE_INST(MoveValueInst, move_value, SingleValueInstruction, None,
@@ -520,6 +521,8 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
520521
SINGLE_VALUE_INST(CopyableToMoveOnlyWrapperAddrInst,
521522
copyable_to_moveonlywrapper_addr, SingleValueInstruction,
522523
None, DoesNotRelease)
524+
SINGLE_VALUE_INST(UncheckedOwnershipInst, unchecked_ownership,
525+
SingleValueInstruction, None, DoesNotRelease)
523526

524527
// IsUnique does not actually write to memory but should be modeled
525528
// as such. Its operand is a pointer to an object reference. The

lib/IRGen/IRGenSIL.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1302,7 +1302,9 @@ class IRGenSILFunction :
13021302
auto e = getLoweredExplosion(i->getOperand());
13031303
setLoweredExplosion(i, e);
13041304
}
1305-
1305+
void visitUncheckedOwnershipInst(UncheckedOwnershipInst *i) {
1306+
llvm_unreachable("unimplemented");
1307+
}
13061308
void visitMergeIsolationRegionInst(MergeIsolationRegionInst *i) {
13071309
llvm_unreachable("Valid only when ownership is enabled");
13081310
}

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ AGGREGATE_OWNERSHIP(DestructureTuple)
421421
AGGREGATE_OWNERSHIP(Enum)
422422
AGGREGATE_OWNERSHIP(UncheckedEnumData)
423423
AGGREGATE_OWNERSHIP(SwitchEnum)
424+
AGGREGATE_OWNERSHIP(UncheckedOwnership)
424425
#undef AGGREGATE_OWNERSHIP
425426

426427
// A begin_borrow is conditionally nested.

lib/SIL/IR/SILPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2367,6 +2367,10 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
23672367
*this << getIDAndType(I->getOperand());
23682368
}
23692369

2370+
void visitUncheckedOwnershipInst(UncheckedOwnershipInst *I) {
2371+
*this << getIDAndType(I->getOperand());
2372+
}
2373+
23702374
void visitUnownedCopyValueInst(UnownedCopyValueInst *I) {
23712375
*this << getIDAndType(I->getOperand());
23722376
}

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ FORWARDING_OWNERSHIP_INST(MarkUnresolvedReferenceBinding)
323323
FORWARDING_OWNERSHIP_INST(MoveOnlyWrapperToCopyableValue)
324324
FORWARDING_OWNERSHIP_INST(CopyableToMoveOnlyWrapperValue)
325325
FORWARDING_OWNERSHIP_INST(MoveOnlyWrapperToCopyableBox)
326+
FORWARDING_OWNERSHIP_INST(UncheckedOwnership)
326327
#undef FORWARDING_OWNERSHIP_INST
327328

328329
ValueOwnershipKind

0 commit comments

Comments
 (0)