Skip to content

Commit 90c0c8b

Browse files
committed
Add rebind_memory SIL instruction.
Required for UnsafeRawPointer.withMemoryReboud(to:). %out_token = rebind_memory %0 : $Builtin.RawPointer to %in_token %0 must be of $Builtin.RawPointer type %in_token represents a cached set of bound types from a prior memory state. %out_token is an opaque $Builtin.Word representing the previously bound types for this memory region. This instruction's semantics are identical to ``bind_memory``, except that the types to which memory will be bound, and the extent of the memory region is unknown at compile time. Instead, the bound-types are represented by a token that was produced by a prior memory binding operation. ``%in_token`` must be the result of bind_memory or
1 parent 17fef2f commit 90c0c8b

File tree

22 files changed

+200
-21
lines changed

22 files changed

+200
-21
lines changed

docs/SIL.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4000,6 +4000,26 @@ was previously bound to. The token cannot, however, be used to
40004000
retrieve a metatype. It's value is only meaningful to the Swift
40014001
runtime for typed pointer verification.
40024002

4003+
rebind_memory
4004+
`````````````
4005+
4006+
::
4007+
4008+
sil-instruction ::= 'rebind_memory' sil-operand ' 'to' sil-value
4009+
4010+
%out_token = rebind_memory %0 : $Builtin.RawPointer to %in_token
4011+
// %0 must be of $Builtin.RawPointer type
4012+
// %in_token represents a cached set of bound types from a prior memory state.
4013+
// %out_token is an opaque $Builtin.Word representing the previously bound
4014+
// types for this memory region.
4015+
4016+
This instruction's semantics are identical to ``bind_memory``, except
4017+
that the types to which memory will be bound, and the extent of the
4018+
memory region is unknown at compile time. Instead, the bound-types are
4019+
represented by a token that was produced by a prior memory binding
4020+
operation. ``%in_token`` must be the result of bind_memory or
4021+
rebind_memory.
4022+
40034023
begin_access
40044024
````````````
40054025

include/swift/AST/Builtins.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,12 @@ BUILTIN_SIL_OPERATION(EndCOWMutation, "endCOWMutation", Special)
458458
/// representing the memory region's previously bound types.
459459
BUILTIN_SIL_OPERATION(BindMemory, "bindMemory", Special)
460460

461+
/// rebindMemory : (Builtin.RawPointer, Builtin.Word) -> Builtin.Word
462+
///
463+
/// Binds memory to the types represented by an opaque token operand. Returns an
464+
/// opaque token representing the memory region's previously bound types.
465+
BUILTIN_SIL_OPERATION(RebindMemory, "rebindMemory", Special)
466+
461467
/// allocWithTailElems_<n>(C.Type,
462468
/// Builtin.Word, E1.Type, ... , Builtin.Word, En.Type) -> C\
463469
///

include/swift/SIL/SILBuilder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,13 @@ class SILBuilder {
10271027
boundType, getFunction()));
10281028
}
10291029

1030+
RebindMemoryInst *createRebindMemory(SILLocation Loc, SILValue base,
1031+
SILValue inToken) {
1032+
auto tokenTy = SILType::getBuiltinWordType(F->getASTContext());
1033+
return insert(new (getModule()) RebindMemoryInst(getSILDebugLocation(Loc),
1034+
base, inToken, tokenTy));
1035+
}
1036+
10301037
ConvertFunctionInst *createConvertFunction(SILLocation Loc, SILValue Op,
10311038
SILType Ty,
10321039
bool WithoutActuallyEscaping) {

include/swift/SIL/SILCloner.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,6 +1351,15 @@ SILCloner<ImplClass>::visitBindMemoryInst(BindMemoryInst *Inst) {
13511351
getOpValue(Inst->getIndex()), getOpType(Inst->getBoundType())));
13521352
}
13531353

1354+
template <typename ImplClass>
1355+
void SILCloner<ImplClass>::visitRebindMemoryInst(RebindMemoryInst *Inst) {
1356+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1357+
recordClonedInstruction(
1358+
Inst, getBuilder().createRebindMemory(getOpLocation(Inst->getLoc()),
1359+
getOpValue(Inst->getBase()),
1360+
getOpValue(Inst->getInToken())));
1361+
}
1362+
13541363
template<typename ImplClass>
13551364
void
13561365
SILCloner<ImplClass>::visitConvertFunctionInst(ConvertFunctionInst *Inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4909,6 +4909,38 @@ class BindMemoryInst final : public InstructionBaseWithTrailingOperands<
49094909
}
49104910
};
49114911

4912+
/// "%out_token = rebind_memory
4913+
/// %0 : $Builtin.RawPointer, %in_token : $Builtin.Word
4914+
///
4915+
/// Binds memory at the raw pointer %0 to the types abstractly represented by
4916+
/// %in_token.
4917+
///
4918+
/// %in_token is itself the result of a bind_memory or rebind_memory and
4919+
/// represents a previously cached set of bound types.
4920+
///
4921+
/// %out_token represents the previously bound types of this memory region,
4922+
/// before binding it to %in_token.
4923+
class RebindMemoryInst final : public SingleValueInstruction {
4924+
FixedOperandList<2> Operands;
4925+
4926+
public:
4927+
enum { BaseOperIdx, InTokenOperIdx };
4928+
4929+
RebindMemoryInst(SILDebugLocation Loc, SILValue Base, SILValue InToken,
4930+
SILType TokenType)
4931+
: SingleValueInstruction(SILInstructionKind::RebindMemoryInst, Loc,
4932+
TokenType),
4933+
Operands{this, Base, InToken} {}
4934+
4935+
public:
4936+
SILValue getBase() const { return getAllOperands()[BaseOperIdx].get(); }
4937+
4938+
SILValue getInToken() const { return getAllOperands()[InTokenOperIdx].get(); }
4939+
4940+
ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
4941+
MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
4942+
};
4943+
49124944
//===----------------------------------------------------------------------===//
49134945
// Conversion instructions.
49144946
//===----------------------------------------------------------------------===//

include/swift/SIL/SILNodes.def

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -750,14 +750,16 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
750750
SINGLE_VALUE_INST(KeyPathInst, keypath,
751751
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
752752

753-
// BindMemory has no physical side effect. Semantically it writes to
754-
// its affected memory region because any reads or writes accessing
753+
// BindMemory and RebindMemory have no physical side effect. Semantically they
754+
// write to their affected memory region because any reads or writes accessing
755755
// that memory must be dependent on the bind operation.
756756
SINGLE_VALUE_INST(BindMemoryInst, bind_memory,
757757
SILInstruction, MayWrite, DoesNotRelease)
758+
SINGLE_VALUE_INST(RebindMemoryInst, rebind_memory,
759+
SILInstruction, MayWrite, DoesNotRelease)
758760

759-
SINGLE_VALUE_INST_RANGE(SingleValueInstruction, AllocStackInst, BindMemoryInst)
760-
NODE_RANGE(ValueBase, SILPhiArgument, BindMemoryInst)
761+
SINGLE_VALUE_INST_RANGE(SingleValueInstruction, AllocStackInst, RebindMemoryInst)
762+
NODE_RANGE(ValueBase, SILPhiArgument, RebindMemoryInst)
761763

762764
// Terminators
763765
ABSTRACT_INST(TermInst, SILInstruction)

lib/AST/Builtins.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,14 @@ static ValueDecl *getBindMemoryOperation(ASTContext &ctx, Identifier id) {
897897
fd->getAttrs().add(new (ctx) DiscardableResultAttr(/*implicit*/true));
898898
return fd;
899899
}
900+
901+
static ValueDecl *getRebindMemoryOperation(ASTContext &ctx, Identifier id) {
902+
FuncDecl *fd = getBuiltinFunction(ctx, id, _thin,
903+
_parameters(_rawPointer,
904+
_word),
905+
_word);
906+
fd->getAttrs().add(new (ctx) DiscardableResultAttr(/*implicit*/true));
907+
return fd;
900908
}
901909

902910
static ValueDecl *getAllocWithTailElemsOperation(ASTContext &Context,
@@ -2632,6 +2640,10 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
26322640
if (!Types.empty()) return nullptr;
26332641
return getBindMemoryOperation(Context, Id);
26342642

2643+
case BuiltinValueKind::RebindMemory:
2644+
if (!Types.empty()) return nullptr;
2645+
return getRebindMemoryOperation(Context, Id);
2646+
26352647
case BuiltinValueKind::ProjectTailElems:
26362648
if (!Types.empty()) return nullptr;
26372649
return getProjectTailElemsOperation(Context, Id);

lib/IRGen/IRGenSIL.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,6 +1265,7 @@ class IRGenSILFunction :
12651265
void visitDestroyAddrInst(DestroyAddrInst *i);
12661266

12671267
void visitBindMemoryInst(BindMemoryInst *i);
1268+
void visitRebindMemoryInst(RebindMemoryInst *i);
12681269

12691270
void visitCondFailInst(CondFailInst *i);
12701271

@@ -6785,10 +6786,13 @@ void IRGenSILFunction::visitCopyAddrInst(swift::CopyAddrInst *i) {
67856786
}
67866787
}
67876788

6788-
// This is a no-op because we do not lower Swift TBAA info to LLVM IR, and it
6789-
// does not produce any values.
6789+
// bind_memory and rebind_memory are no-ops because Swift TBAA info is not
6790+
// lowered to LLVM IR TBAA, and the output token is ignored except for
6791+
// verification.
67906792
void IRGenSILFunction::visitBindMemoryInst(swift::BindMemoryInst *) {}
67916793

6794+
void IRGenSILFunction::visitRebindMemoryInst(swift::RebindMemoryInst *) {}
6795+
67926796
void IRGenSILFunction::visitDestroyAddrInst(swift::DestroyAddrInst *i) {
67936797
SILType addrTy = i->getOperand()->getType();
67946798
const TypeInfo &addrTI = getTypeInfo(addrTy);

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ OPERAND_OWNERSHIP(TrivialUse, AllocRefDynamic) // with tail operand
138138
OPERAND_OWNERSHIP(TrivialUse, BeginAccess)
139139
OPERAND_OWNERSHIP(TrivialUse, BeginUnpairedAccess)
140140
OPERAND_OWNERSHIP(TrivialUse, BindMemory)
141+
OPERAND_OWNERSHIP(TrivialUse, RebindMemory)
141142
OPERAND_OWNERSHIP(TrivialUse, CheckedCastAddrBranch)
142143
OPERAND_OWNERSHIP(TrivialUse, CondBranch)
143144
OPERAND_OWNERSHIP(TrivialUse, CondFail)

lib/SIL/IR/SILPrinter.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1708,7 +1708,12 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
17081708
*this << getIDAndType(BI->getIndex()) << " to ";
17091709
*this << BI->getBoundType();
17101710
}
1711-
1711+
1712+
void visitRebindMemoryInst(RebindMemoryInst *BI) {
1713+
*this << getIDAndType(BI->getBase()) << " to ";
1714+
*this << getIDAndType(BI->getInToken());
1715+
}
1716+
17121717
void visitUnconditionalCheckedCastInst(UnconditionalCheckedCastInst *CI) {
17131718
*this << getIDAndType(CI->getOperand()) << " to " << CI->getTargetFormalType();
17141719
printForwardingOwnershipKind(CI, CI->getOperand());

0 commit comments

Comments
 (0)