Skip to content

Commit 17fef2f

Browse files
committed
Give bind_memory a token result.
Required for UnsafeRawPointer.withMemoryRebound(to:) %token = bind_memory %0 : $Builtin.RawPointer, %1 : $Builtin.Word to $T %0 must be of $Builtin.RawPointer type %1 must be of $Builtin.Word type %token is an opaque $Builtin.Word representing the previously bound types for this memory region.
1 parent d0cc575 commit 17fef2f

File tree

16 files changed

+63
-44
lines changed

16 files changed

+63
-44
lines changed

docs/SIL.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3985,13 +3985,21 @@ bind_memory
39853985

39863986
sil-instruction ::= 'bind_memory' sil-operand ',' sil-operand 'to' sil-type
39873987

3988-
bind_memory %0 : $Builtin.RawPointer, %1 : $Builtin.Word to $T
3988+
%token = bind_memory %0 : $Builtin.RawPointer, %1 : $Builtin.Word to $T
39893989
// %0 must be of $Builtin.RawPointer type
39903990
// %1 must be of $Builtin.Word type
3991+
// %token is an opaque $Builtin.Word representing the previously bound types
3992+
// for this memory region.
39913993

39923994
Binds memory at ``Builtin.RawPointer`` value ``%0`` to type ``$T`` with enough
39933995
capacity to hold ``%1`` values. See SE-0107: UnsafeRawPointer.
39943996

3997+
Produces a opaque token representing the previous memory state. For
3998+
memory binding semantics, this state includes the type that the memory
3999+
was previously bound to. The token cannot, however, be used to
4000+
retrieve a metatype. It's value is only meaningful to the Swift
4001+
runtime for typed pointer verification.
4002+
39954003
begin_access
39964004
````````````
39974005

include/swift/AST/Builtins.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,10 @@ BUILTIN_SIL_OPERATION(BeginCOWMutation_native, "beginCOWMutation_native", Specia
452452
/// inout argument. After calling this builtin, the buffer must not be mutated.
453453
BUILTIN_SIL_OPERATION(EndCOWMutation, "endCOWMutation", Special)
454454

455-
/// bindMemory : <T> (Builtin.RawPointer, Builtin.Word, T.Type) -> ()
455+
/// bindMemory : <T> (Builtin.RawPointer, Builtin.Word, T.Type) -> Builtin.Word
456+
///
457+
/// Binds memory to a statically known type. Returns an opaque token
458+
/// representing the memory region's previously bound types.
456459
BUILTIN_SIL_OPERATION(BindMemory, "bindMemory", Special)
457460

458461
/// allocWithTailElems_<n>(C.Type,

include/swift/SIL/SILInstruction.h

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4866,14 +4866,16 @@ class CopyAddrInst
48664866
MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
48674867
};
48684868

