Skip to content

[Async CC] Move thick context into async context. #34765

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 38 additions & 42 deletions lib/IRGen/GenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ irgen::getAsyncContextLayout(IRGenModule &IGM, CanSILFunctionType originalType,
typeInfos.push_back(&errorTypeInfo);
valTypes.push_back(errorType);

bool canHaveValidError = substitutedType->hasErrorResult();

// IndirectResultTypes *indirectResults...;
auto indirectResults = fnConv.getIndirectSILResults();
for (auto indirectResult : indirectResults) {
Expand Down Expand Up @@ -196,15 +198,35 @@ irgen::getAsyncContextLayout(IRGenModule &IGM, CanSILFunctionType originalType,
}

// SelfType self?;
bool hasLocalContextParameter = hasSelfContextParameter(substitutedType);
bool canHaveValidError = substitutedType->hasErrorResult();
bool hasLocalContext = (hasLocalContextParameter || canHaveValidError);
bool hasSelf = hasSelfContextParameter(substitutedType);
SILParameterInfo localContextParameter =
hasLocalContextParameter ? parameters.back() : SILParameterInfo();
if (hasLocalContextParameter) {
hasSelf ? parameters.back() : SILParameterInfo();
if (hasSelf) {
parameters = parameters.drop_back();
}

Optional<AsyncContextLayout::ArgumentInfo> localContextInfo = llvm::None;
if (hasSelf) {
assert(originalType->getRepresentation() !=
SILFunctionTypeRepresentation::Thick);
SILType ty = IGM.silConv.getSILType(localContextParameter, substitutedType,
IGM.getMaximalTypeExpansionContext());
auto argumentLoweringType =
getArgumentLoweringType(ty.getASTType(), localContextParameter,
/*isNoEscape*/ true);

auto &ti = IGM.getTypeInfoForLowered(argumentLoweringType);
valTypes.push_back(ty);
typeInfos.push_back(&ti);
localContextInfo = {ty, localContextParameter.getConvention()};
} else {
auto &ti = IGM.getNativeObjectTypeInfo();
SILType ty = SILType::getNativeObjectType(IGM.Context);
valTypes.push_back(ty);
typeInfos.push_back(&ti);
localContextInfo = {ty, substitutedType->getCalleeConvention()};
}

// ArgTypes formalArguments...;
for (auto parameter : parameters) {
SILType ty = IGM.silConv.getSILType(parameter, substitutedType,
Expand All @@ -230,31 +252,6 @@ irgen::getAsyncContextLayout(IRGenModule &IGM, CanSILFunctionType originalType,
typeInfos.push_back(&bindingsTI);
}

Optional<AsyncContextLayout::ArgumentInfo> localContextInfo = llvm::None;
if (hasLocalContext) {
if (hasLocalContextParameter) {
SILType ty =
IGM.silConv.getSILType(localContextParameter, substitutedType,
IGM.getMaximalTypeExpansionContext());
auto argumentLoweringType =
getArgumentLoweringType(ty.getASTType(), localContextParameter,
/*isNoEscape*/ true);

auto &ti = IGM.getTypeInfoForLowered(argumentLoweringType);
valTypes.push_back(ty);
typeInfos.push_back(&ti);
localContextInfo = {ty, localContextParameter.getConvention()};
} else {
// TODO: DETERMINE: Is there a field in this case to match the sync ABI?
auto &ti = IGM.getNativeObjectTypeInfo();
SILType ty = SILType::getNativeObjectType(IGM.Context);
valTypes.push_back(ty);
typeInfos.push_back(&ti);
localContextInfo = {ty, substitutedType->getCalleeConvention()};
}
}


Optional<AsyncContextLayout::TrailingWitnessInfo> trailingWitnessInfo;
if (originalType->getRepresentation() ==
SILFunctionTypeRepresentation::WitnessMethod) {
Expand Down Expand Up @@ -778,10 +775,6 @@ void SignatureExpansion::addAsyncParameters() {
ParamIRTypes.push_back(IGM.SwiftTaskPtrTy);
ParamIRTypes.push_back(IGM.SwiftExecutorPtrTy);
ParamIRTypes.push_back(IGM.SwiftContextPtrTy);
if (FnType->getRepresentation() == SILFunctionTypeRepresentation::Thick) {
IGM.addSwiftSelfAttributes(Attrs, ParamIRTypes.size());
ParamIRTypes.push_back(IGM.RefCountedPtrTy);
}
}

void SignatureExpansion::addCoroutineContextParameter() {
Expand Down Expand Up @@ -2314,10 +2307,6 @@ class AsyncCallEmission final : public CallEmission {
asyncExplosion.add(IGF.getAsyncTask());
asyncExplosion.add(IGF.getAsyncExecutor());
asyncExplosion.add(contextBuffer.getAddress());
if (getCallee().getRepresentation() ==
SILFunctionTypeRepresentation::Thick) {
asyncExplosion.add(getCallee().getSwiftContext());
}
super::setArgs(asyncExplosion, false, witnessMetadata);
SILFunctionConventions fnConv(getCallee().getSubstFunctionType(),
IGF.getSILModule());
Expand Down Expand Up @@ -2380,11 +2369,18 @@ class AsyncCallEmission final : public CallEmission {
auto bindingsAddr = bindingLayout.project(IGF, context, /*offsets*/ None);
layout.getBindings().save(IGF, bindingsAddr, llArgs);
}
if (selfValue) {
Explosion selfExplosion;
selfExplosion.add(selfValue);
auto isThick =
getCallee().getRepresentation() == SILFunctionTypeRepresentation::Thick;
if (selfValue || isThick) {
Explosion localExplosion;
if (selfValue) {
assert(!isThick);
localExplosion.add(selfValue);
} else {
localExplosion.add(getCallee().getSwiftContext());
}
auto fieldLayout = layout.getLocalContextLayout();
saveValue(fieldLayout, selfExplosion, isOutlined);
saveValue(fieldLayout, localExplosion, isOutlined);
}
}
void emitCallToUnmappedExplosion(llvm::CallInst *call, Explosion &out) override {
Expand Down
25 changes: 12 additions & 13 deletions lib/IRGen/GenCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ namespace irgen {
// };
// ResultTypes directResults...;
// };
// SelfType self;
// ArgTypes formalArguments...;
// SelfType self?;
// };
struct AsyncContextLayout : StructLayout {
struct ArgumentInfo {
Expand Down Expand Up @@ -177,7 +177,14 @@ namespace irgen {
return getIndexAfterDirectReturns();
}
}
unsigned getFirstArgumentIndex() { return getIndexAfterUnion(); }
unsigned getLocalContextIndex() {
assert(hasLocalContext());
return getIndexAfterUnion();
}
unsigned getIndexAfterLocalContext() {
return getIndexAfterUnion() + (hasLocalContext() ? 1 : 0);
}
unsigned getFirstArgumentIndex() { return getIndexAfterLocalContext(); }
unsigned getIndexAfterArguments() {
return getFirstArgumentIndex() + getArgumentCount();
}
Expand All @@ -188,24 +195,16 @@ namespace irgen {
unsigned getIndexAfterBindings() {
return getIndexAfterArguments() + (hasBindings() ? 1 : 0);
}
unsigned getLocalContextIndex() {
assert(hasLocalContext());
return getIndexAfterBindings();
}
unsigned getIndexAfterLocalContext() {
return getIndexAfterBindings() +
(hasLocalContext() ? 1 : 0);
}
unsigned getSelfMetadataIndex() {
assert(hasTrailingWitnesses());
return getIndexAfterLocalContext();
return getIndexAfterBindings();
}
unsigned getSelfWitnessTableIndex() {
assert(hasTrailingWitnesses());
return getIndexAfterLocalContext() + 1;
return getIndexAfterBindings() + 1;
}
unsigned getIndexAfterTrailingWitnesses() {
return getIndexAfterLocalContext() + (hasTrailingWitnesses() ? 2 : 0);
return getIndexAfterBindings() + (hasTrailingWitnesses() ? 2 : 0);
}

public:
Expand Down
18 changes: 13 additions & 5 deletions lib/IRGen/GenFunc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,6 @@ class AsyncPartialApplicationForwarderEmission
llvm::Value *contextBuffer;
Size contextSize;
Address context;
llvm::Value *heapContextBuffer;
unsigned currentArgumentIndex;
struct DynamicFunction {
using Kind = DynamicFunctionKind;
Expand Down Expand Up @@ -1072,13 +1071,13 @@ class AsyncPartialApplicationForwarderEmission
task = origParams.claimNext();
executor = origParams.claimNext();
contextBuffer = origParams.claimNext();
heapContextBuffer = origParams.claimNext();
}

void begin() override {
super::begin();
assert(task);
assert(executor);
assert(contextBuffer);
assert(heapContextBuffer);
context = layout.emitCastTo(subIGF, contextBuffer);
}
bool transformArgumentToNative(SILParameterInfo origParamInfo, Explosion &in,
Expand Down Expand Up @@ -1125,7 +1124,9 @@ class AsyncPartialApplicationForwarderEmission
SILParameterInfo getParameterInfo(unsigned index) override {
return origType->getParameters()[index];
}
llvm::Value *getContext() override { return heapContextBuffer; }
llvm::Value *getContext() override {
return loadValue(layout.getLocalContextLayout());
}
llvm::Value *getDynamicFunctionPointer() override {
assert(dynamicFunction && dynamicFunction->pointer);
auto *context = dynamicFunction->context;
Expand Down Expand Up @@ -1248,8 +1249,15 @@ class AsyncPartialApplicationForwarderEmission
asyncExplosion.add(contextBuffer);
if (dynamicFunction &&
dynamicFunction->kind == DynamicFunction::Kind::PartialApply) {
// Just before making the call, replace the old thick context with the
// new thick context so that (1) the new thick context is never used by
// this partial apply forwarder and (2) the old thick context is never
// used by the callee partial apply forwarder.
assert(dynamicFunction->context);
asyncExplosion.add(dynamicFunction->context);
auto fieldLayout = layout.getLocalContextLayout();
Explosion explosion;
explosion.add(dynamicFunction->context);
saveValue(fieldLayout, explosion);
}

return subIGF.Builder.CreateCall(fnPtr.getAsFunction(subIGF),
Expand Down
9 changes: 6 additions & 3 deletions lib/IRGen/IRGenSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1754,9 +1754,12 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF,

// Even if we don't have a 'self', if we have an error result, we
// should have a placeholder argument here.
} else if (funcTy->hasErrorResult() ||
funcTy->getRepresentation() == SILFunctionTypeRepresentation::Thick)
{
//
// For async functions, there will be a thick context within the async
// context whenever there is no self context.
} else if (funcTy->isAsync() || funcTy->hasErrorResult() ||
funcTy->getRepresentation() ==
SILFunctionTypeRepresentation::Thick) {
llvm::Value *contextPtr = emission->getContext();
(void)contextPtr;
assert(contextPtr->getType() == IGF.IGM.RefCountedPtrTy);
Expand Down
Loading