Skip to content

Commit f855628

Browse files
Merge pull request #34765 from nate-chandler/concurrency/irgen/thick-context-in-async-context
[Async CC] Move thick context into async context.
2 parents e56af29 + eba057f commit f855628

15 files changed

+101
-95
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ irgen::getAsyncContextLayout(IRGenModule &IGM, CanSILFunctionType originalType,
156156
typeInfos.push_back(&errorTypeInfo);
157157
valTypes.push_back(errorType);
158158

159+
bool canHaveValidError = substitutedType->hasErrorResult();
160+
159161
// IndirectResultTypes *indirectResults...;
160162
auto indirectResults = fnConv.getIndirectSILResults();
161163
for (auto indirectResult : indirectResults) {
@@ -196,15 +198,35 @@ irgen::getAsyncContextLayout(IRGenModule &IGM, CanSILFunctionType originalType,
196198
}
197199

198200
// SelfType self?;
199-
bool hasLocalContextParameter = hasSelfContextParameter(substitutedType);
200-
bool canHaveValidError = substitutedType->hasErrorResult();
201-
bool hasLocalContext = (hasLocalContextParameter || canHaveValidError);
201+
bool hasSelf = hasSelfContextParameter(substitutedType);
202202
SILParameterInfo localContextParameter =
203-
hasLocalContextParameter ? parameters.back() : SILParameterInfo();
204-
if (hasLocalContextParameter) {
203+
hasSelf ? parameters.back() : SILParameterInfo();
204+
if (hasSelf) {
205205
parameters = parameters.drop_back();
206206
}
207207

208+
Optional<AsyncContextLayout::ArgumentInfo> localContextInfo = llvm::None;
209+
if (hasSelf) {
210+
assert(originalType->getRepresentation() !=
211+
SILFunctionTypeRepresentation::Thick);
212+
SILType ty = IGM.silConv.getSILType(localContextParameter, substitutedType,
213+
IGM.getMaximalTypeExpansionContext());
214+
auto argumentLoweringType =
215+
getArgumentLoweringType(ty.getASTType(), localContextParameter,
216+
/*isNoEscape*/ true);
217+
218+
auto &ti = IGM.getTypeInfoForLowered(argumentLoweringType);
219+
valTypes.push_back(ty);
220+
typeInfos.push_back(&ti);
221+
localContextInfo = {ty, localContextParameter.getConvention()};
222+
} else {
223+
auto &ti = IGM.getNativeObjectTypeInfo();
224+
SILType ty = SILType::getNativeObjectType(IGM.Context);
225+
valTypes.push_back(ty);
226+
typeInfos.push_back(&ti);
227+
localContextInfo = {ty, substitutedType->getCalleeConvention()};
228+
}
229+
208230
// ArgTypes formalArguments...;
209231
for (auto parameter : parameters) {
210232
SILType ty = IGM.silConv.getSILType(parameter, substitutedType,
@@ -230,31 +252,6 @@ irgen::getAsyncContextLayout(IRGenModule &IGM, CanSILFunctionType originalType,
230252
typeInfos.push_back(&bindingsTI);
231253
}
232254

233-
Optional<AsyncContextLayout::ArgumentInfo> localContextInfo = llvm::None;
234-
if (hasLocalContext) {
235-
if (hasLocalContextParameter) {
236-
SILType ty =
237-
IGM.silConv.getSILType(localContextParameter, substitutedType,
238-
IGM.getMaximalTypeExpansionContext());
239-
auto argumentLoweringType =
240-
getArgumentLoweringType(ty.getASTType(), localContextParameter,
241-
/*isNoEscape*/ true);
242-
243-
auto &ti = IGM.getTypeInfoForLowered(argumentLoweringType);
244-
valTypes.push_back(ty);
245-
typeInfos.push_back(&ti);
246-
localContextInfo = {ty, localContextParameter.getConvention()};
247-
} else {
248-
// TODO: DETERMINE: Is there a field in this case to match the sync ABI?
249-
auto &ti = IGM.getNativeObjectTypeInfo();
250-
SILType ty = SILType::getNativeObjectType(IGM.Context);
251-
valTypes.push_back(ty);
252-
typeInfos.push_back(&ti);
253-
localContextInfo = {ty, substitutedType->getCalleeConvention()};
254-
}
255-
}
256-
257-
258255
Optional<AsyncContextLayout::TrailingWitnessInfo> trailingWitnessInfo;
259256
if (originalType->getRepresentation() ==
260257
SILFunctionTypeRepresentation::WitnessMethod) {
@@ -778,10 +775,6 @@ void SignatureExpansion::addAsyncParameters() {
778775
ParamIRTypes.push_back(IGM.SwiftTaskPtrTy);
779776
ParamIRTypes.push_back(IGM.SwiftExecutorPtrTy);
780777
ParamIRTypes.push_back(IGM.SwiftContextPtrTy);
781-
if (FnType->getRepresentation() == SILFunctionTypeRepresentation::Thick) {
782-
IGM.addSwiftSelfAttributes(Attrs, ParamIRTypes.size());
783-
ParamIRTypes.push_back(IGM.RefCountedPtrTy);
784-
}
785778
}
786779

787780
void SignatureExpansion::addCoroutineContextParameter() {
@@ -2314,10 +2307,6 @@ class AsyncCallEmission final : public CallEmission {
23142307
asyncExplosion.add(IGF.getAsyncTask());
23152308
asyncExplosion.add(IGF.getAsyncExecutor());
23162309
asyncExplosion.add(contextBuffer.getAddress());
2317-
if (getCallee().getRepresentation() ==
2318-
SILFunctionTypeRepresentation::Thick) {
2319-
asyncExplosion.add(getCallee().getSwiftContext());
2320-
}
23212310
super::setArgs(asyncExplosion, false, witnessMetadata);
23222311
SILFunctionConventions fnConv(getCallee().getSubstFunctionType(),
23232312
IGF.getSILModule());
@@ -2380,11 +2369,18 @@ class AsyncCallEmission final : public CallEmission {
23802369
auto bindingsAddr = bindingLayout.project(IGF, context, /*offsets*/ None);
23812370
layout.getBindings().save(IGF, bindingsAddr, llArgs);
23822371
}
2383-
if (selfValue) {
2384-
Explosion selfExplosion;
2385-
selfExplosion.add(selfValue);
2372+
auto isThick =
2373+
getCallee().getRepresentation() == SILFunctionTypeRepresentation::Thick;
2374+
if (selfValue || isThick) {
2375+
Explosion localExplosion;
2376+
if (selfValue) {
2377+
assert(!isThick);
2378+
localExplosion.add(selfValue);
2379+
} else {
2380+
localExplosion.add(getCallee().getSwiftContext());
2381+
}
23862382
auto fieldLayout = layout.getLocalContextLayout();
2387-
saveValue(fieldLayout, selfExplosion, isOutlined);
2383+
saveValue(fieldLayout, localExplosion, isOutlined);
23882384
}
23892385
}
23902386
void emitCallToUnmappedExplosion(llvm::CallInst *call, Explosion &out) override {

lib/IRGen/GenCall.h

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ namespace irgen {
8181
// };
8282
// ResultTypes directResults...;
8383
// };
84+
// SelfType self;
8485
// ArgTypes formalArguments...;
85-
// SelfType self?;
8686
// };
8787
struct AsyncContextLayout : StructLayout {
8888
struct ArgumentInfo {
@@ -177,7 +177,14 @@ namespace irgen {
177177
return getIndexAfterDirectReturns();
178178
}
179179
}
180-
unsigned getFirstArgumentIndex() { return getIndexAfterUnion(); }
180+
unsigned getLocalContextIndex() {
181+
assert(hasLocalContext());
182+
return getIndexAfterUnion();
183+
}
184+
unsigned getIndexAfterLocalContext() {
185+
return getIndexAfterUnion() + (hasLocalContext() ? 1 : 0);
186+
}
187+
unsigned getFirstArgumentIndex() { return getIndexAfterLocalContext(); }
181188
unsigned getIndexAfterArguments() {
182189
return getFirstArgumentIndex() + getArgumentCount();
183190
}
@@ -188,24 +195,16 @@ namespace irgen {
188195
unsigned getIndexAfterBindings() {
189196
return getIndexAfterArguments() + (hasBindings() ? 1 : 0);
190197
}
191-
unsigned getLocalContextIndex() {
192-
assert(hasLocalContext());
193-
return getIndexAfterBindings();
194-
}
195-
unsigned getIndexAfterLocalContext() {
196-
return getIndexAfterBindings() +
197-
(hasLocalContext() ? 1 : 0);
198-
}
199198
unsigned getSelfMetadataIndex() {
200199
assert(hasTrailingWitnesses());
201-
return getIndexAfterLocalContext();
200+
return getIndexAfterBindings();
202201
}
203202
unsigned getSelfWitnessTableIndex() {
204203
assert(hasTrailingWitnesses());
205-
return getIndexAfterLocalContext() + 1;
204+
return getIndexAfterBindings() + 1;
206205
}
207206
unsigned getIndexAfterTrailingWitnesses() {
208-
return getIndexAfterLocalContext() + (hasTrailingWitnesses() ? 2 : 0);
207+
return getIndexAfterBindings() + (hasTrailingWitnesses() ? 2 : 0);
209208
}
210209

211210
public:

lib/IRGen/GenFunc.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,7 +1019,6 @@ class AsyncPartialApplicationForwarderEmission
10191019
llvm::Value *contextBuffer;
10201020
Size contextSize;
10211021
Address context;
1022-
llvm::Value *heapContextBuffer;
10231022
unsigned currentArgumentIndex;
10241023
struct DynamicFunction {
10251024
using Kind = DynamicFunctionKind;
@@ -1072,13 +1071,13 @@ class AsyncPartialApplicationForwarderEmission
10721071
task = origParams.claimNext();
10731072
executor = origParams.claimNext();
10741073
contextBuffer = origParams.claimNext();
1075-
heapContextBuffer = origParams.claimNext();
10761074
}
10771075

10781076
void begin() override {
10791077
super::begin();
1078+
assert(task);
1079+
assert(executor);
10801080
assert(contextBuffer);
1081-
assert(heapContextBuffer);
10821081
context = layout.emitCastTo(subIGF, contextBuffer);
10831082
}
10841083
bool transformArgumentToNative(SILParameterInfo origParamInfo, Explosion &in,
@@ -1125,7 +1124,9 @@ class AsyncPartialApplicationForwarderEmission
11251124
SILParameterInfo getParameterInfo(unsigned index) override {
11261125
return origType->getParameters()[index];
11271126
}
1128-
llvm::Value *getContext() override { return heapContextBuffer; }
1127+
llvm::Value *getContext() override {
1128+
return loadValue(layout.getLocalContextLayout());
1129+
}
11291130
llvm::Value *getDynamicFunctionPointer() override {
11301131
assert(dynamicFunction && dynamicFunction->pointer);
11311132
auto *context = dynamicFunction->context;
@@ -1248,8 +1249,15 @@ class AsyncPartialApplicationForwarderEmission
12481249
asyncExplosion.add(contextBuffer);
12491250
if (dynamicFunction &&
12501251
dynamicFunction->kind == DynamicFunction::Kind::PartialApply) {
1252+
// Just before making the call, replace the old thick context with the
1253+
// new thick context so that (1) the new thick context is never used by
1254+
// this partial apply forwarder and (2) the old thick context is never
1255+
// used by the callee partial apply forwarder.
12511256
assert(dynamicFunction->context);
1252-
asyncExplosion.add(dynamicFunction->context);
1257+
auto fieldLayout = layout.getLocalContextLayout();
1258+
Explosion explosion;
1259+
explosion.add(dynamicFunction->context);
1260+
saveValue(fieldLayout, explosion);
12531261
}
12541262

12551263
return subIGF.Builder.CreateCall(fnPtr.getAsFunction(subIGF),

lib/IRGen/IRGenSIL.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,9 +1754,12 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF,
17541754

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

0 commit comments

Comments
 (0)