Skip to content

Commit 25929b3

Browse files
committed
[IRGen] Move some typed error code in CallEmission into separate function
This is in preparation of adding support for async calls, so the code can be shared between sync and async calls.
1 parent b6c6e86 commit 25929b3

File tree

2 files changed

+95
-77
lines changed

2 files changed

+95
-77
lines changed

lib/IRGen/CallEmission.h

+5
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ class CallEmission {
110110
TemporarySet &temporaries,
111111
bool isOutlined);
112112

113+
bool mayReturnTypedErrorDirectly() const;
114+
void emitToUnmappedExplosionWithDirectTypedError(SILType resultType,
115+
llvm::Value *result,
116+
Explosion &out);
117+
113118
CallEmission(IRGenFunction &IGF, llvm::Value *selfValue, Callee &&callee)
114119
: IGF(IGF), selfValue(selfValue), CurCallee(std::move(callee)) {}
115120

lib/IRGen/GenCall.cpp

+90-77
Original file line numberDiff line numberDiff line change
@@ -2745,17 +2745,7 @@ class SyncCallEmission final : public CallEmission {
27452745
Explosion &out) override {
27462746
SILFunctionConventions fnConv(getCallee().getOrigFunctionType(),
27472747
IGF.getSILModule());
2748-
bool mayReturnErrorDirectly = false;
2749-
if (!convertDirectToIndirectReturn &&
2750-
!fnConv.hasIndirectSILErrorResults() &&
2751-
fnConv.funcTy->hasErrorResult() && fnConv.isTypedError()) {
2752-
auto errorType =
2753-
fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext());
2754-
auto &errorSchema =
2755-
IGF.IGM.getTypeInfo(errorType).nativeReturnValueSchema(IGF.IGM);
2756-
2757-
mayReturnErrorDirectly = !errorSchema.shouldReturnTypedErrorIndirectly();
2758-
}
2748+
bool mayReturnErrorDirectly = mayReturnTypedErrorDirectly();
27592749

27602750
// Bail out immediately on a void result.
27612751
llvm::Value *result = call;
@@ -2812,72 +2802,8 @@ class SyncCallEmission final : public CallEmission {
28122802

28132803
// Handle direct return of typed errors
28142804
if (mayReturnErrorDirectly && !nativeSchema.requiresIndirect()) {
2815-
auto errorType =
2816-
fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext());
2817-
auto &errorSchema =
2818-
IGF.IGM.getTypeInfo(errorType).nativeReturnValueSchema(IGF.IGM);
2819-
2820-
auto combined =
2821-
combineResultAndTypedErrorType(IGF.IGM, nativeSchema, errorSchema);
2822-
2823-
if (combined.combinedTy->isVoidTy()) {
2824-
typedErrorExplosion = Explosion();
2825-
return;
2826-
}
2827-
2828-
Explosion nativeExplosion;
2829-
extractScalarResults(IGF, result->getType(), result, nativeExplosion);
2830-
auto values = nativeExplosion.claimAll();
2831-
2832-
auto convertIfNecessary = [&](llvm::Type *nativeTy,
2833-
llvm::Value *elt) -> llvm::Value * {
2834-
auto *eltTy = elt->getType();
2835-
if (nativeTy->isIntOrPtrTy() && eltTy->isIntOrPtrTy() &&
2836-
nativeTy->getPrimitiveSizeInBits() !=
2837-
eltTy->getPrimitiveSizeInBits()) {
2838-
return IGF.Builder.CreateTruncOrBitCast(elt, nativeTy);
2839-
}
2840-
return elt;
2841-
};
2842-
2843-
Explosion errorExplosion;
2844-
if (!errorSchema.empty()) {
2845-
if (auto *structTy = dyn_cast<llvm::StructType>(
2846-
errorSchema.getExpandedType(IGF.IGM))) {
2847-
for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) {
2848-
llvm::Value *elt = values[combined.errorValueMapping[i]];
2849-
auto *nativeTy = structTy->getElementType(i);
2850-
elt = convertIfNecessary(nativeTy, elt);
2851-
errorExplosion.add(elt);
2852-
}
2853-
} else {
2854-
errorExplosion.add(convertIfNecessary(
2855-
combined.combinedTy, values[combined.errorValueMapping[0]]));
2856-
}
2857-
2858-
typedErrorExplosion =
2859-
errorSchema.mapFromNative(IGF.IGM, IGF, errorExplosion, errorType);
2860-
} else {
2861-
typedErrorExplosion = std::move(errorExplosion);
2862-
}
2863-
2864-
// If the regular result type is void, there is nothing to explode
2865-
if (!resultType.isVoid()) {
2866-
Explosion resultExplosion;
2867-
if (auto *structTy = dyn_cast<llvm::StructType>(
2868-
nativeSchema.getExpandedType(IGF.IGM))) {
2869-
for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) {
2870-
auto *nativeTy = structTy->getElementType(i);
2871-
resultExplosion.add(convertIfNecessary(nativeTy, values[i]));
2872-
}
2873-
} else {
2874-
resultExplosion.add(
2875-
convertIfNecessary(combined.combinedTy, values[0]));
2876-
}
2877-
out = nativeSchema.mapFromNative(IGF.IGM, IGF, resultExplosion,
2878-
resultType);
2879-
}
2880-
return;
2805+
return emitToUnmappedExplosionWithDirectTypedError(resultType, result,
2806+
out);
28812807
}
28822808

