Skip to content

Commit d874479

Browse files
committed
Add builtins to initialize and destroy a default-actor member.
It would be more abstractly correct if this got DI support so that we destroy the member if the constructor terminates abnormally, but we can get to that later.
1 parent 1177cde commit d874479

File tree

14 files changed

+175
-11
lines changed

14 files changed

+175
-11
lines changed

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,22 @@ FUNCTION(TaskSwitchFunc,
15281528
ARGS(SwiftTaskPtrTy, SwiftExecutorPtrTy, SwiftExecutorPtrTy),
15291529
ATTRS(NoUnwind))
15301530

1531+
// void swift_defaultActor_initialize(DefaultActor *actor);
1532+
FUNCTION(DefaultActorInitialize,
1533+
swift_defaultActor_initialize, SwiftCC,
1534+
ConcurrencyAvailability,
1535+
RETURNS(VoidTy),
1536+
ARGS(RefCountedPtrTy),
1537+
ATTRS(NoUnwind))
1538+
1539+
// void swift_defaultActor_destroy(DefaultActor *actor);
1540+
FUNCTION(DefaultActorDestroy,
1541+
swift_defaultActor_destroy, SwiftCC,
1542+
ConcurrencyAvailability,
1543+
RETURNS(VoidTy),
1544+
ARGS(RefCountedPtrTy),
1545+
ATTRS(NoUnwind))
1546+
15311547
// AutoDiffLinearMapContext *swift_autoDiffCreateLinearMapContext(size_t);
15321548
FUNCTION(AutoDiffCreateLinearMapContext,
15331549
swift_autoDiffCreateLinearMapContext, SwiftCC,

lib/IRGen/GenBuiltin.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,22 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
266266
return;
267267
}
268268

