Skip to content

Commit 35d06c3

Browse files
committed
[CoroutineAccessors] Witness and vtable dispatch.
And thunking.
1 parent f5d03a6 commit 35d06c3

27 files changed

+527
-31
lines changed

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ NODE(DependentGenericInverseConformanceRequirement)
408408
NODE(Integer)
409409
NODE(NegativeInteger)
410410
NODE(DependentGenericParamValueMarker)
411+
NODE(CoroFunctionPointer)
411412

412413
#undef CONTEXT_NODE
413414
#undef NODE

include/swift/IRGen/Linking.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,11 @@ class LinkEntity {
585585
/// The pointer is the llvm::Function* for a partial apply forwarder.
586586
PartialApplyForwarderCoroFunctionPointer,
587587

588+
/// An coro function pointer to a function which is known to exist whose
589+
/// name is known.
590+
/// The pointer is a const char* of the name.
591+
KnownCoroFunctionPointer,
592+
588593
/// An coro function pointer for a distributed accessor (method or
589594
/// property).
590595
/// The pointer is a SILFunction*.
@@ -1553,6 +1558,15 @@ class LinkEntity {
15531558
return entity;
15541559
}
15551560

1561+
static LinkEntity forKnownCoroFunctionPointer(const char *name) {
1562+
LinkEntity entity;
1563+
entity.Pointer = const_cast<char *>(name);
1564+
entity.SecondaryPointer = nullptr;
1565+
entity.Data =
1566+
LINKENTITY_SET_FIELD(Kind, unsigned(Kind::KnownCoroFunctionPointer));
1567+
return entity;
1568+
}
1569+
15561570
LinkEntity getUnderlyingEntityForCoroFunctionPointer() const {
15571571
LinkEntity entity;
15581572
entity.Pointer = Pointer;

include/swift/SIL/SILDeclRef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,7 @@ struct SILDeclRef {
612612
}
613613

614614
bool hasAsync() const;
615+
bool isCalleeAllocatedCoroutine() const;
615616

616617
private:
617618
friend struct llvm::DenseMapInfo<swift::SILDeclRef>;

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10931,7 +10931,7 @@ bool AccessorDecl::isRequirementWithSynthesizedDefaultImplementation() const {
1093110931
if (!requiresFeatureCoroutineAccessors(getAccessorKind())) {
1093210932
return false;
1093310933
}
10934-
if (getStorage()->getOverrideLoc()) {
10934+
if (!requiresNewWitnessTableEntry()) {
1093510935
return false;
1093610936
}
1093710937
return getStorage()->requiresCorrespondingUnderscoredCoroutineAccessor(

lib/Demangling/NodePrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,7 @@ class NodePrinter {
657657
case Node::Kind::ObjectiveCProtocolSymbolicReference:
658658
case Node::Kind::DependentGenericInverseConformanceRequirement:
659659
case Node::Kind::DependentGenericParamValueMarker:
660+
case Node::Kind::CoroFunctionPointer:
660661
return false;
661662
}
662663
printer_unreachable("bad node kind");
@@ -3478,6 +3479,9 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
34783479
Printer << signedValue;
34793480
return nullptr;
34803481
}
3482+
case Node::Kind::CoroFunctionPointer:
3483+
Printer << "coro function pointer to ";
3484+
return nullptr;
34813485
}
34823486

34833487
printer_unreachable("bad node kind!");

lib/IRGen/Callee.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,11 @@ namespace irgen {
206206
FunctionPointerKind(SpecialKind kind)
207207
: value(unsigned(kind) + SpecialOffset) {}
208208
FunctionPointerKind(CanSILFunctionType fnType)
209-
: FunctionPointerKind(fnType->isAsync()
210-
? BasicKind::AsyncFunctionPointer
211-
: BasicKind::Function) {}
209+
: FunctionPointerKind(fnType->isAsync()
210+
? BasicKind::AsyncFunctionPointer
211+
: fnType->isCalleeAllocatedCoroutine()
212+
? BasicKind::CoroFunctionPointer
213+
: BasicKind::Function) {}
212214

213215
static FunctionPointerKind defaultSync() {
214216
return BasicKind::Function;

lib/IRGen/GenCall.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5151,13 +5151,11 @@ static llvm::Constant *getCoroAllocWrapperFn(IRGenModule &IGM) {
51515151
/*optionalLinkageOverride=*/nullptr, llvm::CallingConv::SwiftCoro);
51525152
}
51535153

5154-
void irgen::emitYieldOnce2CoroutineEntry(
5155-
IRGenFunction &IGF, LinkEntity coroFunction, CanSILFunctionType fnType,
5156-
NativeCCEntryPointArgumentEmission &emission) {
5157-
auto *buffer = emission.getCoroutineBuffer();
5158-
auto cfp = cast<llvm::GlobalVariable>(
5159-
IGF.IGM.getAddrOfCoroFunctionPointer(coroFunction));
5160-
llvm::Value *allocator = emission.getCoroutineAllocator();
5154+
void irgen::emitYieldOnce2CoroutineEntry(IRGenFunction &IGF,
5155+
CanSILFunctionType fnType,
5156+
llvm::Value *buffer,
5157+
llvm::Value *allocator,
5158+
llvm::GlobalVariable *cfp) {
51615159
IGF.setCoroutineAllocator(allocator);
51625160
auto isSwiftCoroCCAvailable =
51635161
IGF.IGM.SwiftCoroCC == llvm::CallingConv::SwiftCoro;
@@ -5170,6 +5168,15 @@ void irgen::emitYieldOnce2CoroutineEntry(
51705168
Size(-1) /*dynamic-to-IRGen size*/, IGF.IGM.getCoroStaticFrameAlignment(),
51715169
{cfp, allocator}, allocFn, deallocFn, {});
51725170
}
5171+
void irgen::emitYieldOnce2CoroutineEntry(
5172+
IRGenFunction &IGF, LinkEntity coroFunction, CanSILFunctionType fnType,
5173+
NativeCCEntryPointArgumentEmission &emission) {
5174+
auto *buffer = emission.getCoroutineBuffer();
5175+
auto cfp = cast<llvm::GlobalVariable>(
5176+
IGF.IGM.getAddrOfCoroFunctionPointer(coroFunction));
5177+
llvm::Value *allocator = emission.getCoroutineAllocator();
5178+
emitYieldOnce2CoroutineEntry(IGF, fnType, buffer, allocator, cfp);
5179+
}
51735180

51745181
static Address createOpaqueBufferAlloca(IRGenFunction &IGF,
51755182
Size size, Alignment align) {

lib/IRGen/GenCall.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ namespace irgen {
231231
emitYieldOnce2CoroutineEntry(IRGenFunction &IGF, LinkEntity coroFunction,
232232
CanSILFunctionType coroutineType,
233233
NativeCCEntryPointArgumentEmission &emission);
234+
void emitYieldOnce2CoroutineEntry(IRGenFunction &IGF,
235+
CanSILFunctionType fnType,
236+
llvm::Value *buffer, llvm::Value *allocator,
237+
llvm::GlobalVariable *cfp);
234238

235239
Address emitAllocYieldManyCoroutineBuffer(IRGenFunction &IGF);
236240
void emitDeallocYieldManyCoroutineBuffer(IRGenFunction &IGF, Address buffer);

lib/IRGen/GenClass.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3103,11 +3103,19 @@ FunctionPointer irgen::emitVirtualMethodValue(IRGenFunction &IGF,
31033103
auto fnPtr = llvm::ConstantExpr::getBitCast(methodInfo.getDirectImpl(),
31043104
signature.getType()->getPointerTo());
31053105
llvm::Constant *secondaryValue = nullptr;
3106+
auto *accessor = dyn_cast<AccessorDecl>(method.getDecl());
31063107
if (cast<AbstractFunctionDecl>(method.getDecl())->hasAsync()) {
31073108
auto *silFn = IGF.IGM.getSILFunctionForAsyncFunctionPointer(
31083109
methodInfo.getDirectImpl());
31093110
secondaryValue = cast<llvm::Constant>(
31103111
IGF.IGM.getAddrOfSILFunction(silFn, NotForDefinition));
3112+
} else if (accessor &&
3113+
requiresFeatureCoroutineAccessors(accessor->getAccessorKind())) {
3114+
assert(methodType->isCalleeAllocatedCoroutine());
3115+
auto *silFn = IGF.IGM.getSILFunctionForCoroFunctionPointer(
3116+
methodInfo.getDirectImpl());
3117+
secondaryValue = cast<llvm::Constant>(
3118+
IGF.IGM.getAddrOfSILFunction(silFn, NotForDefinition));
31113119
}
31123120
return FunctionPointer::forDirect(methodType, fnPtr, secondaryValue,
31133121
signature, true);

lib/IRGen/GenConstant.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,13 @@ Explosion irgen::emitConstantValue(IRGenModule &IGM, SILValue operand,
396396
llvm::Constant *fnPtr = IGM.getAddrOfSILFunction(fn, NotForDefinition);
397397
CanSILFunctionType fnType = FRI->getType().getAs<SILFunctionType>();
398398

399-
if (irgen::classifyFunctionPointerKind(fn).isAsyncFunctionPointer()) {
399+
auto fpKind = irgen::classifyFunctionPointerKind(fn);
400+
if (fpKind.isAsyncFunctionPointer()) {
400401
llvm::Constant *asyncFnPtr = IGM.getAddrOfAsyncFunctionPointer(fn);
401402
fnPtr = llvm::ConstantExpr::getBitCast(asyncFnPtr, fnPtr->getType());
403+
} else if (fpKind.isCoroFunctionPointer()) {
404+
llvm::Constant *coroFnPtr = IGM.getAddrOfCoroFunctionPointer(fn);
405+
fnPtr = llvm::ConstantExpr::getBitCast(coroFnPtr, fnPtr->getType());
402406
}
403407

404408
auto authInfo = PointerAuthInfo::forFunctionPointer(IGM, fnType);

0 commit comments

Comments
 (0)