Skip to content

Commit 5e36ae1

Browse files
committed
[sil] Add a forwarding cast called unchecked_value_cast.
Today unchecked_bitwise_cast returns a value with ObjCUnowned ownership. This is important to do since the instruction can truncate memory meaning we want to treat it as a new object that must be copied before use. This means that in OSSA we do not have a purely ossa forwarding unchecked layout-compatible assuming cast. This role is filled by unchecked_value_cast.
1 parent d1a54a5 commit 5e36ae1

File tree

22 files changed

+132
-1
lines changed

22 files changed

+132
-1
lines changed

docs/SIL.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5148,6 +5148,21 @@ unchecked_bitwise_cast
51485148
Bitwise copies an object of type ``A`` into a new object of type ``B``
51495149
of the same size or smaller.
51505150

5151+
unchecked_value_cast
5152+
````````````````````
5153+
::
5154+
5155+
sil-instruction ::= 'unchecked_value_cast' sil-operand 'to' sil-type
5156+
5157+
%1 = unchecked_value_cast %0 : $A to $B
5158+
5159+
Bitwise copies an object of type ``A`` into a new layout-compatible object of
5160+
type ``B`` of the same size.
5161+
5162+
This instruction is assumed to forward a fixed ownership (set upon its
5163+
construction) and lowers to 'unchecked_bitwise_cast' in non-ossa code. This
5164+
causes the cast to lose its guarantee of layout-compatibility.
5165+
51515166
ref_to_raw_pointer
51525167
``````````````````
51535168
::

include/swift/SIL/SILBuilder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,12 @@ class SILBuilder {
11021102
getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes));
11031103
}
11041104

1105+
UncheckedValueCastInst *createUncheckedValueCast(SILLocation Loc, SILValue Op,
1106+
SILType Ty) {
1107+
return insert(UncheckedValueCastInst::create(
1108+
getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes));
1109+
}
1110+
11051111
RefToBridgeObjectInst *createRefToBridgeObject(SILLocation Loc, SILValue Ref,
11061112
SILValue Bits) {
11071113
auto Ty = SILType::getBridgeObjectType(getASTContext());

include/swift/SIL/SILCloner.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,6 +1538,16 @@ visitUncheckedBitwiseCastInst(UncheckedBitwiseCastInst *Inst) {
15381538
getOpType(Inst->getType())));
15391539
}
15401540

1541+
template <typename ImplClass>
1542+
void SILCloner<ImplClass>::visitUncheckedValueCastInst(
1543+
UncheckedValueCastInst *Inst) {
1544+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1545+
recordClonedInstruction(Inst, getBuilder().createUncheckedValueCast(
1546+
getOpLocation(Inst->getLoc()),
1547+
getOpValue(Inst->getOperand()),
1548+
getOpType(Inst->getType())));
1549+
}
1550+
15411551
template<typename ImplClass>
15421552
void
15431553
SILCloner<ImplClass>::

include/swift/SIL/SILInstruction.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4576,6 +4576,23 @@ class UncheckedBitwiseCastInst final
45764576
SILFunction &F, SILOpenedArchetypesState &OpenedArchetypes);
45774577
};
45784578