269+
if (Builtin.ID == BuiltinValueKind::InitializeDefaultActor ||
270+
Builtin.ID == BuiltinValueKind::DestroyDefaultActor) {
271+
auto fn = Builtin.ID == BuiltinValueKind::InitializeDefaultActor
272+
? IGF.IGM.getDefaultActorInitializeFn()
273+
: IGF.IGM.getDefaultActorDestroyFn();
274+
auto actor = args.claimNext();
275+
actor = IGF.Builder.CreateBitCast(actor, IGF.IGM.RefCountedPtrTy);
276+
auto call = IGF.Builder.CreateCall(fn, {actor});
277+
call->setCallingConv(IGF.IGM.SwiftCC);
278+
call->setDoesNotThrow();
279+
return;
280+
}
281+
282+
if (Builtin.ID == BuiltinValueKind::DestroyDefaultActor) {
283+
}
284+
269285
// If this is an LLVM IR intrinsic, lower it to an intrinsic call.
270286
const IntrinsicInfo &IInfo = IGF.getSILModule().getIntrinsicInfo(FnId);
271287
llvm::Intrinsic::ID IID = IInfo.ID;

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,8 @@ CONSTANT_OWNERSHIP_BUILTIN(None, NonLifetimeEnding, AutoDiffCreateLinearMapConte
879879
CONSTANT_OWNERSHIP_BUILTIN(Guaranteed, NonLifetimeEnding, AutoDiffAllocateSubcontext)
880880
CONSTANT_OWNERSHIP_BUILTIN(Guaranteed, NonLifetimeEnding, AutoDiffProjectTopLevelSubcontext)
881881
CONSTANT_OWNERSHIP_BUILTIN(Owned, LifetimeEnding, ConvertTaskToJob)
882+
CONSTANT_OWNERSHIP_BUILTIN(Guaranteed, NonLifetimeEnding, InitializeDefaultActor)
883+
CONSTANT_OWNERSHIP_BUILTIN(Guaranteed, NonLifetimeEnding, DestroyDefaultActor)
882884

883885
#undef CONSTANT_OWNERSHIP_BUILTIN
884886

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,8 @@ CONSTANT_OWNERSHIP_BUILTIN(None, CancelAsyncTask)
546546
CONSTANT_OWNERSHIP_BUILTIN(Owned, CreateAsyncTask)
547547
CONSTANT_OWNERSHIP_BUILTIN(Owned, CreateAsyncTaskFuture)
548548
CONSTANT_OWNERSHIP_BUILTIN(None, ConvertTaskToJob)
549+
CONSTANT_OWNERSHIP_BUILTIN(None, InitializeDefaultActor)
550+
CONSTANT_OWNERSHIP_BUILTIN(None, DestroyDefaultActor)
549551
CONSTANT_OWNERSHIP_BUILTIN(Owned, AutoDiffCreateLinearMapContext)
550552
CONSTANT_OWNERSHIP_BUILTIN(None, AutoDiffProjectTopLevelSubcontext)
551553
CONSTANT_OWNERSHIP_BUILTIN(None, AutoDiffAllocateSubcontext)

lib/SIL/Utils/MemAccessUtils.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,6 +1807,8 @@ static void visitBuiltinAddress(BuiltinInst *builtin,
18071807
case BuiltinValueKind::CreateAsyncTaskFuture:
18081808
case BuiltinValueKind::AutoDiffCreateLinearMapContext:
18091809
case BuiltinValueKind::AutoDiffAllocateSubcontext:
1810+
case BuiltinValueKind::InitializeDefaultActor:
1811+
case BuiltinValueKind::DestroyDefaultActor:
18101812
return;
18111813

18121814
// General memory access to a pointer in first operand position.

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,13 +1782,27 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
17821782
return;
17831783
}
17841784

1785+
auto builtinKind = BI->getBuiltinKind();
1786+
17851787
// Check that 'getCurrentAsyncTask' only occurs within an async function.
1786-
if (BI->getBuiltinKind() &&
1787-
*BI->getBuiltinKind() == BuiltinValueKind::GetCurrentAsyncTask) {
1788+
if (builtinKind == BuiltinValueKind::GetCurrentAsyncTask) {
17881789
require(F.isAsync(),
17891790
"getCurrentAsyncTask builtin can only be used in an async function");
17901791
return;
17911792
}
1793+
1794+
if (builtinKind == BuiltinValueKind::InitializeDefaultActor ||
1795+
builtinKind == BuiltinValueKind::DestroyDefaultActor) {
1796+
auto arguments = BI->getArguments();
1797+
require(arguments.size() == 1,
1798+
"default-actor builtin can only operate on a single object");
1799+
auto argType = arguments[0]->getType().getASTType();
1800+
auto argClass = argType.getClassOrBoundGenericClass();
1801+
require((argClass && argClass->isRootDefaultActor()) ||
1802+
isa<BuiltinNativeObjectType>(argType),
1803+
"default-actor builtin can only operate on default actors");
1804+
return;
1805+
}
17921806
}
17931807

17941808
void checkFunctionRefBaseInst(FunctionRefBaseInst *FRI) {

lib/SILGen/SILGenConstructor.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,19 @@ void SILGenFunction::emitClassConstructorAllocator(ConstructorDecl *ctor) {
650650
initedSelfValue);
651651
}
652652

653+
static void emitDefaultActorInitialization(SILGenFunction &SGF,
654+
SILLocation loc,
655+
ManagedValue self) {
656+
auto &ctx = SGF.getASTContext();
657+
auto builtinName = ctx.getIdentifier(
658+
getBuiltinName(BuiltinValueKind::InitializeDefaultActor));
659+
auto resultTy = SGF.SGM.Types.getEmptyTupleType();
660+
661+
FullExpr scope(SGF.Cleanups, CleanupLocation::get(loc));
662+
SGF.B.createBuiltin(loc, builtinName, resultTy, /*subs*/{},
663+
{ self.borrow(SGF, loc).getValue() });
664+
}
665+
653666
void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
654667
MagicFunctionName = SILGenModule::getMagicFunctionName(ctor);
655668

@@ -719,6 +732,13 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
719732
B.createDebugValue(PrologueLoc, selfArg.getValue(), DbgVar);
720733
}
721734