4869-
/// BindMemoryInst -
4870-
/// "bind_memory %0 : $Builtin.RawPointer, %1 : $Builtin.Word to $T"
4869+
/// "%token = bind_memory %0 : $Builtin.RawPointer, %1 : $Builtin.Word to $T"
4870+
///
48714871
/// Binds memory at the raw pointer %0 to type $T with enough capacity
4872-
/// to hold $1 values.
4873-
class BindMemoryInst final :
4874-
public InstructionBaseWithTrailingOperands<
4875-
SILInstructionKind::BindMemoryInst,
4876-
BindMemoryInst, NonValueInstruction> {
4872+
/// to hold %1 values.
4873+
///
4874+
/// %token is an opaque word representing the previously bound types of this
4875+
/// memory region, before binding it to a contiguous region of type $T.
4876+
class BindMemoryInst final : public InstructionBaseWithTrailingOperands<
4877+
SILInstructionKind::BindMemoryInst,
4878+
BindMemoryInst, SingleValueInstruction> {
48774879
friend SILBuilder;
48784880

48794881
SILType BoundType;
@@ -4883,10 +4885,11 @@ class BindMemoryInst final :
48834885
SILFunction &F);
48844886

48854887
BindMemoryInst(SILDebugLocation Loc, SILValue Base, SILValue Index,
4886-
SILType BoundType,
4888+
SILType BoundType, SILType TokenType,
48874889
ArrayRef<SILValue> TypeDependentOperands)
4888-
: InstructionBaseWithTrailingOperands(Base, Index, TypeDependentOperands,
4889-
Loc), BoundType(BoundType) {}
4890+
: InstructionBaseWithTrailingOperands(Base, Index, TypeDependentOperands,
4891+
Loc, TokenType),
4892+
BoundType(BoundType) {}
48904893

48914894
public:
48924895
enum { BaseOperIdx, IndexOperIdx, NumFixedOpers };

include/swift/SIL/SILNodes.def

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

753-
SINGLE_VALUE_INST_RANGE(SingleValueInstruction, AllocStackInst, KeyPathInst)
753+
// BindMemory has no physical side effect. Semantically it writes to
754+
// its affected memory region because any reads or writes accessing
755+
// that memory must be dependent on the bind operation.
756+
SINGLE_VALUE_INST(BindMemoryInst, bind_memory,
757+
SILInstruction, MayWrite, DoesNotRelease)
754758

755-
NODE_RANGE(ValueBase, SILPhiArgument, KeyPathInst)
759+
SINGLE_VALUE_INST_RANGE(SingleValueInstruction, AllocStackInst, BindMemoryInst)
760+
NODE_RANGE(ValueBase, SILPhiArgument, BindMemoryInst)
756761

757762
// Terminators
758763
ABSTRACT_INST(TermInst, SILInstruction)
@@ -840,12 +845,6 @@ ABSTRACT_INST(RefCountingInst, SILInstruction)
840845
DoesNotRelease)
841846
INST_RANGE(RefCountingInst, StrongRetainInst, AutoreleaseValueInst)
842847

843-
// BindMemory has no physical side effect. Semantically it writes to
844-
// its affected memory region because any reads or writes accessing
845-
// that memory must be dependent on the bind operation.
846-
NON_VALUE_INST(BindMemoryInst, bind_memory,
847-
SILInstruction, MayWrite, DoesNotRelease)
848-
849848
// FIXME: Is MayHaveSideEffects appropriate?
850849
BRIDGED_NON_VALUE_INST(FixLifetimeInst, fix_lifetime,
851850
SILInstruction, MayHaveSideEffects, DoesNotRelease)

lib/AST/Builtins.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -888,12 +888,15 @@ static ValueDecl *getEndCOWMutation(ASTContext &ctx, Identifier id) {
888888
}
889889

890890
static ValueDecl *getBindMemoryOperation(ASTContext &ctx, Identifier id) {
891-
return getBuiltinFunction(ctx, id, _thin,
892-
_generics(_unrestricted),
893-
_parameters(_rawPointer,
894-
_word,
895-
_metatype(_typeparam(0))),
896-
_void);
891+
FuncDecl *fd = getBuiltinFunction(ctx, id, _thin,
892+
_generics(_unrestricted),
893+
_parameters(_rawPointer,
894+
_word,
895+
_metatype(_typeparam(0))),
896+
_word);
897+
fd->getAttrs().add(new (ctx) DiscardableResultAttr(/*implicit*/true));
898+
return fd;
899+
}
897900
}
898901

