diff --git a/lib/IRGen/CallEmission.h b/lib/IRGen/CallEmission.h index 6c615db50be2d..5f189f4c4c705 100644 --- a/lib/IRGen/CallEmission.h +++ b/lib/IRGen/CallEmission.h @@ -19,7 +19,6 @@ #include "Address.h" #include "Callee.h" -#include "Explosion.h" #include "Temporary.h" namespace llvm { @@ -89,7 +88,6 @@ class CallEmission { unsigned IndirectTypedErrorArgIdx = 0; - std::optional typedErrorExplosion; virtual void setFromCallee(); void emitToUnmappedMemory(Address addr); @@ -110,11 +108,6 @@ class CallEmission { TemporarySet &temporaries, bool isOutlined); - bool mayReturnTypedErrorDirectly() const; - void emitToUnmappedExplosionWithDirectTypedError(SILType resultType, - llvm::Value *result, - Explosion &out); - CallEmission(IRGenFunction &IGF, llvm::Value *selfValue, Callee &&callee) : IGF(IGF), selfValue(selfValue), CurCallee(std::move(callee)) {} @@ -130,10 +123,6 @@ class CallEmission { return CurCallee.getSubstitutions(); } - std::optional &getTypedErrorExplosion() { - return typedErrorExplosion; - } - virtual void begin(); virtual void end(); virtual SILType getParameterType(unsigned index) = 0; diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index a201435ce7135..89bf71cdccb93 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -377,81 +377,6 @@ static void addIndirectResultAttributes(IRGenModule &IGM, attrs = attrs.addParamAttributes(IGM.getLLVMContext(), paramIndex, b); } -// This function should only be called with directly returnable -// result and error types. Errors can only be returned directly if -// they consists solely of int and ptr values. -CombinedResultAndErrorType irgen::combineResultAndTypedErrorType( - const IRGenModule &IGM, const NativeConventionSchema &resultSchema, - const NativeConventionSchema &errorSchema) { - assert(!resultSchema.requiresIndirect()); - assert(!errorSchema.shouldReturnTypedErrorIndirectly()); - - CombinedResultAndErrorType result; - SmallVector elts; - resultSchema.enumerateComponents( - [&](clang::CharUnits offset, clang::CharUnits end, llvm::Type *type) { - elts.push_back(type); - }); - - SmallVector errorElts; - errorSchema.enumerateComponents( - [&](clang::CharUnits offset, clang::CharUnits end, llvm::Type *type) { - errorElts.push_back(type); - }); - - llvm::SmallVector combined; - - auto resIt = elts.begin(); - auto errorIt = errorElts.begin(); - - while (resIt < elts.end() && errorIt < errorElts.end()) { - auto *res = *resIt; - if (!res->isIntOrPtrTy()) { - combined.push_back(res); - ++resIt; - continue; - } - - auto *error = *errorIt; - assert(error->isIntOrPtrTy() && - "Direct errors must only consist of int or ptr values"); - result.errorValueMapping.push_back(combined.size()); - - if (res == error) { - combined.push_back(res); - } else { - auto maxSize = std::max(IGM.DataLayout.getTypeSizeInBits(res), - IGM.DataLayout.getTypeSizeInBits(error)); - combined.push_back(llvm::IntegerType::get(IGM.getLLVMContext(), maxSize)); - } - - ++resIt; - ++errorIt; - } - - while (resIt < elts.end()) { - combined.push_back(*resIt); - ++resIt; - } - - while (errorIt < errorElts.end()) { - result.errorValueMapping.push_back(combined.size()); - combined.push_back(*errorIt); - ++errorIt; - } - - if (combined.empty()) { - result.combinedTy = llvm::Type::getVoidTy(IGM.getLLVMContext()); - } else if (combined.size() == 1) { - result.combinedTy = combined[0]; - } else { - result.combinedTy = - llvm::StructType::get(IGM.getLLVMContext(), combined, /*packed*/ false); - } - - return result; -} - void IRGenModule::addSwiftAsyncContextAttributes(llvm::AttributeList &attrs, unsigned argIndex) { llvm::AttrBuilder b(getLLVMContext()); @@ -598,7 +523,6 @@ namespace { /// the direct result of this function. If the result is passed indirectly, /// a void type is returned instead, with a \c null type info. std::pair expandDirectResult(); - std::pair expandDirectErrorType(); void expandIndirectResults(); void expandParameters(SignatureExpansionABIDetails *recordedABIDetails); void expandKeyPathAccessorParameters(); @@ -653,17 +577,6 @@ void SignatureExpansion::expandResult( const TypeInfo *directResultTypeInfo; std::tie(ResultIRType, directResultTypeInfo) = expandDirectResult(); - if (!fnConv.hasIndirectSILResults() && !fnConv.hasIndirectSILErrorResults()) { - llvm::Type *directErrorType; - const TypeInfo *directErrorTypeInfo; - std::tie(directErrorType, directErrorTypeInfo) = expandDirectErrorType(); - if ((directResultTypeInfo || ResultIRType->isVoidTy()) && - directErrorTypeInfo) { - ResultIRType = directErrorType; - directResultTypeInfo = directErrorTypeInfo; - } - } - // Expand the indirect results. expandIndirectResults(); @@ -895,8 +808,9 @@ llvm::Type *NativeConventionSchema::getExpandedType(IRGenModule &IGM) const { if (empty()) return IGM.VoidTy; SmallVector elts; - enumerateComponents([&](clang::CharUnits offset, clang::CharUnits end, - llvm::Type *type) { elts.push_back(type); }); + Lowering.enumerateComponents([&](clang::CharUnits offset, + clang::CharUnits end, + llvm::Type *type) { elts.push_back(type); }); if (elts.size() == 1) return elts[0]; @@ -920,7 +834,7 @@ NativeConventionSchema::getCoercionTypes( unsigned idx = 0; // Mark overlapping ranges. - enumerateComponents( + Lowering.enumerateComponents( [&](clang::CharUnits offset, clang::CharUnits end, llvm::Type *type) { if (offset < lastEnd) { overlappedWithSuccessor.insert(idx); @@ -935,7 +849,7 @@ NativeConventionSchema::getCoercionTypes( lastEnd = clang::CharUnits::Zero(); SmallVector elts; bool packed = false; - enumerateComponents( + Lowering.enumerateComponents( [&](clang::CharUnits begin, clang::CharUnits end, llvm::Type *type) { bool overlapped = overlappedWithSuccessor.count(idx) || (idx && overlappedWithSuccessor.count(idx - 1)); @@ -975,7 +889,7 @@ NativeConventionSchema::getCoercionTypes( lastEnd = clang::CharUnits::Zero(); elts.clear(); packed = false; - enumerateComponents( + Lowering.enumerateComponents( [&](clang::CharUnits begin, clang::CharUnits end, llvm::Type *type) { bool overlapped = overlappedWithSuccessor.count(idx) || (idx && overlappedWithSuccessor.count(idx - 1)); @@ -1040,38 +954,6 @@ SignatureExpansion::expandDirectResult() { llvm_unreachable("Not a valid SILFunctionLanguage."); } -std::pair -SignatureExpansion::expandDirectErrorType() { - if (!getSILFuncConventions().funcTy->hasErrorResult() || - !getSILFuncConventions().isTypedError()) { - return std::make_pair(nullptr, nullptr); - } - - switch (FnType->getLanguage()) { - case SILFunctionLanguage::C: - llvm_unreachable("Expanding C/ObjC parameters in the wrong place!"); - break; - case SILFunctionLanguage::Swift: { - auto resultType = getSILFuncConventions().getSILResultType( - IGM.getMaximalTypeExpansionContext()); - auto errorType = getSILFuncConventions().getSILErrorType( - IGM.getMaximalTypeExpansionContext()); - const auto &ti = IGM.getTypeInfo(resultType); - auto &native = ti.nativeReturnValueSchema(IGM); - const auto &errorTI = IGM.getTypeInfo(errorType); - auto &errorNative = errorTI.nativeReturnValueSchema(IGM); - if (native.requiresIndirect() || - errorNative.shouldReturnTypedErrorIndirectly()) { - return std::make_pair(nullptr, nullptr); - } - - auto combined = combineResultAndTypedErrorType(IGM, native, errorNative); - - return std::make_pair(combined.combinedTy, &errorTI); - } - } -} - static const clang::FieldDecl * getLargestUnionField(const clang::RecordDecl *record, const clang::ASTContext &ctx) { @@ -2033,22 +1915,10 @@ void SignatureExpansion::expandParameters( if (recordedABIDetails) recordedABIDetails->hasErrorResult = true; if (getSILFuncConventions().isTypedError()) { - - auto resultType = getSILFuncConventions().getSILResultType( - IGM.getMaximalTypeExpansionContext()); - auto &resultTI = IGM.getTypeInfo(resultType); - auto &native = resultTI.nativeReturnValueSchema(IGM); - auto errorType = getSILFuncConventions().getSILErrorType( - IGM.getMaximalTypeExpansionContext()); - auto &errorTI = IGM.getTypeInfo(errorType); - auto &nativeError = errorTI.nativeReturnValueSchema(IGM); - - if (getSILFuncConventions().hasIndirectSILResults() || - getSILFuncConventions().hasIndirectSILErrorResults() || - native.requiresIndirect() || - nativeError.shouldReturnTypedErrorIndirectly()) { - ParamIRTypes.push_back(IGM.getStorageType(errorType)->getPointerTo()); - } + ParamIRTypes.push_back( + IGM.getStorageType(getSILFuncConventions().getSILType( + FnType->getErrorResult(), IGM.getMaximalTypeExpansionContext()) + )->getPointerTo()); } } @@ -2125,40 +1995,10 @@ void SignatureExpansion::expandAsyncReturnType() { } }; - auto fnConv = getSILFuncConventions(); - - auto resultType = - fnConv.getSILResultType(IGM.getMaximalTypeExpansionContext()); + auto resultType = getSILFuncConventions().getSILResultType( + IGM.getMaximalTypeExpansionContext()); auto &ti = IGM.getTypeInfo(resultType); auto &native = ti.nativeReturnValueSchema(IGM); - - if (!fnConv.hasIndirectSILResults() && !fnConv.hasIndirectSILErrorResults() && - !native.requiresIndirect() && fnConv.funcTy->hasErrorResult() && - fnConv.isTypedError()) { - auto errorType = getSILFuncConventions().getSILErrorType( - IGM.getMaximalTypeExpansionContext()); - auto &errorTi = IGM.getTypeInfo(errorType); - auto &nativeError = errorTi.nativeReturnValueSchema(IGM); - if (!nativeError.shouldReturnTypedErrorIndirectly()) { - auto combined = combineResultAndTypedErrorType(IGM, native, nativeError); - - if (combined.combinedTy->isVoidTy()) { - addErrorResult(); - return; - } - - if (auto *structTy = dyn_cast(combined.combinedTy)) { - for (auto *elem : structTy->elements()) { - ParamIRTypes.push_back(elem); - } - } else { - ParamIRTypes.push_back(combined.combinedTy); - } - } - addErrorResult(); - return; - } - if (native.requiresIndirect() || native.empty()) { addErrorResult(); return; @@ -2176,23 +2016,11 @@ void SignatureExpansion::expandAsyncReturnType() { void SignatureExpansion::addIndirectThrowingResult() { if (getSILFuncConventions().funcTy->hasErrorResult() && getSILFuncConventions().isTypedError()) { - auto resultType = getSILFuncConventions().getSILResultType( - IGM.getMaximalTypeExpansionContext()); - auto &ti = IGM.getTypeInfo(resultType); - auto &native = ti.nativeReturnValueSchema(IGM); - - auto errorType = getSILFuncConventions().getSILErrorType( - IGM.getMaximalTypeExpansionContext()); - const TypeInfo &errorTI = IGM.getTypeInfo(errorType); - auto &nativeError = errorTI.nativeReturnValueSchema(IGM); - - if (getSILFuncConventions().hasIndirectSILResults() || - getSILFuncConventions().hasIndirectSILErrorResults() || - native.requiresIndirect() || - nativeError.shouldReturnTypedErrorIndirectly()) { - auto errorStorageTy = errorTI.getStorageType(); - ParamIRTypes.push_back(errorStorageTy->getPointerTo()); - } + auto resultType = getSILFuncConventions().getSILErrorType( + IGM.getMaximalTypeExpansionContext()); + const TypeInfo &resultTI = IGM.getTypeInfo(resultType); + auto storageTy = resultTI.getStorageType(); + ParamIRTypes.push_back(storageTy->getPointerTo()); } } @@ -2318,33 +2146,6 @@ void SignatureExpansion::expandAsyncAwaitType() { IGM.getMaximalTypeExpansionContext()); auto &ti = IGM.getTypeInfo(resultType); auto &native = ti.nativeReturnValueSchema(IGM); - - if (!getSILFuncConventions().hasIndirectSILResults() && - !getSILFuncConventions().hasIndirectSILErrorResults() && - getSILFuncConventions().funcTy->hasErrorResult() && - !native.requiresIndirect() && getSILFuncConventions().isTypedError()) { - auto errorType = getSILFuncConventions().getSILErrorType( - IGM.getMaximalTypeExpansionContext()); - auto &errorTi = IGM.getTypeInfo(errorType); - auto &nativeError = errorTi.nativeReturnValueSchema(IGM); - if (!nativeError.shouldReturnTypedErrorIndirectly()) { - auto combined = combineResultAndTypedErrorType(IGM, native, nativeError); - - if (!combined.combinedTy->isVoidTy()) { - if (auto *structTy = dyn_cast(combined.combinedTy)) { - for (auto *elem : structTy->elements()) { - components.push_back(elem); - } - } else { - components.push_back(combined.combinedTy); - } - } - addErrorResult(); - ResultIRType = llvm::StructType::get(IGM.getLLVMContext(), components); - return; - } - } - if (native.requiresIndirect() || native.empty()) { addErrorResult(); ResultIRType = llvm::StructType::get(IGM.getLLVMContext(), components); @@ -2358,6 +2159,7 @@ void SignatureExpansion::expandAsyncAwaitType() { }); addErrorResult(); + ResultIRType = llvm::StructType::get(IGM.getLLVMContext(), components); } @@ -2665,23 +2467,10 @@ class SyncCallEmission final : public CallEmission { setIndirectTypedErrorResultSlotArgsIndex(--LastArgWritten); Args[LastArgWritten] = nullptr; } else { - auto silResultTy = - fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()); - auto silErrorTy = - fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); - - auto &nativeSchema = - IGF.IGM.getTypeInfo(silResultTy).nativeReturnValueSchema(IGF.IGM); - auto &errorSchema = - IGF.IGM.getTypeInfo(silErrorTy).nativeReturnValueSchema(IGF.IGM); - - if (fnConv.hasIndirectSILResults() || - nativeSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly()) { - // Return the error indirectly. - auto buf = IGF.getCalleeTypedErrorResultSlot(silErrorTy); - Args[--LastArgWritten] = buf.getAddress(); - } + // Return the error indirectly. + auto buf = IGF.getCalleeTypedErrorResultSlot( + fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext())); + Args[--LastArgWritten] = buf.getAddress(); } } Args[--LastArgWritten] = errorResultSlot.getAddress(); @@ -2824,15 +2613,14 @@ class SyncCallEmission final : public CallEmission { } void emitCallToUnmappedExplosion(llvm::CallBase *call, Explosion &out) override { - SILFunctionConventions fnConv(getCallee().getOrigFunctionType(), - IGF.getSILModule()); - bool mayReturnErrorDirectly = mayReturnTypedErrorDirectly(); - // Bail out immediately on a void result. llvm::Value *result = call; - if (result->getType()->isVoidTy() && !mayReturnErrorDirectly) + if (result->getType()->isVoidTy()) return; + SILFunctionConventions fnConv(getCallee().getOrigFunctionType(), + IGF.getSILModule()); + // If the result was returned autoreleased, implicitly insert the reclaim. // This is only allowed on a single direct result. if (fnConv.getNumDirectSILResults() == 1 @@ -2871,15 +2659,6 @@ class SyncCallEmission final : public CallEmission { auto &nativeSchema = IGF.IGM.getTypeInfo(resultType).nativeReturnValueSchema(IGF.IGM); - // Handle direct return of typed errors - if (mayReturnErrorDirectly && !nativeSchema.requiresIndirect()) { - return emitToUnmappedExplosionWithDirectTypedError(resultType, result, - out); - } - - if (result->getType()->isVoidTy()) - return; - // For ABI reasons the result type of the call might not actually match the // expected result type. // @@ -3019,25 +2798,9 @@ class AsyncCallEmission final : public CallEmission { setIndirectTypedErrorResultSlotArgsIndex(--LastArgWritten); Args[LastArgWritten] = nullptr; } else { - auto silResultTy = - fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()); - auto silErrorTy = - fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); - - auto &nativeSchema = - IGF.IGM.getTypeInfo(silResultTy).nativeReturnValueSchema(IGF.IGM); - auto &errorSchema = - IGF.IGM.getTypeInfo(silErrorTy).nativeReturnValueSchema(IGF.IGM); - - if (nativeSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly() || - (errorSchema.empty() && fnConv.hasIndirectSILResults())) { // direct empty typed errors are passed - // indirectly for compatibility with generic - // functions. - // Return the error indirectly. - auto buf = IGF.getCalleeTypedErrorResultSlot(silErrorTy); - Args[--LastArgWritten] = buf.getAddress(); - } + auto buf = IGF.getCalleeTypedErrorResultSlot( + fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext())); + Args[--LastArgWritten] = buf.getAddress(); } } @@ -3219,34 +2982,7 @@ class AsyncCallEmission final : public CallEmission { errorType = substConv.getSILErrorType(IGM.getMaximalTypeExpansionContext()); - SILFunctionConventions fnConv(getCallee().getOrigFunctionType(), - IGF.getSILModule()); - - // Get the natural IR type in the body of the function that makes - // the call. This may be different than the IR type returned by the - // call itself due to ABI type coercion. - auto resultType = - fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()); - auto &nativeSchema = - IGF.IGM.getTypeInfo(resultType).nativeReturnValueSchema(IGF.IGM); - - bool mayReturnErrorDirectly = mayReturnTypedErrorDirectly(); - if (mayReturnErrorDirectly && !nativeSchema.requiresIndirect()) { - llvm::Value *resultAgg; - if (resultTys.size() == 1) { - resultAgg = Builder.CreateExtractValue(result, numAsyncContextParams); - } else { - auto resultTy = llvm::StructType::get(IGM.getLLVMContext(), resultTys); - resultAgg = llvm::UndefValue::get(resultTy); - for (unsigned i = 0, e = resultTys.size(); i != e; ++i) { - llvm::Value *elt = - Builder.CreateExtractValue(result, numAsyncContextParams + i); - resultAgg = Builder.CreateInsertValue(resultAgg, elt, i); - } - } - return emitToUnmappedExplosionWithDirectTypedError(resultType, resultAgg, - out); - } else if (resultTys.size() == 1) { + if (resultTys.size() == 1) { result = Builder.CreateExtractValue(result, numAsyncContextParams); if (hasError) { Address errorAddr = IGF.getCalleeErrorResultSlot(errorType, @@ -3278,6 +3014,17 @@ class AsyncCallEmission final : public CallEmission { result = resultAgg; } + SILFunctionConventions fnConv(getCallee().getOrigFunctionType(), + IGF.getSILModule()); + + // Get the natural IR type in the body of the function that makes + // the call. This may be different than the IR type returned by the + // call itself due to ABI type coercion. + auto resultType = + fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()); + auto &nativeSchema = + IGF.IGM.getTypeInfo(resultType).nativeReturnValueSchema(IGF.IGM); + // For ABI reasons the result type of the call might not actually match the // expected result type. // @@ -3416,7 +3163,7 @@ void CallEmission::emitToUnmappedMemory(Address result) { #ifndef NDEBUG LastArgWritten = 0; // appease an assert #endif - + auto call = emitCallSite(); // Async calls need to store the error result that is passed as a parameter. @@ -4463,90 +4210,6 @@ void CallEmission::externalizeArguments(IRGenFunction &IGF, const Callee &callee } } -bool CallEmission::mayReturnTypedErrorDirectly() const { - SILFunctionConventions fnConv(getCallee().getOrigFunctionType(), - IGF.getSILModule()); - bool mayReturnErrorDirectly = false; - if (!convertDirectToIndirectReturn && !fnConv.hasIndirectSILResults() && - !fnConv.hasIndirectSILErrorResults() && fnConv.funcTy->hasErrorResult() && - fnConv.isTypedError()) { - auto errorType = - fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); - auto &errorSchema = - IGF.IGM.getTypeInfo(errorType).nativeReturnValueSchema(IGF.IGM); - - mayReturnErrorDirectly = !errorSchema.shouldReturnTypedErrorIndirectly(); - } - - return mayReturnErrorDirectly; -} - -void CallEmission::emitToUnmappedExplosionWithDirectTypedError( - SILType resultType, llvm::Value *result, Explosion &out) { - SILFunctionConventions fnConv(getCallee().getOrigFunctionType(), - IGF.getSILModule()); - auto &nativeSchema = - IGF.IGM.getTypeInfo(resultType).nativeReturnValueSchema(IGF.IGM); - auto errorType = - fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); - auto &errorSchema = - IGF.IGM.getTypeInfo(errorType).nativeReturnValueSchema(IGF.IGM); - - auto combined = - combineResultAndTypedErrorType(IGF.IGM, nativeSchema, errorSchema); - - if (combined.combinedTy->isVoidTy()) { - typedErrorExplosion = Explosion(); - return; - } - - Explosion nativeExplosion; - extractScalarResults(IGF, result->getType(), result, nativeExplosion); - auto values = nativeExplosion.claimAll(); - - Explosion errorExplosion; - if (!errorSchema.empty()) { - if (auto *structTy = - dyn_cast(errorSchema.getExpandedType(IGF.IGM))) { - for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) { - llvm::Value *elt = values[combined.errorValueMapping[i]]; - auto *nativeTy = structTy->getElementType(i); - elt = convertForDirectError(IGF, elt, nativeTy, /*forExtraction*/ true); - errorExplosion.add(elt); - } - } else { - auto *converted = - convertForDirectError(IGF, values[combined.errorValueMapping[0]], - combined.combinedTy, /*forExtraction*/ true); - errorExplosion.add(converted); - } - - typedErrorExplosion = - errorSchema.mapFromNative(IGF.IGM, IGF, errorExplosion, errorType); - } else { - typedErrorExplosion = std::move(errorExplosion); - } - - // If the regular result type is void, there is nothing to explode - if (!resultType.isVoid()) { - Explosion resultExplosion; - if (auto *structTy = - dyn_cast(nativeSchema.getExpandedType(IGF.IGM))) { - for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) { - auto *nativeTy = structTy->getElementType(i); - auto *converted = convertForDirectError(IGF, values[i], nativeTy, - /*forExtraction*/ true); - resultExplosion.add(converted); - } - } else { - auto *converted = convertForDirectError( - IGF, values[0], combined.combinedTy, /*forExtraction*/ true); - resultExplosion.add(converted); - } - out = nativeSchema.mapFromNative(IGF.IGM, IGF, resultExplosion, resultType); - } -} - void CallEmission::setKeyPathAccessorArguments(Explosion &in, bool isOutlined, Explosion &out) { auto origCalleeType = CurCallee.getOrigFunctionType(); @@ -5407,30 +5070,6 @@ llvm::Value* IRGenFunction::coerceValue(llvm::Value *value, llvm::Type *toTy, return loaded; } -llvm::Value *irgen::convertForDirectError(IRGenFunction &IGF, - llvm::Value *value, llvm::Type *toTy, - bool forExtraction) { - auto &Builder = IGF.Builder; - auto *fromTy = value->getType(); - if (toTy->isIntOrPtrTy() && fromTy->isIntOrPtrTy() && toTy != fromTy) { - - if (toTy->isPointerTy()) { - if (fromTy->isPointerTy()) - return Builder.CreateBitCast(value, toTy); - return Builder.CreateIntToPtr(value, toTy); - } else if (fromTy->isPointerTy()) { - return Builder.CreatePtrToInt(value, toTy); - } - - if (forExtraction) { - return Builder.CreateTruncOrBitCast(value, toTy); - } else { - return Builder.CreateZExtOrBitCast(value, toTy); - } - } - return value; -} - void IRGenFunction::emitScalarReturn(llvm::Type *resultType, Explosion &result) { if (result.empty()) { @@ -5482,8 +5121,9 @@ unsigned NativeConventionSchema::size() const { if (empty()) return 0; unsigned size = 0; - enumerateComponents([&](clang::CharUnits offset, clang::CharUnits end, - llvm::Type *type) { ++size; }); + Lowering.enumerateComponents([&](clang::CharUnits offset, + clang::CharUnits end, + llvm::Type *type) { ++size; }); return size; } @@ -5825,16 +5465,8 @@ Explosion IRGenFunction::coerceValueTo(SILType fromTy, Explosion &from, void IRGenFunction::emitScalarReturn(SILType returnResultType, SILType funcResultType, Explosion &result, - bool isSwiftCCReturn, bool isOutlined, - SILType errorType) { - bool mayReturnErrorDirectly = false; - if (errorType) { - auto &errorTI = IGM.getTypeInfo(errorType); - auto &nativeError = errorTI.nativeReturnValueSchema(IGM); - mayReturnErrorDirectly = !nativeError.shouldReturnTypedErrorIndirectly(); - } - - if (result.empty() && !mayReturnErrorDirectly) { + bool isSwiftCCReturn, bool isOutlined) { + if (result.empty()) { assert(IGM.getTypeInfo(returnResultType) .nativeReturnValueSchema(IGM) .empty() && @@ -5846,63 +5478,24 @@ void IRGenFunction::emitScalarReturn(SILType returnResultType, // In the native case no coercion is needed. if (isSwiftCCReturn) { - auto &resultTI = IGM.getTypeInfo(funcResultType); - auto &nativeSchema = resultTI.nativeReturnValueSchema(IGM); - assert(!nativeSchema.requiresIndirect()); result = coerceValueTo(returnResultType, result, funcResultType); + auto &nativeSchema = + IGM.getTypeInfo(funcResultType).nativeReturnValueSchema(IGM); + assert(!nativeSchema.requiresIndirect()); Explosion native = nativeSchema.mapIntoNative(IGM, *this, result, funcResultType, isOutlined); - llvm::Value *nativeAgg = nullptr; - - if (mayReturnErrorDirectly) { - auto &errorTI = IGM.getTypeInfo(errorType); - auto &nativeError = errorTI.nativeReturnValueSchema(IGM); - auto *combinedTy = - combineResultAndTypedErrorType(IGM, nativeSchema, nativeError) - .combinedTy; - - if (combinedTy->isVoidTy()) { - Builder.CreateRetVoid(); - return; - } - - if (native.empty()) { - Builder.CreateRet(llvm::UndefValue::get(combinedTy)); - return; - } - - if (auto *structTy = dyn_cast(combinedTy)) { - nativeAgg = llvm::UndefValue::get(combinedTy); - for (unsigned i = 0, e = native.size(); i != e; ++i) { - llvm::Value *elt = native.claimNext(); - auto *nativeTy = structTy->getElementType(i); - elt = convertForDirectError(*this, elt, nativeTy, - /*forExtraction*/ false); - nativeAgg = Builder.CreateInsertValue(nativeAgg, elt, i); - } - } else { - nativeAgg = convertForDirectError(*this, native.claimNext(), combinedTy, - /*forExtraction*/ false); - } + if (native.size() == 1) { + Builder.CreateRet(native.claimNext()); + return; } - - if (!nativeAgg) { - if (native.size() == 1) { - Builder.CreateRet(native.claimNext()); - return; - } - - nativeAgg = llvm::UndefValue::get(nativeSchema.getExpandedType(IGM)); - - for (unsigned i = 0, e = native.size(); i != e; ++i) { - llvm::Value *elt = native.claimNext(); - nativeAgg = Builder.CreateInsertValue(nativeAgg, elt, i); - } + llvm::Value *nativeAgg = + llvm::UndefValue::get(nativeSchema.getExpandedType(IGM)); + for (unsigned i = 0, e = native.size(); i != e; ++i) { + llvm::Value *elt = native.claimNext(); + nativeAgg = Builder.CreateInsertValue(nativeAgg, elt, i); } - Builder.CreateRet(nativeAgg); - return; } @@ -6193,51 +5786,6 @@ void irgen::emitAsyncReturn(IRGenFunction &IGF, AsyncContextLayout &asyncLayout, SILFunctionConventions conv(fnType, IGF.getSILModule()); auto &nativeSchema = IGM.getTypeInfo(funcResultTypeInContext).nativeReturnValueSchema(IGM); - - if (fnType->hasErrorResult() && !conv.hasIndirectSILResults() && - !conv.hasIndirectSILErrorResults() && !nativeSchema.requiresIndirect() && - conv.isTypedError()) { - auto errorType = conv.getSILErrorType(IGM.getMaximalTypeExpansionContext()); - auto &errorTI = IGM.getTypeInfo(errorType); - auto &nativeError = errorTI.nativeReturnValueSchema(IGM); - if (!nativeError.shouldReturnTypedErrorIndirectly()) { - assert(!error.empty() && "Direct error return must have error value"); - auto *combinedTy = - combineResultAndTypedErrorType(IGM, nativeSchema, nativeError) - .combinedTy; - - if (combinedTy->isVoidTy()) { - assert(result.empty() && "Unexpected result values"); - } else { - if (auto *structTy = dyn_cast(combinedTy)) { - llvm::Value *nativeAgg = llvm::UndefValue::get(structTy); - for (unsigned i = 0, e = result.size(); i != e; ++i) { - llvm::Value *elt = result.claimNext(); - auto *nativeTy = structTy->getElementType(i); - elt = convertForDirectError(IGF, elt, nativeTy, - /*forExtraction*/ false); - nativeAgg = IGF.Builder.CreateInsertValue(nativeAgg, elt, i); - } - Explosion out; - IGF.emitAllExtractValues(nativeAgg, structTy, out); - while (!out.empty()) { - nativeResultsStorage.push_back(out.claimNext()); - } - } else { - auto *converted = convertForDirectError( - IGF, result.claimNext(), combinedTy, /*forExtraction*/ false); - nativeResultsStorage.push_back(converted); - } - } - - nativeResultsStorage.push_back(error.claimNext()); - nativeResults = nativeResultsStorage; - - emitAsyncReturn(IGF, asyncLayout, fnType, nativeResults); - return; - } - } - if (result.empty() && !nativeSchema.empty()) { if (!nativeSchema.requiresIndirect()) // When we throw, we set the return values to undef. @@ -6507,46 +6055,3 @@ llvm::FunctionType *FunctionPointer::getFunctionType() const { return Sig.getType(); } - -void irgen::buildDirectError(IRGenFunction &IGF, - const CombinedResultAndErrorType &combined, - const NativeConventionSchema &errorSchema, - SILType silErrorTy, Explosion &errorResult, - bool forAsync, Explosion &out) { - if (combined.combinedTy->isVoidTy()) { - return; - } - - llvm::Value *expandedResult = llvm::UndefValue::get(combined.combinedTy); - auto *structTy = dyn_cast(combined.combinedTy); - - if (!errorSchema.getExpandedType(IGF.IGM)->isVoidTy()) { - auto nativeError = - errorSchema.mapIntoNative(IGF.IGM, IGF, errorResult, silErrorTy, false); - - if (structTy) { - for (unsigned i : combined.errorValueMapping) { - llvm::Value *elt = nativeError.claimNext(); - auto *nativeTy = structTy->getElementType(i); - elt = convertForDirectError(IGF, elt, nativeTy, - /*forExtraction*/ false); - expandedResult = IGF.Builder.CreateInsertValue(expandedResult, elt, i); - } - if (forAsync) { - IGF.emitAllExtractValues(expandedResult, structTy, out); - } else { - out = expandedResult; - } - } else if (!errorSchema.getExpandedType(IGF.IGM)->isVoidTy()) { - out = convertForDirectError(IGF, nativeError.claimNext(), - combined.combinedTy, - /*forExtraction*/ false); - } - } else { - if (forAsync && structTy) { - IGF.emitAllExtractValues(expandedResult, structTy, out); - } else { - out = expandedResult; - } - } -} diff --git a/lib/IRGen/GenCall.h b/lib/IRGen/GenCall.h index 8584d7c35f8fa..7adca3f8afc39 100644 --- a/lib/IRGen/GenCall.h +++ b/lib/IRGen/GenCall.h @@ -121,15 +121,6 @@ namespace irgen { CanSILFunctionType substitutedType, SubstitutionMap substitutionMap); - struct CombinedResultAndErrorType { - llvm::Type *combinedTy; - llvm::SmallVector errorValueMapping; - }; - CombinedResultAndErrorType - combineResultAndTypedErrorType(const IRGenModule &IGM, - const NativeConventionSchema &resultSchema, - const NativeConventionSchema &errorSchema); - /// Given an async function, get the pointer to the function to be called and /// the size of the context to be allocated. /// @@ -274,15 +265,6 @@ namespace irgen { void forwardAsyncCallResult(IRGenFunction &IGF, CanSILFunctionType fnType, AsyncContextLayout &layout, llvm::CallInst *call); - /// Converts a value for direct error return. - llvm::Value *convertForDirectError(IRGenFunction &IGF, llvm::Value *value, - llvm::Type *toTy, bool forExtraction); - - void buildDirectError(IRGenFunction &IGF, - const CombinedResultAndErrorType &combined, - const NativeConventionSchema &errorSchema, - SILType silErrorTy, Explosion &errorResult, - bool forAsync, Explosion &out); } // end namespace irgen } // end namespace swift diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp index 72e4c7c9e81f6..c59cab27a0587 100644 --- a/lib/IRGen/GenFunc.cpp +++ b/lib/IRGen/GenFunc.cpp @@ -1177,19 +1177,8 @@ class SyncPartialApplicationForwarderEmission llvm::Value *errorResultPtr = origParams.claimNext(); args.add(errorResultPtr); if (origConv.isTypedError()) { - auto errorType = - origConv.getSILErrorType(IGM.getMaximalTypeExpansionContext()); - auto silResultTy = - origConv.getSILResultType(IGM.getMaximalTypeExpansionContext()); - auto &errorTI = IGM.getTypeInfo(errorType); - auto &resultTI = IGM.getTypeInfo(silResultTy); - auto &resultSchema = resultTI.nativeReturnValueSchema(IGM); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGM); - - if (resultSchema.requiresIndirect() || errorSchema.shouldReturnTypedErrorIndirectly() || outConv.hasIndirectSILErrorResults()) { - auto *typedErrorResultPtr = origParams.claimNext(); - args.add(typedErrorResultPtr); - } + auto *typedErrorResultPtr = origParams.claimNext(); + args.add(typedErrorResultPtr); } } llvm::CallInst *createCall(FunctionPointer &fnPtr) override { @@ -1365,21 +1354,8 @@ class AsyncPartialApplicationForwarderEmission // The error result pointer is already in the appropriate position but the // type error address is not. if (origConv.isTypedError()) { - auto errorType = - origConv.getSILErrorType(IGM.getMaximalTypeExpansionContext()); - auto silResultTy = - origConv.getSILResultType(IGM.getMaximalTypeExpansionContext()); - auto &errorTI = IGM.getTypeInfo(errorType); - auto &resultTI = IGM.getTypeInfo(silResultTy); - auto &resultSchema = resultTI.nativeReturnValueSchema(IGM); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGM); - - if (resultSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly() || - outConv.hasIndirectSILErrorResults()) { - auto *typedErrorResultPtr = origParams.claimNext(); - args.add(typedErrorResultPtr); - } + auto *typedErrorResultPtr = origParams.claimNext(); + args.add(typedErrorResultPtr); } } llvm::CallInst *createCall(FunctionPointer &fnPtr) override { @@ -2917,11 +2893,9 @@ IRGenFunction::createAsyncDispatchFn(const FunctionPointer &fnPtr, : originalAuthInfo; auto callee = FunctionPointer::createSigned( fnPtr.getKind(), fnPtrArg, newAuthInfo, fnPtr.getSignature()); - auto call = Builder.CreateCall(callee, callArgs); call->setTailCallKind(IGM.AsyncTailCallKind); Builder.CreateRetVoid(); - return dispatch; } diff --git a/lib/IRGen/GenThunk.cpp b/lib/IRGen/GenThunk.cpp index ff93d672be400..1c3df3840e0f6 100644 --- a/lib/IRGen/GenThunk.cpp +++ b/lib/IRGen/GenThunk.cpp @@ -143,23 +143,14 @@ void IRGenThunk::prepareArguments() { // Set the typed error value result slot. if (conv.isTypedError() && !conv.hasIndirectSILErrorResults()) { + auto directTypedErrorAddr = original.takeLast(); auto errorType = conv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); auto &errorTI = cast(IGF.getTypeInfo(errorType)); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGF.IGM); - auto resultType = - conv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()); - auto &resultTI = cast(IGF.getTypeInfo(resultType)); - auto &resultSchema = resultTI.nativeReturnValueSchema(IGF.IGM); - - if (resultSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly() || - conv.hasIndirectSILResults()) { - auto directTypedErrorAddr = original.takeLast(); - IGF.setCalleeTypedErrorResultSlot(Address(directTypedErrorAddr, - errorTI.getStorageType(), - errorTI.getFixedAlignment())); - } + + IGF.setCalleeTypedErrorResultSlot(Address(directTypedErrorAddr, + errorTI.getStorageType(), + errorTI.getFixedAlignment())); } else if (conv.isTypedError()) { auto directTypedErrorAddr = original.takeLast(); // Store for later processing when we know the argument index. @@ -336,8 +327,7 @@ void IRGenThunk::emit() { llvm::Value *errorValue = nullptr; - if (emission->getTypedErrorExplosion() || - (isAsync && origTy->hasErrorResult())) { + if (isAsync && origTy->hasErrorResult()) { SILType errorType = conv.getSILErrorType(expansionContext); Address calleeErrorSlot = emission->getCalleeErrorSlot( errorType, /*isCalleeAsync=*/origTy->isAsync()); @@ -346,106 +336,23 @@ void IRGenThunk::emit() { emission->end(); - // FIXME: we shouldn't have to generate all of this. We should just forward - // the value as is - if (auto &error = emission->getTypedErrorExplosion()) { - llvm::BasicBlock *successBB = IGF.createBasicBlock("success"); - llvm::BasicBlock *errorBB = IGF.createBasicBlock("failure"); - - llvm::Value *nil = llvm::ConstantPointerNull::get( - cast(errorValue->getType())); - auto *hasError = IGF.Builder.CreateICmpNE(errorValue, nil); - - // Predict no error is thrown. - hasError = - IGF.IGM.getSILModule().getOptions().EnableThrowsPrediction ? - IGF.Builder.CreateExpectCond(IGF.IGM, hasError, false) : hasError; - - IGF.Builder.CreateCondBr(hasError, errorBB, successBB); - - IGF.Builder.emitBlock(errorBB); - if (isAsync) { - auto &IGM = IGF.IGM; - SILType silErrorTy = conv.getSILErrorType(expansionContext); - auto &errorTI = IGF.IGM.getTypeInfo(silErrorTy); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGF.IGM); - auto combined = combineResultAndTypedErrorType(IGM, schema, errorSchema); - - Explosion errorArgValues; - - if (!combined.combinedTy->isVoidTy()) { - llvm::Value *expandedResult = - llvm::UndefValue::get(combined.combinedTy); - if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { - auto nativeError = - errorSchema.mapIntoNative(IGM, IGF, *error, silErrorTy, false); - - if (auto *structTy = - dyn_cast(combined.combinedTy)) { - for (unsigned i : combined.errorValueMapping) { - llvm::Value *elt = nativeError.claimNext(); - auto *nativeTy = structTy->getElementType(i); - elt = convertForDirectError(IGF, elt, nativeTy, - /*forExtraction*/ false); - expandedResult = - IGF.Builder.CreateInsertValue(expandedResult, elt, i); - } - IGF.emitAllExtractValues(expandedResult, structTy, errorArgValues); - } else if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { - errorArgValues = convertForDirectError(IGF, nativeError.claimNext(), - combined.combinedTy, - /*forExtraction*/ false); - } - } else if (auto *structTy = - dyn_cast(combined.combinedTy)) { - IGF.emitAllExtractValues(expandedResult, structTy, errorArgValues); - } else { - errorArgValues = expandedResult; - } - } - errorArgValues.add(errorValue); - emitAsyncReturn(IGF, *asyncLayout, origTy, errorArgValues.claimAll()); - } else { - if (!error->empty()) { - // Map the direct error explosion from the call back to the native - // explosion for the return. - SILType silErrorTy = conv.getSILErrorType(expansionContext); - auto &errorTI = IGF.IGM.getTypeInfo(silErrorTy); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGF.IGM); - auto combined = - combineResultAndTypedErrorType(IGF.IGM, schema, errorSchema); - Explosion nativeAgg; - buildDirectError(IGF, combined, errorSchema, silErrorTy, *error, - /*forAsync*/ false, nativeAgg); - IGF.emitScalarReturn(IGF.CurFn->getReturnType(), nativeAgg); - } else { - IGF.emitScalarReturn(IGF.CurFn->getReturnType(), *error); - } - } - IGF.Builder.emitBlock(successBB); - } else { - if (isAsync) { - Explosion error; - if (errorValue) - error.add(errorValue); - emitAsyncReturn(IGF, *asyncLayout, directResultType, origTy, result, - error); - return; - } + if (isAsync) { + Explosion error; + if (errorValue) + error.add(errorValue); + emitAsyncReturn(IGF, *asyncLayout, directResultType, origTy, result, error); + return; } // Return the result. if (result.empty()) { - if (emission->getTypedErrorExplosion()) { - IGF.Builder.CreateRet(llvm::UndefValue::get(IGF.CurFn->getReturnType())); - } else { - IGF.Builder.CreateRetVoid(); - } + IGF.Builder.CreateRetVoid(); return; } auto resultTy = conv.getSILResultType(expansionContext); resultTy = resultTy.subst(IGF.getSILModule(), subMap); + IGF.emitScalarReturn(resultTy, resultTy, result, /*swiftCCReturn=*/false, /*isOutlined=*/false); diff --git a/lib/IRGen/IRGenFunction.h b/lib/IRGen/IRGenFunction.h index 266347e3a1633..f85666cf2f0cf 100644 --- a/lib/IRGen/IRGenFunction.h +++ b/lib/IRGen/IRGenFunction.h @@ -102,7 +102,7 @@ class IRGenFunction { Explosion collectParameters(); void emitScalarReturn(SILType returnResultType, SILType funcResultType, Explosion &scalars, bool isSwiftCCReturn, - bool isOutlined, SILType errorType = {}); + bool isOutlined); void emitScalarReturn(llvm::Type *resultTy, Explosion &scalars); void emitBBForReturn(); diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index c9ce17e0ab245..aa53d1a34f307 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -2163,7 +2163,7 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, // Remap the entry block. IGF.LoweredBBs[&*IGF.CurSILFn->begin()] = LoweredBB(IGF.Builder.GetInsertBlock(), {}); } - } + } // Bind the error result by popping it off the parameter list. if (funcTy->hasErrorResult()) { @@ -2175,21 +2175,14 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, bool isIndirectError = fnConv.hasIndirectSILErrorResults(); if (isTypedError && !isIndirectError) { - auto resultType = - fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()); - auto inContextResultType = IGF.CurSILFn->mapTypeIntoContext(resultType); - auto &resultTI = - cast(IGF.getTypeInfo(inContextResultType)); - auto &errorTI = cast(IGF.getTypeInfo(inContextErrorType)); - auto &native = resultTI.nativeReturnValueSchema(IGF.IGM); - auto &nativeError = errorTI.nativeReturnValueSchema(IGF.IGM); - if (fnConv.hasIndirectSILResults() || native.requiresIndirect() || - nativeError.shouldReturnTypedErrorIndirectly()) { - IGF.setCallerTypedErrorResultSlot( - Address(emission->getCallerTypedErrorResultArgument(), - errorTI.getStorageType(), errorTI.getFixedAlignment())); - } + auto &errorTI = cast(IGF.getTypeInfo(errorType)); + IGF.setCallerTypedErrorResultSlot(Address( + emission->getCallerTypedErrorResultArgument(), + errorTI.getStorageType(), + errorTI.getFixedAlignment())); + } else if (isTypedError && isIndirectError) { + auto &errorTI = IGF.getTypeInfo(inContextErrorType); auto ptr = emission->getCallerTypedErrorResultArgument(); auto addr = errorTI.getAddressForPointer(ptr); @@ -2336,6 +2329,7 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, return IGF.getLoweredSingletonExplosion(parameter); }); } + assert(allParamValues.empty() && "didn't claim all parameters!"); } @@ -3873,8 +3867,8 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) { // See below. Builder.CreateStore(nullError, calleeErrorSlot); } - auto hasTypedDirectError = - substConv.isTypedError() && !substConv.hasIndirectSILErrorResults(); + auto hasTypedDirectError = substConv.isTypedError() && + !substConv.hasIndirectSILErrorResults(); llvm::BasicBlock *typedErrorLoadBB = nullptr; if (hasTypedDirectError) { typedErrorLoadBB = createBasicBlock("typed.error.load"); @@ -3917,42 +3911,12 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) { } else { Builder.emitBlock(typedErrorLoadBB); - auto &errorTI = cast(IGM.getTypeInfo(errorType)); - auto silResultTy = - substConv.getSILResultType(IGM.getMaximalTypeExpansionContext()); - auto &resultTI = cast(IGM.getTypeInfo(silResultTy)); - - auto &resultSchema = resultTI.nativeReturnValueSchema(IGM); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGM); - - if (substConv.hasIndirectSILResults() || - substConv.hasIndirectSILErrorResults() || - resultSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly()) { - Explosion errorValue; - errorTI.loadAsTake(*this, getCalleeTypedErrorResultSlot(errorType), - errorValue); - for (unsigned i = 0, e = errorDest.phis.size(); i != e; ++i) { - errorDest.phis[i]->addIncoming(errorValue.claimNext(), - Builder.GetInsertBlock()); - } - } else { - auto combined = - combineResultAndTypedErrorType(IGM, resultSchema, errorSchema); - if (auto &errorValue = emission->getTypedErrorExplosion()) { - if (errorDest.phis.empty()) { - errorValue->reset(); - } else { - for (unsigned i = 0, e = errorDest.phis.size(); i != e; ++i) { - errorDest.phis[i]->addIncoming(errorValue->claimNext(), - Builder.GetInsertBlock()); - } - } - } else { - llvm_unreachable("No explosion set for direct typed error result"); - } + auto &ti = cast(IGM.getTypeInfo(errorType)); + Explosion errorValue; + ti.loadAsTake(*this, getCalleeTypedErrorResultSlot(errorType), errorValue); + for (unsigned i = 0, e = errorDest.phis.size(); i != e; ++i) { + errorDest.phis[i]->addIncoming(errorValue.claimNext(), Builder.GetInsertBlock()); } - Builder.CreateBr(errorDest.bb); } @@ -4385,21 +4349,14 @@ static void emitReturnInst(IRGenSILFunction &IGF, if (fnType->hasErrorResult()) { error.add(getNullErrorValue()); } - emitAsyncReturn(IGF, asyncLayout, funcResultType, fnType, result, error); } else { auto funcLang = IGF.CurSILFn->getLoweredFunctionType()->getLanguage(); auto swiftCCReturn = funcLang == SILFunctionLanguage::Swift; assert(swiftCCReturn || funcLang == SILFunctionLanguage::C && "Need to handle all cases"); - SILType errorType; - if (fnType->hasErrorResult() && conv.isTypedError() && - !conv.hasIndirectSILResults() && !conv.hasIndirectSILErrorResults()) { - errorType = - conv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); - } - IGF.emitScalarReturn(resultTy, funcResultType, result, swiftCCReturn, false, - errorType); + IGF.emitScalarReturn(resultTy, funcResultType, result, swiftCCReturn, + false); } } @@ -4427,51 +4384,23 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { assert(!conv.hasIndirectSILErrorResults()); if (!isAsync()) { - auto fnTy = CurFn->getFunctionType(); - auto retTy = fnTy->getReturnType(); if (conv.isTypedError()) { llvm::Constant *flag = llvm::ConstantInt::get(IGM.IntPtrTy, 1); flag = llvm::ConstantExpr::getIntToPtr(flag, IGM.Int8PtrTy); Explosion errorResult = getLoweredExplosion(i->getOperand()); - auto silErrorTy = - conv.getSILErrorType(IGM.getMaximalTypeExpansionContext()); - auto &errorTI = cast(IGM.getTypeInfo(silErrorTy)); + auto &ti = cast(IGM.getTypeInfo(conv.getSILErrorType( + IGM.getMaximalTypeExpansionContext()))); + ti.initialize(*this, errorResult, getCallerTypedErrorResultSlot(), false); - auto silResultTy = - conv.getSILResultType(IGM.getMaximalTypeExpansionContext()); - - if (silErrorTy.getASTType()->isNever()) { - emitTrap("Never can't be initialized", true); - return; - } else { - auto &resultTI = cast(IGM.getTypeInfo(silResultTy)); - auto &resultSchema = resultTI.nativeReturnValueSchema(IGM); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGM); - - Builder.CreateStore(flag, getCallerErrorResultSlot()); - if (conv.hasIndirectSILResults() || conv.hasIndirectSILErrorResults() || - resultSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly()) { - errorTI.initialize(*this, errorResult, getCallerTypedErrorResultSlot(), - false); - } else { - auto combined = - combineResultAndTypedErrorType(IGM, resultSchema, errorSchema); - Explosion nativeAgg; - buildDirectError(*this, combined, errorSchema, silErrorTy, - errorResult, - /*forAsync*/ false, nativeAgg); - - emitScalarReturn(combined.combinedTy, nativeAgg); - return; - } - } + Builder.CreateStore(flag, getCallerErrorResultSlot()); } else { Explosion errorResult = getLoweredExplosion(i->getOperand()); Builder.CreateStore(errorResult.claimNext(), getCallerErrorResultSlot()); } // Create a normal return, but leaving the return value undefined. + auto fnTy = CurFn->getFunctionType(); + auto retTy = fnTy->getReturnType(); if (retTy->isVoidTy()) { Builder.CreateRetVoid(); } else { @@ -4488,44 +4417,11 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { conv.getSILResultType(IGM.getMaximalTypeExpansionContext())); if (conv.isTypedError()) { - auto silErrorTy = - conv.getSILErrorType(IGM.getMaximalTypeExpansionContext()); - auto &errorTI = cast(IGM.getTypeInfo(silErrorTy)); - - auto silResultTy = - conv.getSILResultType(IGM.getMaximalTypeExpansionContext()); - auto &resultTI = cast(IGM.getTypeInfo(silResultTy)); - auto &resultSchema = resultTI.nativeReturnValueSchema(IGM); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGM); - + auto &ti = cast(IGM.getTypeInfo(conv.getSILErrorType( + IGM.getMaximalTypeExpansionContext()))); + ti.initialize(*this, exn, getCallerTypedErrorResultSlot(), false); llvm::Constant *flag = llvm::ConstantInt::get(IGM.IntPtrTy, 1); flag = llvm::ConstantExpr::getIntToPtr(flag, IGM.Int8PtrTy); - - if (conv.hasIndirectSILResults() || conv.hasIndirectSILErrorResults() || - resultSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly()) { - errorTI.initialize(*this, exn, getCallerTypedErrorResultSlot(), false); - } else { - Explosion nativeAgg; - auto combined = - combineResultAndTypedErrorType(IGM, resultSchema, errorSchema); - buildDirectError(*this, combined, errorSchema, silErrorTy, exn, - /*forAsync*/ true, nativeAgg); - assert(exn.empty() && "Unclaimed typed error results"); - - SmallVector nativeResultArgs; - while (!nativeAgg.empty()) { - nativeResultArgs.push_back(nativeAgg.claimNext()); - } - nativeResultArgs.push_back(flag); - - emitAsyncReturn(*this, layout, - i->getFunction()->getLoweredFunctionType(), - nativeResultArgs); - - return; - } - assert(exn.empty() && "Unclaimed typed error results"); exn.reset(); exn.add(flag); diff --git a/lib/IRGen/NativeConventionSchema.h b/lib/IRGen/NativeConventionSchema.h index c1230d3f04e5f..218786ceaef47 100644 --- a/lib/IRGen/NativeConventionSchema.h +++ b/lib/IRGen/NativeConventionSchema.h @@ -42,9 +42,6 @@ class NativeConventionSchema { NativeConventionSchema &operator=(const NativeConventionSchema&) = delete; bool requiresIndirect() const { return RequiresIndirect; } - bool shouldReturnTypedErrorIndirectly() const { - return requiresIndirect() || Lowering.shouldReturnTypedErrorIndirectly(); - } bool empty() const { return Lowering.empty(); } llvm::Type *getExpandedType(IRGenModule &IGM) const; diff --git a/test/IRGen/typed_throws.sil b/test/IRGen/typed_throws.sil index 8d5caa462ee53..3338156abf65d 100644 --- a/test/IRGen/typed_throws.sil +++ b/test/IRGen/typed_throws.sil @@ -18,13 +18,15 @@ sil_vtable A {} sil @create_error : $@convention(thin) () -> @owned A -// CHECK: define{{.*}} swiftcc { ptr, ptr } @throw_error(ptr swiftself %0, ptr noalias nocapture swifterror dereferenceable({{.*}}) %1) +// CHECK: define{{.*}} swiftcc void @throw_error(ptr swiftself %0, ptr noalias nocapture swifterror dereferenceable({{.*}}) %1, ptr %2) // CHECK: [[ERR:%.*]] = call swiftcc ptr @create_error() // CHECK: call ptr @swift_retain(ptr returned [[ERR]]) +// CHECK: [[F1:%.*]] = getelementptr inbounds %T12typed_throws1SV, ptr %2, i32 0, i32 0 +// CHECK: store ptr [[ERR]], ptr [[F1]] +// CHECK: [[F2:%.*]] = getelementptr inbounds %T12typed_throws1SV, ptr %2, i32 0, i32 1 +// CHECK: store ptr [[ERR]], ptr [[F2]] // CHECK: store ptr inttoptr (i64 1 to ptr), ptr %1 -// CHECK: [[RET_v1:%.*]] = insertvalue { ptr, ptr } undef, ptr [[ERR]], 0 -// CHECK: [[RET_v2:%.*]] = insertvalue { ptr, ptr } [[RET_v1]], ptr [[ERR]], 1 -// CHECK: ret { ptr, ptr } [[RET_v2]] +// CHECK: ret void // CHECK: } sil @throw_error : $@convention(thin) () -> @error S { @@ -47,24 +49,27 @@ sil @try_apply_helper : $@convention(thin) (@owned AnyObject) -> (@owned AnyObje // CHECK: entry: // CHECK: %swifterror = alloca swifterror ptr // CHECK: store ptr null, ptr %swifterror -// CHECK: [[RES:%.*]] = call swiftcc { ptr, ptr } @try_apply_helper(ptr %0, ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable({{.*}}) %swifterror) -// CHECK: [[RES_0:%.*]] = extractvalue { ptr, ptr } [[RES]], 0 -// CHECK: [[RES_1:%.*]] = extractvalue { ptr, ptr } [[RES]], 1 +// CHECK: %swifterror1 = alloca %T12typed_throws1SV +// CHECK: [[RES:%.*]] = call swiftcc ptr @try_apply_helper(ptr %0, ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable({{.*}}) %swifterror, ptr %swifterror1) // CHECK: [[ERRFLAG:%.*]] = load ptr, ptr %swifterror // CHECK: [[C:%.*]] = icmp ne ptr [[ERRFLAG]], null // CHECK: br i1 [[C]], label %[[ERR_B:.*]], label %[[SUCC_B:[0-9]+]] // CHECK: [[ERR_B]]: +// CHECK: %swifterror1.x = getelementptr inbounds %T12typed_throws1SV, ptr %swifterror1, i32 0, i32 0 +// CHECK: [[ERR_v1:%.*]] = load ptr, ptr %swifterror1.x +// CHECK: %swifterror1.y = getelementptr inbounds %T12typed_throws1SV, ptr %swifterror1, i32 0, i32 1 +// CHECK: [[ERR_v2:%.*]] = load ptr, ptr %swifterror1.y // CHECK: br label %[[ERR2_B:[0-9]+]] // CHECK: [[SUCC_B]]: -// CHECK: [[R:%.*]] = phi ptr [ [[RES_0]], %entry ] +// CHECK: [[R:%.*]] = phi ptr [ [[RES]], %entry ] // CHECK: call void @swift_{{.*}}elease(ptr [[R]]) // CHECK: br label %[[RET_B:[0-9]+]] // CHECK: [[ERR2_B]]: -// CHECK: [[E1:%.*]] = phi ptr [ [[RES_0]], %[[ERR_B]] ] -// CHECK: [[E2:%.*]] = phi ptr [ [[RES_1]], %[[ERR_B]] ] +// CHECK: [[E1:%.*]] = phi ptr [ [[ERR_v1]], %[[ERR_B]] ] +// CHECK: [[E2:%.*]] = phi ptr [ [[ERR_v2]], %[[ERR_B]] ] // CHECK: store ptr null, ptr %swifterror // CHECK: call void @swift_release(ptr [[E1]]) // CHECK: call void @swift_release(ptr [[E2]]) @@ -125,14 +130,13 @@ bb6: return %7 : $() } -// CHECK: define{{.*}} swifttailcc void @does_throw_async(ptr swiftasync %0) -// CHECK: [[ERR:%.*]] = call swiftcc ptr @create_error() -// CHECK: [[INS0:%.*]] = insertvalue { ptr, ptr } undef, ptr [[ERR]], 0 -// CHECK: [[INS1:%.*]] = insertvalue { ptr, ptr } [[INS0]], ptr [[ERR]], 1 -// CHECK: [[P0:%.*]] = extractvalue { ptr, ptr } [[INS1]], 0 -// CHECK: [[P1:%.*]] = extractvalue { ptr, ptr } [[INS1]], 1 -// CHECK: call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{%.*}}, i1 false, ptr @does_throw_async.0, ptr {{%.*}}, ptr {{%.*}}, ptr [[P0]], ptr [[P1]], ptr inttoptr (i64 1 to ptr)) -// CHECK: unreachable +// CHECK: define{{.*}} swifttailcc void @does_throw_async(ptr swiftasync %0, ptr %1) +// CHECK: %.x = getelementptr inbounds %T12typed_throws1SV, ptr %1, i32 0, i32 0 +// CHECK: store ptr {{.*}}, ptr %.x +// CHECK: %.y = getelementptr inbounds %T12typed_throws1SV, ptr %1, i32 0, i32 1 +// CHECK: store ptr {{.*}}, ptr %.y +// CHECK: call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{.*}}, i1 false, ptr @does_throw_async.0, ptr {{.*}}, ptr {{.*}}, ptr inttoptr (i64 1 to ptr)) +// CHECK: ret void sil @does_throw_async : $@convention(thin) @async () -> @error S { %0 = function_ref @create_error : $@convention(thin) () -> @owned A @@ -142,13 +146,10 @@ sil @does_throw_async : $@convention(thin) @async () -> @error S { throw %2 : $S } -// CHECK: define{{.*}} swifttailcc void @does_not_throw_async(ptr swiftasync %0) +// CHECK: define{{.*}} swifttailcc void @does_not_throw_async(ptr swiftasync %0, ptr %1) // CHECK: [[R:%.*]] = call swiftcc ptr @create_error() -// CHECK: [[CMB:%.*]] = insertvalue { ptr, ptr } undef, ptr [[R]], 0 -// CHECK: [[P0:%.*]] = extractvalue { ptr, ptr } [[CMB:%.*]], 0 -// CHECK: [[P1:%.*]] = extractvalue { ptr, ptr } [[CMB]], 1 -// CHECK: call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{.*}}, i1 false, ptr @does_not_throw_async.0, ptr {{.*}}, ptr {{.*}}, ptr [[P0]], ptr [[P1]], ptr null) -// CHECK: unreachable +// CHECK: call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{.*}}, i1 false, ptr @does_not_throw_async.0, ptr {{.*}}, ptr {{.*}}, ptr [[R]], ptr null) +// CHECK: ret void sil @does_not_throw_async : $@convention(thin) @async () -> (@owned A, @error S) { %0 = function_ref @create_error : $@convention(thin) () -> @owned A %1 = apply %0() : $@convention(thin) () -> @owned A @@ -209,9 +210,9 @@ bb6: return %7 : $() } -// CHECK: define{{.*}} internal swiftcc { ptr, ptr } @"$s16try_apply_helperTA"(ptr swiftself %0, ptr noalias nocapture swifterror dereferenceable({{.*}}) %1) -// CHECK: tail call swiftcc { ptr, ptr } @try_apply_helper(ptr {{.*}}, ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable({{.*}}) %1) -// CHECK: ret { ptr, ptr } +// CHECK: define{{.*}} internal swiftcc ptr @"$s16try_apply_helperTA"(ptr swiftself %0, ptr noalias nocapture swifterror dereferenceable({{.*}}) %1, ptr %2) +// CHECK: tail call swiftcc ptr @try_apply_helper(ptr {{.*}}, ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable({{.*}}) %1, ptr %2) +// CHECK: ret ptr sil @partial_apply_test : $@convention(thin) (@owned AnyObject) -> @owned @callee_guaranteed () ->(@owned AnyObject, @error S) { entry(%0: $AnyObject): @@ -220,8 +221,8 @@ entry(%0: $AnyObject): return %36 : $@callee_guaranteed () ->(@owned AnyObject, @error S) } -// CHECK: define{{.*}} internal swifttailcc void @"$s22try_apply_helper_asyncTA"(ptr swiftasync %0, ptr swiftself %1) -// CHECK: call { ptr, ptr, ptr, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0p0p0p0s(i32 768, ptr {{.*}}, ptr @__swift_async_resume_project_context, ptr @"$s22try_apply_helper_asyncTA.0", ptr @try_apply_helper_async, ptr {{.*}}, ptr {{.*}}) +// CHECK: define{{.*}} internal swifttailcc void @"$s22try_apply_helper_asyncTA"(ptr swiftasync %0, ptr swiftself %1, ptr %2) +// CHECK: call { ptr, ptr, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0p0p0s(i32 512, ptr {{.*}}, ptr @__swift_async_resume_project_context, ptr @"$s22try_apply_helper_asyncTA.0", ptr @try_apply_helper_async, ptr {{.*}}, ptr {{.*}}, ptr %2) sil @partial_apply_test_async : $@convention(thin) (@owned AnyObject) -> @owned @callee_guaranteed @async () ->(@owned AnyObject, @error S) { entry(%0: $AnyObject): @@ -234,7 +235,8 @@ entry(%0: $AnyObject): // CHECK:entry: // CHECK: %swifterror = alloca swifterror ptr // CHECK: store ptr null, ptr %swifterror -// CHECK: call swiftcc { ptr, ptr } %0(ptr swiftself %1, ptr noalias nocapture swifterror dereferenceable({{[0-9]+}}) %swifterror) +// CHECK: %swifterror1 = alloca %T12typed_throws1SV +// CHECK: call swiftcc ptr %0(ptr swiftself %1, ptr noalias nocapture swifterror dereferenceable({{[0-9]+}}) %swifterror, ptr %swifterror1) sil @apply_closure : $@convention(thin) (@guaranteed @callee_guaranteed () -> (@owned AnyObject, @error S)) -> () { entry(%0 : $@callee_guaranteed () ->(@owned AnyObject, @error S)): @@ -254,7 +256,8 @@ bb6: } // CHECK: define{{.*}} swifttailcc void @apply_closure_async(ptr swiftasync %0, ptr %1, ptr %2) -// CHECK: call { ptr, ptr, ptr, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0p0p0p0s(i32 768, ptr %{{[0-9]+}}, ptr @__swift_async_resume_project_context, ptr @apply_closure_async.0, ptr %{{[0-9]+}},{{( i64 [0-9]+,)?}} ptr %{{[0-9]+}}, ptr %2) +// CHECK: %swifterror = alloca %T12typed_throws1SV +// CHECK: call { ptr, ptr, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0p0p0s(i32 512, ptr %{{[0-9]+}}, ptr @__swift_async_resume_project_context, ptr @apply_closure_async.0, ptr %{{[0-9]+}},{{( i64 [0-9]+,)?}} ptr %{{[0-9]+}}, ptr %2, ptr %swifterror) sil @apply_closure_async : $@convention(thin) @async (@guaranteed @callee_guaranteed @async () -> (@owned AnyObject, @error S)) -> () { entry(%0 : $@callee_guaranteed @async () ->(@owned AnyObject, @error S)): try_apply %0() : $@callee_guaranteed @async () -> (@owned AnyObject, @error S), normal bb4, error bb5 @@ -458,61 +461,3 @@ bb6: %t = tuple() return %t : $() } - -sil @callee : $@convention(thin) @async (Int64) -> (@out (), @error Never) { -bb0(%0 : $*(), %1: $Int64): - %17 = tuple () - return %17 : $() -} - -// CHECK: define{{.*}} swifttailcc void @callee(ptr {{.*}} %0, ptr swiftasync %1, i64 %2, ptr %3) - -// CHECK: define{{.*}} swifttailcc void @caller(ptr swiftasync %0) {{.*}} { -// CHECK-NOT: define -// CHECK: [[CTXT:%.*]] = call swiftcc ptr @swift_task_alloc -// CHECK-NOT: define -// CHECK: call {{.*}} @llvm.coro.suspend.async.sl_p0p0s(i32 256, ptr {{.*}}, ptr @__swift_async_resume_project_context, ptr @caller.0, ptr @callee, ptr undef, ptr [[CTXT]], i64 66, ptr %swifterror) - -sil @caller : $@convention(thin) @async () -> () { -bb0: - %5 = integer_literal $Builtin.Int64, 66 - %6 = struct $Int64 (%5 : $Builtin.Int64) - %9 = alloc_stack $() - %10 = function_ref @callee : $@convention(thin) @async (Int64) -> (@out (), @error Never) - try_apply %10(%9, %6) : $@convention(thin) @async (Int64) -> (@out (), @error Never), normal bb1, error bb2 - -bb1(%12 : $()): - dealloc_stack %9 : $*() - %17 = tuple () - return %17 : $() - -bb2(%19 : $Never): - unreachable -} - -sil @callee2 : $@convention(thin) @async (Int) -> (Int, @error Never) { -bb0(%0 : $Int): - %5 = integer_literal $Builtin.Int64, 66 - %6 = struct $Int (%5 : $Builtin.Int64) - return %6 : $Int -} - -// CHECK: define{{.*}} swifttailcc void @callee2(ptr swiftasync %0, i64 %1) - -// CHECK: define{{.*}} swifttailcc void @caller2(ptr swiftasync %0) -// CHECK: [[CTXT:%.*]] = call swiftcc ptr @swift_task_alloc -// CHECK: @llvm.coro.suspend.async.sl_p0i64p0s({{.*}} ptr @callee2, ptr [[CTXT]], i64 67) -sil @caller2 : $@convention(thin) @async () -> () { -bb0: - %5 = integer_literal $Builtin.Int64, 67 - %6 = struct $Int (%5 : $Builtin.Int64) - %10 = function_ref @callee2 : $@convention(thin) @async (Int) -> (Int, @error Never) - try_apply %10(%6) : $@convention(thin) @async (Int) -> (Int, @error Never), normal bb1, error bb2 - -bb1(%12 : $Int): - %17 = tuple () - return %17 : $() - -bb2(%19 : $Never): - unreachable -} diff --git a/test/IRGen/typed_throws.swift b/test/IRGen/typed_throws.swift index 4766849a3c905..32b37dd34237a 100644 --- a/test/IRGen/typed_throws.swift +++ b/test/IRGen/typed_throws.swift @@ -4,18 +4,14 @@ // RUN: %target-swift-frontend -primary-file %s -emit-ir | %FileCheck %s --check-prefix=CHECK -// RUN: %target-swift-frontend -primary-file %s -emit-ir -enable-library-evolution - -// RUN: %target-swift-frontend -primary-file %s -emit-ir -O - // XFAIL: CPU=arm64e // REQUIRES: PTRSIZE=64 public enum MyBigError: Error { case epicFail - case evenBiggerFail } + // CHECK-MANGLE: @"$s12typed_throws1XVAA1PAAWP" = hidden global [2 x ptr] [ptr @"$s12typed_throws1XVAA1PAAMc", ptr getelementptr inbounds (i8, ptr @"symbolic ySi_____YKc 12typed_throws10MyBigErrorO", {{i32|i64}} 1)] @available(SwiftStdlib 6.0, *) struct X: P { @@ -44,8 +40,8 @@ func buildMetatype() -> Any.Type { return Fn.self } -// // CHECK-NOMANGLE: define linkonce_odr hidden swiftcc %swift.metadata_response @"$sySi12typed_throws10MyBigErrorOYKcMa" -// // CHECK-NOMANGLE: @swift_getExtendedFunctionTypeMetadata({{.*}}@"$s12typed_throws10MyBigErrorOMf" +// CHECK-NOMANGLE: define linkonce_odr hidden swiftcc %swift.metadata_response @"$sySi12typed_throws10MyBigErrorOYKcMa" +// CHECK-NOMANGLE: @swift_getExtendedFunctionTypeMetadata({{.*}}@"$s12typed_throws10MyBigErrorOMf" protocol P { associatedtype A @@ -60,7 +56,7 @@ func five() -> Int { 5 } func fiveOrBust() throws -> Int { 5 } -func fiveOrTypedBust() throws(MyBigError) -> Int { throw MyBigError.epicFail } +func fiveOrTypedBust() throws(MyBigError) -> Int { 5 } func reabstractAsNonthrowing() -> Int { passthroughCall(five) @@ -77,8 +73,7 @@ func reabstractAsConcreteThrowing() throws -> Int { // CHECK-LABEL: define {{.*}} swiftcc void @"$sSi12typed_throws10MyBigErrorOIgdzo_SiACIegrzr_TR"(ptr noalias nocapture sret(%TSi) %0, ptr %1, ptr %2, ptr swiftself %3, ptr noalias nocapture swifterror dereferenceable(8) %4, ptr %5) // CHECK: call swiftcc {{i32|i64}} %1 -// CHECK: [[CMP:%.*]] = icmp ne ptr {{%.*}}, null -// CHECK: br i1 [[CMP]], label %typed.error.load +// CHECK: br i1 %8, label %typed.error.load, label %10 struct S : Error { } @@ -96,154 +91,3 @@ func testit() throws (S) { public struct TypeH { public var method: (Int) throws(MyBigError) -> String } - -struct SmallError: Error { - let x: Int -} - -@inline(never) -func throwsSmallError() throws(SmallError) -> (Float, Int) { - throw SmallError(x: 1) -} - -// CHECK: define hidden swiftcc i64 @"$s12typed_throws17catchesSmallErrorSiyF"() -// CHECK: [[RES:%.*]] = call swiftcc { float, i64 } @"$s12typed_throws0B10SmallErrorSf_SityAA0cD0VYKF"(ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable(8) %swifterror) -// CHECK: [[R0:%.*]] = extractvalue { float, i64 } [[RES]], 0 -// CHECK: [[R1:%.*]] = extractvalue { float, i64 } [[RES]], 1 -// CHECK: phi i64 [ [[R1]], %typed.error.load ] -// CHECK: } -func catchesSmallError() -> Int { - do { - return try throwsSmallError().1 - } catch { - return error.x - } -} - -struct MyError: Error { - let x: AnyObject -} - -// CHECK: define hidden swiftcc { float, i64, float } @"$s12typed_throws8mayThrow1x1ySf_s5Int32VSftSb_yXltAA7MyErrorVYKF" -// CHECK: [[CONVERTED:%.*]] = ptrtoint ptr {{%.*}} to i64 -// CHECK: insertvalue { float, i64, float } undef, i64 [[CONVERTED]], 1 -// CHECK: } -@inline(never) -func mayThrow(x: Bool, y: AnyObject) throws(MyError) -> (Float, Int32, Float) { - guard x else { - throw MyError(x: y) - } - return (3.0, 4, 5.0) -} - -// CHECK: define hidden swiftcc { i64, i64 } @"$s12typed_throws25directErrorMergePtrAndInt1x1yyXl_SitSb_yXltAA05SmallD0VYKF" -// CHECK: [[RES:%.*]] = call swiftcc { i64, i64 } @"$s12typed_throws25directErrorMergePtrAndInt1x1yyXl_SitSb_yXltAA05SmallD0VYKF" -// CHECK: [[R0:%.*]] = extractvalue { i64, i64 } [[RES]], 0 -// CHECK: inttoptr i64 [[R0]] to ptr -// CHECK: } -func directErrorMergePtrAndInt(x: Bool, y: AnyObject) throws(SmallError) -> (AnyObject, Int) { - guard x else { - throw SmallError(x: 1) - } - - return try directErrorMergePtrAndInt(x: !x, y: y) -} - -// This used to crash at compile time, because it was trying to use a direct -// error return in combination with an indirect result, which is illegal. -func genericThrows(x: Bool, y: T) throws(SmallError) -> T { - guard x else { - throw SmallError(x: 1) - } - - return y -} - -func throwsGeneric(x: Bool, y: T) throws(T) -> Int { - guard x else { - throw y - } - - return 32 -} - -@available(SwiftStdlib 6.0, *) -func mayThrowAsync(x: Bool, y: AnyObject) async throws(MyError) -> (Float, Int32, Float) { - guard x else { - throw MyError(x: y) - } - return (3.0, 4, 5.0) -} - -@available(SwiftStdlib 6.0, *) -func genericThrowsAsync(x: Bool, y: T) async throws(SmallError) -> T { - guard x else { - throw SmallError(x: 1) - } - - return y -} - -@available(SwiftStdlib 6.0, *) -func throwsGenericAsync(x: Bool, y: T) async throws(T) -> Int { - guard x else { - throw y - } - - return 32 -} - -enum TinyError: Error { - case a -} - -@available(SwiftStdlib 6.0, *) -func mayThrowAsyncTiny(x: Bool) async throws(TinyError) -> Bool { - guard x else { - throw .a - } - return false -} - -@available(SwiftStdlib 6.0, *) -func callsMayThrowAsyncTiny(x: Bool) async { - _ = try! await mayThrowAsyncTiny(x: x) -} - -struct EmptyError: Error {} - -@available(SwiftStdlib 6.0, *) -func mayThrowEmptyErrorAsync(x: Bool) async throws(EmptyError) -> String? { - guard x else { - throw EmptyError() - } - - return "" -} - - -enum SP: Error { - case a - case b(Int32) -} - -protocol Proto { - // This used to crash. - static func f() throws(SP) -> Self - - // This used to crash. - static func f2() throws(SP) -> Int64 -} - -@inline(never) -@available(SwiftStdlib 6.0, *) -public func passthroughAsync(f: () async throws(E) -> T) async throws(E) -> T { - try await f() -} - -@available(SwiftStdlib 6.0, *) -public func reabstractAsyncVoidThrowsNever() async { - await passthroughAsync { - () - } -} diff --git a/test/IRGen/typed_throws_32_bit.swift b/test/IRGen/typed_throws_32_bit.swift deleted file mode 100644 index e5927e0c8b756..0000000000000 --- a/test/IRGen/typed_throws_32_bit.swift +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: %target-swift-frontend -emit-ir -primary-file %s - -// REQUIRES: CPU=arm64_32 || CPU=armv7k - -public class MyClass { - let x: Int64 - init(x: Int64) { - self.x = x - } -} - -public struct MyError: Error { - let x: MyClass -} - -@inline(never) -public func foo(f: () throws(MyError) -> Int64) throws(MyError) -> Int64 { - return try f() -} - -public func bar(f: () throws(MyError) -> Int64) -> Int64 { - do { - return try foo(f: f) - } catch { - return error.x.x - } -} diff --git a/test/IRGen/typed_throws_thunks.swift b/test/IRGen/typed_throws_thunks.swift index 5002cde9a4440..8799a3c5acb05 100644 --- a/test/IRGen/typed_throws_thunks.swift +++ b/test/IRGen/typed_throws_thunks.swift @@ -34,9 +34,9 @@ extension P { } } - // CHECK-LABEL: define{{.*}} swifttailcc void @"$s19typed_throws_thunks1PP2g44bodyyyyAA9FixedSizeVYKXE_tYaAGYKFTj"(ptr swiftasync %0, ptr %1, ptr %2, ptr noalias swiftself %3, ptr %4, ptr %5) + // CHECK-LABEL: define{{.*}} swifttailcc void @"$s19typed_throws_thunks1PP2g44bodyyyyAA9FixedSizeVYKXE_tYaAGYKFTj"(ptr swiftasync %0, ptr %1, ptr %2, ptr noalias swiftself %3, ptr %4, ptr %5, ptr %6) // CHECK-NOT: ret - // CHECK: call { ptr, i64, i64, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0i64i64p0s({{.*}} ptr %1, ptr %2, ptr %3, ptr %4, ptr %5) + // CHECK: call { ptr, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0p0s({{.*}} ptr %1, ptr %2, ptr %3, ptr %4, ptr %5, ptr %6) public func g4(body: () throws(FixedSize) -> Void) async throws(FixedSize) { do { return try await f(body: body) @@ -57,9 +57,9 @@ extension P { } } - // CHECK-LABEL: define{{.*}} swiftcc { i64, i64 } @"$s19typed_throws_thunks1PP2g34bodyyyyAA9FixedSizeVYKXE_tAGYKFTj"(ptr %0, ptr %1, ptr noalias swiftself %2, ptr noalias nocapture swifterror dereferenceable(8) %3, ptr %4, ptr %5) + // CHECK-LABEL: define{{.*}} swiftcc void @"$s19typed_throws_thunks1PP2g34bodyyyyAA9FixedSizeVYKXE_tAGYKFTj"(ptr %0, ptr %1, ptr noalias swiftself %2, ptr noalias nocapture swifterror dereferenceable(8) %3, ptr %4, ptr %5, ptr %6) // CHECK-NOT: ret - // CHECK: call swiftcc { i64, i64 } {{.*}}(ptr %0, ptr %1, ptr noalias swiftself %2, ptr noalias nocapture swifterror dereferenceable(8) %3, ptr %4, ptr %5) + // CHECK: call swiftcc void {{.*}}(ptr %0, ptr %1, ptr noalias swiftself %2, ptr noalias nocapture swifterror dereferenceable(8) %3, ptr %4, ptr %5, ptr %6) public func g3(body: () throws(FixedSize) -> Void) throws(FixedSize) {