735+
// Initialize the default-actor instance.
736+
if (selfClassDecl->isRootDefaultActor() && !isDelegating) {
737+
SILLocation PrologueLoc(selfDecl);
738+
PrologueLoc.markAsPrologue();
739+
emitDefaultActorInitialization(*this, PrologueLoc, selfArg);
740+
}
741+
722742
if (!ctor->hasStubImplementation()) {
723743
assert(selfTy.hasReferenceSemantics() &&
724744
"can't emit a value type ctor here");

lib/SILGen/SILGenDestructor.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,15 @@ void SILGenFunction::emitClassMemberDestruction(ManagedValue selfValue,
193193
B.createEndAccess(cleanupLoc, addr, false /*is aborting*/);
194194
}
195195
}
196+
197+
if (cd->isRootDefaultActor()) {
198+
auto builtinName = getASTContext().getIdentifier(
199+
getBuiltinName(BuiltinValueKind::DestroyDefaultActor));
200+
auto resultTy = SGM.Types.getEmptyTupleType();
201+
202+
B.createBuiltin(cleanupLoc, builtinName, resultTy, /*subs*/{},
203+
{ selfValue.getValue() });
204+
}
196205
}
197206

198207

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2026,6 +2026,18 @@ void LifetimeChecker::processUninitializedReleaseOfBox(
20262026
Destroys.push_back(B.createDeallocBox(Release->getLoc(), MUI));
20272027
}
20282028

2029+
static void emitDefaultActorDestroy(SILBuilder &B, SILLocation loc,
2030+
SILValue self) {
2031+
auto builtinName = B.getASTContext().getIdentifier(
2032+
getBuiltinName(BuiltinValueKind::DestroyDefaultActor));
2033+
auto resultTy = B.getModule().Types.getEmptyTupleType();
2034+
2035+
self = B.createBeginBorrow(loc, self);
2036+
B.createBuiltin(loc, builtinName, resultTy, /*subs*/{},
2037+
{ self });
2038+
B.createEndBorrow(loc, self);
2039+
}
2040+
20292041
void LifetimeChecker::processUninitializedRelease(SILInstruction *Release,
20302042
bool consumed,
20312043
SILBasicBlock::iterator InsertPt) {
@@ -2076,6 +2088,15 @@ void LifetimeChecker::processUninitializedRelease(SILInstruction *Release,
20762088
else
20772089
Metatype = B.createMetatype(Loc, SILMetatypeTy);
20782090

2091+
// If this is a root default actor, destroy the default-actor state.
2092+
// SILGen ensures that this is unconditionally initialized, so we
2093+
// don't need to track it specially.
2094+
if (!TheMemory.isDelegatingInit()) {
2095+
auto classDecl = TheMemory.getASTType().getClassOrBoundGenericClass();
2096+
if (classDecl && classDecl->isRootDefaultActor())
2097+
emitDefaultActorDestroy(B, Loc, Pointer);
2098+
}
2099+
20792100
// We've already destroyed any instance variables initialized by this
20802101
// constructor, now destroy instance variables initialized by subclass
20812102
// constructors that delegated to us, and finally free the memory.

lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ static bool isBarrier(SILInstruction *inst) {
170170
case BuiltinValueKind::CreateAsyncTask:
171171
case BuiltinValueKind::CreateAsyncTaskFuture:
172172
case BuiltinValueKind::ConvertTaskToJob:
173+
case BuiltinValueKind::InitializeDefaultActor:
174+
case BuiltinValueKind::DestroyDefaultActor:
173175
case BuiltinValueKind::AutoDiffProjectTopLevelSubcontext:
174176
case BuiltinValueKind::AutoDiffAllocateSubcontext:
175177
return true;

0 commit comments

Comments
 (0)