4579+
/// Bitwise copy a value into another value of the same size.
4580+
class UncheckedValueCastInst final
4581+
: public UnaryInstructionWithTypeDependentOperandsBase<
4582+
SILInstructionKind::UncheckedValueCastInst, UncheckedValueCastInst,
4583+
OwnershipForwardingConversionInst> {
4584+
friend SILBuilder;
4585+
4586+
UncheckedValueCastInst(SILDebugLocation DebugLoc, SILValue Operand,
4587+
ArrayRef<SILValue> TypeDependentOperands, SILType Ty)
4588+
: UnaryInstructionWithTypeDependentOperandsBase(
4589+
DebugLoc, Operand, TypeDependentOperands, Ty,
4590+
Operand.getOwnershipKind()) {}
4591+
static UncheckedValueCastInst *
4592+
create(SILDebugLocation DebugLoc, SILValue Operand, SILType Ty,
4593+
SILFunction &F, SILOpenedArchetypesState &OpenedArchetypes);
4594+
};
4595+
45794596
/// Build a Builtin.BridgeObject from a heap object reference by bitwise-or-ing
45804597
/// in bits from a word.
45814598
class RefToBridgeObjectInst

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,8 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
500500
ConversionInst, None, DoesNotRelease)
501501
SINGLE_VALUE_INST(UncheckedBitwiseCastInst, unchecked_bitwise_cast,
502502
ConversionInst, None, DoesNotRelease)
503+
SINGLE_VALUE_INST(UncheckedValueCastInst, unchecked_value_cast,
504+
ConversionInst, None, DoesNotRelease)
503505
SINGLE_VALUE_INST(RefToRawPointerInst, ref_to_raw_pointer,
504506
ConversionInst, None, DoesNotRelease)
505507
SINGLE_VALUE_INST(RawPointerToRefInst, raw_pointer_to_ref,

lib/IRGen/IRGenSIL.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,9 @@ class IRGenSILFunction :
10261026
void visitUncheckedAddrCastInst(UncheckedAddrCastInst *i);
10271027
void visitUncheckedTrivialBitCastInst(UncheckedTrivialBitCastInst *i);
10281028
void visitUncheckedBitwiseCastInst(UncheckedBitwiseCastInst *i);
1029+
void visitUncheckedValueCastInst(UncheckedValueCastInst *i) {
1030+
llvm_unreachable("Should never be seen in Lowered SIL");
1031+
}
10291032
void visitRefToRawPointerInst(RefToRawPointerInst *i);
10301033
void visitRawPointerToRefInst(RawPointerToRefInst *i);
10311034
void visitThinToThickFunctionInst(ThinToThickFunctionInst *i);

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ FORWARD_ANY_OWNERSHIP_INST(DestructureTuple)
350350
FORWARD_ANY_OWNERSHIP_INST(InitExistentialRef)
351351
FORWARD_ANY_OWNERSHIP_INST(DifferentiableFunction)
352352
FORWARD_ANY_OWNERSHIP_INST(LinearFunction)
353+
FORWARD_ANY_OWNERSHIP_INST(UncheckedValueCast)
353354
#undef FORWARD_ANY_OWNERSHIP_INST
354355

355356
// An instruction that forwards a constant ownership or trivial ownership.

lib/SIL/IR/SILInstructions.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2217,6 +2217,21 @@ UncheckedRefCastInst::create(SILDebugLocation DebugLoc, SILValue Operand,
22172217
TypeDependentOperands, Ty);
22182218
}
22192219

2220+
UncheckedValueCastInst *
2221+
UncheckedValueCastInst::create(SILDebugLocation DebugLoc, SILValue Operand,
2222+
SILType Ty, SILFunction &F,
2223+
SILOpenedArchetypesState &OpenedArchetypes) {
2224+
SILModule &Mod = F.getModule();
2225+
SmallVector<SILValue, 8> TypeDependentOperands;
2226+
collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, F,
2227+
Ty.getASTType());
2228+
unsigned size =
2229+
totalSizeToAlloc<swift::Operand>(1 + TypeDependentOperands.size());
2230+
void *Buffer = Mod.allocateInst(size, alignof(UncheckedValueCastInst));
2231+
return ::new (Buffer)
2232+
UncheckedValueCastInst(DebugLoc, Operand, TypeDependentOperands, Ty);
2233+
}
2234+
22202235
UncheckedAddrCastInst *
22212236
UncheckedAddrCastInst::create(SILDebugLocation DebugLoc, SILValue Operand,
22222237
SILType Ty, SILFunction &F,

lib/SIL/IR/SILPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1620,6 +1620,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
16201620
void visitUncheckedBitwiseCastInst(UncheckedBitwiseCastInst *CI) {
16211621
printUncheckedConversionInst(CI, CI->getOperand());
16221622
}
1623+
void visitUncheckedValueCastInst(UncheckedValueCastInst *CI) {
1624+
printUncheckedConversionInst(CI, CI->getOperand());
1625+
}
16231626
void visitRefToRawPointerInst(RefToRawPointerInst *CI) {
16241627
printUncheckedConversionInst(CI, CI->getOperand());
16251628
}

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ FORWARDING_OWNERSHIP_INST(Tuple)
254254
FORWARDING_OWNERSHIP_INST(UncheckedRefCast)
255255
FORWARDING_OWNERSHIP_INST(UnconditionalCheckedCast)
256256
FORWARDING_OWNERSHIP_INST(Upcast)
257+
FORWARDING_OWNERSHIP_INST(UncheckedValueCast)
257258
FORWARDING_OWNERSHIP_INST(UncheckedEnumData)
258259
FORWARDING_OWNERSHIP_INST(SelectEnum)
259260
FORWARDING_OWNERSHIP_INST(Enum)

0 commit comments

Comments
 (0)