@@ -790,7 +790,7 @@ static bool isDistributedActorCtor(SILFunction &F) {
790
790
// / Injects a hop_to_executor instruction after the specified insertion point.
791
791
static void injectHopToExecutorAfter (SILLocation loc,
792
792
SILBasicBlock::iterator insertPt,
793
- SILValue actor, bool needsBorrow = true ) {
793
+ DIMemoryObjectInfo &TheMemory ) {
794
794
795
795
LLVM_DEBUG (llvm::dbgs () << " hop-injector: requested insertion after "
796
796
<< *insertPt);
@@ -805,20 +805,30 @@ static void injectHopToExecutorAfter(SILLocation loc,
805
805
auto injectAfter = [&](SILInstruction *insertPt) -> void {
806
806
LLVM_DEBUG (llvm::dbgs () << " hop-injector: injecting after " << *insertPt);
807
807
SILBuilderWithScope::insertAfter (insertPt, [&](SILBuilder &b) {
808
- if (needsBorrow)
809
- actor = b.createBeginBorrow (loc, actor);
808
+
809
+ const bool delegating = !TheMemory.isNonDelegatingInit ();
810
+ SILValue val = TheMemory.getUninitializedValue ();
811
+
812
+ // delegating inits always have an alloc we need to load it from.
813
+ if (delegating)
814
+ val = b.createLoad (loc.asAutoGenerated (), val,
815
+ LoadOwnershipQualifier::Copy);
816
+
817
+ SILValue actor = b.createBeginBorrow (loc.asAutoGenerated (), val);
810
818
811
819
b.createHopToExecutor (loc.asAutoGenerated (), actor, /* mandatory=*/ false );
812
820
813
821
// Distributed actors also need to notify their transport immediately
814
822
// after performing the hop.
815
- if (isDistributedActorCtor (b.getFunction ())) {
823
+ if (!delegating && isDistributedActorCtor (b.getFunction ())) {
816
824
auto transport = findFirstDistributedActorSystemArg (b.getFunction ());
817
825
emitActorReadyCall (b, loc.asAutoGenerated (), actor, transport);
818
826
}
819
827
820
- if (needsBorrow)
821
- b.createEndBorrow (loc, actor);
828
+ b.createEndBorrow (loc.asAutoGenerated (), actor);
829
+
830
+ if (delegating)
831
+ b.createDestroyValue (loc.asAutoGenerated (), val);
822
832
});
823
833
};
824
834
@@ -892,7 +902,7 @@ void LifetimeChecker::injectActorHopForBlock(
892
902
// Make sure we found the initializing use of TheMemory.
893
903
assert (bbi != bbe && " this block is not initializing?" );
894
904
895
- injectHopToExecutorAfter (loc, bbi, TheMemory. getUninitializedValue () );
905
+ injectHopToExecutorAfter (loc, bbi, TheMemory);
896
906
}
897
907
898
908
static bool isFailableInitReturnUseOfEnum (EnumInst *EI);
@@ -929,8 +939,8 @@ void LifetimeChecker::injectActorHops() {
929
939
// We insert this directly after the mark_uninitialized instruction, so
930
940
// that it happens as early as `self` is available.`
931
941
if (TheMemory.getNumElements () == 0 ) {
932
- auto *selfDef = TheMemory.getUninitializedValue ();
933
- return injectHopToExecutorAfter (ctor, selfDef->getIterator (), selfDef );
942
+ auto *selfDef = TheMemory.getUninitializedValue (); // FIXME: this might be wrong for convenience inits (rdar://87485045)
943
+ return injectHopToExecutorAfter (ctor, selfDef->getIterator (), TheMemory );
934
944
}
935
945
936
946
// Returns true iff a block returns normally from the initializer,
0 commit comments