28832809
if (result->getType()->isVoidTy())
@@ -4434,6 +4360,93 @@ void CallEmission::externalizeArguments(IRGenFunction &IGF, const Callee &callee
44344360
}
44354361
}
44364362

4363+
bool CallEmission::mayReturnTypedErrorDirectly() const {
4364+
SILFunctionConventions fnConv(getCallee().getOrigFunctionType(),
4365+
IGF.getSILModule());
4366+
bool mayReturnErrorDirectly = false;
4367+
if (!convertDirectToIndirectReturn && !fnConv.hasIndirectSILErrorResults() &&
4368+
fnConv.funcTy->hasErrorResult() && fnConv.isTypedError()) {
4369+
auto errorType =
4370+
fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext());
4371+
auto &errorSchema =
4372+
IGF.IGM.getTypeInfo(errorType).nativeReturnValueSchema(IGF.IGM);
4373+
4374+
mayReturnErrorDirectly = !errorSchema.shouldReturnTypedErrorIndirectly();
4375+
}
4376+
4377+
return mayReturnErrorDirectly;
4378+
}
4379+
4380+
void CallEmission::emitToUnmappedExplosionWithDirectTypedError(
4381+
SILType resultType, llvm::Value *result, Explosion &out) {
4382+
SILFunctionConventions fnConv(getCallee().getOrigFunctionType(),
4383+
IGF.getSILModule());
4384+
auto &nativeSchema =
4385+
IGF.IGM.getTypeInfo(resultType).nativeReturnValueSchema(IGF.IGM);
4386+
auto errorType =
4387+
fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext());
4388+
auto &errorSchema =
4389+
IGF.IGM.getTypeInfo(errorType).nativeReturnValueSchema(IGF.IGM);
4390+
4391+
auto combined =
4392+
combineResultAndTypedErrorType(IGF.IGM, nativeSchema, errorSchema);
4393+
4394+
if (combined.combinedTy->isVoidTy()) {
4395+
typedErrorExplosion = Explosion();
4396+
return;
4397+
}
4398+
4399+
Explosion nativeExplosion;
4400+
extractScalarResults(IGF, result->getType(), result, nativeExplosion);
4401+
auto values = nativeExplosion.claimAll();
4402+
4403+
auto convertIfNecessary = [&](llvm::Type *nativeTy,
4404+
llvm::Value *elt) -> llvm::Value * {
4405+
auto *eltTy = elt->getType();
4406+
if (nativeTy->isIntOrPtrTy() && eltTy->isIntOrPtrTy() &&
4407+
nativeTy->getPrimitiveSizeInBits() != eltTy->getPrimitiveSizeInBits()) {
4408+
return IGF.Builder.CreateTruncOrBitCast(elt, nativeTy);
4409+
}
4410+
return elt;
4411+
};
4412+
4413+
Explosion errorExplosion;
4414+
if (!errorSchema.empty()) {
4415+
if (auto *structTy =
4416+
dyn_cast<llvm::StructType>(errorSchema.getExpandedType(IGF.IGM))) {
4417+
for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) {
4418+
llvm::Value *elt = values[combined.errorValueMapping[i]];
4419+
auto *nativeTy = structTy->getElementType(i);
4420+
elt = convertIfNecessary(nativeTy, elt);
4421+
errorExplosion.add(elt);
4422+
}
4423+
} else {
4424+
errorExplosion.add(convertIfNecessary(
4425+
combined.combinedTy, values[combined.errorValueMapping[0]]));
4426+
}
4427+
4428+
typedErrorExplosion =
4429+
errorSchema.mapFromNative(IGF.IGM, IGF, errorExplosion, errorType);
4430+
} else {
4431+
typedErrorExplosion = std::move(errorExplosion);
4432+
}
4433+
4434+
// If the regular result type is void, there is nothing to explode
4435+
if (!resultType.isVoid()) {
4436+
Explosion resultExplosion;
4437+
if (auto *structTy =
4438+
dyn_cast<llvm::StructType>(nativeSchema.getExpandedType(IGF.IGM))) {
4439+
for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) {
4440+
auto *nativeTy = structTy->getElementType(i);
4441+
resultExplosion.add(convertIfNecessary(nativeTy, values[i]));
4442+
}
4443+
} else {
4444+
resultExplosion.add(convertIfNecessary(combined.combinedTy, values[0]));
4445+
}
4446+
out = nativeSchema.mapFromNative(IGF.IGM, IGF, resultExplosion, resultType);
4447+
}
4448+
}
4449+
44374450
void CallEmission::setKeyPathAccessorArguments(Explosion &in, bool isOutlined,
44384451
Explosion &out) {
44394452
auto origCalleeType = CurCallee.getOrigFunctionType();

0 commit comments

Comments
 (0)