899902
static ValueDecl *getAllocWithTailElemsOperation(ASTContext &Context,

lib/SIL/IR/SILInstructions.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,12 +1144,14 @@ CopyAddrInst::CopyAddrInst(SILDebugLocation Loc, SILValue SrcLValue,
11441144
BindMemoryInst *
11451145
BindMemoryInst::create(SILDebugLocation Loc, SILValue Base, SILValue Index,
11461146
SILType BoundType, SILFunction &F) {
1147+
auto tokenTy = SILType::getBuiltinWordType(F.getASTContext());
11471148
SmallVector<SILValue, 8> TypeDependentOperands;
1148-
collectTypeDependentOperands(TypeDependentOperands, F, BoundType.getASTType());
1149+
collectTypeDependentOperands(TypeDependentOperands, F,
1150+
BoundType.getASTType());
11491151
auto Size = totalSizeToAlloc<swift::Operand>(TypeDependentOperands.size() +
11501152
NumFixedOpers);
11511153
auto Buffer = F.getModule().allocateInst(Size, alignof(BindMemoryInst));
1152-
return ::new (Buffer) BindMemoryInst(Loc, Base, Index, BoundType,
1154+
return ::new (Buffer) BindMemoryInst(Loc, Base, Index, BoundType, tokenTy,
11531155
TypeDependentOperands);
11541156
}
11551157

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ CONSTANT_OWNERSHIP_INST(Owned, ObjCMetatypeToObject)
9494
CONSTANT_OWNERSHIP_INST(None, AddressToPointer)
9595
CONSTANT_OWNERSHIP_INST(None, AllocStack)
9696
CONSTANT_OWNERSHIP_INST(None, BeginAccess)
97+
CONSTANT_OWNERSHIP_INST(None, BindMemory)
9798
CONSTANT_OWNERSHIP_INST(None, BridgeObjectToWord)
9899
CONSTANT_OWNERSHIP_INST(None, ClassMethod)
99100
CONSTANT_OWNERSHIP_INST(None, ClassifyBridgeObject)

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -961,16 +961,16 @@ static ManagedValue emitBuiltinBindMemory(SILGenFunction &SGF,
961961
ArrayRef<ManagedValue> args,
962962
SGFContext C) {
963963
assert(subs.getReplacementTypes().size() == 1 && "bindMemory should have a single substitution");
964-
assert(args.size() == 3 && "bindMemory should have three argument");
964+
assert(args.size() == 3 && "bindMemory should have three arguments");
965965

966966
// The substitution determines the element type for bound memory.
967967
CanType boundFormalType = subs.getReplacementTypes()[0]->getCanonicalType();
968968
SILType boundType = SGF.getLoweredType(boundFormalType);
969969

970-
SGF.B.createBindMemory(loc, args[0].getValue(),
971-
args[1].getValue(), boundType);
970+
auto *bindMemory = SGF.B.createBindMemory(loc, args[0].getValue(),
971+
args[1].getValue(), boundType);
972972

973-
return ManagedValue::forUnmanaged(SGF.emitEmptyTuple(loc));
973+
return ManagedValue::forUnmanaged(bindMemory);
974974
}
975975

976976
static ManagedValue emitBuiltinAllocWithTailElems(SILGenFunction &SGF,

lib/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5656
/// describe what change you made. The content of this comment isn't important;
5757
/// it just ensures a conflict if two people change the module format.
5858
/// Don't worry about adhering to the 80-column limit for this line.
59-
const uint16_t SWIFTMODULE_VERSION_MINOR = 642; // Type Sequence Bits in Generic Parameters
59+
const uint16_t SWIFTMODULE_VERSION_MINOR = 643; // bind_memory tokens
6060

6161
/// A standard hash seed used for all string hashes in a serialized module.
6262
///

test/SIL/Parser/basic.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1611,7 +1611,7 @@ bb0(%0 : $Builtin.RawPointer, %1 : $X):
16111611
// CHECK-LABEL: sil @test_bind_memory
16121612
sil @test_bind_memory : $(Builtin.RawPointer, Builtin.Word) -> () {
16131613
bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.Word):
1614-
bind_memory %0 : $Builtin.RawPointer, %1 : $Builtin.Word to $*X
1614+
%2 = bind_memory %0 : $Builtin.RawPointer, %1 : $Builtin.Word to $*X
16151615
// CHECK: bind_memory {{%.*}} : $Builtin.RawPointer, {{%.*}} : $Builtin.Word to $*X
16161616
%28 = tuple ()
16171617
return %28 : $()

test/SILGen/builtins.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ func unsafeGuaranteedEnd(_ t: Builtin.Int8) {
791791

792792
// CHECK-LABEL: sil hidden [ossa] @$s8builtins10bindMemory{{[_0-9a-zA-Z]*}}F
793793
// CHECK: bb0([[P:%.*]] : $Builtin.RawPointer, [[I:%.*]] : $Builtin.Word, [[T:%.*]] : $@thick T.Type):
794-
// CHECK: bind_memory [[P]] : $Builtin.RawPointer, [[I]] : $Builtin.Word to $*T
794+
// CHECK: %{{.*}} = bind_memory [[P]] : $Builtin.RawPointer, [[I]] : $Builtin.Word to $*T
795795
// CHECK: return {{%.*}} : $()
796796
// CHECK: }
797797
func bindMemory<T>(ptr: Builtin.RawPointer, idx: Builtin.Word, _: T.Type) {

test/SILOptimizer/redundant_load_elim_with_casts.sil

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,10 @@ bb0(%0 : $Builtin.RawPointer, %1 : $A2):
115115
%2 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*A
116116
%3 = load %2 : $*A
117117
%4 = integer_literal $Builtin.Word, 1
118-
bind_memory %0 : $Builtin.RawPointer, %4 : $Builtin.Word to $A2
119-
%5 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*A2
120-
store %1 to %5 : $*A2
121-
bind_memory %0 : $Builtin.RawPointer, %4 : $Builtin.Word to $A
118+
%5 = bind_memory %0 : $Builtin.RawPointer, %4 : $Builtin.Word to $A2
119+
%6 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*A2
120+
store %1 to %6 : $*A2
121+
%8 = bind_memory %0 : $Builtin.RawPointer, %4 : $Builtin.Word to $A
122122
%20 = load %2 : $*A
123123
%30 = tuple(%3 : $A, %20 : $A)
124124
return %30 : $(A, A)

test/SILOptimizer/retain_release_code_motion.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ sil @testCopyArray : $@convention(thin) (_ContiguousArrayBuffer<AnyObject>, Buil
808808
bb0(%0 : $_ContiguousArrayBuffer<AnyObject>, %1 : $Builtin.Word, %2 : $Builtin.Word):
809809
%eltty = metatype $@thick AnyObject.Protocol
810810
%newptr = builtin "allocRaw"(%1 : $Builtin.Word, %1 : $Builtin.Word) : $Builtin.RawPointer
811-
bind_memory %newptr : $Builtin.RawPointer, %1 : $Builtin.Word to $*AnyObject
811+
%token = bind_memory %newptr : $Builtin.RawPointer, %1 : $Builtin.Word to $*AnyObject
812812
%storage = struct_extract %0 : $_ContiguousArrayBuffer<AnyObject>, #_ContiguousArrayBuffer._storage
813813
%elements = ref_tail_addr %storage : $__ContiguousArrayStorageBase, $AnyObject
814814
%eltptr = address_to_pointer %elements : $*AnyObject to $Builtin.RawPointer

test/SILOptimizer/specialize.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ sil hidden @test_bind : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Typ
563563
bb0(%0 : $Builtin.RawPointer, %1 : $@thick T.Type):
564564
%4 = integer_literal $Builtin.Word, 1
565565
%5 = metatype $@thick T.Type
566-
bind_memory %0 : $Builtin.RawPointer, %4 : $Builtin.Word to $*T
566+
%6 = bind_memory %0 : $Builtin.RawPointer, %4 : $Builtin.Word to $*T
567567
%7 = tuple ()
568568
%8 = tuple ()
569569
return %8 : $()

test/SILOptimizer/specialize_ossa.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ sil hidden [ossa] @test_bind : $@convention(thin) <T> (Builtin.RawPointer, @thic
611611
bb0(%0 : $Builtin.RawPointer, %1 : $@thick T.Type):
612612
%4 = integer_literal $Builtin.Word, 1
613613
%5 = metatype $@thick T.Type
614-
bind_memory %0 : $Builtin.RawPointer, %4 : $Builtin.Word to $*T
614+
%6 = bind_memory %0 : $Builtin.RawPointer, %4 : $Builtin.Word to $*T
615615
%7 = tuple ()
616616
%8 = tuple ()
617617
return %8 : $()

test/Serialization/Inputs/def_basic.sil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,8 +1050,8 @@ bb0(%0 : $Builtin.RawPointer, %1 : $X):
10501050
// CHECK-LABEL: sil public_external [transparent] [serialized] @test_bind_memory
10511051
sil [transparent] [serialized] @test_bind_memory : $@convention(thin) (Builtin.RawPointer, Builtin.Word) -> () {
10521052
bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.Word):
1053-
bind_memory %0 : $Builtin.RawPointer, %1 : $Builtin.Word to $*X
1054-
// CHECK: bind_memory {{%.*}} : $Builtin.RawPointer, {{%.*}} : $Builtin.Word to $*X
1053+
%2 = bind_memory %0 : $Builtin.RawPointer, %1 : $Builtin.Word to $*X
1054+
// CHECK: %2 = bind_memory {{%.*}} : $Builtin.RawPointer, {{%.*}} : $Builtin.Word to $*X
10551055
%28 = tuple ()
10561056
return %28 : $()
10571057
}

0 commit comments

Comments
 (0)