Skip to content

Commit f18a9b8

Browse files
committed
[Concurrency] SIL: add hop_to_executor instruction
This instructions ensures that all instructions, which need to run on the specified executor actually run on that executor. For details see the description in SIL.rst.
1 parent fba839a commit f18a9b8

File tree

17 files changed

+138
-1
lines changed

17 files changed

+138
-1
lines changed

docs/SIL.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2885,6 +2885,27 @@ initialized with the resume value, and that value is then owned by the current
28852885
function. If ``await_async_continuation`` instead resumes to its ``error``
28862886
successor, then the memory remains uninitialized.
28872887

2888+
hop_to_executor
2889+
```````````````
2890+
2891+
::
2892+
2893+
sil-instruction ::= 'hop_to_executor' sil-operand
2894+
2895+
hop_to_executor %0 : $T
2896+
2897+
// $T must conform to the Actor protocol
2898+
2899+
Ensures that all instructions, which need to run on the actor's executor
2900+
actually run on that executor.
2901+
This instruction can only be used inside an ``@async`` function.
2902+
2903+
Checks if the current executor is the one which is bound to the operand actor.
2904+
If not, begins a suspension point and enqueues the continuation to the executor
2905+
which is bound to the operand actor.
2906+
2907+
The operand is a guaranteed operand, i.e. not consumed.
2908+
28882909
dealloc_stack
28892910
`````````````
28902911
::

include/swift/SIL/SILBuilder.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1935,6 +1935,10 @@ class SILBuilder {
19351935
getSILDebugLocation(Loc), Operand, Index));
19361936
}
19371937

1938+
//===--------------------------------------------------------------------===//
1939+
// Concurrency instructions
1940+
//===--------------------------------------------------------------------===//
1941+
19381942
GetAsyncContinuationInst *createGetAsyncContinuation(SILLocation Loc,
19391943
SILType ContinuationTy) {
19401944
return insert(new (getModule()) GetAsyncContinuationInst(getSILDebugLocation(Loc),
@@ -1949,6 +1953,11 @@ class SILBuilder {
19491953
ContinuationTy));
19501954
}
19511955

1956+
HopToExecutorInst *createHopToExecutor(SILLocation Loc, SILValue Actor) {
1957+
return insert(new (getModule()) HopToExecutorInst(getSILDebugLocation(Loc),
1958+
Actor, hasOwnership()));
1959+
}
1960+
19521961
//===--------------------------------------------------------------------===//
19531962
// Terminator SILInstruction Creation Methods
19541963
//===--------------------------------------------------------------------===//

include/swift/SIL/SILCloner.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2964,6 +2964,17 @@ ::visitAwaitAsyncContinuationInst(AwaitAsyncContinuationInst *Inst) {
29642964
: nullptr));
29652965
}
29662966

2967+
template <typename ImplClass>
2968+
void SILCloner<ImplClass>
2969+
::visitHopToExecutorInst(HopToExecutorInst *Inst) {
2970+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
2971+
recordClonedInstruction(Inst,
2972+
getBuilder().createHopToExecutor(
2973+
getOpLocation(Inst->getLoc()),
2974+
getOpValue(Inst->getActor())));
2975+
}
2976+
2977+
29672978
} // end namespace swift
29682979

29692980
#endif

include/swift/SIL/SILInstruction.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3102,6 +3102,21 @@ class GetAsyncContinuationAddrInst final
31023102
{}
31033103
};
31043104

3105+
/// Begins a suspension point and enqueues the continuation to the executor
3106+
/// which is bound to the operand actor.
3107+
class HopToExecutorInst
3108+
: public UnaryInstructionBase<SILInstructionKind::HopToExecutorInst,
3109+
NonValueInstruction>
3110+
{
3111+
friend SILBuilder;
3112+
3113+
HopToExecutorInst(SILDebugLocation DebugLoc, SILValue Actor, bool HasOwnership)
3114+
: UnaryInstructionBase(DebugLoc, Actor) { }
3115+
3116+
public:
3117+
SILValue getActor() const { return getOperand(); }
3118+
};
3119+
31053120
/// Instantiates a key path object.
31063121
class KeyPathInst final
31073122
: public InstructionBase<SILInstructionKind::KeyPathInst,

include/swift/SIL/SILNodes.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,9 @@ NON_VALUE_INST(BindMemoryInst, bind_memory,
834834
NON_VALUE_INST(FixLifetimeInst, fix_lifetime,
835835
SILInstruction, MayHaveSideEffects, DoesNotRelease)
836836

837+
NON_VALUE_INST(HopToExecutorInst, hop_to_executor,
838+
SILInstruction, MayHaveSideEffects, DoesNotRelease)
839+
837840
NON_VALUE_INST(DestroyValueInst, destroy_value,
838841
SILInstruction, MayHaveSideEffects, MayRelease)
839842
NON_VALUE_INST(EndBorrowInst, end_borrow,

lib/IRGen/IRGenSIL.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,10 @@ class IRGenSILFunction :
11361136
llvm_unreachable("not implemented");
11371137
}
11381138

1139+
void visitHopToExecutorInst(HopToExecutorInst *i) {
1140+
//TODO(async)
1141+
}
1142+
11391143
void visitKeyPathInst(KeyPathInst *I);
11401144

11411145
void visitDifferentiableFunctionInst(DifferentiableFunctionInst *i);

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ CONSTANT_OWNERSHIP_INST(None, MustBeLive, EndAccess)
193193
CONSTANT_OWNERSHIP_INST(None, MustBeLive, EndApply)
194194
CONSTANT_OWNERSHIP_INST(None, MustBeLive, EndUnpairedAccess)
195195
CONSTANT_OWNERSHIP_INST(None, MustBeLive, GetAsyncContinuationAddr)
196+
CONSTANT_OWNERSHIP_INST(None, MustBeLive, HopToExecutor)
196197
CONSTANT_OWNERSHIP_INST(None, MustBeLive, IndexAddr)
197198
CONSTANT_OWNERSHIP_INST(None, MustBeLive, IndexRawPointer)
198199
CONSTANT_OWNERSHIP_INST(None, MustBeLive, InitBlockStorageHeader)

lib/SIL/IR/SILPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,6 +2096,10 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
20962096
}
20972097
}
20982098

2099+
void visitHopToExecutorInst(HopToExecutorInst *HTEI) {
2100+
*this << getIDAndType(HTEI->getActor());
2101+
}
2102+
20992103
void visitSwitchValueInst(SwitchValueInst *SII) {
21002104
*this << getIDAndType(SII->getOperand());
21012105
for (unsigned i = 0, e = SII->getNumCases(); i < e; ++i) {

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2951,6 +2951,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
29512951
UNARY_INSTRUCTION(EndBorrow)
29522952
UNARY_INSTRUCTION(DestructureStruct)
29532953
UNARY_INSTRUCTION(DestructureTuple)
2954+
UNARY_INSTRUCTION(HopToExecutor)
29542955
REFCOUNTING_INSTRUCTION(UnmanagedReleaseValue)
29552956
REFCOUNTING_INSTRUCTION(UnmanagedRetainValue)
29562957
REFCOUNTING_INSTRUCTION(UnmanagedAutoreleaseValue)

lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ static bool hasOpaqueArchetype(TypeExpansionContext context,
339339
case SILInstructionKind::GetAsyncContinuationInst:
340340
case SILInstructionKind::GetAsyncContinuationAddrInst:
341341
case SILInstructionKind::AwaitAsyncContinuationInst:
342+
case SILInstructionKind::HopToExecutorInst:
342343
// Handle by operand and result check.
343344
break;
344345

0 commit comments

Comments
 (0)