Skip to content

Commit 41f051d

Browse files
committed
[region-isolation] Add support for project_block_storage.
rdar://119743743
1 parent 912a485 commit 41f051d

File tree

6 files changed

+63
-10
lines changed

6 files changed

+63
-10
lines changed

include/swift/SIL/MemAccessUtils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1591,6 +1591,9 @@ inline bool isAccessStorageTypeCast(SingleValueInstruction *svi) {
15911591
switch (svi->getKind()) {
15921592
default:
15931593
return false;
1594+
// This extracts out the block storage from an alloc_stack. We do not want
1595+
// to treat it as any more than a cast of the underlying value.
1596+
case SILInstructionKind::ProjectBlockStorageInst:
15941597
// Simply pass-thru the incoming address. But change its type!
15951598
case SILInstructionKind::MoveOnlyWrapperToCopyableAddrInst:
15961599
case SILInstructionKind::CopyableToMoveOnlyWrapperAddrInst:

include/swift/SIL/Projection.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ enum class ProjectionKind : unsigned {
9494
RefCast = 1,
9595
BitwiseCast = 2,
9696
TailElems = 3,
97+
BlockStorageCast = 4,
9798
FirstPointerKind = Upcast,
9899
LastPointerKind = TailElems,
99100

@@ -120,6 +121,7 @@ static inline bool isCastProjectionKind(ProjectionKind Kind) {
120121
case ProjectionKind::Upcast:
121122
case ProjectionKind::RefCast:
122123
case ProjectionKind::BitwiseCast:
124+
case ProjectionKind::BlockStorageCast:
123125
return true;
124126
case ProjectionKind::Struct:
125127
case ProjectionKind::Tuple:
@@ -318,15 +320,19 @@ class Projection {
318320
auto *Ty = getPointer();
319321
assert(Ty->isCanonical());
320322
switch (getKind()) {
321-
case ProjectionKind::Upcast:
322-
case ProjectionKind::RefCast:
323-
case ProjectionKind::BitwiseCast:
324-
return SILType::getPrimitiveType(Ty->getCanonicalType(),
325-
BaseType.getCategory());
326-
case ProjectionKind::TailElems:
327-
return SILType::getPrimitiveAddressType(Ty->getCanonicalType());
328-
default:
329-
llvm_unreachable("unknown cast projection type");
323+
case ProjectionKind::Upcast:
324+
case ProjectionKind::RefCast:
325+
case ProjectionKind::BitwiseCast:
326+
return SILType::getPrimitiveType(Ty->getCanonicalType(),
327+
BaseType.getCategory());
328+
case ProjectionKind::TailElems:
329+
return SILType::getPrimitiveAddressType(Ty->getCanonicalType());
330+
case ProjectionKind::BlockStorageCast: {
331+
auto blockStorageTy = Ty->getCanonicalType()->castTo<SILBlockStorageType>();
332+
return blockStorageTy->getCaptureAddressType();
333+
}
334+
default:
335+
llvm_unreachable("unknown cast projection type");
330336
}
331337
}
332338

@@ -421,6 +427,7 @@ class Projection {
421427
case ProjectionKind::BitwiseCast:
422428
return true;
423429
case ProjectionKind::Upcast:
430+
case ProjectionKind::BlockStorageCast:
424431
case ProjectionKind::Struct:
425432
case ProjectionKind::Tuple:
426433
case ProjectionKind::Index:
@@ -445,6 +452,7 @@ class Projection {
445452
case ProjectionKind::RefCast:
446453
case ProjectionKind::Tuple:
447454
case ProjectionKind::Upcast:
455+
case ProjectionKind::BlockStorageCast:
448456
case ProjectionKind::Box:
449457
case ProjectionKind::TailElems:
450458
return false;

lib/SIL/Utils/Projection.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,13 @@ Projection::Projection(SingleValueInstruction *I) : Value() {
154154
}
155155
break;
156156
}
157+
case SILInstructionKind::ProjectBlockStorageInst: {
158+
auto *Ty = I->getType().getASTType().getPointer();
159+
assert(Ty->isCanonical());
160+
Value = ValueTy(ProjectionKind::BlockStorageCast, Ty);
161+
assert(getKind() == ProjectionKind::BlockStorageCast);
162+
break;
163+
}
157164
case SILInstructionKind::UpcastInst: {
158165
auto *Ty = I->getType().getASTType().getPointer();
159166
assert(Ty->isCanonical());
@@ -199,6 +206,7 @@ SILType Projection::getType(SILType BaseType, SILModule &M,
199206
case ProjectionKind::Tuple:
200207
return BaseType.getTupleElementType(getIndex());
201208
case ProjectionKind::Upcast:
209+
case ProjectionKind::BlockStorageCast:
202210
case ProjectionKind::RefCast:
203211
case ProjectionKind::BitwiseCast:
204212
case ProjectionKind::TailElems:
@@ -238,6 +246,8 @@ Projection::createObjectProjection(SILBuilder &B, SILLocation Loc,
238246
return nullptr;
239247
case ProjectionKind::Box:
240248
return nullptr;
249+
case ProjectionKind::BlockStorageCast:
250+
return nullptr;
241251
case ProjectionKind::Upcast:
242252
return B.createUpcast(Loc, Base, getCastType(BaseTy));
243253
case ProjectionKind::RefCast:
@@ -285,6 +295,8 @@ Projection::createAddressProjection(SILBuilder &B, SILLocation Loc,
285295
return B.createRefTailAddr(Loc, Base, getCastType(BaseTy));
286296
case ProjectionKind::Box:
287297
return B.createProjectBox(Loc, Base, getIndex());
298+
case ProjectionKind::BlockStorageCast:
299+
return B.createProjectBlockStorage(Loc, Base);
288300
case ProjectionKind::Upcast:
289301
return B.createUpcast(Loc, Base, getCastType(BaseTy));
290302
case ProjectionKind::RefCast:
@@ -600,6 +612,10 @@ void Projection::print(raw_ostream &os, SILType baseType) const {
600612
os << " Box over";
601613
break;
602614
}
615+
case ProjectionKind::BlockStorageCast: {
616+
os << "BlockStorageCast";
617+
break;
618+
}
603619
case ProjectionKind::Upcast: {
604620
os << "UpCast";
605621
break;
@@ -872,6 +888,7 @@ SILValue Projection::getOperandForAggregate(SILInstruction *I) const {
872888
case ProjectionKind::Class:
873889
case ProjectionKind::TailElems:
874890
case ProjectionKind::Box:
891+
case ProjectionKind::BlockStorageCast:
875892
case ProjectionKind::Upcast:
876893
case ProjectionKind::RefCast:
877894
case ProjectionKind::BitwiseCast:
@@ -931,6 +948,7 @@ static bool isSupportedProjection(const Projection &p) {
931948
case ProjectionKind::Enum:
932949
case ProjectionKind::Box:
933950
case ProjectionKind::Upcast:
951+
case ProjectionKind::BlockStorageCast:
934952
case ProjectionKind::RefCast:
935953
case ProjectionKind::BitwiseCast:
936954
case ProjectionKind::TailElems:

lib/SILOptimizer/Mandatory/TransferNonSendable.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ struct UseDefChainVisitor
142142
switch (p.getKind()) {
143143
case ProjectionKind::Upcast:
144144
case ProjectionKind::RefCast:
145+
case ProjectionKind::BlockStorageCast:
145146
case ProjectionKind::BitwiseCast:
146147
case ProjectionKind::TailElems:
147148
case ProjectionKind::Box:
@@ -2341,6 +2342,7 @@ CONSTANT_TRANSLATION(MarkUninitializedInst, LookThrough)
23412342
// We identify destructured results with their operand's region.
23422343
CONSTANT_TRANSLATION(DestructureTupleInst, LookThrough)
23432344
CONSTANT_TRANSLATION(DestructureStructInst, LookThrough)
2345+
CONSTANT_TRANSLATION(ProjectBlockStorageInst, LookThrough)
23442346

23452347
// These are treated as stores - meaning that they could write values into
23462348
// memory. The beahvior of this depends on whether the tgt addr is aliased,
@@ -2429,7 +2431,6 @@ CONSTANT_TRANSLATION(PackLengthInst, Unhandled)
24292431
CONSTANT_TRANSLATION(DynamicPackIndexInst, Unhandled)
24302432
CONSTANT_TRANSLATION(PackPackIndexInst, Unhandled)
24312433
CONSTANT_TRANSLATION(ScalarPackIndexInst, Unhandled)
2432-
CONSTANT_TRANSLATION(ProjectBlockStorageInst, Unhandled)
24332434
CONSTANT_TRANSLATION(DifferentiableFunctionInst, Unhandled)
24342435
CONSTANT_TRANSLATION(LinearFunctionInst, Unhandled)
24352436
CONSTANT_TRANSLATION(DifferentiableFunctionExtractInst, Unhandled)

lib/SILOptimizer/Transforms/AssemblyVisionRemarkGenerator.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ void ValueToDeclInferrer::printAccessPath(llvm::raw_string_ostream &stream) {
156156

157157
// WARNING: This must be kept insync with isSupportedProjection!
158158
switch (proj.getKind()) {
159+
case ProjectionKind::BlockStorageCast:
160+
stream << "project_block_storage<" << proj.getCastType(baseType) << ">";
161+
continue;
159162
case ProjectionKind::Upcast:
160163
stream << "upcast<" << proj.getCastType(baseType) << ">";
161164
continue;
@@ -204,6 +207,7 @@ static SingleValueInstruction *isSupportedProjection(Projection p, SILValue v) {
204207
switch (p.getKind()) {
205208
case ProjectionKind::Upcast:
206209
case ProjectionKind::RefCast:
210+
case ProjectionKind::BlockStorageCast:
207211
case ProjectionKind::BitwiseCast:
208212
case ProjectionKind::Struct:
209213
case ProjectionKind::Tuple:

test/Concurrency/transfernonsendable_instruction_matching.sil

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,3 +298,22 @@ bb0(%0 : $*NonSendableStruct):
298298
%9999 = tuple ()
299299
return %9999 : $()
300300
}
301+
302+
sil [ossa] @project_block_storage_test : $@convention(thin) @async (@owned @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>) -> () {
303+
bb0(%0 : @owned $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>):
304+
%allocBlock = alloc_stack $@block_storage @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>
305+
%blockAddr = project_block_storage %allocBlock : $*@block_storage @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>
306+
store %0 to [init] %blockAddr : $*@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>
307+
%4 = function_ref @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
308+
apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %4<() -> ()>(%blockAddr) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
309+
// expected-warning @-1 {{call site passes `self` or a non-sendable argument of this function to another thread, potentially yielding a race with the caller}}
310+
311+
%5 = function_ref @useIndirect : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
312+
apply %5<() -> ()>(%blockAddr) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
313+
314+
destroy_addr %allocBlock : $*@block_storage @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>
315+
dealloc_stack %allocBlock : $*@block_storage @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>
316+
%9999 = tuple ()
317+
return %9999 : $()
318+
}
319+

0 commit comments

Comments
 (0)