From 147144baa60531e5f91169e844f87296241fff31 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 30 Apr 2020 08:59:59 -0700 Subject: [PATCH 1/3] SIL: Thread type expansion context through to function convention apis This became necessary after recent function type changes that keep substituted generic function types abstract even after substitution to correctly handle automatic opaque result type substitution. Instead of performing the opaque result type substitution as part of substituting the generic args the underlying type will now be reified as part of looking at the parameter/return types which happens as part of the function convention apis. rdar://62560867 --- include/swift/AST/Types.h | 61 ++++---- include/swift/SIL/ApplySite.h | 6 +- include/swift/SIL/SILFunction.h | 2 +- include/swift/SIL/SILFunctionConventions.h | 132 +++++++++------- include/swift/SIL/SILInstruction.h | 3 +- include/swift/SIL/SILType.h | 4 +- .../SILOptimizer/Differentiation/Common.h | 5 +- lib/IRGen/GenCall.cpp | 68 +++++--- lib/IRGen/GenClangType.cpp | 14 +- lib/IRGen/GenFunc.cpp | 79 ++++++---- lib/IRGen/GenObjC.cpp | 19 ++- lib/IRGen/GenPointerAuth.cpp | 9 +- lib/IRGen/GenProto.cpp | 26 ++-- lib/IRGen/GenThunk.cpp | 4 +- lib/IRGen/IRGenDebugInfo.cpp | 19 ++- lib/IRGen/IRGenSIL.cpp | 58 ++++--- lib/IRGen/LoadableByAddress.cpp | 3 +- lib/SIL/IR/SILBuilder.cpp | 4 +- lib/SIL/IR/SILFunction.cpp | 7 +- lib/SIL/IR/SILFunctionType.cpp | 96 ++++++++---- lib/SIL/IR/SILInstructions.cpp | 4 +- lib/SIL/IR/SILType.cpp | 14 +- lib/SIL/IR/TypeLowering.cpp | 40 +++-- lib/SIL/Parser/ParseSIL.cpp | 12 +- lib/SIL/Verifier/SILVerifier.cpp | 145 +++++++++++------- lib/SILGen/ResultPlan.cpp | 25 +-- lib/SILGen/SILGen.cpp | 29 ++-- lib/SILGen/SILGenApply.cpp | 55 ++++--- lib/SILGen/SILGenBridging.cpp | 65 ++++---- lib/SILGen/SILGenEpilog.cpp | 4 +- lib/SILGen/SILGenExpr.cpp | 24 +-- lib/SILGen/SILGenFunction.cpp | 16 +- lib/SILGen/SILGenFunction.h | 13 +- lib/SILGen/SILGenLValue.cpp | 8 +- lib/SILGen/SILGenPoly.cpp | 33 ++-- lib/SILGen/SILGenProlog.cpp | 2 +- lib/SILOptimizer/Analysis/ArraySemantic.cpp | 6 +- lib/SILOptimizer/Analysis/EscapeAnalysis.cpp | 4 +- lib/SILOptimizer/Differentiation/Thunk.cpp | 9 +- .../ExistentialTransform.cpp | 12 +- .../FunctionSignatureOpts.cpp | 7 +- lib/SILOptimizer/IPO/CapturePromotion.cpp | 8 +- lib/SILOptimizer/IPO/ClosureSpecializer.cpp | 11 +- lib/SILOptimizer/IPO/EagerSpecializer.cpp | 19 ++- .../Mandatory/AddressLowering.cpp | 14 +- .../Mandatory/DataflowDiagnostics.cpp | 5 +- .../SILCombiner/SILCombinerApplyVisitors.cpp | 32 ++-- .../Transforms/ObjectOutliner.cpp | 6 +- .../Transforms/PerformanceInliner.cpp | 4 +- lib/SILOptimizer/Transforms/SimplifyCFG.cpp | 9 +- .../Transforms/SpeculativeDevirtualizer.cpp | 3 +- lib/SILOptimizer/Utils/CastOptimizer.cpp | 8 +- lib/SILOptimizer/Utils/ConstExpr.cpp | 12 +- lib/SILOptimizer/Utils/Devirtualize.cpp | 39 +++-- lib/SILOptimizer/Utils/Generics.cpp | 37 +++-- lib/Serialization/DeserializeSIL.cpp | 10 +- .../Inputs/opaque_result_types.swift | 76 +++++++++ .../specialize_opaque_result_types.sil | 75 +++++++++ 58 files changed, 975 insertions(+), 539 deletions(-) create mode 100644 test/SILOptimizer/Inputs/opaque_result_types.swift create mode 100644 test/SILOptimizer/specialize_opaque_result_types.sil diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 9f964ab633c1a..de6c9599e84f5 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -3776,8 +3776,7 @@ class SILParameterInfo { /// Return the type of a call argument matching this parameter. /// /// \c t must refer back to the function type this is a parameter for. - CanType getArgumentType(SILModule &M, - const SILFunctionType *t) const; + CanType getArgumentType(SILModule &M, const SILFunctionType *t, TypeExpansionContext context) const; ParameterConvention getConvention() const { return TypeAndConvention.getInt(); } @@ -3832,8 +3831,9 @@ class SILParameterInfo { /// storage. Therefore they will be passed using an indirect formal /// convention, and this method will return an address type. However, in /// canonical SIL the opaque arguments might not have an address type. - SILType getSILStorageType(SILModule &M, - const SILFunctionType *t) const; // in SILFunctionConventions.h + SILType getSILStorageType( + SILModule &M, const SILFunctionType *t, + TypeExpansionContext context) const; // in SILFunctionConventions.h SILType getSILStorageInterfaceType() const; /// Return a version of this parameter info with the type replaced. @@ -3865,9 +3865,9 @@ class SILParameterInfo { /// type, apply any substitutions from the function type to it to /// get a substituted version of it, as you would get from /// SILFunctionType::getUnsubstitutedType. - SILParameterInfo getUnsubstituted(SILModule &M, - const SILFunctionType *fnType) const { - return getWithInterfaceType(getArgumentType(M, fnType)); + SILParameterInfo getUnsubstituted(SILModule &M, const SILFunctionType *fnType, + TypeExpansionContext context) const { + return getWithInterfaceType(getArgumentType(M, fnType, context)); } void profile(llvm::FoldingSetNodeID &id) { @@ -3952,9 +3952,9 @@ class SILResultInfo { /// The type of a return value corresponding to this result. /// /// \c t must refer back to the function type this is a parameter for. - CanType getReturnValueType(SILModule &M, - const SILFunctionType *t) const; - + CanType getReturnValueType(SILModule &M, const SILFunctionType *t, + TypeExpansionContext context) const; + ResultConvention getConvention() const { return TypeAndConvention.getInt(); } @@ -3964,8 +3964,9 @@ class SILResultInfo { /// storage. Therefore they will be returned using an indirect formal /// convention, and this method will return an address type. However, in /// canonical SIL the opaque results might not have an address type. - SILType getSILStorageType(SILModule &M, - const SILFunctionType *t) const; // in SILFunctionConventions.h + SILType getSILStorageType( + SILModule &M, const SILFunctionType *t, + TypeExpansionContext context) const; // in SILFunctionConventions.h SILType getSILStorageInterfaceType() const; /// Return a version of this result info with the type replaced. SILResultInfo getWithInterfaceType(CanType type) const { @@ -4006,9 +4007,9 @@ class SILResultInfo { /// type, apply any substitutions from the function type to it to /// get a substituted version of it, as you would get from /// SILFunctionType::getUnsubstitutedType. - SILResultInfo getUnsubstituted(SILModule &M, - const SILFunctionType *fnType) const { - return getWithInterfaceType(getReturnValueType(M, fnType)); + SILResultInfo getUnsubstituted(SILModule &M, const SILFunctionType *fnType, + TypeExpansionContext context) const { + return getWithInterfaceType(getReturnValueType(M, fnType, context)); } void profile(llvm::FoldingSetNodeID &id) { @@ -4066,18 +4067,18 @@ class SILYieldInfo : public SILParameterInfo { ->getCanonicalType()); } - CanType getYieldValueType(SILModule &M, - const SILFunctionType *fnType) const { - return getArgumentType(M, fnType); + CanType getYieldValueType(SILModule &M, const SILFunctionType *fnType, + TypeExpansionContext context) const { + return getArgumentType(M, fnType, context); } /// Treating this yield info as a component of the given function /// type, apply any substitutions from the function type to it to /// get a substituted version of it, as you would get from /// SILFunctionType::getUnsubstitutedType. - SILYieldInfo getUnsubstituted(SILModule &M, - const SILFunctionType *fnType) const { - return getWithInterfaceType(getYieldValueType(M, fnType)); + SILYieldInfo getUnsubstituted(SILModule &M, const SILFunctionType *fnType, + TypeExpansionContext context) const { + return getWithInterfaceType(getYieldValueType(M, fnType, context)); } }; @@ -4528,14 +4529,15 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, /// this function depends on the current SIL stage and is known by /// SILFunctionConventions. It may be a wider tuple that includes formally /// indirect results. - SILType getDirectFormalResultsType(SILModule &M); + SILType getDirectFormalResultsType(SILModule &M, + TypeExpansionContext expansion); /// Get a single non-address SILType for all SIL results regardless of whether /// they are formally indirect. The actual SIL result type of an apply /// instruction that calls this function depends on the current SIL stage and /// is known by SILFunctionConventions. It may be a narrower tuple that omits /// formally indirect results. - SILType getAllResultsSubstType(SILModule &M); + SILType getAllResultsSubstType(SILModule &M, TypeExpansionContext expansion); SILType getAllResultsInterfaceType(); /// Does this function have a blessed Swift-native error result? @@ -4678,12 +4680,13 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, return getInvocationGenericSignature() && !getInvocationSubstitutions(); } - CanType getSelfInstanceType(SILModule &M) const; + CanType getSelfInstanceType(SILModule &M, TypeExpansionContext context) const; /// If this is a @convention(witness_method) function with a class /// constrained self parameter, return the class constraint for the /// Self type. - ClassDecl *getWitnessMethodClass(SILModule &M) const; + ClassDecl *getWitnessMethodClass(SILModule &M, + TypeExpansionContext context) const; /// If this is a @convention(witness_method) function, return the conformance /// for which the method is a witness. If it isn't that convention, return @@ -4875,8 +4878,9 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, return getExtInfo().getDifferentiabilityKind(); } - bool isNoReturnFunction(SILModule &M) const; // Defined in SILType.cpp - + bool isNoReturnFunction(SILModule &M, TypeExpansionContext context) + const; // Defined in SILType.cpp + /// Create a SILFunctionType with the same structure as this one, /// but with a different (or new) set of invocation substitutions. /// The substitutions must have the same generic signature as this. @@ -4956,7 +4960,8 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, TypeExpansionContext context); SILType substInterfaceType(SILModule &M, - SILType interfaceType) const; + SILType interfaceType, + TypeExpansionContext context) const; /// Return the unsubstituted function type equivalent to this type; that is, the type that has the same /// argument and result types as `this` type after substitutions, if any. diff --git a/include/swift/SIL/ApplySite.h b/include/swift/SIL/ApplySite.h index c367aec119c0a..6f8b911f46369 100644 --- a/include/swift/SIL/ApplySite.h +++ b/include/swift/SIL/ApplySite.h @@ -23,6 +23,7 @@ #include "swift/SIL/SILBasicBlock.h" #include "swift/SIL/SILInstruction.h" +#include "swift/SIL/SILFunction.h" namespace swift { @@ -180,7 +181,10 @@ class ApplySite { } /// Return the type. - SILType getType() const { return getSubstCalleeConv().getSILResultType(); } + SILType getType() const { + return getSubstCalleeConv().getSILResultType( + getFunction()->getTypeExpansionContext()); + } /// Get the type of the callee without the applied substitutions. CanSILFunctionType getOrigCalleeType() const { diff --git a/include/swift/SIL/SILFunction.h b/include/swift/SIL/SILFunction.h index 6213188af2fba..a04159e4eb649 100644 --- a/include/swift/SIL/SILFunction.h +++ b/include/swift/SIL/SILFunction.h @@ -416,7 +416,7 @@ class SILFunction void setEntryCount(ProfileCounter Count) { EntryCount = Count; } - bool isNoReturnFunction() const; + bool isNoReturnFunction(TypeExpansionContext context) const; /// Unsafely rewrite the lowered type of this function. /// diff --git a/include/swift/SIL/SILFunctionConventions.h b/include/swift/SIL/SILFunctionConventions.h index 7d55a08b9177d..ff148628bf7f6 100644 --- a/include/swift/SIL/SILFunctionConventions.h +++ b/include/swift/SIL/SILFunctionConventions.h @@ -109,30 +109,30 @@ class SILModuleConventions { return isIndirectSILResult(result, loweredAddresses); } - SILType getSILType(SILParameterInfo param, - CanSILFunctionType funcTy) const { + SILType getSILType(SILParameterInfo param, CanSILFunctionType funcTy, + TypeExpansionContext context) const { auto interfaceTy = getSILParamInterfaceType(param, loweredAddresses); // TODO: Always require a function type if (funcTy) - return funcTy->substInterfaceType(*M, interfaceTy); + return funcTy->substInterfaceType(*M, interfaceTy, context); return interfaceTy; } - SILType getSILType(SILYieldInfo yield, - CanSILFunctionType funcTy) const { + SILType getSILType(SILYieldInfo yield, CanSILFunctionType funcTy, + TypeExpansionContext context) const { auto interfaceTy = getSILYieldInterfaceType(yield, loweredAddresses); // TODO: Always require a function type if (funcTy) - return funcTy->substInterfaceType(*M, interfaceTy); + return funcTy->substInterfaceType(*M, interfaceTy, context); return interfaceTy; } - SILType getSILType(SILResultInfo result, - CanSILFunctionType funcTy) const { + SILType getSILType(SILResultInfo result, CanSILFunctionType funcTy, + TypeExpansionContext context) const { auto interfaceTy = getSILResultInterfaceType(result, loweredAddresses); // TODO: Always require a function type if (funcTy) - return funcTy->substInterfaceType(*M, interfaceTy); + return funcTy->substInterfaceType(*M, interfaceTy, context); return interfaceTy; } }; @@ -170,16 +170,17 @@ class SILFunctionConventions { return silConv.isSILIndirect(result); } - SILType getSILType(SILParameterInfo param) const { - return silConv.getSILType(param, funcTy); + SILType getSILType(SILParameterInfo param, + TypeExpansionContext context) const { + return silConv.getSILType(param, funcTy, context); } - SILType getSILType(SILYieldInfo yield) const { - return silConv.getSILType(yield, funcTy); + SILType getSILType(SILYieldInfo yield, TypeExpansionContext context) const { + return silConv.getSILType(yield, funcTy, context); } - SILType getSILType(SILResultInfo result) const { - return silConv.getSILType(result, funcTy); + SILType getSILType(SILResultInfo result, TypeExpansionContext context) const { + return silConv.getSILType(result, funcTy, context); } //===--------------------------------------------------------------------===// @@ -188,20 +189,22 @@ class SILFunctionConventions { /// Get the normal result type of an apply that calls this function. /// This does not include indirect SIL results. - SILType getSILResultType() { + SILType getSILResultType(TypeExpansionContext context) { if (silConv.loweredAddresses) - return funcTy->getDirectFormalResultsType(silConv.getModule()); + return funcTy->getDirectFormalResultsType(silConv.getModule(), context); - return funcTy->getAllResultsSubstType(silConv.getModule()); + return funcTy->getAllResultsSubstType(silConv.getModule(), context); } /// Get the SIL type for the single result which may be direct or indirect. - SILType getSingleSILResultType() { - return getSILType(funcTy->getSingleResult()); + SILType getSingleSILResultType(TypeExpansionContext context) { + return getSILType(funcTy->getSingleResult(), context); } /// Get the error result type. - SILType getSILErrorType() { return getSILType(funcTy->getErrorResult()); } + SILType getSILErrorType(TypeExpansionContext context) { + return getSILType(funcTy->getErrorResult(), context); + } /// Returns an array of result info. /// Provides convenient access to the underlying SILFunctionType. @@ -243,8 +246,9 @@ class SILFunctionConventions { /// Return a range of SILTypes for each result passed as an address-typed SIL /// argument. - template - IndirectSILResultTypeRange<_> getIndirectSILResultTypes() const; + template + IndirectSILResultTypeRange<_> + getIndirectSILResultTypes(TypeExpansionContext context) const; /// Get the number of SIL results directly returned by SIL value. unsigned getNumDirectSILResults() const { @@ -279,8 +283,9 @@ class SILFunctionConventions { /// Return a range of SILTypes for each result directly returned /// by SIL value. - template - DirectSILResultTypeRange<_> getDirectSILResultTypes() const; + template + DirectSILResultTypeRange<_> + getDirectSILResultTypes(TypeExpansionContext context) const; //===--------------------------------------------------------------------===// // SIL parameters types. @@ -311,8 +316,9 @@ class SILFunctionConventions { /// Return a range of SILTypes for each function parameter, not including /// indirect results. - template - SILParameterTypeRange<_> getParameterSILTypes() const; + template + SILParameterTypeRange<_> + getParameterSILTypes(TypeExpansionContext context) const; //===--------------------------------------------------------------------===// // SIL yield types. @@ -332,7 +338,7 @@ class SILFunctionConventions { using SILYieldTypeRange = iterator_range>; template - SILYieldTypeRange<_> getYieldSILTypes() const; + SILYieldTypeRange<_> getYieldSILTypes(TypeExpansionContext context) const; SILYieldInfo getYieldInfoForOperandIndex(unsigned opIndex) const { return getYields()[opIndex]; @@ -388,63 +394,74 @@ class SILFunctionConventions { // See SILArgument.h. /// Return the SIL type of the apply/entry argument at the given index. - SILType getSILArgumentType(unsigned index) const; + SILType getSILArgumentType(unsigned index, + TypeExpansionContext context) const; }; struct SILFunctionConventions::SILResultTypeFunc { SILFunctionConventions silConv; - SILResultTypeFunc(const SILFunctionConventions &silConv) - : silConv(silConv) {} + TypeExpansionContext context; + SILResultTypeFunc(const SILFunctionConventions &silConv, + TypeExpansionContext context) + : silConv(silConv), context(context) {} SILType operator()(SILResultInfo result) const { - return silConv.getSILType(result); + return silConv.getSILType(result, context); } }; -template +template SILFunctionConventions::IndirectSILResultTypeRange<_> -SILFunctionConventions::getIndirectSILResultTypes() const { - return llvm::map_range(getIndirectSILResults(), SILResultTypeFunc(*this)); - } +SILFunctionConventions::getIndirectSILResultTypes( + TypeExpansionContext context) const { + return llvm::map_range(getIndirectSILResults(), + SILResultTypeFunc(*this, context)); +} -template +template SILFunctionConventions::DirectSILResultTypeRange<_> -SILFunctionConventions::getDirectSILResultTypes() const { - return llvm::map_range(getDirectSILResults(), SILResultTypeFunc(*this)); +SILFunctionConventions::getDirectSILResultTypes( + TypeExpansionContext context) const { + return llvm::map_range(getDirectSILResults(), + SILResultTypeFunc(*this, context)); } struct SILFunctionConventions::SILParameterTypeFunc { SILFunctionConventions silConv; - SILParameterTypeFunc(const SILFunctionConventions &silConv) - : silConv(silConv) {} + TypeExpansionContext context; + SILParameterTypeFunc(const SILFunctionConventions &silConv, + TypeExpansionContext context) + : silConv(silConv), context(context) {} SILType operator()(SILParameterInfo param) const { - return silConv.getSILType(param); + return silConv.getSILType(param, context); } }; -template +template SILFunctionConventions::SILParameterTypeRange<_> -SILFunctionConventions::getParameterSILTypes() const { +SILFunctionConventions::getParameterSILTypes( + TypeExpansionContext context) const { return llvm::map_range(funcTy->getParameters(), - SILParameterTypeFunc(*this)); + SILParameterTypeFunc(*this, context)); } -template +template SILFunctionConventions::SILYieldTypeRange<_> -SILFunctionConventions::getYieldSILTypes() const { +SILFunctionConventions::getYieldSILTypes(TypeExpansionContext context) const { return llvm::map_range(funcTy->getYields(), - SILParameterTypeFunc(*this)); + SILParameterTypeFunc(*this, context)); } inline SILType -SILFunctionConventions::getSILArgumentType(unsigned index) const { +SILFunctionConventions::getSILArgumentType(unsigned index, + TypeExpansionContext context) const { assert(index <= getNumSILArguments()); if (index < getNumIndirectSILResults()) { - return *std::next(getIndirectSILResultTypes().begin(), index); + return *std::next(getIndirectSILResultTypes(context).begin(), index); } return getSILType( - funcTy->getParameters()[index - getNumIndirectSILResults()]); + funcTy->getParameters()[index - getNumIndirectSILResults()], context); } inline SILFunctionConventions @@ -527,14 +544,17 @@ SILResultInfo::getSILStorageInterfaceType() const { inline SILType SILParameterInfo::getSILStorageType(SILModule &M, - const SILFunctionType *funcTy) const { - return funcTy->substInterfaceType(M, getSILStorageInterfaceType()); + const SILFunctionType *funcTy, + TypeExpansionContext context) const { + return funcTy->substInterfaceType(M, getSILStorageInterfaceType(), + context); } inline SILType -SILResultInfo::getSILStorageType(SILModule &M, - const SILFunctionType *funcTy) const { - return funcTy->substInterfaceType(M, getSILStorageInterfaceType()); +SILResultInfo::getSILStorageType(SILModule &M, const SILFunctionType *funcTy, + TypeExpansionContext context) const { + return funcTy->substInterfaceType(M, getSILStorageInterfaceType(), + context); } } // end swift namespace diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h index 27acf6738fa2f..23a47ff99198c 100644 --- a/include/swift/SIL/SILInstruction.h +++ b/include/swift/SIL/SILInstruction.h @@ -1955,7 +1955,8 @@ class ApplyInstBase : public Base { } bool isCalleeNoReturn() const { - return getSubstCalleeSILType().isNoReturnFunction(this->getModule()); + return getSubstCalleeSILType().isNoReturnFunction( + this->getModule(), TypeExpansionContext(*this->getFunction())); } bool isCalleeThin() const { diff --git a/include/swift/SIL/SILType.h b/include/swift/SIL/SILType.h index 46cf21731ce8f..752c33f7ef8a3 100644 --- a/include/swift/SIL/SILType.h +++ b/include/swift/SIL/SILType.h @@ -294,7 +294,7 @@ class SILType { /// Returns true if the referenced type is a function type that never /// returns. - bool isNoReturnFunction(SILModule &M) const; + bool isNoReturnFunction(SILModule &M, TypeExpansionContext context) const; /// Returns true if the referenced AST type has reference semantics, even if /// the lowered SIL type is known to be trivial. @@ -509,6 +509,8 @@ class SILType { SILType subst(Lowering::TypeConverter &tc, SubstitutionMap subs) const; SILType subst(SILModule &M, SubstitutionMap subs) const; + SILType subst(SILModule &M, SubstitutionMap subs, + TypeExpansionContext context) const; /// Return true if this type references a "ref" type that has a single pointer /// representation. Class existentials do not always qualify. diff --git a/include/swift/SILOptimizer/Differentiation/Common.h b/include/swift/SILOptimizer/Differentiation/Common.h index 7b29b564d1f1a..2deecd9d9e496 100644 --- a/include/swift/SILOptimizer/Differentiation/Common.h +++ b/include/swift/SILOptimizer/Differentiation/Common.h @@ -212,13 +212,14 @@ inline void createEntryArguments(SILFunction *f) { entry->createFunctionArgument(type, decl); }; // f->getLoweredFunctionType()->remap - for (auto indResTy : conv.getIndirectSILResultTypes()) { + for (auto indResTy : + conv.getIndirectSILResultTypes(f->getTypeExpansionContext())) { if (indResTy.hasArchetype()) indResTy = indResTy.mapTypeOutOfContext(); createFunctionArgument(f->mapTypeIntoContext(indResTy).getAddressType()); // createFunctionArgument(indResTy.getAddressType()); } - for (auto paramTy : conv.getParameterSILTypes()) { + for (auto paramTy : conv.getParameterSILTypes(f->getTypeExpansionContext())) { if (paramTy.hasArchetype()) paramTy = paramTy.mapTypeOutOfContext(); createFunctionArgument(f->mapTypeIntoContext(paramTy)); diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index ddc4f87c8bc7c..a1a0e1fe6a62b 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -302,7 +302,8 @@ namespace { } // end namespace swift llvm::Type *SignatureExpansion::addIndirectResult() { - auto resultType = getSILFuncConventions().getSILResultType(); + auto resultType = getSILFuncConventions().getSILResultType( + IGM.getMaximalTypeExpansionContext()); const TypeInfo &resultTI = IGM.getTypeInfo(resultType); addIndirectResultAttributes(IGM, Attrs, ParamIRTypes.size(), claimSRet()); addPointerParameter(resultTI.getStorageType()); @@ -328,7 +329,8 @@ void SignatureExpansion::expandResult() { ResultIRType = expandDirectResult(); // Expand the indirect results. - for (auto indirectResultType : fnConv.getIndirectSILResultTypes()) { + for (auto indirectResultType : + fnConv.getIndirectSILResultTypes(IGM.getMaximalTypeExpansionContext())) { addIndirectResultAttributes(IGM, Attrs, ParamIRTypes.size(), claimSRet()); addPointerParameter(IGM.getStorageType(indirectResultType)); } @@ -343,8 +345,9 @@ namespace { public: YieldSchema(IRGenModule &IGM, SILFunctionConventions fnConv, SILYieldInfo yield) - : YieldTy(fnConv.getSILType(yield)), - YieldTI(IGM.getTypeInfo(YieldTy)) { + : YieldTy( + fnConv.getSILType(yield, IGM.getMaximalTypeExpansionContext())), + YieldTI(IGM.getTypeInfo(YieldTy)) { if (isFormalIndirect()) { IsIndirect = true; } else { @@ -630,7 +633,8 @@ NativeConventionSchema::getCoercionTypes( llvm::Type *SignatureExpansion::expandDirectResult() { // Handle the direct result type, checking for supposedly scalar // result types that we actually want to return indirectly. - auto resultType = getSILFuncConventions().getSILResultType(); + auto resultType = getSILFuncConventions().getSILResultType( + IGM.getMaximalTypeExpansionContext()); // Fast-path the empty tuple type. if (auto tuple = resultType.getAs()) @@ -1204,7 +1208,8 @@ void SignatureExpansion::expandExternalSignatureTypes() { assert(i >= clangToSwiftParamOffset && "Unexpected index for indirect byval argument"); auto ¶m = params[i - clangToSwiftParamOffset]; - auto paramTy = getSILFuncConventions().getSILType(param); + auto paramTy = getSILFuncConventions().getSILType( + param, IGM.getMaximalTypeExpansionContext()); auto ¶mTI = cast(IGM.getTypeInfo(paramTy)); if (AI.getIndirectByVal()) addByvalArgumentAttributes( @@ -1244,23 +1249,24 @@ static ArrayRef expandScalarOrStructTypeToArray(llvm::Type *&ty) { void SignatureExpansion::expand(SILParameterInfo param) { - auto paramSILType = getSILFuncConventions().getSILType(param); + auto paramSILType = getSILFuncConventions().getSILType( + param, IGM.getMaximalTypeExpansionContext()); auto &ti = IGM.getTypeInfo(paramSILType); switch (auto conv = param.getConvention()) { case ParameterConvention::Indirect_In: case ParameterConvention::Indirect_In_Constant: case ParameterConvention::Indirect_In_Guaranteed: addIndirectValueParameterAttributes(IGM, Attrs, ti, ParamIRTypes.size()); - addPointerParameter( - IGM.getStorageType(getSILFuncConventions().getSILType(param))); + addPointerParameter(IGM.getStorageType(getSILFuncConventions().getSILType( + param, IGM.getMaximalTypeExpansionContext()))); return; case ParameterConvention::Indirect_Inout: case ParameterConvention::Indirect_InoutAliasable: addInoutParameterAttributes(IGM, Attrs, ti, ParamIRTypes.size(), conv == ParameterConvention::Indirect_InoutAliasable); - addPointerParameter( - IGM.getStorageType(getSILFuncConventions().getSILType(param))); + addPointerParameter(IGM.getStorageType(getSILFuncConventions().getSILType( + param, IGM.getMaximalTypeExpansionContext()))); return; case ParameterConvention::Direct_Owned: @@ -1407,8 +1413,9 @@ void SignatureExpansion::expandParameters() { if (FnType->hasErrorResult()) { if (claimError()) IGM.addSwiftErrorAttributes(Attrs, ParamIRTypes.size()); - llvm::Type *errorType = IGM.getStorageType( - getSILFuncConventions().getSILType(FnType->getErrorResult())); + llvm::Type *errorType = + IGM.getStorageType(getSILFuncConventions().getSILType( + FnType->getErrorResult(), IGM.getMaximalTypeExpansionContext())); ParamIRTypes.push_back(errorType->getPointerTo()); } @@ -1536,7 +1543,8 @@ void CallEmission::emitToUnmappedExplosion(Explosion &out) { // Specially handle noreturn c function which would return a 'Never' SIL result // type. if (origFnType->getLanguage() == SILFunctionLanguage::C && - origFnType->isNoReturnFunction(IGF.getSILModule())) { + origFnType->isNoReturnFunction( + IGF.getSILModule(), IGF.IGM.getMaximalTypeExpansionContext())) { auto clangResultTy = result->getType(); extractScalarResults(IGF, clangResultTy, result, out); return; @@ -1545,7 +1553,8 @@ void CallEmission::emitToUnmappedExplosion(Explosion &out) { // 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(); + 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 @@ -1694,10 +1703,16 @@ void CallEmission::emitToMemory(Address addr, // result that's actually being passed indirectly. // // TODO: SIL address lowering should be able to handle such cases earlier. - auto origResultType = origFnType->getDirectFormalResultsType(IGF.IGM.getSILModule()) - .getASTType(); - auto substResultType = substFnType->getDirectFormalResultsType(IGF.IGM.getSILModule()) - .getASTType(); + auto origResultType = + origFnType + ->getDirectFormalResultsType(IGF.IGM.getSILModule(), + IGF.IGM.getMaximalTypeExpansionContext()) + .getASTType(); + auto substResultType = + substFnType + ->getDirectFormalResultsType(IGF.IGM.getSILModule(), + IGF.IGM.getMaximalTypeExpansionContext()) + .getASTType(); if (origResultType->hasTypeParameter()) origResultType = IGF.IGM.getGenericEnvironment() @@ -1817,7 +1832,8 @@ void CallEmission::emitToExplosion(Explosion &out, bool isOutlined) { SILFunctionConventions fnConv(getCallee().getSubstFunctionType(), IGF.getSILModule()); - SILType substResultType = fnConv.getSILResultType(); + SILType substResultType = + fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()); auto &substResultTI = cast(IGF.getTypeInfo(substResultType)); @@ -1825,7 +1841,8 @@ void CallEmission::emitToExplosion(Explosion &out, bool isOutlined) { auto origFnType = getCallee().getOrigFunctionType(); auto isNoReturnCFunction = origFnType->getLanguage() == SILFunctionLanguage::C && - origFnType->isNoReturnFunction(IGF.getSILModule()); + origFnType->isNoReturnFunction(IGF.getSILModule(), + IGF.IGM.getMaximalTypeExpansionContext()); // If the call is naturally to memory, emit it that way and then // explode that temporary. @@ -1993,7 +2010,8 @@ void CallEmission::setFromCallee() { // The invariant is that this is always zero-initialized, so we // don't need to do anything extra here. SILFunctionConventions fnConv(fnType, IGF.getSILModule()); - Address errorResultSlot = IGF.getErrorResultSlot(fnConv.getSILErrorType()); + Address errorResultSlot = IGF.getErrorResultSlot( + fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext())); assert(LastArgWritten > 0); Args[--LastArgWritten] = errorResultSlot.getAddress(); @@ -2331,7 +2349,8 @@ static void externalizeArguments(IRGenFunction &IGF, const Callee &callee, if (auto *padType = AI.getPaddingType()) out.add(llvm::UndefValue::get(padType)); - SILType paramType = silConv.getSILType(params[i - firstParam]); + SILType paramType = silConv.getSILType( + params[i - firstParam], IGF.IGM.getMaximalTypeExpansionContext()); switch (AI.getKind()) { case clang::CodeGen::ABIArgInfo::Extend: { bool signExt = clangParamTy->hasSignedIntegerRepresentation(); @@ -2412,7 +2431,8 @@ bool irgen::addNativeArgument(IRGenFunction &IGF, out.add(in.claimNext()); return false; } - auto paramType = IGF.IGM.silConv.getSILType(origParamInfo, fnTy); + auto paramType = IGF.IGM.silConv.getSILType( + origParamInfo, fnTy, IGF.IGM.getMaximalTypeExpansionContext()); auto &ti = cast(IGF.getTypeInfo(paramType)); auto schema = ti.getSchema(); auto &nativeSchema = ti.nativeParameterValueSchema(IGF.IGM); diff --git a/lib/IRGen/GenClangType.cpp b/lib/IRGen/GenClangType.cpp index 53419d7cb82c3..104f908cca0e0 100644 --- a/lib/IRGen/GenClangType.cpp +++ b/lib/IRGen/GenClangType.cpp @@ -585,8 +585,10 @@ clang::CanQualType GenClangType::visitSILFunctionType(CanSILFunctionType type) { if (allResults.empty()) { resultType = clangCtx.VoidTy; } else { - resultType = Converter.convert(IGM, - allResults[0].getReturnValueType(IGM.getSILModule(), type)); + resultType = Converter.convert( + IGM, + allResults[0].getReturnValueType(IGM.getSILModule(), type, + IGM.getMaximalTypeExpansionContext())); if (resultType.isNull()) return clang::CanQualType(); } @@ -614,8 +616,9 @@ clang::CanQualType GenClangType::visitSILFunctionType(CanSILFunctionType type) { case ParameterConvention::Indirect_In_Guaranteed: llvm_unreachable("block takes indirect parameter"); } - auto param = Converter.convert(IGM, - paramTy.getArgumentType(IGM.getSILModule(), type)); + auto param = Converter.convert( + IGM, paramTy.getArgumentType(IGM.getSILModule(), type, + IGM.getMaximalTypeExpansionContext())); if (param.isNull()) return clang::CanQualType(); @@ -791,7 +794,8 @@ clang::CanQualType IRGenModule::getClangType(SILType type) { clang::CanQualType IRGenModule::getClangType(SILParameterInfo params, CanSILFunctionType funcTy) { - auto paramTy = params.getSILStorageType(getSILModule(), funcTy); + auto paramTy = params.getSILStorageType(getSILModule(), funcTy, + getMaximalTypeExpansionContext()); auto clangType = getClangType(paramTy); // @block_storage types must be @inout_aliasable and have // special lowering diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp index 554c52e247633..cebd2a5caa886 100644 --- a/lib/IRGen/GenFunc.cpp +++ b/lib/IRGen/GenFunc.cpp @@ -616,10 +616,10 @@ static void emitApplyArgument(IRGenFunction &IGF, Explosion &in, Explosion &out) { auto silConv = IGF.IGM.silConv; - + auto context = IGF.IGM.getMaximalTypeExpansionContext(); bool isSubstituted = - (silConv.getSILType(substParam, substFnTy) - != silConv.getSILType(origParam, origFnTy)); + (silConv.getSILType(substParam, substFnTy, context) + != silConv.getSILType(origParam, origFnTy, context)); // For indirect arguments, we just need to pass a pointer. if (silConv.isSILIndirect(origParam)) { @@ -628,8 +628,8 @@ static void emitApplyArgument(IRGenFunction &IGF, // If a substitution is in play, just bitcast the address. if (isSubstituted) { - auto origType = - IGF.IGM.getStoragePointerType(silConv.getSILType(origParam, origFnTy)); + auto origType = IGF.IGM.getStoragePointerType( + silConv.getSILType(origParam, origFnTy, context)); addr = IGF.Builder.CreateBitCast(addr, origType); } @@ -645,13 +645,14 @@ static void emitApplyArgument(IRGenFunction &IGF, // Handle the last unsubstituted case. if (!isSubstituted) { auto &substArgTI = cast( - IGF.getTypeInfo(silConv.getSILType(substParam, substFnTy))); + IGF.getTypeInfo(silConv.getSILType(substParam, substFnTy, context))); substArgTI.reexplode(IGF, in, out); return; } - reemitAsUnsubstituted(IGF, silConv.getSILType(origParam, origFnTy), - silConv.getSILType(substParam, substFnTy), in, out); + reemitAsUnsubstituted(IGF, silConv.getSILType(origParam, origFnTy, context), + silConv.getSILType(substParam, substFnTy, context), in, + out); } static CanType getArgumentLoweringType(CanType type, SILParameterInfo paramInfo, @@ -689,7 +690,8 @@ static bool isABIIgnoredParameterWithoutStorage(IRGenModule &IGM, if (param.isFormalIndirect()) return false; - SILType argType = IGM.silConv.getSILType(param, substType); + SILType argType = IGM.silConv.getSILType( + param, substType, IGM.getMaximalTypeExpansionContext()); auto &ti = IGF.getTypeInfoForLowered(argType.getASTType()); // Empty values don't matter. return ti.getSchema().empty(); @@ -772,9 +774,11 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, GenericContextScope scope(IGM, origType->getInvocationGenericSignature()); SILFunctionConventions origConv(origType, IGM.getSILModule()); - auto &outResultTI = IGM.getTypeInfo(outConv.getSILResultType()); + auto &outResultTI = IGM.getTypeInfo( + outConv.getSILResultType(IGM.getMaximalTypeExpansionContext())); auto &nativeResultSchema = outResultTI.nativeReturnValueSchema(IGM); - auto &origResultTI = IGM.getTypeInfo(origConv.getSILResultType()); + auto &origResultTI = IGM.getTypeInfo( + origConv.getSILResultType(IGM.getMaximalTypeExpansionContext())); auto &origNativeSchema = origResultTI.nativeReturnValueSchema(IGM); // Forward the indirect return values. We might have to reabstract the @@ -783,34 +787,39 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, assert(origNativeSchema.requiresIndirect()); auto resultAddr = origParams.claimNext(); resultAddr = subIGF.Builder.CreateBitCast( - resultAddr, IGM.getStoragePointerType(origConv.getSILResultType())); + resultAddr, IGM.getStoragePointerType(origConv.getSILResultType( + IGM.getMaximalTypeExpansionContext()))); args.add(resultAddr); } else if (origNativeSchema.requiresIndirect()) { assert(!nativeResultSchema.requiresIndirect()); auto stackAddr = outResultTI.allocateStack( - subIGF, outConv.getSILResultType(), "return.temp"); + subIGF, + outConv.getSILResultType(IGM.getMaximalTypeExpansionContext()), + "return.temp"); resultValueAddr = stackAddr.getAddress(); auto resultAddr = subIGF.Builder.CreateBitCast( - resultValueAddr, - IGM.getStoragePointerType(origConv.getSILResultType())); + resultValueAddr, IGM.getStoragePointerType(origConv.getSILResultType( + IGM.getMaximalTypeExpansionContext()))); args.add(resultAddr.getAddress()); } - for (auto resultType : origConv.getIndirectSILResultTypes()) { + for (auto resultType : origConv.getIndirectSILResultTypes( + IGM.getMaximalTypeExpansionContext())) { auto addr = origParams.claimNext(); addr = subIGF.Builder.CreateBitCast( addr, IGM.getStoragePointerType(resultType)); args.add(addr); } - + // Reemit the parameters as unsubstituted. for (unsigned i = 0; i < outType->getParameters().size(); ++i) { auto origParamInfo = origType->getParameters()[i]; - auto &ti = IGM.getTypeInfoForLowered( - origParamInfo.getArgumentType(IGM.getSILModule(), origType)); + auto &ti = IGM.getTypeInfoForLowered(origParamInfo.getArgumentType( + IGM.getSILModule(), origType, IGM.getMaximalTypeExpansionContext())); auto schema = ti.getSchema(); - - auto origParamSILType = IGM.silConv.getSILType(origParamInfo, origType); + + auto origParamSILType = IGM.silConv.getSILType( + origParamInfo, origType, IGM.getMaximalTypeExpansionContext()); // Forward the address of indirect value params. auto &nativeSchemaOrigParam = ti.nativeParameterValueSchema(IGM); bool isIndirectParam = origConv.isSILIndirect(origParamInfo); @@ -837,7 +846,8 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, } // Map from the native calling convention into the explosion schema. - auto outTypeParamSILType = IGM.silConv.getSILType(origParamInfo, origType); + auto outTypeParamSILType = IGM.silConv.getSILType( + origParamInfo, origType, IGM.getMaximalTypeExpansionContext()); auto &nativeSchemaOutTypeParam = IGM.getTypeInfo(outTypeParamSILType).nativeParameterValueSchema(IGM); Explosion nativeParam; @@ -950,8 +960,8 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, findSinglePartiallyAppliedParameterIndexIgnoringEmptyTypes( subIGF, substType, outType); auto paramInfo = substType->getParameters()[paramI]; - auto &ti = IGM.getTypeInfoForLowered( - paramInfo.getArgumentType(IGM.getSILModule(), substType)); + auto &ti = IGM.getTypeInfoForLowered(paramInfo.getArgumentType( + IGM.getSILModule(), substType, IGM.getMaximalTypeExpansionContext())); Explosion param; auto ref = rawData; // We can get a '{ swift.refcounted* }' type for AnyObject on linux. @@ -1299,7 +1309,8 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, // Reabstract the result value as substituted. SILFunctionConventions origConv(origType, IGM.getSILModule()); - auto &outResultTI = IGM.getTypeInfo(outConv.getSILResultType()); + auto &outResultTI = IGM.getTypeInfo( + outConv.getSILResultType(IGM.getMaximalTypeExpansionContext())); auto &nativeResultSchema = outResultTI.nativeReturnValueSchema(IGM); if (call->getType()->isVoidTy()) { if (!resultValueAddr.isValid()) @@ -1312,9 +1323,12 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, cast(outResultTI) .loadAsTake(subIGF, resultValueAddr, loadedResult); Explosion nativeResult = nativeResultSchema.mapIntoNative( - IGM, subIGF, loadedResult, outConv.getSILResultType(), false); - outResultTI.deallocateStack(subIGF, resultValueAddr, - outConv.getSILResultType()); + IGM, subIGF, loadedResult, + outConv.getSILResultType(IGM.getMaximalTypeExpansionContext()), + false); + outResultTI.deallocateStack( + subIGF, resultValueAddr, + outConv.getSILResultType(IGM.getMaximalTypeExpansionContext())); if (nativeResult.size() == 1) subIGF.Builder.CreateRet(nativeResult.claimNext()); else { @@ -1331,7 +1345,8 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, llvm::Value *callResult = call; // If the result type is dependent on a type parameter we might have to // cast to the result type - it could be substituted. - if (origConv.getSILResultType().hasTypeParameter()) { + if (origConv.getSILResultType(IGM.getMaximalTypeExpansionContext()) + .hasTypeParameter()) { auto ResType = fwd->getReturnType(); if (ResType != callResult->getType()) callResult = subIGF.coerceValue(callResult, ResType, subIGF.IGM.DataLayout); @@ -1373,7 +1388,8 @@ Optional irgen::emitFunctionPartialApplication( // destructor function. bool considerParameterSources = true; for (auto param : params) { - SILType argType = IGF.IGM.silConv.getSILType(param, origType); + SILType argType = IGF.IGM.silConv.getSILType( + param, origType, IGF.IGM.getMaximalTypeExpansionContext()); auto argLoweringTy = getArgumentLoweringType(argType.getASTType(), param, outType->isNoEscape()); auto &ti = IGF.getTypeInfoForLowered(argLoweringTy); @@ -1400,7 +1416,8 @@ Optional irgen::emitFunctionPartialApplication( // Collect the type infos for the context parameters. for (auto param : params) { - SILType argType = IGF.IGM.silConv.getSILType(param, origType); + SILType argType = IGF.IGM.silConv.getSILType( + param, origType, IGF.IGM.getMaximalTypeExpansionContext()); auto argLoweringTy = getArgumentLoweringType(argType.getASTType(), param, outType->isNoEscape()); diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp index 4b6c2c08b78cd..ec583b9a54997 100644 --- a/lib/IRGen/GenObjC.cpp +++ b/lib/IRGen/GenObjC.cpp @@ -775,7 +775,8 @@ static llvm::Function *emitObjCPartialApplicationForwarder(IRGenModule &IGM, assert(origMethodType->getNumIndirectFormalResults() == 1); formalIndirectResult = params.claimNext(); } else { - SILType appliedResultTy = origMethodType->getDirectFormalResultsType(IGM.getSILModule()); + SILType appliedResultTy = origMethodType->getDirectFormalResultsType( + IGM.getSILModule(), IGM.getMaximalTypeExpansionContext()); indirectedResultTI = &cast(IGM.getTypeInfo(appliedResultTy)); auto &nativeSchema = indirectedResultTI->nativeReturnValueSchema(IGM); @@ -804,8 +805,12 @@ static llvm::Function *emitObjCPartialApplicationForwarder(IRGenModule &IGM, } // Otherwise, we have a loadable type that can either be passed directly or // indirectly. - assert(info.getSILStorageType(IGM.getSILModule(), origMethodType).isObject()); - auto curSILType = info.getSILStorageType(IGM.getSILModule(), origMethodType); + assert(info.getSILStorageType(IGM.getSILModule(), origMethodType, + IGM.getMaximalTypeExpansionContext()) + .isObject()); + auto curSILType = + info.getSILStorageType(IGM.getSILModule(), origMethodType, + IGM.getMaximalTypeExpansionContext()); auto &ti = cast(IGM.getTypeInfo(curSILType)); // Load the indirectly passed parameter. @@ -858,8 +863,8 @@ static llvm::Function *emitObjCPartialApplicationForwarder(IRGenModule &IGM, emission.emitToExplosion(result, false); cleanup(); auto &callee = emission.getCallee(); - auto resultType = - callee.getOrigFunctionType()->getDirectFormalResultsType(IGM.getSILModule()); + auto resultType = callee.getOrigFunctionType()->getDirectFormalResultsType( + IGM.getSILModule(), IGM.getMaximalTypeExpansionContext()); subIGF.emitScalarReturn(resultType, resultType, result, true /*isSwiftCCReturn*/, false); } @@ -1080,8 +1085,8 @@ static llvm::Constant *getObjCEncodingForTypes(IRGenModule &IGM, // TODO. Encode type qualifier, 'in', 'inout', etc. for the parameter. std::string paramsString; for (auto param : params) { - auto clangType = IGM.getClangType( - param.getArgumentType(IGM.getSILModule(), fnType)); + auto clangType = IGM.getClangType(param.getArgumentType( + IGM.getSILModule(), fnType, IGM.getMaximalTypeExpansionContext())); if (clangType.isNull()) return llvm::ConstantPointerNull::get(IGM.Int8PtrTy); diff --git a/lib/IRGen/GenPointerAuth.cpp b/lib/IRGen/GenPointerAuth.cpp index c345e991808b8..10edd40a0dea2 100644 --- a/lib/IRGen/GenPointerAuth.cpp +++ b/lib/IRGen/GenPointerAuth.cpp @@ -457,7 +457,8 @@ static void hashStringForList(IRGenModule &IGM, const ArrayRef &list, // Indirect params and return values have to be opaque. Out << "-indirect"; } else { - CanType Ty = paramOrRetVal.getArgumentType(IGM.getSILModule(), fnType); + CanType Ty = paramOrRetVal.getArgumentType( + IGM.getSILModule(), fnType, IGM.getMaximalTypeExpansionContext()); if (Ty->hasTypeParameter()) Ty = genericEnv->mapTypeIntoContext(Ty)->getCanonicalType(); hashStringForType(IGM, Ty, Out, genericEnv); @@ -475,7 +476,8 @@ static void hashStringForList(IRGenModule &IGM, // Indirect params and return values have to be opaque. Out << "-indirect"; } else { - CanType Ty = paramOrRetVal.getReturnValueType(IGM.getSILModule(), fnType); + CanType Ty = paramOrRetVal.getReturnValueType( + IGM.getSILModule(), fnType, IGM.getMaximalTypeExpansionContext()); if (Ty->hasTypeParameter()) Ty = genericEnv->mapTypeIntoContext(Ty)->getCanonicalType(); hashStringForType(IGM, Ty, Out, genericEnv); @@ -546,7 +548,8 @@ static uint64_t getYieldTypesHash(IRGenModule &IGM, CanSILFunctionType type) { } else if (yield.isFormalIndirect()) { out << "indirect"; } else { - CanType Ty = yield.getArgumentType(IGM.getSILModule(), type); + CanType Ty = yield.getArgumentType(IGM.getSILModule(), type, + IGM.getMaximalTypeExpansionContext()); if (Ty->hasTypeParameter()) Ty = genericEnv->mapTypeIntoContext(Ty)->getCanonicalType(); hashStringForType(IGM, Ty, out, genericEnv); diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index 97db4b0a6b3c4..27a1fbf837a4f 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -326,7 +326,8 @@ bool PolymorphicConvention::considerType(CanType type, IsExact_t isExact, } void PolymorphicConvention::considerWitnessSelf(CanSILFunctionType fnType) { - CanType selfTy = fnType->getSelfInstanceType(IGM.getSILModule()); + CanType selfTy = fnType->getSelfInstanceType( + IGM.getSILModule(), IGM.getMaximalTypeExpansionContext()); auto conformance = fnType->getWitnessMethodConformanceOrInvalid(); // First, bind type metadata for Self. @@ -351,7 +352,8 @@ void PolymorphicConvention::considerWitnessSelf(CanSILFunctionType fnType) { void PolymorphicConvention::considerObjCGenericSelf(CanSILFunctionType fnType) { // If this is a static method, get the instance type. - CanType selfTy = fnType->getSelfInstanceType(IGM.getSILModule()); + CanType selfTy = fnType->getSelfInstanceType( + IGM.getSILModule(), IGM.getMaximalTypeExpansionContext()); unsigned paramIndex = fnType->getParameters().size() - 1; // Bind type metadata for Self. @@ -368,7 +370,8 @@ void PolymorphicConvention::considerObjCGenericSelf(CanSILFunctionType fnType) { void PolymorphicConvention::considerParameter(SILParameterInfo param, unsigned paramIndex, bool isSelfParameter) { - auto type = param.getArgumentType(IGM.getSILModule(), FnType); + auto type = param.getArgumentType(IGM.getSILModule(), FnType, + IGM.getMaximalTypeExpansionContext()); switch (param.getConvention()) { // Indirect parameters do give us a value we can use, but right now // we don't bother, for no good reason. But if this is 'self', @@ -518,8 +521,8 @@ CanType EmitPolymorphicParameters::getTypeInContext(CanType type) const { } CanType EmitPolymorphicParameters::getArgTypeInContext(unsigned paramIndex) const { - return getTypeInContext(FnType->getParameters()[paramIndex] - .getArgumentType(IGM.getSILModule(), FnType)); + return getTypeInContext(FnType->getParameters()[paramIndex].getArgumentType( + IGM.getSILModule(), FnType, IGM.getMaximalTypeExpansionContext())); } void EmitPolymorphicParameters::bindExtraSource(const MetadataSource &source, @@ -548,7 +551,8 @@ void EmitPolymorphicParameters::bindExtraSource(const MetadataSource &source, assert(metadata && "no Self metadata for witness method"); // Mark this as the cached metatype for Self. - auto selfTy = FnType->getSelfInstanceType(IGM.getSILModule()); + auto selfTy = FnType->getSelfInstanceType( + IGM.getSILModule(), IGM.getMaximalTypeExpansionContext()); CanType argTy = getTypeInContext(selfTy); setTypeMetadataName(IGF.IGM, metadata, argTy); auto *CD = selfTy.getClassOrBoundGenericClass(); @@ -571,7 +575,8 @@ void EmitPolymorphicParameters::bindExtraSource(const MetadataSource &source, auto conformance = FnType->getWitnessMethodConformanceOrInvalid(); auto selfProto = conformance.getRequirement(); - auto selfTy = FnType->getSelfInstanceType(IGM.getSILModule()); + auto selfTy = FnType->getSelfInstanceType( + IGM.getSILModule(), IGM.getMaximalTypeExpansionContext()); CanType argTy = getTypeInContext(selfTy); setProtocolWitnessTableName(IGF.IGM, selfTable, argTy, selfProto); @@ -702,8 +707,8 @@ void BindPolymorphicParameter::emit(Explosion &nativeParam, unsigned paramIndex) return; assert(nativeParam.size() == 1); - auto paramType = SubstFnType->getParameters()[paramIndex] - .getArgumentType(IGM.getSILModule(), SubstFnType); + auto paramType = SubstFnType->getParameters()[paramIndex].getArgumentType( + IGM.getSILModule(), SubstFnType, IGM.getMaximalTypeExpansionContext()); llvm::Value *instanceRef = nativeParam.getAll()[0]; SILType instanceType = SILType::getPrimitiveObjectType(paramType); llvm::Value *metadata = @@ -2843,7 +2848,8 @@ static CanType getSubstSelfType(IRGenModule &IGM, assert(!origFnType->getParameters().empty()); auto selfParam = origFnType->getParameters().back(); - CanType inputType = selfParam.getArgumentType(IGM.getSILModule(), origFnType); + CanType inputType = selfParam.getArgumentType( + IGM.getSILModule(), origFnType, IGM.getMaximalTypeExpansionContext()); // If the parameter is a direct metatype parameter, this is a static method // of the instance type. We can assume this because: // - metatypes cannot directly conform to protocols diff --git a/lib/IRGen/GenThunk.cpp b/lib/IRGen/GenThunk.cpp index db4d67356ac81..b49d8f1aad8a9 100644 --- a/lib/IRGen/GenThunk.cpp +++ b/lib/IRGen/GenThunk.cpp @@ -84,8 +84,8 @@ static FunctionPointer lookupMethod(IRGenFunction &IGF, SILDeclRef declRef) { else self = (IGF.CurFn->arg_end() - 1); - auto selfTy = funcTy->getSelfParameter() - .getSILStorageType(IGF.IGM.getSILModule(), funcTy); + auto selfTy = funcTy->getSelfParameter().getSILStorageType( + IGF.IGM.getSILModule(), funcTy, IGF.IGM.getMaximalTypeExpansionContext()); llvm::Value *metadata; if (selfTy.is()) { diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index 94f0d6446a189..a921d9176a32f 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -590,13 +590,16 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { static SILType getResultTypeForDebugInfo(IRGenModule &IGM, CanSILFunctionType fnTy) { if (fnTy->getNumResults() == 1) { - return fnTy->getResults()[0].getSILStorageType(IGM.getSILModule(), fnTy); + return fnTy->getResults()[0].getSILStorageType( + IGM.getSILModule(), fnTy, IGM.getMaximalTypeExpansionContext()); } else if (!fnTy->getNumIndirectFormalResults()) { - return fnTy->getDirectFormalResultsType(IGM.getSILModule()); + return fnTy->getDirectFormalResultsType( + IGM.getSILModule(), IGM.getMaximalTypeExpansionContext()); } else { SmallVector eltTys; for (auto &result : fnTy->getResults()) { - eltTys.push_back(result.getReturnValueType(IGM.getSILModule(), fnTy)); + eltTys.push_back(result.getReturnValueType( + IGM.getSILModule(), fnTy, IGM.getMaximalTypeExpansionContext())); } return SILType::getPrimitiveAddressType( CanType(TupleType::get(eltTys, fnTy->getASTContext()))); @@ -621,7 +624,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { // type. We currently represent a function with one n-tuple argument // as an n-ary function. for (auto Param : FnTy->getParameters()) - createParameterType(Parameters, IGM.silConv.getSILType(Param, FnTy)); + createParameterType( + Parameters, IGM.silConv.getSILType( + Param, FnTy, IGM.getMaximalTypeExpansionContext())); return DBuilder.getOrCreateTypeArray(Parameters); } @@ -2164,8 +2169,10 @@ IRGenDebugInfoImpl::emitFunction(const SILDebugScope *DS, llvm::Function *Fn, if (FnTy) if (auto ErrorInfo = FnTy->getOptionalErrorResult()) { auto DTI = DebugTypeInfo::getFromTypeInfo( - ErrorInfo->getReturnValueType(IGM.getSILModule(), FnTy), - IGM.getTypeInfo(IGM.silConv.getSILType(*ErrorInfo, FnTy))); + ErrorInfo->getReturnValueType(IGM.getSILModule(), FnTy, + IGM.getMaximalTypeExpansionContext()), + IGM.getTypeInfo(IGM.silConv.getSILType( + *ErrorInfo, FnTy, IGM.getMaximalTypeExpansionContext()))); Error = DBuilder.getOrCreateArray({getOrCreateType(DTI)}).get(); } diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index aa06d47d78b0c..8611830a97e71 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -1268,8 +1268,8 @@ static ArrayRef emitEntryPointIndirectReturn( // Map an indirect return for a type SIL considers loadable but still // requires an indirect return at the IR level. SILFunctionConventions fnConv(funcTy, IGF.getSILModule()); - SILType directResultType = - IGF.CurSILFn->mapTypeIntoContext(fnConv.getSILResultType()); + SILType directResultType = IGF.CurSILFn->mapTypeIntoContext( + fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext())); if (requiresIndirectResult(directResultType)) { auto ¶mTI = IGF.IGM.getTypeInfo(directResultType); auto &retTI = @@ -1288,7 +1288,8 @@ static ArrayRef emitEntryPointIndirectReturn( // Map the indirect returns if present. unsigned numIndirectResults = fnConv.getNumIndirectSILResults(); unsigned idx = 0; - for (auto indirectResultType : fnConv.getIndirectSILResultTypes()) { + for (auto indirectResultType : fnConv.getIndirectSILResultTypes( + IGF.IGM.getMaximalTypeExpansionContext())) { SILArgument *ret = bbargs[idx]; auto inContextResultType = IGF.CurSILFn->mapTypeIntoContext(indirectResultType); @@ -1415,9 +1416,11 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, Explosion selfTemp; selfTemp.add(allParamValues.takeLast()); - bindParameter(IGF, selfParam, - conv.getSILArgumentType(conv.getNumSILArguments() - 1), - selfTemp); + bindParameter( + IGF, selfParam, + conv.getSILArgumentType(conv.getNumSILArguments() - 1, + IGF.IGM.getMaximalTypeExpansionContext()), + selfTemp); // Even if we don't have a 'self', if we have an error result, we // should have a placeholder argument here. @@ -1432,7 +1435,10 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, unsigned i = 0; for (SILArgument *param : params) { auto argIdx = conv.getSILArgIndexOfFirstParam() + i; - bindParameter(IGF, param, conv.getSILArgumentType(argIdx), allParamValues); + bindParameter(IGF, param, + conv.getSILArgumentType( + argIdx, IGF.IGM.getMaximalTypeExpansionContext()), + allParamValues); ++i; } @@ -2194,7 +2200,8 @@ emitWitnessTableForLoweredCallee(IRGenSILFunction &IGF, CanSILFunctionType substCalleeType) { // This use of getSelfInstanceType() assumes that the instance type is // always a meaningful formal type. - auto substSelfType = substCalleeType->getSelfInstanceType(IGF.IGM.getSILModule()); + auto substSelfType = substCalleeType->getSelfInstanceType( + IGF.IGM.getSILModule(), IGF.IGM.getMaximalTypeExpansionContext()); auto substConformance = substCalleeType->getWitnessMethodConformanceOrInvalid(); @@ -2221,8 +2228,9 @@ Callee LoweredValue::getCallee(IRGenFunction &IGF, // Convert a metatype 'self' argument to the ObjC class pointer. // FIXME: why on earth is this not correctly represented in SIL? if (auto metatype = dyn_cast( - calleeInfo.OrigFnType->getSelfParameter() - .getArgumentType(IGF.IGM.getSILModule(), calleeInfo.OrigFnType))) { + calleeInfo.OrigFnType->getSelfParameter().getArgumentType( + IGF.IGM.getSILModule(), calleeInfo.OrigFnType, + IGF.IGM.getMaximalTypeExpansionContext()))) { selfValue = getObjCClassForValue(IGF, selfValue, metatype); } @@ -2427,7 +2435,9 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) { // Turn the formal SIL parameters into IR-gen things. for (auto index : indices(args)) { - emitApplyArgument(*this, args[index], origConv.getSILArgumentType(index), + emitApplyArgument(*this, args[index], + origConv.getSILArgumentType( + index, IGM.getMaximalTypeExpansionContext()), llArgs); } @@ -2467,7 +2477,8 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) { // Load the error value. SILFunctionConventions substConv(substCalleeType, getSILModule()); - SILType errorType = substConv.getSILErrorType(); + SILType errorType = + substConv.getSILErrorType(IGM.getMaximalTypeExpansionContext()); Address errorSlot = getErrorResultSlot(errorType); auto errorValue = Builder.CreateLoad(errorSlot); @@ -2594,7 +2605,8 @@ void IRGenSILFunction::visitPartialApplyInst(swift::PartialApplyInst *i) { GenericContextScope scope(IGM, i->getOrigCalleeType()->getSubstGenericSignature()); for (auto index : indices(args)) { - auto paramTy = IGM.silConv.getSILType(params[index], calleeTy); + auto paramTy = IGM.silConv.getSILType( + params[index], calleeTy, IGM.getMaximalTypeExpansionContext()); assert(args[index]->getType() == paramTy); emitApplyArgument(*this, args[index], paramTy, llArgs); } @@ -2736,8 +2748,8 @@ static void emitReturnInst(IRGenSILFunction &IGF, funcLang == SILFunctionLanguage::C && "Need to handle all cases"); SILFunctionConventions conv(IGF.CurSILFn->getLoweredFunctionType(), IGF.getSILModule()); - auto funcResultType = - IGF.CurSILFn->mapTypeIntoContext(conv.getSILResultType()); + auto funcResultType = IGF.CurSILFn->mapTypeIntoContext( + conv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext())); IGF.emitScalarReturn(resultTy, funcResultType, result, swiftCCReturn, false); } @@ -2796,7 +2808,10 @@ void IRGenSILFunction::visitYieldInst(swift::YieldInst *i) { for (auto idx : indices(yieldedValues)) { SILValue value = yieldedValues[idx]; SILParameterInfo yield = yields[idx]; - emitApplyArgument(*this, value, coroConv.getSILType(yield), values); + emitApplyArgument( + *this, value, + coroConv.getSILType(yield, IGM.getMaximalTypeExpansionContext()), + values); } // Emit the yield intrinsic. @@ -3751,8 +3766,8 @@ void IRGenSILFunction::emitErrorResultVar(CanSILFunctionType FnTy, // swifterror in a register. if (IGM.IsSwiftErrorInRegister) return; - auto ErrorResultSlot = getErrorResultSlot( - IGM.silConv.getSILType(ErrorInfo, FnTy)); + auto ErrorResultSlot = getErrorResultSlot(IGM.silConv.getSILType( + ErrorInfo, FnTy, IGM.getMaximalTypeExpansionContext())); auto Var = DbgValue->getVarInfo(); assert(Var && "error result without debug info"); auto Storage = emitShadowCopyIfNeeded(ErrorResultSlot.getAddress(), @@ -3760,9 +3775,10 @@ void IRGenSILFunction::emitErrorResultVar(CanSILFunctionType FnTy, if (!IGM.DebugInfo) return; auto DbgTy = DebugTypeInfo::getErrorResult( - ErrorInfo.getReturnValueType(IGM.getSILModule(), FnTy), - ErrorResultSlot->getType(), - IGM.getPointerSize(), IGM.getPointerAlignment()); + ErrorInfo.getReturnValueType(IGM.getSILModule(), FnTy, + IGM.getMaximalTypeExpansionContext()), + ErrorResultSlot->getType(), IGM.getPointerSize(), + IGM.getPointerAlignment()); IGM.DebugInfo->emitVariableDeclaration(Builder, Storage, DbgTy, getDebugScope(), nullptr, *Var, IndirectValue, ArtificialValue); diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp index 40d4f8f99aff7..ea3fd56973801 100644 --- a/lib/IRGen/LoadableByAddress.cpp +++ b/lib/IRGen/LoadableByAddress.cpp @@ -1510,7 +1510,8 @@ void LoadableStorageAllocation::convertApplyResults() { continue; } auto resultContextTy = origSILFunctionType->substInterfaceType( - pass.F->getModule(), resultStorageType); + pass.F->getModule(), resultStorageType, + pass.F->getTypeExpansionContext()); auto newSILType = pass.getNewSILType(origSILFunctionType, resultContextTy); auto *newVal = allocateForApply(currIns, newSILType.getObjectType()); diff --git a/lib/SIL/IR/SILBuilder.cpp b/lib/SIL/IR/SILBuilder.cpp index 07ba5ff5d2b5a..37b3ce61d0d79 100644 --- a/lib/SIL/IR/SILBuilder.cpp +++ b/lib/SIL/IR/SILBuilder.cpp @@ -78,10 +78,10 @@ SILType SILBuilder::getPartialApplyResultType( results.append(FTI->getResults().begin(), FTI->getResults().end()); for (auto &result : results) { if (result.getConvention() == ResultConvention::UnownedInnerPointer) - result = SILResultInfo(result.getReturnValueType(M, FTI), + result = SILResultInfo(result.getReturnValueType(M, FTI, context), ResultConvention::Unowned); else if (result.getConvention() == ResultConvention::Autoreleased) - result = SILResultInfo(result.getReturnValueType(M, FTI), + result = SILResultInfo(result.getReturnValueType(M, FTI, context), ResultConvention::Owned); } diff --git a/lib/SIL/IR/SILFunction.cpp b/lib/SIL/IR/SILFunction.cpp index 391f4ac302311..c31d6e1fb7340 100644 --- a/lib/SIL/IR/SILFunction.cpp +++ b/lib/SIL/IR/SILFunction.cpp @@ -238,9 +238,9 @@ SILType GenericEnvironment::mapTypeIntoContext(SILModule &M, genericSig); } -bool SILFunction::isNoReturnFunction() const { +bool SILFunction::isNoReturnFunction(TypeExpansionContext context) const { return SILType::getPrimitiveObjectType(getLoweredFunctionType()) - .isNoReturnFunction(getModule()); + .isNoReturnFunction(getModule(), context); } const TypeLowering & @@ -516,7 +516,8 @@ void SILFunction::viewCFGOnly() const { bool SILFunction::hasSelfMetadataParam() const { - auto paramTypes = getConventions().getParameterSILTypes(); + auto paramTypes = + getConventions().getParameterSILTypes(TypeExpansionContext::minimal()); if (paramTypes.empty()) return false; diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 39bf2c3f9a1a7..74f05d3963192 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -42,12 +42,13 @@ using namespace swift; using namespace swift::Lowering; SILType SILFunctionType::substInterfaceType(SILModule &M, - SILType interfaceType) const { + SILType interfaceType, + TypeExpansionContext context) const { // Apply pattern substitutions first, then invocation substitutions. if (auto subs = getPatternSubstitutions()) - interfaceType = interfaceType.subst(M, subs); + interfaceType = interfaceType.subst(M, subs, context); if (auto subs = getInvocationSubstitutions()) - interfaceType = interfaceType.subst(M, subs); + interfaceType = interfaceType.subst(M, subs, context); return interfaceType; } @@ -102,33 +103,39 @@ CanSILFunctionType SILFunctionType::getUnsubstitutedType(SILModule &M) const { } CanType SILParameterInfo::getArgumentType(SILModule &M, - const SILFunctionType *t) const { + const SILFunctionType *t, + TypeExpansionContext context) const { // TODO: We should always require a function type. if (t) - return t->substInterfaceType(M, - SILType::getPrimitiveAddressType(getInterfaceType())) - .getASTType(); - + return t + ->substInterfaceType( + M, SILType::getPrimitiveAddressType(getInterfaceType()), context) + .getASTType(); + return getInterfaceType(); } CanType SILResultInfo::getReturnValueType(SILModule &M, - const SILFunctionType *t) const { + const SILFunctionType *t, + TypeExpansionContext context) const { // TODO: We should always require a function type. if (t) - return t->substInterfaceType(M, - SILType::getPrimitiveAddressType(getInterfaceType())) - .getASTType(); + return t + ->substInterfaceType( + M, SILType::getPrimitiveAddressType(getInterfaceType()), context) + .getASTType(); return getInterfaceType(); } -SILType SILFunctionType::getDirectFormalResultsType(SILModule &M) { +SILType +SILFunctionType::getDirectFormalResultsType(SILModule &M, + TypeExpansionContext context) { CanType type; if (getNumDirectFormalResults() == 0) { type = getASTContext().TheEmptyTupleType; } else if (getNumDirectFormalResults() == 1) { - type = getSingleDirectFormalResult().getReturnValueType(M, this); + type = getSingleDirectFormalResult().getReturnValueType(M, this, context); } else { auto &cache = getMutableFormalResultsCache(); if (cache) { @@ -137,7 +144,7 @@ SILType SILFunctionType::getDirectFormalResultsType(SILModule &M) { SmallVector elts; for (auto result : getResults()) if (!result.isFormalIndirect()) - elts.push_back(result.getReturnValueType(M, this)); + elts.push_back(result.getReturnValueType(M, this, context)); type = CanType(TupleType::get(elts, getASTContext())); cache = type; } @@ -166,18 +173,21 @@ SILType SILFunctionType::getAllResultsInterfaceType() { return SILType::getPrimitiveObjectType(type); } -SILType SILFunctionType::getAllResultsSubstType(SILModule &M) { - return substInterfaceType(M, getAllResultsInterfaceType()); +SILType SILFunctionType::getAllResultsSubstType(SILModule &M, + TypeExpansionContext context) { + return substInterfaceType(M, getAllResultsInterfaceType(), context); } SILType SILFunctionType::getFormalCSemanticResult(SILModule &M) { assert(getLanguage() == SILFunctionLanguage::C); assert(getNumResults() <= 1); - return getDirectFormalResultsType(M); + return getDirectFormalResultsType(M, TypeExpansionContext::minimal()); } -CanType SILFunctionType::getSelfInstanceType(SILModule &M) const { - auto selfTy = getSelfParameter().getArgumentType(M, this); +CanType +SILFunctionType::getSelfInstanceType(SILModule &M, + TypeExpansionContext context) const { + auto selfTy = getSelfParameter().getArgumentType(M, this, context); // If this is a static method, get the instance type. if (auto metaTy = dyn_cast(selfTy)) @@ -187,10 +197,11 @@ CanType SILFunctionType::getSelfInstanceType(SILModule &M) const { } ClassDecl * -SILFunctionType::getWitnessMethodClass(SILModule &M) const { +SILFunctionType::getWitnessMethodClass(SILModule &M, + TypeExpansionContext context) const { // TODO: When witnesses use substituted types, we'd get this from the // substitution map. - auto selfTy = getSelfInstanceType(M); + auto selfTy = getSelfInstanceType(M, context); auto genericSig = getSubstGenericSignature(); if (auto paramTy = dyn_cast(selfTy)) { assert(paramTy->getDepth() == 0 && paramTy->getIndex() == 0); @@ -3521,7 +3532,10 @@ class SILTypeSubstituter : auto witnessConformance = substWitnessConformance(origType); substType = substType->withPatternSpecialization(nullptr, subs, witnessConformance); - + if (typeExpansionContext.shouldLookThroughOpaqueTypeArchetypes()) { + substType = + substType->substituteOpaqueArchetypes(TC, typeExpansionContext); + } return substType; } // else fall down to component substitution @@ -3750,6 +3764,18 @@ SILType SILType::subst(SILModule &M, SubstitutionMap subs) const{ return subst(M.Types, subs); } +SILType SILType::subst(SILModule &M, SubstitutionMap subs, + TypeExpansionContext context) const { + if (!hasArchetype() && !hasTypeParameter() && + !getASTType()->hasOpaqueArchetype()) + return *this; + SILTypeSubstituter STST(M.Types, context, QuerySubstitutionMap{subs}, + LookUpConformanceInSubstitutionMap(subs), + subs.getGenericSignature().getCanonicalSignature(), + false); + return STST.subst(*this); +} + /// Apply a substitution to this polymorphic SILFunctionType so that /// it has the form of the normal SILFunctionType for the substituted /// type, except using the original conventions. @@ -4178,9 +4204,11 @@ SILFunctionType::isABICompatibleWith(CanSILFunctionType other, return ABICompatibilityCheckResult::DifferentReturnValueConventions; if (!areABICompatibleParamsOrReturns( - result1.getSILStorageType(context.getModule(), this), - result2.getSILStorageType(context.getModule(), other), - &context)) { + result1.getSILStorageType(context.getModule(), this, + context.getTypeExpansionContext()), + result2.getSILStorageType(context.getModule(), other, + context.getTypeExpansionContext()), + &context)) { return ABICompatibilityCheckResult::ABIIncompatibleReturnValues; } } @@ -4195,9 +4223,11 @@ SILFunctionType::isABICompatibleWith(CanSILFunctionType other, return ABICompatibilityCheckResult::DifferentErrorResultConventions; if (!areABICompatibleParamsOrReturns( - error1.getSILStorageType(context.getModule(), this), - error2.getSILStorageType(context.getModule(), other), - &context)) + error1.getSILStorageType(context.getModule(), this, + context.getTypeExpansionContext()), + error2.getSILStorageType(context.getModule(), other, + context.getTypeExpansionContext()), + &context)) return ABICompatibilityCheckResult::ABIIncompatibleErrorResults; } @@ -4214,9 +4244,11 @@ SILFunctionType::isABICompatibleWith(CanSILFunctionType other, if (param1.getConvention() != param2.getConvention()) return {ABICompatibilityCheckResult::DifferingParameterConvention, i}; if (!areABICompatibleParamsOrReturns( - param1.getSILStorageType(context.getModule(), this), - param2.getSILStorageType(context.getModule(), other), - &context)) + param1.getSILStorageType(context.getModule(), this, + context.getTypeExpansionContext()), + param2.getSILStorageType(context.getModule(), other, + context.getTypeExpansionContext()), + &context)) return {ABICompatibilityCheckResult::ABIIncompatibleParameterType, i}; } diff --git a/lib/SIL/IR/SILInstructions.cpp b/lib/SIL/IR/SILInstructions.cpp index 0379109e982e3..f72f53628ad8a 100644 --- a/lib/SIL/IR/SILInstructions.cpp +++ b/lib/SIL/IR/SILInstructions.cpp @@ -422,7 +422,7 @@ ApplyInst::create(SILDebugLocation Loc, SILValue Callee, SubstitutionMap Subs, ModuleConventions.hasValue() ? ModuleConventions.getValue() : SILModuleConventions(F.getModule())); - SILType Result = Conv.getSILResultType(); + SILType Result = Conv.getSILResultType(F.getTypeExpansionContext()); SmallVector TypeDependentOperands; collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, F, @@ -474,7 +474,7 @@ BeginApplyInst::create(SILDebugLocation loc, SILValue callee, SmallVector resultOwnerships; for (auto &yield : substCalleeType->getYields()) { - auto yieldType = conv.getSILType(yield); + auto yieldType = conv.getSILType(yield, F.getTypeExpansionContext()); auto convention = SILArgumentConvention(yield.getConvention()); resultTypes.push_back(yieldType); resultOwnerships.push_back( diff --git a/lib/SIL/IR/SILType.cpp b/lib/SIL/IR/SILType.cpp index cd3193096b925..48ca1e5cbc47d 100644 --- a/lib/SIL/IR/SILType.cpp +++ b/lib/SIL/IR/SILType.cpp @@ -92,9 +92,10 @@ bool SILType::isReferenceCounted(SILModule &M) const { .isReferenceCounted(); } -bool SILType::isNoReturnFunction(SILModule &M) const { +bool SILType::isNoReturnFunction(SILModule &M, + TypeExpansionContext context) const { if (auto funcTy = dyn_cast(getASTType())) - return funcTy->isNoReturnFunction(M); + return funcTy->isNoReturnFunction(M, context); return false; } @@ -425,7 +426,8 @@ SILResultInfo::getOwnershipKind(SILFunction &F, CanSILFunctionType FTy) const { auto &M = F.getModule(); - bool IsTrivial = getSILStorageType(M, FTy).isTrivial(F); + bool IsTrivial = + getSILStorageType(M, FTy, TypeExpansionContext::minimal()).isTrivial(F); switch (getConvention()) { case ResultConvention::Indirect: return SILModuleConventions(M).isSILIndirect(*this) @@ -469,10 +471,10 @@ bool SILModuleConventions::isPassedIndirectlyInSIL(SILType type, SILModule &M) { return false; } - -bool SILFunctionType::isNoReturnFunction(SILModule &M) const { +bool SILFunctionType::isNoReturnFunction(SILModule &M, + TypeExpansionContext context) const { for (unsigned i = 0, e = getNumResults(); i < e; ++i) { - if (getResults()[i].getReturnValueType(M, this)->isUninhabited()) + if (getResults()[i].getReturnValueType(M, this, context)->isUninhabited()) return true; } diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp index 9a2360080ba80..60b8274e90b08 100644 --- a/lib/SIL/IR/TypeLowering.cpp +++ b/lib/SIL/IR/TypeLowering.cpp @@ -2784,8 +2784,9 @@ checkForABIDifferencesInYield(TypeConverter &TC, SILModule &M, return TypeConverter::ABIDifference::NeedsThunk; // Also make sure that the actual yield types match in ABI. - return TC.checkForABIDifferences(M, yield1.getSILStorageType(M, fnTy1), - yield2.getSILStorageType(M, fnTy2)); + return TC.checkForABIDifferences( + M, yield1.getSILStorageType(M, fnTy1, TypeExpansionContext::minimal()), + yield2.getSILStorageType(M, fnTy2, TypeExpansionContext::minimal())); } TypeConverter::ABIDifference @@ -2833,10 +2834,13 @@ TypeConverter::checkFunctionForABIDifferences(SILModule &M, return ABIDifference::NeedsThunk; if (checkForABIDifferences(M, - result1.getSILStorageType(M, fnTy1), - result2.getSILStorageType(M, fnTy2), - /*thunk iuos*/ fnTy1->getLanguage() == SILFunctionLanguage::Swift) - != ABIDifference::CompatibleRepresentation) + result1.getSILStorageType( + M, fnTy1, TypeExpansionContext::minimal()), + result2.getSILStorageType( + M, fnTy2, TypeExpansionContext::minimal()), + /*thunk iuos*/ fnTy1->getLanguage() == + SILFunctionLanguage::Swift) != + ABIDifference::CompatibleRepresentation) return ABIDifference::NeedsThunk; } @@ -2861,11 +2865,13 @@ TypeConverter::checkFunctionForABIDifferences(SILModule &M, if (error1.getConvention() != error2.getConvention()) return ABIDifference::NeedsThunk; - if (checkForABIDifferences(M, - error1.getSILStorageType(M, fnTy1), - error2.getSILStorageType(M, fnTy2), - /*thunk iuos*/ fnTy1->getLanguage() == SILFunctionLanguage::Swift) - != ABIDifference::CompatibleRepresentation) + if (checkForABIDifferences( + M, + error1.getSILStorageType(M, fnTy1, TypeExpansionContext::minimal()), + error2.getSILStorageType(M, fnTy2, TypeExpansionContext::minimal()), + /*thunk iuos*/ fnTy1->getLanguage() == + SILFunctionLanguage::Swift) != + ABIDifference::CompatibleRepresentation) return ABIDifference::NeedsThunk; } @@ -2877,11 +2883,13 @@ TypeConverter::checkFunctionForABIDifferences(SILModule &M, // Parameters are contravariant and our relation is not symmetric, so // make sure to flip the relation around. - if (checkForABIDifferences(M, - param2.getSILStorageType(M, fnTy2), - param1.getSILStorageType(M, fnTy1), - /*thunk iuos*/ fnTy1->getLanguage() == SILFunctionLanguage::Swift) - != ABIDifference::CompatibleRepresentation) + if (checkForABIDifferences( + M, + param2.getSILStorageType(M, fnTy2, TypeExpansionContext::minimal()), + param1.getSILStorageType(M, fnTy1, TypeExpansionContext::minimal()), + /*thunk iuos*/ fnTy1->getLanguage() == + SILFunctionLanguage::Swift) != + ABIDifference::CompatibleRepresentation) return ABIDifference::NeedsThunk; } diff --git a/lib/SIL/Parser/ParseSIL.cpp b/lib/SIL/Parser/ParseSIL.cpp index 049cd14000227..4857b84e44bca 100644 --- a/lib/SIL/Parser/ParseSIL.cpp +++ b/lib/SIL/Parser/ParseSIL.cpp @@ -5399,7 +5399,8 @@ bool SILParser::parseCallInstruction(SILLocation InstLoc, unsigned ArgNo = 0; SmallVector Args; for (auto &ArgName : ArgNames) { - SILType expectedTy = substConv.getSILArgumentType(ArgNo++); + SILType expectedTy = + substConv.getSILArgumentType(ArgNo++, B.getTypeExpansionContext()); Args.push_back(getLocalValue(ArgName, expectedTy, InstLoc, B)); } @@ -5413,7 +5414,8 @@ bool SILParser::parseCallInstruction(SILLocation InstLoc, unsigned ArgNo = 0; SmallVector Args; for (auto &ArgName : ArgNames) { - SILType expectedTy = substConv.getSILArgumentType(ArgNo++); + SILType expectedTy = + substConv.getSILArgumentType(ArgNo++, B.getTypeExpansionContext()); Args.push_back(getLocalValue(ArgName, expectedTy, InstLoc, B)); } @@ -5430,7 +5432,8 @@ bool SILParser::parseCallInstruction(SILLocation InstLoc, SmallVector Args; unsigned ArgNo = substConv.getNumSILArguments() - ArgNames.size(); for (auto &ArgName : ArgNames) { - SILType expectedTy = substConv.getSILArgumentType(ArgNo++); + SILType expectedTy = + substConv.getSILArgumentType(ArgNo++, B.getTypeExpansionContext()); Args.push_back(getLocalValue(ArgName, expectedTy, InstLoc, B)); } @@ -5458,7 +5461,8 @@ bool SILParser::parseCallInstruction(SILLocation InstLoc, unsigned argNo = 0; SmallVector args; for (auto &argName : ArgNames) { - SILType expectedTy = substConv.getSILArgumentType(argNo++); + SILType expectedTy = + substConv.getSILArgumentType(argNo++, B.getTypeExpansionContext()); args.push_back(getLocalValue(argName, expectedTy, InstLoc, B)); } diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index d6942b9c8de39..a29afb42d6fae 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -285,7 +285,7 @@ void verifyKeyPathComponent(SILModule &M, auto baseParam = substGetterType->getParameters()[0]; require(baseParam.getConvention() == normalArgConvention, "getter base parameter should have normal arg convention"); - require(baseParam.getArgumentType(M, substGetterType) + require(baseParam.getArgumentType(M, substGetterType, typeExpansionContext) == loweredBaseTy.getASTType(), "getter base parameter should match base of component"); @@ -294,9 +294,11 @@ void verifyKeyPathComponent(SILModule &M, require(indicesParam.getConvention() == ParameterConvention::Direct_Unowned, "indices pointer should be trivial"); - require(indicesParam.getArgumentType(M, substGetterType)->getAnyNominal() - == C.getUnsafeRawPointerDecl(), - "indices pointer should be an UnsafeRawPointer"); + require( + indicesParam + .getArgumentType(M, substGetterType, typeExpansionContext) + ->getAnyNominal() == C.getUnsafeRawPointerDecl(), + "indices pointer should be an UnsafeRawPointer"); } require(substGetterType->getNumResults() == 1, @@ -304,10 +306,11 @@ void verifyKeyPathComponent(SILModule &M, auto result = substGetterType->getResults()[0]; require(result.getConvention() == ResultConvention::Indirect, "getter result should be @out"); - require(result.getReturnValueType(M, substGetterType) - == loweredComponentTy.getASTType(), - "getter result should match the maximal abstraction of the " - "formal component type"); + require( + result.getReturnValueType(M, substGetterType, typeExpansionContext) == + loweredComponentTy.getASTType(), + "getter result should match the maximal abstraction of the " + "formal component type"); } if (kind == KeyPathPatternComponent::Kind::SettableProperty) { @@ -349,16 +352,19 @@ void verifyKeyPathComponent(SILModule &M, require(indicesParam.getConvention() == ParameterConvention::Direct_Unowned, "indices pointer should be trivial"); - require(indicesParam.getArgumentType(M, substSetterType)->getAnyNominal() - == C.getUnsafeRawPointerDecl(), - "indices pointer should be an UnsafeRawPointer"); + require( + indicesParam + .getArgumentType(M, substSetterType, typeExpansionContext) + ->getAnyNominal() == C.getUnsafeRawPointerDecl(), + "indices pointer should be an UnsafeRawPointer"); } - require(newValueParam.getArgumentType(M, substSetterType) == - loweredComponentTy.getASTType(), + require(newValueParam.getArgumentType(M, substSetterType, + typeExpansionContext) == + loweredComponentTy.getASTType(), "setter value should match the maximal abstraction of the " "formal component type"); - + require(substSetterType->getNumResults() == 0, "setter should have no results"); } @@ -1437,9 +1443,10 @@ class SILVerifier : public SILVerifierBase { require(site.getNumArguments() == substConv.getNumSILArguments(), "apply doesn't have right number of arguments for function"); for (size_t i = 0, size = site.getNumArguments(); i < size; ++i) { - requireSameType(site.getArguments()[i]->getType(), - substConv.getSILArgumentType(i), - "operand of 'apply' doesn't match function input type"); + requireSameType( + site.getArguments()[i]->getType(), + substConv.getSILArgumentType(i, F.getTypeExpansionContext()), + "operand of 'apply' doesn't match function input type"); } } @@ -1448,7 +1455,7 @@ class SILVerifier : public SILVerifierBase { SILFunctionConventions calleeConv(AI->getSubstCalleeType(), F.getModule()); requireSameType( - AI->getType(), calleeConv.getSILResultType(), + AI->getType(), calleeConv.getSILResultType(F.getTypeExpansionContext()), "type of apply instruction doesn't match function result type"); if (AI->isNonThrowing()) { require(calleeConv.funcTy->hasErrorResult(), @@ -1482,7 +1489,7 @@ class SILVerifier : public SILVerifierBase { require(normalBB->args_size() == 1, "normal destination of try_apply must take one argument"); requireSameType((*normalBB->args_begin())->getType(), - calleeConv.getSILResultType(), + calleeConv.getSILResultType(F.getTypeExpansionContext()), "normal destination of try_apply must take argument " "of normal result type"); @@ -1492,7 +1499,7 @@ class SILVerifier : public SILVerifierBase { require(errorBB->args_size() == 1, "error destination of try_apply must take one argument"); requireSameType((*errorBB->args_begin())->getType(), - calleeConv.getSILErrorType(), + calleeConv.getSILErrorType(F.getTypeExpansionContext()), "error destination of try_apply must take argument " "of error result type"); } @@ -1507,7 +1514,8 @@ class SILVerifier : public SILVerifierBase { "length mismatch in callee yields vs. begin_apply results"); for (auto i : indices(yields)) { requireSameType( - yieldResults[i]->getType(), calleeConv.getSILType(yields[i]), + yieldResults[i]->getType(), + calleeConv.getSILType(yields[i], F.getTypeExpansionContext()), "callee yield type does not match begin_apply result type"); } @@ -1597,7 +1605,8 @@ class SILVerifier : public SILVerifierBase { for (unsigned i = 0, size = PAI->getArguments().size(); i < size; ++i) { requireSameType( PAI->getArguments()[i]->getType(), - substConv.getSILArgumentType(appliedArgStartIdx + i), + substConv.getSILArgumentType(appliedArgStartIdx + i, + F.getTypeExpansionContext()), "applied argument types do not match suffix of function type's " "inputs"); } @@ -1624,8 +1633,9 @@ class SILVerifier : public SILVerifierBase { if (expectedResult.getConvention() == ResultConvention::UnownedInnerPointer) { expectedResult = SILResultInfo( - expectedResult.getReturnValueType(F.getModule(), substTy), - ResultConvention::Unowned); + expectedResult.getReturnValueType(F.getModule(), substTy, + F.getTypeExpansionContext()), + ResultConvention::Unowned); require(originalResult == expectedResult, "result type of result function type for partially applied " "@unowned_inner_pointer function should have @unowned" @@ -1637,8 +1647,9 @@ class SILVerifier : public SILVerifierBase { } else if (expectedResult.getConvention() == ResultConvention::Autoreleased) { expectedResult = SILResultInfo( - expectedResult.getReturnValueType(F.getModule(), substTy), - ResultConvention::Owned); + expectedResult.getReturnValueType(F.getModule(), substTy, + F.getTypeExpansionContext()), + ResultConvention::Owned); require(originalResult == expectedResult, "result type of result function type for partially applied " "@autoreleased function should have @owned convention"); @@ -2066,7 +2077,8 @@ class SILVerifier : public SILVerifierBase { } require(argIdx < conv.getNumSILArguments(), "initializer or setter has too few arguments"); - SILType argTy = conv.getSILArgumentType(argIdx++); + SILType argTy = + conv.getSILArgumentType(argIdx++, F.getTypeExpansionContext()); if (ty.isAddress() && argTy.isObject()) ty = ty.getObjectType(); requireSameType(ty, argTy, "wrong argument type of initializer or setter"); @@ -2093,16 +2105,20 @@ class SILVerifier : public SILVerifierBase { case 0: require(initConv.getNumDirectSILResults() == 1, "wrong number of init function results"); - requireSameType(Dest->getType().getObjectType(), - *initConv.getDirectSILResultTypes().begin(), - "wrong init function result type"); + requireSameType( + Dest->getType().getObjectType(), + *initConv.getDirectSILResultTypes(F.getTypeExpansionContext()) + .begin(), + "wrong init function result type"); break; case 1: require(initConv.getNumDirectSILResults() == 0, "wrong number of init function results"); - requireSameType(Dest->getType(), - *initConv.getIndirectSILResultTypes().begin(), - "wrong indirect init function result type"); + requireSameType( + Dest->getType(), + *initConv.getIndirectSILResultTypes(F.getTypeExpansionContext()) + .begin(), + "wrong indirect init function result type"); break; default: require(false, "wrong number of indirect init function results"); @@ -2870,7 +2886,8 @@ class SILVerifier : public SILVerifierBase { } SILType getMethodSelfType(CanSILFunctionType ft) { - return fnConv.getSILType(ft->getParameters().back()); + return fnConv.getSILType(ft->getParameters().back(), + F.getTypeExpansionContext()); } void checkWitnessMethodInst(WitnessMethodInst *AMI) { @@ -2968,9 +2985,11 @@ class SILVerifier : public SILVerifierBase { if (fnDecl->hasDynamicSelfResult()) { auto anyObjectTy = C.getAnyObjectType(); for (auto &dynResult : dynResults) { - auto newResultTy - = dynResult.getReturnValueType(F.getModule(), methodTy) - ->replaceCovariantResultType(anyObjectTy, 0); + auto newResultTy = + dynResult + .getReturnValueType(F.getModule(), methodTy, + F.getTypeExpansionContext()) + ->replaceCovariantResultType(anyObjectTy, 0); dynResult = SILResultInfo(newResultTy->getCanonicalType(), dynResult.getConvention()); } @@ -3980,9 +3999,12 @@ class SILVerifier : public SILVerifierBase { LLVM_DEBUG(RI->print(llvm::dbgs())); SILType functionResultType = - F.getLoweredType( - F.mapTypeIntoContext(fnConv.getSILResultType()).getASTType()) - .getCategoryType(fnConv.getSILResultType().getCategory()); + F.getLoweredType(F.mapTypeIntoContext(fnConv.getSILResultType( + F.getTypeExpansionContext())) + .getASTType()) + .getCategoryType( + fnConv.getSILResultType(F.getTypeExpansionContext()) + .getCategory()); SILType instResultType = RI->getOperand()->getType(); LLVM_DEBUG(llvm::dbgs() << "function return type: "; functionResultType.dump(); @@ -3999,9 +4021,11 @@ class SILVerifier : public SILVerifierBase { "throw in function that doesn't have an error result"); SILType functionResultType = - F.getLoweredType( - F.mapTypeIntoContext(fnConv.getSILErrorType()).getASTType()) - .getCategoryType(fnConv.getSILErrorType().getCategory()); + F.getLoweredType(F.mapTypeIntoContext(fnConv.getSILErrorType( + F.getTypeExpansionContext())) + .getASTType()) + .getCategoryType(fnConv.getSILErrorType(F.getTypeExpansionContext()) + .getCategory()); SILType instResultType = TI->getOperand()->getType(); LLVM_DEBUG(llvm::dbgs() << "function error result type: "; functionResultType.dump(); @@ -4026,8 +4050,8 @@ class SILVerifier : public SILVerifierBase { require(yieldedValues.size() == yieldInfos.size(), "wrong number of yielded values for function"); for (auto i : indices(yieldedValues)) { - SILType yieldType = - F.mapTypeIntoContext(fnConv.getSILType(yieldInfos[i])); + SILType yieldType = F.mapTypeIntoContext( + fnConv.getSILType(yieldInfos[i], F.getTypeExpansionContext())); requireSameType(yieldedValues[i]->getType(), yieldType, "yielded value does not match yield type of coroutine"); } @@ -4468,7 +4492,9 @@ class SILVerifier : public SILVerifierBase { "invoke function must take block storage as @inout_aliasable " "parameter"); requireSameType( - storageParam.getArgumentType(F.getModule(), invokeTy), storageTy, + storageParam.getArgumentType(F.getModule(), invokeTy, + F.getTypeExpansionContext()), + storageTy, "invoke function must take block storage type as first parameter"); require(IBSHI->getType().isObject(), "result must be a value"); @@ -4729,16 +4755,18 @@ class SILVerifier : public SILVerifierBase { void verifyEntryBlock(SILBasicBlock *entry) { require(entry->pred_empty(), "entry block cannot have predecessors"); - LLVM_DEBUG(llvm::dbgs() << "Argument types for entry point BB:\n"; - for (auto *arg - : make_range(entry->args_begin(), entry->args_end())) - arg->getType() - .dump(); - llvm::dbgs() << "Input types for SIL function type "; - F.getLoweredFunctionType()->print(llvm::dbgs()); - llvm::dbgs() << ":\n"; - for (auto paramTy - : fnConv.getParameterSILTypes()) { paramTy.dump(); }); + LLVM_DEBUG( + llvm::dbgs() << "Argument types for entry point BB:\n"; + for (auto *arg + : make_range(entry->args_begin(), entry->args_end())) + arg->getType() + .dump(); + llvm::dbgs() << "Input types for SIL function type "; + F.getLoweredFunctionType()->print(llvm::dbgs()); llvm::dbgs() << ":\n"; + for (auto paramTy + : fnConv.getParameterSILTypes(F.getTypeExpansionContext())) { + paramTy.dump(); + }); require(entry->args_size() == (fnConv.getNumIndirectSILResults() + fnConv.getNumParameters()), @@ -4778,10 +4806,11 @@ class SILVerifier : public SILVerifierBase { for (auto result : fnConv.getIndirectSILResults()) { assert(fnConv.isSILIndirect(result)); - check("indirect result", fnConv.getSILType(result)); + check("indirect result", + fnConv.getSILType(result, F.getTypeExpansionContext())); } for (auto param : F.getLoweredFunctionType()->getParameters()) { - check("parameter", fnConv.getSILType(param)); + check("parameter", fnConv.getSILType(param, F.getTypeExpansionContext())); } require(matched, "entry point argument types do not match function type"); diff --git a/lib/SILGen/ResultPlan.cpp b/lib/SILGen/ResultPlan.cpp index f53fc3f4152d9..d22b3be26efad 100644 --- a/lib/SILGen/ResultPlan.cpp +++ b/lib/SILGen/ResultPlan.cpp @@ -473,7 +473,8 @@ class ForeignErrorInitializationPlan final : public ResultPlan { substFnType->getParameters()[errorParamIndex]; // We assume that there's no interesting reabstraction here beyond a layer // of optional. - errorPtrType = errorParameter.getArgumentType(SGF.SGM.M, substFnType); + errorPtrType = errorParameter.getArgumentType( + SGF.SGM.M, substFnType, SGF.getTypeExpansionContext()); unwrappedPtrType = errorPtrType; Type unwrapped = errorPtrType->getOptionalObjectType(); isOptional = (bool) unwrapped; @@ -572,8 +573,10 @@ ResultPlanPtr ResultPlanBuilder::buildTopLevelResult(Initialization *init, case ForeignErrorConvention::NilResult: { assert(allResults.size() == 1); auto substFnTy = calleeTypeInfo.substFnType; - CanType objectType = allResults[0].getReturnValueType(SGF.SGM.M, substFnTy) - .getOptionalObjectType(); + CanType objectType = allResults[0] + .getReturnValueType(SGF.SGM.M, substFnTy, + SGF.getTypeExpansionContext()) + .getOptionalObjectType(); SILResultInfo optResult = allResults[0].getWithInterfaceType(objectType); allResults.clear(); allResults.push_back(optResult); @@ -608,8 +611,9 @@ ResultPlanPtr ResultPlanBuilder::build(Initialization *init, if (init && init->canPerformInPlaceInitialization() && SGF.silConv.isSILIndirect(result) && !SGF.getLoweredType(substType).getAddressType().hasAbstractionDifference( - calleeTypeInfo.getOverrideRep(), - result.getSILStorageType(SGF.SGM.M, calleeTy))) { + calleeTypeInfo.getOverrideRep(), + result.getSILStorageType(SGF.SGM.M, calleeTy, + SGF.getTypeExpansionContext()))) { return ResultPlanPtr(new InPlaceInitializationResultPlan(init)); } @@ -624,8 +628,11 @@ ResultPlanPtr ResultPlanBuilder::build(Initialization *init, // then we need to evaluate the arguments first in order to have access to // the opened Self type. A special result plan defers allocating the stack // slot to the point the call is emitted. - if (result.getReturnValueType(SGF.SGM.M, calleeTy)->hasOpenedExistential() - && SGF.silConv.isSILIndirect(result)) { + if (result + .getReturnValueType(SGF.SGM.M, calleeTy, + SGF.getTypeExpansionContext()) + ->hasOpenedExistential() && + SGF.silConv.isSILIndirect(result)) { return ResultPlanPtr( new IndirectOpenedSelfResultPlan(SGF, origType, substType)); } @@ -633,8 +640,8 @@ ResultPlanPtr ResultPlanBuilder::build(Initialization *init, // Create a temporary if the result is indirect. std::unique_ptr temporary; if (SGF.silConv.isSILIndirect(result)) { - auto &resultTL = SGF.getTypeLowering( - result.getReturnValueType(SGF.SGM.M, calleeTy)); + auto &resultTL = SGF.getTypeLowering(result.getReturnValueType( + SGF.SGM.M, calleeTy, SGF.getTypeExpansionContext())); temporary = SGF.emitTemporary(loc, resultTL); } diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp index 5004872a1192b..9e47438e3d134 100644 --- a/lib/SILGen/SILGen.cpp +++ b/lib/SILGen/SILGen.cpp @@ -118,18 +118,20 @@ getBridgingFn(Optional &cacheSlot, return SGM.Types.getLoweredType(ty, TypeExpansionContext::minimal()); }; - if (fnConv.hasIndirectSILResults() - || funcTy->getNumParameters() != inputTypes.size() - || !std::equal( - fnConv.getParameterSILTypes().begin(), - fnConv.getParameterSILTypes().end(), - makeTransformIterator(inputTypes.begin(), toSILType))) { + if (fnConv.hasIndirectSILResults() || + funcTy->getNumParameters() != inputTypes.size() || + !std::equal( + fnConv.getParameterSILTypes(TypeExpansionContext::minimal()) + .begin(), + fnConv.getParameterSILTypes(TypeExpansionContext::minimal()).end(), + makeTransformIterator(inputTypes.begin(), toSILType))) { SGM.diagnose(fd->getLoc(), diag::bridging_function_not_correct_type, moduleName.str(), functionName); llvm::report_fatal_error("unable to set up the ObjC bridge!"); } - if (fnConv.getSingleSILResultType() != toSILType(outputType)) { + if (fnConv.getSingleSILResultType(TypeExpansionContext::minimal()) != + toSILType(outputType)) { SGM.diagnose(fd->getLoc(), diag::bridging_function_not_correct_type, moduleName.str(), functionName); llvm::report_fatal_error("unable to set up the ObjC bridge!"); @@ -1680,8 +1682,10 @@ class SourceFileScope { auto prologueLoc = RegularLocation::getModuleLocation(); prologueLoc.markAsPrologue(); auto entry = sgm.TopLevelSGF->B.getInsertionBB(); - auto paramTypeIter = - sgm.TopLevelSGF->F.getConventions().getParameterSILTypes().begin(); + auto context = sgm.TopLevelSGF->getTypeExpansionContext(); + auto paramTypeIter = sgm.TopLevelSGF->F.getConventions() + .getParameterSILTypes(context) + .begin(); entry->createFunctionArgument(*paramTypeIter); entry->createFunctionArgument(*std::next(paramTypeIter)); @@ -1704,7 +1708,8 @@ class SourceFileScope { auto returnLoc = returnInfo.second; returnLoc.markAutoGenerated(); - SILType returnType = SGF.F.getConventions().getSingleSILResultType(); + SILType returnType = SGF.F.getConventions().getSingleSILResultType( + SGF.getTypeExpansionContext()); auto emitTopLevelReturnValue = [&](unsigned value) -> SILValue { // Create an integer literal for the value. auto litType = SILType::getBuiltinIntegerType(32, sgm.getASTContext()); @@ -1795,7 +1800,9 @@ class SourceFileScope { SILGenFunction SGF(sgm, *toplevel, sf); auto entry = SGF.B.getInsertionBB(); auto paramTypeIter = - SGF.F.getConventions().getParameterSILTypes().begin(); + SGF.F.getConventions() + .getParameterSILTypes(SGF.getTypeExpansionContext()) + .begin(); entry->createFunctionArgument(*paramTypeIter); entry->createFunctionArgument(*std::next(paramTypeIter)); SGF.emitArtificialTopLevel(mainDecl); diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index 9d4307623df06..172447aba7727 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -1722,7 +1722,8 @@ static void emitRawApply(SILGenFunction &SGF, #ifndef NDEBUG assert(indirectResultAddrs.size() == substFnConv.getNumIndirectSILResults()); unsigned resultIdx = 0; - for (auto indResultTy : substFnConv.getIndirectSILResultTypes()) { + for (auto indResultTy : + substFnConv.getIndirectSILResultTypes(SGF.getTypeExpansionContext())) { assert(indResultTy == indirectResultAddrs[resultIdx++]->getType()); } #endif @@ -1736,7 +1737,8 @@ static void emitRawApply(SILGenFunction &SGF, auto argValue = (inputParams[i].isConsumed() ? args[i].forward(SGF) : args[i].getValue()); #ifndef NDEBUG - auto inputTy = substFnConv.getSILType(inputParams[i]); + auto inputTy = + substFnConv.getSILType(inputParams[i], SGF.getTypeExpansionContext()); if (argValue->getType() != inputTy) { auto &out = llvm::errs(); out << "TYPE MISMATCH IN ARGUMENT " << i << " OF APPLY AT "; @@ -1752,7 +1754,7 @@ static void emitRawApply(SILGenFunction &SGF, argValues.push_back(argValue); } - auto resultType = substFnConv.getSILResultType(); + auto resultType = substFnConv.getSILResultType(SGF.getTypeExpansionContext()); // If the function is a coroutine, we need to use 'begin_apply'. if (substFnType->isCoroutine()) { @@ -3337,11 +3339,12 @@ struct ParamLowering { unsigned ClaimedForeignSelf = -1; SILFunctionTypeRepresentation Rep; SILFunctionConventions fnConv; + TypeExpansionContext typeExpansionContext; ParamLowering(CanSILFunctionType fnType, SILGenFunction &SGF) : Params(fnType->getUnsubstitutedType(SGF.SGM.M)->getParameters()), - Rep(fnType->getRepresentation()), - fnConv(fnType, SGF.SGM.M) {} + Rep(fnType->getRepresentation()), fnConv(fnType, SGF.SGM.M), + typeExpansionContext(SGF.getTypeExpansionContext()) {} ClaimedParamsRef claimParams(AbstractionPattern origFormalType, @@ -3399,8 +3402,8 @@ struct ParamLowering { #ifndef NDEBUG assert(Params.size() >= captures.size() && "more captures than params?!"); for (unsigned i = 0; i < captures.size(); ++i) { - assert(fnConv.getSILType(Params[i + firstCapture]) == - captures[i].getType() && + assert(fnConv.getSILType(Params[i + firstCapture], + typeExpansionContext) == captures[i].getType() && "capture doesn't match param type"); } #endif @@ -3932,9 +3935,10 @@ CallEmission::applySpecializedEmitter(SpecializedEmitter &specializedEmitter, rawArgs.push_back(maybePlusOne.forward(SGF)); } - SILValue rawResult = - SGF.B.createBuiltin(loc, builtinName, substConv.getSILResultType(), - callee.getSubstitutions(), rawArgs); + SILValue rawResult = SGF.B.createBuiltin( + loc, builtinName, + substConv.getSILResultType(SGF.getTypeExpansionContext()), + callee.getSubstitutions(), rawArgs); if (argScope.hasValue()) std::move(argScope)->pop(); @@ -4213,7 +4217,7 @@ RValue SILGenFunction::emitApply(ResultPlanPtr &&resultPlan, // Pop the argument scope. argScope.pop(); - if (substFnType->isNoReturnFunction(SGM.M)) + if (substFnType->isNoReturnFunction(SGM.M, getTypeExpansionContext())) loc.markAutoGenerated(); // Explode the direct results. @@ -4221,8 +4225,8 @@ RValue SILGenFunction::emitApply(ResultPlanPtr &&resultPlan, SmallVector directResults; auto addManagedDirectResult = [&](SILValue result, const SILResultInfo &resultInfo) { - auto &resultTL = - getTypeLowering(resultInfo.getReturnValueType(SGM.M, substFnType)); + auto &resultTL = getTypeLowering(resultInfo.getReturnValueType( + SGM.M, substFnType, getTypeExpansionContext())); switch (resultInfo.getConvention()) { case ResultConvention::Indirect: @@ -4320,7 +4324,7 @@ SILValue SILGenFunction::emitApplyWithRethrow(SILLocation loc, SILValue fn, ArrayRef args) { CanSILFunctionType silFnType = substFnType.castTo(); SILFunctionConventions fnConv(silFnType, SGM.M); - SILType resultType = fnConv.getSILResultType(); + SILType resultType = fnConv.getSILResultType(getTypeExpansionContext()); if (!silFnType->hasErrorResult()) { return B.createApply(loc, fn, subs, args); @@ -4333,8 +4337,9 @@ SILValue SILGenFunction::emitApplyWithRethrow(SILLocation loc, SILValue fn, // Emit the rethrow logic. { B.emitBlock(errorBB); - SILValue error = errorBB->createPhiArgument(fnConv.getSILErrorType(), - ValueOwnershipKind::Owned); + SILValue error = errorBB->createPhiArgument( + fnConv.getSILErrorType(getTypeExpansionContext()), + ValueOwnershipKind::Owned); Cleanups.emitCleanupsForReturn(CleanupLocation::get(loc), IsForUnwind); B.createThrow(loc, error); @@ -4390,11 +4395,11 @@ void SILGenFunction::emitYield(SILLocation loc, ->getUnsubstitutedType(SGM.M); SmallVector substYieldTys; for (auto origYield : fnType->getYields()) { - substYieldTys.push_back({ - F.mapTypeIntoContext(origYield.getArgumentType(SGM.M, fnType)) - ->getCanonicalType(), - origYield.getConvention() - }); + substYieldTys.push_back( + {F.mapTypeIntoContext(origYield.getArgumentType( + SGM.M, fnType, getTypeExpansionContext())) + ->getCanonicalType(), + origYield.getConvention()}); } ArgEmitter emitter(*this, fnType->getRepresentation(), /*yield*/ true, @@ -4645,8 +4650,8 @@ RValue SILGenFunction::emitApplyAllocatingInitializer(SILLocation loc, // Determine the self metatype type. CanSILFunctionType substFnType = initConstant.SILFnType->substGenericArgs( SGM.M, subs, getTypeExpansionContext()); - SILType selfParamMetaTy = getSILType(substFnType->getSelfParameter(), - substFnType); + SILType selfParamMetaTy = + getSILType(substFnType->getSelfParameter(), substFnType); if (overriddenSelfType) { // If the 'self' type has been overridden, form a metatype to the @@ -4747,8 +4752,8 @@ RValue SILGenFunction::emitApplyMethod(SILLocation loc, ConcreteDeclRef declRef, CanSILFunctionType substFnType = declRefConstant.SILFnType->substGenericArgs(SGM.M, subs, getTypeExpansionContext()); - SILType selfParamMetaTy = getSILType(substFnType->getSelfParameter(), - substFnType); + SILType selfParamMetaTy = + getSILType(substFnType->getSelfParameter(), substFnType); selfMetaTy = selfParamMetaTy; } diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp index 2430f1df4b3d7..e5214379747f9 100644 --- a/lib/SILGen/SILGenBridging.cpp +++ b/lib/SILGen/SILGenBridging.cpp @@ -220,9 +220,9 @@ emitBridgeObjectiveCToNative(SILGenFunction &SGF, assert(isa(metatypeParam.getInterfaceType()) && cast(metatypeParam.getInterfaceType()).getInstanceType() == swiftValueType); - SILValue metatypeValue = - SGF.B.createMetatype(loc, - metatypeParam.getSILStorageType(SGF.SGM.M, witnessFnTy)); + SILValue metatypeValue = SGF.B.createMetatype( + loc, metatypeParam.getSILStorageType(SGF.SGM.M, witnessFnTy, + SGF.getTypeExpansionContext())); auto witnessCI = SGF.getConstantInfo(SGF.getTypeExpansionContext(), witnessConstant); @@ -371,7 +371,8 @@ static void buildFuncToBlockInvokeBody(SILGenFunction &SGF, formalBlockType = getBridgedBlockType(SGF.SGM, formalBlockType); // Set up the indirect result. - SILType blockResultTy = blockTy->getAllResultsSubstType(SGF.SGM.M); + SILType blockResultTy = + blockTy->getAllResultsSubstType(SGF.SGM.M, SGF.getTypeExpansionContext()); SILValue indirectResult; if (blockTy->getNumResults() != 0) { auto result = blockTy->getSingleResult(); @@ -399,7 +400,8 @@ static void buildFuncToBlockInvokeBody(SILGenFunction &SGF, SmallVector args; for (unsigned i : indices(funcTy->getParameters())) { auto ¶m = blockTy->getParameters()[i]; - SILType paramTy = blockConv.getSILType(param); + SILType paramTy = + blockConv.getSILType(param, SGF.getTypeExpansionContext()); SILValue v = entry->createFunctionArgument(paramTy); ManagedValue mv; @@ -433,9 +435,9 @@ static void buildFuncToBlockInvokeBody(SILGenFunction &SGF, CanType formalBridgedType = bridgedParamTypes[i]; CanType formalNativeType = nativeParamTypes[i]; - SILType loweredNativeTy = - funcTy->getParameters()[i].getSILStorageType(SGF.SGM.M, funcTy); - + SILType loweredNativeTy = funcTy->getParameters()[i].getSILStorageType( + SGF.SGM.M, funcTy, SGF.getTypeExpansionContext()); + args.push_back(SGF.emitBridgedToNativeValue(loc, mv, formalBridgedType, formalNativeType, loweredNativeTy)); @@ -835,7 +837,8 @@ static void buildBlockToFuncThunkBody(SILGenFunction &SGF, if (funcTy->getNumResults() != 0) { auto result = funcTy->getSingleResult(); if (result.getConvention() == ResultConvention::Indirect) { - SILType resultTy = fnConv.getSILType(result); + SILType resultTy = + fnConv.getSILType(result, SGF.getTypeExpansionContext()); indirectResult = entry->createFunctionArgument(resultTy); } } @@ -851,14 +854,14 @@ static void buildBlockToFuncThunkBody(SILGenFunction &SGF, CanType formalBlockParamTy = formalBlockParams[i]; CanType formalFuncParamTy = formalFuncParams[i]; - auto paramTy = fnConv.getSILType(param); + auto paramTy = fnConv.getSILType(param, SGF.getTypeExpansionContext()); SILValue v = entry->createFunctionArgument(paramTy); // First get the managed parameter for this function. auto mv = emitManagedParameter(SGF, loc, param, v); - SILType loweredBlockArgTy = blockTy->getParameters()[i] - .getSILStorageType(SGF.SGM.M, blockTy); + SILType loweredBlockArgTy = blockTy->getParameters()[i].getSILStorageType( + SGF.SGM.M, blockTy, SGF.getTypeExpansionContext()); // Then bridge the native value to its bridged variant. mv = SGF.emitNativeToBridgedValue(loc, mv, formalFuncParamTy, @@ -904,7 +907,9 @@ static void buildBlockToFuncThunkBody(SILGenFunction &SGF, init->finishInitialization(SGF); } init->getManagedAddress().forward(SGF); - r = SGF.B.createTuple(loc, fnConv.getSILResultType(), ArrayRef()); + r = SGF.B.createTuple( + loc, fnConv.getSILResultType(SGF.getTypeExpansionContext()), + ArrayRef()); // Otherwise, return the result at +1. } else { @@ -1376,14 +1381,12 @@ static SILFunctionType *emitObjCThunkArguments(SILGenFunction &SGF, for (unsigned i = 0, size = bridgedArgs.size(); i < size; ++i) { // Consider the bridged values to be "call results" since they're coming // from potentially nil-unsound ObjC callers. - ManagedValue native = - SGF.emitBridgedToNativeValue(loc, - bridgedArgs[i], - bridgedFormalTypes[i], - nativeFormalTypes[i], - swiftFnTy->getParameters()[i].getSILStorageType(SGF.SGM.M, swiftFnTy), - SGFContext(), - /*isCallResult*/ true); + ManagedValue native = SGF.emitBridgedToNativeValue( + loc, bridgedArgs[i], bridgedFormalTypes[i], nativeFormalTypes[i], + swiftFnTy->getParameters()[i].getSILStorageType( + SGF.SGM.M, swiftFnTy, SGF.getTypeExpansionContext()), + SGFContext(), + /*isCallResult*/ true); SILValue argValue; // This can happen if the value is resilient in the calling convention @@ -1445,8 +1448,8 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) { SmallVector args; if (substConv.hasIndirectSILResults()) { - args.push_back( - emitTemporaryAllocation(loc, substConv.getSingleSILResultType())); + args.push_back(emitTemporaryAllocation( + loc, substConv.getSingleSILResultType(getTypeExpansionContext()))); } // If the '@objc' was inferred due to deprecated rules, @@ -1521,8 +1524,9 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) { SILFunctionConventions objcConv(CanSILFunctionType(objcFnTy), SGM.M); SILFunctionConventions nativeConv(CanSILFunctionType(nativeInfo.SILFnType), SGM.M); - auto swiftResultTy = F.mapTypeIntoContext(nativeConv.getSILResultType()); - auto objcResultTy = objcConv.getSILResultType(); + auto swiftResultTy = F.mapTypeIntoContext( + nativeConv.getSILResultType(getTypeExpansionContext())); + auto objcResultTy = objcConv.getSILResultType(getTypeExpansionContext()); // Call the native entry point. SILValue nativeFn = emitGlobalFunctionRef(loc, native, nativeInfo); @@ -1578,7 +1582,8 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) { { B.emitBlock(errorBB); SILValue nativeError = errorBB->createPhiArgument( - substConv.getSILErrorType(), ValueOwnershipKind::Owned); + substConv.getSILErrorType(getTypeExpansionContext()), + ValueOwnershipKind::Owned); // In this branch, the eventual return value is mostly invented. // Store the native error in the appropriate location and return. @@ -1657,8 +1662,8 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) { if (nativeConv.hasIndirectSILResults()) { assert(nativeConv.getNumIndirectSILResults() == 1 && "bridged exploded result?!"); - indirectResult = - F.begin()->createFunctionArgument(nativeConv.getSingleSILResultType()); + indirectResult = F.begin()->createFunctionArgument( + nativeConv.getSingleSILResultType(F.getTypeExpansionContext())); } // Forward the arguments. @@ -1775,8 +1780,8 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) { auto foreignParam = foreignFnTy->getParameters()[foreignArgIndex++]; SILType foreignLoweredTy = - F.mapTypeIntoContext( - foreignParam.getSILStorageType(F.getModule(), foreignFnTy)); + F.mapTypeIntoContext(foreignParam.getSILStorageType( + F.getModule(), foreignFnTy, F.getTypeExpansionContext())); auto bridged = emitNativeToBridgedValue(fd, param, nativeFormalType, foreignFormalType, diff --git a/lib/SILGen/SILGenEpilog.cpp b/lib/SILGen/SILGenEpilog.cpp index b17d1e7f0b0ff..f42c9780732eb 100644 --- a/lib/SILGen/SILGenEpilog.cpp +++ b/lib/SILGen/SILGenEpilog.cpp @@ -29,8 +29,8 @@ void SILGenFunction::prepareEpilog(bool hasDirectResults, bool isThrowing, // emits unreachable if there is no source level return. NeedsReturn = (fnConv.funcTy->getNumResults() != 0); for (auto directResult : fnConv.getDirectSILResults()) { - SILType resultType = F.getLoweredType( - F.mapTypeIntoContext(fnConv.getSILType(directResult))); + SILType resultType = F.getLoweredType(F.mapTypeIntoContext( + fnConv.getSILType(directResult, getTypeExpansionContext()))); epilogBB->createPhiArgument(resultType, ValueOwnershipKind::Owned); } } diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index dbfb32a679b32..d04d6aa71cdfa 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -2772,9 +2772,9 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM, auto entry = thunk->begin(); auto resultArgTy = signature->getSingleResult().getSILStorageType( - SGM.M, signature); + SGM.M, signature, subSGF.F.getTypeExpansionContext()); auto baseArgTy = signature->getParameters()[0].getSILStorageType( - SGM.M, signature); + SGM.M, signature, subSGF.F.getTypeExpansionContext()); if (genericEnv) { resultArgTy = genericEnv->mapTypeIntoContext(SGM.M, resultArgTy); baseArgTy = genericEnv->mapTypeIntoContext(SGM.M, baseArgTy); @@ -2784,7 +2784,7 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM, SILValue indexPtrArg; if (!indexes.empty()) { auto indexArgTy = signature->getParameters()[1].getSILStorageType( - SGM.M, signature); + SGM.M, signature, subSGF.F.getTypeExpansionContext()); indexPtrArg = entry->createFunctionArgument(indexArgTy); } @@ -2922,9 +2922,9 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM, auto entry = thunk->begin(); auto valueArgTy = signature->getParameters()[0].getSILStorageType( - SGM.M, signature); + SGM.M, signature, subSGF.getTypeExpansionContext()); auto baseArgTy = signature->getParameters()[1].getSILStorageType( - SGM.M, signature); + SGM.M, signature, subSGF.getTypeExpansionContext()); if (genericEnv) { valueArgTy = genericEnv->mapTypeIntoContext(SGM.M, valueArgTy); baseArgTy = genericEnv->mapTypeIntoContext(SGM.M, baseArgTy); @@ -2935,7 +2935,7 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM, if (!indexes.empty()) { auto indexArgTy = signature->getParameters()[2].getSILStorageType( - SGM.M, signature); + SGM.M, signature, subSGF.getTypeExpansionContext()); indexPtrArg = entry->createFunctionArgument(indexArgTy); } @@ -3089,10 +3089,10 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, SILGenFunction subSGF(SGM, *equals, SGM.SwiftModule); equals->setGenericEnvironment(genericEnv); auto entry = equals->begin(); - auto lhsPtr = - entry->createFunctionArgument(params[0].getSILStorageType(SGM.M, signature)); - auto rhsPtr = - entry->createFunctionArgument(params[1].getSILStorageType(SGM.M, signature)); + auto lhsPtr = entry->createFunctionArgument(params[0].getSILStorageType( + SGM.M, signature, subSGF.getTypeExpansionContext())); + auto rhsPtr = entry->createFunctionArgument(params[1].getSILStorageType( + SGM.M, signature, subSGF.getTypeExpansionContext())); Scope scope(subSGF, loc); @@ -3264,8 +3264,8 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, SILGenFunction subSGF(SGM, *hash, SGM.SwiftModule); hash->setGenericEnvironment(genericEnv); auto entry = hash->begin(); - auto indexPtr = entry->createFunctionArgument( - params[0].getSILStorageType(SGM.M, signature)); + auto indexPtr = entry->createFunctionArgument(params[0].getSILStorageType( + SGM.M, signature, subSGF.getTypeExpansionContext())); SILValue hashCode; diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp index 247242b1ddc59..2974e7a8f0f3e 100644 --- a/lib/SILGen/SILGenFunction.cpp +++ b/lib/SILGen/SILGenFunction.cpp @@ -627,15 +627,17 @@ void SILGenFunction::emitArtificialTopLevel(Decl *mainDecl) { ManagedValue optName = emitManagedRValueWithCleanup(optNameValue); // Fix up the string parameters to have the right type. - SILType nameArgTy = fnConv.getSILArgumentType(3); - assert(nameArgTy == fnConv.getSILArgumentType(2)); + SILType nameArgTy = + fnConv.getSILArgumentType(3, B.getTypeExpansionContext()); + assert(nameArgTy == + fnConv.getSILArgumentType(2, B.getTypeExpansionContext())); (void)nameArgTy; assert(optName.getType() == nameArgTy); SILValue nilValue = getOptionalNoneValue(mainClass, getTypeLowering(OptNSStringTy)); // Fix up argv to have the right type. - auto argvTy = fnConv.getSILArgumentType(1); + auto argvTy = fnConv.getSILArgumentType(1, B.getTypeExpansionContext()); SILType unwrappedTy = argvTy; if (Type innerTy = argvTy.getASTType()->getOptionalObjectType()) { @@ -666,7 +668,8 @@ void SILGenFunction::emitArtificialTopLevel(Decl *mainDecl) { B.createApply(mainClass, UIApplicationMain, SubstitutionMap(), args); SILValue r = B.createIntegerLiteral(mainClass, SILType::getBuiltinIntegerType(32, ctx), 0); - auto rType = F.getConventions().getSingleSILResultType(); + auto rType = + F.getConventions().getSingleSILResultType(B.getTypeExpansionContext()); if (r->getType() != rType) r = B.createStruct(mainClass, rType, r); @@ -714,7 +717,8 @@ void SILGenFunction::emitArtificialTopLevel(Decl *mainDecl) { B.createApply(mainClass, NSApplicationMain, SubstitutionMap(), args); SILValue r = B.createIntegerLiteral(mainClass, SILType::getBuiltinIntegerType(32, getASTContext()), 0); - auto rType = F.getConventions().getSingleSILResultType(); + auto rType = + F.getConventions().getSingleSILResultType(B.getTypeExpansionContext()); if (r->getType() != rType) r = B.createStruct(mainClass, rType, r); B.createReturn(mainClass, r); @@ -751,7 +755,7 @@ void SILGenFunction::emitArtificialTopLevel(Decl *mainDecl) { B.setInsertionPoint(exitBlock); SILValue exitCode = exitBlock->createPhiArgument(builtinInt32Type, ValueOwnershipKind::None); - auto returnType = F.getConventions().getSingleSILResultType(); + auto returnType = F.getConventions().getSingleSILResultType(B.getTypeExpansionContext()); if (exitCode->getType() != returnType) exitCode = B.createStruct(moduleLoc, returnType, exitCode); B.createReturn(moduleLoc, exitCode); diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h index 5474bc87dd62b..305a2a12086d2 100644 --- a/lib/SILGen/SILGenFunction.h +++ b/lib/SILGen/SILGenFunction.h @@ -490,12 +490,13 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction } SILFunction &getFunction() { return F; } + const SILFunction &getFunction() const { return F; } SILModule &getModule() { return F.getModule(); } SILGenBuilder &getBuilder() { return B; } const SILOptions &getOptions() { return getModule().getOptions(); } // Returns the type expansion context for types in this function. - TypeExpansionContext getTypeExpansionContext() { + TypeExpansionContext getTypeExpansionContext() const { return TypeExpansionContext(getFunction()); } @@ -531,17 +532,19 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction } SILType getSILInterfaceType(SILParameterInfo param) const { - return silConv.getSILType(param, CanSILFunctionType()); + return silConv.getSILType(param, CanSILFunctionType(), + getTypeExpansionContext()); } SILType getSILInterfaceType(SILResultInfo result) const { - return silConv.getSILType(result, CanSILFunctionType()); + return silConv.getSILType(result, CanSILFunctionType(), + getTypeExpansionContext()); } SILType getSILType(SILParameterInfo param, CanSILFunctionType fnTy) const { - return silConv.getSILType(param, fnTy); + return silConv.getSILType(param, fnTy, getTypeExpansionContext()); } SILType getSILType(SILResultInfo result, CanSILFunctionType fnTy) const { - return silConv.getSILType(result, fnTy); + return silConv.getSILType(result, fnTy, getTypeExpansionContext()); } SILType getSILTypeInContext(SILResultInfo result, CanSILFunctionType fnTy) { diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp index 8cd45ba46bed8..dd71c1f7a8d0d 100644 --- a/lib/SILGen/SILGenLValue.cpp +++ b/lib/SILGen/SILGenLValue.cpp @@ -1492,7 +1492,8 @@ namespace { // nonmutating setter, for example. if (base.getType().isAddress() && base.getType().getObjectType() == - setterConv.getSILArgumentType(argIdx)) { + setterConv.getSILArgumentType(argIdx, + SGF.getTypeExpansionContext())) { capturedBase = SGF.B.createTrivialLoadOr( loc, capturedBase, LoadOwnershipQualifier::Take); } @@ -1517,8 +1518,9 @@ namespace { SILType::getPrimitiveAddressType(loweredSubstArgType.getASTType()); } auto loweredSubstParamTy = SILType::getPrimitiveType( - param.getArgumentType(SGF.SGM.M, substSetterTy), - loweredSubstArgType.getCategory()); + param.getArgumentType(SGF.SGM.M, substSetterTy, + SGF.getTypeExpansionContext()), + loweredSubstArgType.getCategory()); // Handle reabstraction differences. if (Mval.getType() != loweredSubstParamTy) { Mval = SGF.emitSubstToOrigValue(loc, Mval, diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp index 41c87507021a9..6e7a8f353897f 100644 --- a/lib/SILGen/SILGenPoly.cpp +++ b/lib/SILGen/SILGenPoly.cpp @@ -804,7 +804,8 @@ void SILGenFunction::collectThunkParams( SILLocation loc, SmallVectorImpl ¶ms, SmallVectorImpl *indirectResults) { // Add the indirect results. - for (auto resultTy : F.getConventions().getIndirectSILResultTypes()) { + for (auto resultTy : F.getConventions().getIndirectSILResultTypes( + getTypeExpansionContext())) { auto paramTy = F.mapTypeIntoContext(resultTy); // Lower result parameters in the context of the function: opaque result // types will be lowered to their underlying type if allowed by resilience. @@ -818,7 +819,8 @@ void SILGenFunction::collectThunkParams( // Add the parameters. auto paramTypes = F.getLoweredFunctionType()->getParameters(); for (auto param : paramTypes) { - auto paramTy = F.mapTypeIntoContext(F.getConventions().getSILType(param)); + auto paramTy = F.mapTypeIntoContext( + F.getConventions().getSILType(param, getTypeExpansionContext())); // Lower parameters in the context of the function: opaque result types will // be lowered to their underlying type if allowed by resilience. auto inContextParamTy = F.getLoweredType(paramTy.getASTType()) @@ -1669,8 +1671,9 @@ static void forwardFunctionArguments(SILGenFunction &SGF, for (auto index : indices(managedArgs)) { auto arg = managedArgs[index]; auto argTy = argTypes[index]; - auto argSubstTy = argTy.getArgumentType(SGF.SGM.M, fTy); - + auto argSubstTy = + argTy.getArgumentType(SGF.SGM.M, fTy, SGF.getTypeExpansionContext()); + arg = applyTrivialConversions(SGF, loc, arg, SILType::getPrimitiveObjectType(argSubstTy)); @@ -3789,7 +3792,8 @@ ManagedValue SILGenFunction::getThunkedAutoDiffLinearMap( } // Convert indirect result to direct result. if (fromRes.isFormalIndirect()) { - SILType resultTy = fromConv.getSILType(fromRes); + SILType resultTy = + fromConv.getSILType(fromRes, thunkSGF.getTypeExpansionContext()); assert(resultTy.isAddress()); auto *indRes = createAllocStack(resultTy); arguments.push_back(indRes); @@ -3811,7 +3815,8 @@ ManagedValue SILGenFunction::getThunkedAutoDiffLinearMap( } // Convert indirect parameter to direct parameter. if (fromParam.isFormalIndirect()) { - auto paramTy = fromConv.getSILType(fromType->getParameters()[paramIdx]); + auto paramTy = fromConv.getSILType(fromType->getParameters()[paramIdx], + thunkSGF.getTypeExpansionContext()); if (!paramTy.hasArchetype()) paramTy = thunk->mapTypeIntoContext(paramTy); assert(paramTy.isAddress()); @@ -3883,7 +3888,8 @@ ManagedValue SILGenFunction::getThunkedAutoDiffLinearMap( } // Store direct results to indirect results. assert(toRes.isFormalIndirect()); - SILType resultTy = toConv.getSILType(toRes); + SILType resultTy = + toConv.getSILType(toRes, thunkSGF.getTypeExpansionContext()); assert(resultTy.isAddress()); auto indRes = *toIndResultsIter++; thunkSGF.emitSemanticStore(loc, *fromDirResultsIter++, indRes, @@ -4052,16 +4058,19 @@ SILFunction *SILGenModule::getOrCreateCustomDerivativeThunk( linearMap = thunkSGF.getThunkedAutoDiffLinearMap( linearMap, linearMapKind, linearMapFnType, targetLinearMapFnType, reorderSelf); - + auto typeExpansionContext = thunkSGF.getTypeExpansionContext(); SILType linearMapResultType = thunk - ->getLoweredType( - thunk->mapTypeIntoContext(conv.getSILResultType()).getASTType()) - .getCategoryType(conv.getSILResultType().getCategory()); + ->getLoweredType(thunk + ->mapTypeIntoContext( + conv.getSILResultType(typeExpansionContext)) + .getASTType()) + .getCategoryType( + conv.getSILResultType(typeExpansionContext).getCategory()); if (auto tupleType = linearMapResultType.getAs()) { linearMapResultType = SILType::getPrimitiveType( tupleType->getElementTypes().back()->getCanonicalType(), - conv.getSILResultType().getCategory()); + conv.getSILResultType(typeExpansionContext).getCategory()); } auto targetLinearMapUnsubstFnType = diff --git a/lib/SILGen/SILGenProlog.cpp b/lib/SILGen/SILGenProlog.cpp index cd184e7e014bc..ba7023f38463a 100644 --- a/lib/SILGen/SILGenProlog.cpp +++ b/lib/SILGen/SILGenProlog.cpp @@ -114,7 +114,7 @@ class EmitBBArguments : public CanTypeVisitor()); diff --git a/lib/SILOptimizer/Analysis/ArraySemantic.cpp b/lib/SILOptimizer/Analysis/ArraySemantic.cpp index 807a4d67017d6..c4d47098c2960 100644 --- a/lib/SILOptimizer/Analysis/ArraySemantic.cpp +++ b/lib/SILOptimizer/Analysis/ArraySemantic.cpp @@ -750,8 +750,10 @@ bool swift::ArraySemanticsCall::replaceByAppendingValues( ReserveFnRef->getType().castTo(); assert(ReserveFnTy->getNumParameters() == 2); StructType *IntType = - ReserveFnTy->getParameters()[0].getArgumentType(F->getModule(), ReserveFnTy) - ->castTo(); + ReserveFnTy->getParameters()[0] + .getArgumentType(F->getModule(), ReserveFnTy, + Builder.getTypeExpansionContext()) + ->castTo(); StructDecl *IntDecl = IntType->getDecl(); VarDecl *field = IntDecl->getStoredProperties()[0]; SILType BuiltinIntTy =SILType::getPrimitiveObjectType( diff --git a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp index 9bd5f51b20d1e..5b02943c33a88 100644 --- a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp @@ -1022,8 +1022,8 @@ EscapeAnalysis::ConnectionGraph::getValueContent(SILValue ptrVal) { CGNode *EscapeAnalysis::ConnectionGraph::getReturnNode() { if (!ReturnNode) { - SILType resultTy = - F->mapTypeIntoContext(F->getConventions().getSILResultType()); + SILType resultTy = F->mapTypeIntoContext( + F->getConventions().getSILResultType(F->getTypeExpansionContext())); bool hasReferenceOnly = EA->hasReferenceOnly(resultTy, *F); ReturnNode = allocNode(nullptr, NodeType::Return, false, hasReferenceOnly); } diff --git a/lib/SILOptimizer/Differentiation/Thunk.cpp b/lib/SILOptimizer/Differentiation/Thunk.cpp index 8c54c9485f425..4a387a182e92d 100644 --- a/lib/SILOptimizer/Differentiation/Thunk.cpp +++ b/lib/SILOptimizer/Differentiation/Thunk.cpp @@ -321,7 +321,8 @@ SILFunction *getOrCreateReabstractionThunk(SILOptFunctionBuilder &fb, } // Convert indirect result to direct result. if (fromRes.isFormalIndirect()) { - SILType resultTy = fromConv.getSILType(fromRes); + SILType resultTy = + fromConv.getSILType(fromRes, builder.getTypeExpansionContext()); assert(resultTy.isAddress()); auto *indRes = createAllocStack(resultTy); arguments.push_back(indRes); @@ -344,7 +345,8 @@ SILFunction *getOrCreateReabstractionThunk(SILOptFunctionBuilder &fb, } // Convert indirect parameter to direct parameter. if (fromParam.isFormalIndirect()) { - auto paramTy = fromConv.getSILType(fromType->getParameters()[paramIdx]); + auto paramTy = fromConv.getSILType(fromType->getParameters()[paramIdx], + builder.getTypeExpansionContext()); if (!paramTy.hasArchetype()) paramTy = thunk->mapTypeIntoContext(paramTy); assert(paramTy.isAddress()); @@ -401,7 +403,8 @@ SILFunction *getOrCreateReabstractionThunk(SILOptFunctionBuilder &fb, } // Store direct results to indirect results. assert(toRes.isFormalIndirect()); - SILType resultTy = toConv.getSILType(toRes); + SILType resultTy = + toConv.getSILType(toRes, builder.getTypeExpansionContext()); assert(resultTy.isAddress()); auto indRes = *toIndResultsIter++; builder.createStore(loc, *fromDirResultsIter++, indRes, diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp index 3b6c6d366858a..be18e74779b45 100644 --- a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp +++ b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp @@ -162,7 +162,8 @@ void ExistentialSpecializerCloner::cloneArguments( auto iter = ArgToGenericTypeMap.find(ArgDesc.Index); if (iter == ArgToGenericTypeMap.end()) { // Clone arguments that are not rewritten. - auto Ty = params[ArgDesc.Index].getArgumentType(M, NewFTy); + auto Ty = params[ArgDesc.Index].getArgumentType( + M, NewFTy, NewF.getTypeExpansionContext()); auto LoweredTy = NewF.getLoweredType(NewF.mapTypeIntoContext(Ty)); auto MappedTy = LoweredTy.getCategoryType(ArgDesc.Arg->getType().getCategory()); @@ -301,7 +302,7 @@ void ExistentialTransform::convertExistentialArgTypesToGenericArgTypes( for (auto const &IdxIt : ExistentialArgDescriptor) { int Idx = IdxIt.first; auto ¶m = params[Idx]; - auto PType = param.getArgumentType(M, FTy); + auto PType = param.getArgumentType(M, FTy, F->getTypeExpansionContext()); assert(PType.isExistentialType()); /// Generate new generic parameter. auto *NewGenericParam = GenericTypeParamType::get(Depth, GPIdx++, Ctx); @@ -537,7 +538,7 @@ void ExistentialTransform::populateThunkBody() { SILValue ReturnValue; auto FunctionTy = NewF->getLoweredFunctionType(); SILFunctionConventions Conv(SubstCalleeType, M); - SILType ResultType = Conv.getSILResultType(); + SILType ResultType = Conv.getSILResultType(Builder.getTypeExpansionContext()); /// If the original function has error results, we need to generate a /// try_apply to call a function with an error result. @@ -548,7 +549,8 @@ void ExistentialTransform::populateThunkBody() { NormalBlock->createPhiArgument(ResultType, ValueOwnershipKind::Owned); SILBasicBlock *ErrorBlock = Thunk->createBasicBlock(); - SILType Error = Conv.getSILType(FunctionTy->getErrorResult()); + SILType Error = Conv.getSILType(FunctionTy->getErrorResult(), + Builder.getTypeExpansionContext()); auto *ErrorArg = ErrorBlock->createPhiArgument(Error, ValueOwnershipKind::Owned); Builder.createTryApply(Loc, FRI, SubMap, ApplyArgs, NormalBlock, @@ -580,7 +582,7 @@ void ExistentialTransform::populateThunkBody() { Builder.createDeallocStack(cleanupLoc, Temp.DeallocStackEntry); } /// Set up the return results. - if (NewF->isNoReturnFunction()) { + if (NewF->isNoReturnFunction(Builder.getTypeExpansionContext())) { Builder.createUnreachable(Loc); } else { Builder.createReturn(Loc, ReturnValue); diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp index fe78d40870192..4528e3ed2bc65 100644 --- a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp +++ b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp @@ -583,7 +583,8 @@ void FunctionSignatureTransform::createFunctionSignatureOptimizedFunction() { SILValue ReturnValue; SILType LoweredType = NewF->getLoweredType(); - SILType ResultType = NewF->getConventions().getSILResultType(); + SILType ResultType = NewF->getConventions().getSILResultType( + Builder.getTypeExpansionContext()); auto GenCalleeType = NewF->getLoweredFunctionType(); auto SubstCalleeSILType = LoweredType; SubstitutionMap Subs; @@ -596,7 +597,7 @@ void FunctionSignatureTransform::createFunctionSignatureOptimizedFunction() { M, Subs, Builder.getTypeExpansionContext()); SubstCalleeSILType = SILType::getPrimitiveObjectType(SubstCalleeType); SILFunctionConventions Conv(SubstCalleeType, M); - ResultType = Conv.getSILResultType(); + ResultType = Conv.getSILResultType(Builder.getTypeExpansionContext()); } auto FunctionTy = LoweredType.castTo(); if (FunctionTy->hasErrorResult()) { @@ -620,7 +621,7 @@ void FunctionSignatureTransform::createFunctionSignatureOptimizedFunction() { } // Set up the return results. - if (NewF->isNoReturnFunction()) { + if (NewF->isNoReturnFunction(Builder.getTypeExpansionContext())) { Builder.createUnreachable(Loc); } else { Builder.createReturn(Loc, ReturnValue); diff --git a/lib/SILOptimizer/IPO/CapturePromotion.cpp b/lib/SILOptimizer/IPO/CapturePromotion.cpp index 6c8245e71f5a0..37533fef306fc 100644 --- a/lib/SILOptimizer/IPO/CapturePromotion.cpp +++ b/lib/SILOptimizer/IPO/CapturePromotion.cpp @@ -362,8 +362,9 @@ computeNewArgInterfaceTypes(SILFunction *F, IndicesSet &PromotableIndices, // Perform the proper conversions and then add it to the new parameter list // for the type. assert(!param.isFormalIndirect()); - auto paramTy = param.getSILStorageType(fnConv.silConv.getModule(), - fnConv.funcTy); + auto paramTy = + param.getSILStorageType(fnConv.silConv.getModule(), fnConv.funcTy, + TypeExpansionContext::minimal()); auto paramBoxTy = paramTy.castTo(); assert(paramBoxTy->getLayout()->getFields().size() == 1 && "promoting compound box not implemented yet"); @@ -1322,7 +1323,8 @@ processPartialApplyInst(SILOptFunctionBuilder &FuncBuilder, // alloc_box. Otherwise, it is on the specific iterated copy_value that we // started with. SILParameterInfo CPInfo = CalleePInfo[Index - NumIndirectResults]; - assert(calleeConv.getSILType(CPInfo) == Box->getType() && + assert(calleeConv.getSILType(CPInfo, B.getTypeExpansionContext()) == + Box->getType() && "SILType of parameter info does not match type of parameter"); releasePartialApplyCapturedArg(B, PAI->getLoc(), Box, CPInfo); ++NumCapturesPromoted; diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp index 2330cddf381ff..97a444b0e0d28 100644 --- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp +++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp @@ -649,7 +649,11 @@ ClosureSpecCloner::initCloned(SILOptFunctionBuilder &FunctionBuilder, || ParamConv == ParameterConvention::Indirect_Inout || ParamConv == ParameterConvention::Indirect_InoutAliasable); } else { - ParamConv = ClosedOverFunConv.getSILType(PInfo).isTrivial(*ClosureUser) + ParamConv = ClosedOverFunConv + .getSILType(PInfo, CallSiteDesc.getApplyInst() + .getFunction() + ->getTypeExpansionContext()) + .isTrivial(*ClosureUser) ? ParameterConvention::Direct_Unowned : ParameterConvention::Direct_Owned; } @@ -814,6 +818,7 @@ void ClosureSpecCloner::populateCloned() { // such arguments. After this pass is done the only thing that will reference // the arguments is the partial apply that we will create. SILFunction *ClosedOverFun = CallSiteDesc.getClosureCallee(); + SILBuilder &Builder = getBuilder(); auto ClosedOverFunConv = ClosedOverFun->getConventions(); unsigned NumTotalParams = ClosedOverFunConv.getNumParameters(); unsigned NumNotCaptured = NumTotalParams - CallSiteDesc.getNumArguments(); @@ -821,7 +826,8 @@ void ClosureSpecCloner::populateCloned() { llvm::DenseMap CapturedMap; unsigned idx = 0; for (auto &PInfo : ClosedOverFunConv.getParameters().slice(NumNotCaptured)) { - auto paramTy = ClosedOverFunConv.getSILType(PInfo); + auto paramTy = + ClosedOverFunConv.getSILType(PInfo, Builder.getTypeExpansionContext()); // Get the type in context of the new function. paramTy = Cloned->getLoweredType(paramTy); SILValue MappedValue = ClonedEntryBB->createFunctionArgument(paramTy); @@ -831,7 +837,6 @@ void ClosureSpecCloner::populateCloned() { CapturedMap[CapturedVal] = MappedValue; } - SILBuilder &Builder = getBuilder(); Builder.setInsertionPoint(ClonedEntryBB); // Clone FRI and PAI, and replace usage of the removed closure argument diff --git a/lib/SILOptimizer/IPO/EagerSpecializer.cpp b/lib/SILOptimizer/IPO/EagerSpecializer.cpp index 5015b1273cb7d..677f5dc7aea20 100644 --- a/lib/SILOptimizer/IPO/EagerSpecializer.cpp +++ b/lib/SILOptimizer/IPO/EagerSpecializer.cpp @@ -169,8 +169,9 @@ emitApplyWithRethrow(SILBuilder &Builder, { // Emit the rethrow logic. Builder.emitBlock(ErrorBB); - SILValue Error = ErrorBB->createPhiArgument(fnConv.getSILErrorType(), - ValueOwnershipKind::Owned); + SILValue Error = ErrorBB->createPhiArgument( + fnConv.getSILErrorType(F.getTypeExpansionContext()), + ValueOwnershipKind::Owned); EmitCleanup(Builder, Loc); addThrowValue(ErrorBB, Error); @@ -179,8 +180,9 @@ emitApplyWithRethrow(SILBuilder &Builder, // result value. Builder.clearInsertionPoint(); Builder.emitBlock(NormalBB); - return Builder.getInsertionBB()->createPhiArgument(fnConv.getSILResultType(), - ValueOwnershipKind::Owned); + return Builder.getInsertionBB()->createPhiArgument( + fnConv.getSILResultType(F.getTypeExpansionContext()), + ValueOwnershipKind::Owned); } /// Emits code to invoke the specified specialized CalleeFunc using the @@ -403,10 +405,12 @@ void EagerDispatch::emitDispatchTo(SILFunction *NewFunc) { Result = Builder.createTuple(Loc, VoidTy, { }); // Function marked as @NoReturn must be followed by 'unreachable'. - if (NewFunc->isNoReturnFunction() || !OldReturnBB) + if (NewFunc->isNoReturnFunction(Builder.getTypeExpansionContext()) || + !OldReturnBB) Builder.createUnreachable(Loc); else { - auto resultTy = GenericFunc->getConventions().getSILResultType(); + auto resultTy = GenericFunc->getConventions().getSILResultType( + Builder.getTypeExpansionContext()); auto GenResultTy = GenericFunc->mapTypeIntoContext(resultTy); auto CastResult = Builder.createUncheckedBitCast(Loc, Result, GenResultTy); addReturnValue(Builder.getInsertionBB(), OldReturnBB, CastResult); @@ -592,7 +596,8 @@ SILValue EagerDispatch::emitArgumentCast(CanSILFunctionType CalleeSubstFnTy, unsigned Idx) { SILFunctionConventions substConv(CalleeSubstFnTy, Builder.getModule()); - auto CastTy = substConv.getSILArgumentType(Idx); + auto CastTy = + substConv.getSILArgumentType(Idx, Builder.getTypeExpansionContext()); assert(CastTy.isAddress() == (OrigArg->isIndirectResult() || substConv.isSILIndirect(OrigArg->getKnownParameterInfo())) diff --git a/lib/SILOptimizer/Mandatory/AddressLowering.cpp b/lib/SILOptimizer/Mandatory/AddressLowering.cpp index 77a5b73b52a93..788dd4760e03a 100644 --- a/lib/SILOptimizer/Mandatory/AddressLowering.cpp +++ b/lib/SILOptimizer/Mandatory/AddressLowering.cpp @@ -447,7 +447,8 @@ void OpaqueStorageAllocation::convertIndirectFunctionArgs() { unsigned OpaqueStorageAllocation::insertIndirectReturnArgs() { auto &ctx = pass.F->getModule().getASTContext(); unsigned argIdx = 0; - for (auto resultTy : pass.loweredFnConv.getIndirectSILResultTypes()) { + for (auto resultTy : pass.loweredFnConv.getIndirectSILResultTypes( + pass.F->getTypeExpansionContext())) { auto bodyResultTy = pass.F->mapTypeIntoContext(resultTy); auto var = new (ctx) ParamDecl(SourceLoc(), SourceLoc(), @@ -944,7 +945,9 @@ void ApplyRewriter::convertApplyWithIndirectResults() { if (loweredCalleeConv.isSILIndirect(resultInfo)) { SILValue indirectResultAddr = materializeIndirectResultAddress( - origDirectResultVal, loweredCalleeConv.getSILType(resultInfo)); + origDirectResultVal, + loweredCalleeConv.getSILType( + resultInfo, callBuilder.getTypeExpansionContext())); // Record the new indirect call argument. newCallArgs[newResultArgIdx++] = indirectResultAddr; // Leave a placeholder for indirect results. @@ -1131,9 +1134,10 @@ void ReturnRewriter::rewriteReturn(ReturnInst *returnInst) { } else if (newDirectResults.size() == 1) { newReturnVal = newDirectResults[0]; } else { - newReturnVal = - B.createTuple(returnInst->getLoc(), - pass.loweredFnConv.getSILResultType(), newDirectResults); + newReturnVal = B.createTuple( + returnInst->getLoc(), + pass.loweredFnConv.getSILResultType(B.getTypeExpansionContext()), + newDirectResults); } SILValue origFullResult = returnInst->getOperand(); returnInst->setOperand(newReturnVal); diff --git a/lib/SILOptimizer/Mandatory/DataflowDiagnostics.cpp b/lib/SILOptimizer/Mandatory/DataflowDiagnostics.cpp index 64d815c502254..1482a9c264e08 100644 --- a/lib/SILOptimizer/Mandatory/DataflowDiagnostics.cpp +++ b/lib/SILOptimizer/Mandatory/DataflowDiagnostics.cpp @@ -73,8 +73,9 @@ static void diagnoseMissingReturn(const UnreachableInst *UI, } } } - auto diagID = F->isNoReturnFunction() ? diag::missing_never_call - : diag::missing_return; + auto diagID = F->isNoReturnFunction(F->getTypeExpansionContext()) + ? diag::missing_never_call + : diag::missing_return; diagnose(Context, L.getEndSourceLoc(), diagID, ResTy, diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp index 1b46ba110db6e..f25de2558ad73 100644 --- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp @@ -153,8 +153,10 @@ SILCombiner::optimizeApplyOfConvertFunctionInst(FullApplySite AI, // Bail if the result type of the converted callee is different from the callee's // result type of the apply instruction. - if (SubstCalleeTy->getAllResultsSubstType(AI.getModule()) - != ConvertCalleeTy->getAllResultsSubstType(AI.getModule())) { + if (SubstCalleeTy->getAllResultsSubstType( + AI.getModule(), AI.getFunction()->getTypeExpansionContext()) != + ConvertCalleeTy->getAllResultsSubstType( + AI.getModule(), AI.getFunction()->getTypeExpansionContext())) { return nullptr; } @@ -164,8 +166,9 @@ SILCombiner::optimizeApplyOfConvertFunctionInst(FullApplySite AI, OperandValueArrayRef Ops = AI.getArgumentsWithoutIndirectResults(); SILFunctionConventions substConventions(SubstCalleeTy, FRI->getModule()); SILFunctionConventions convertConventions(ConvertCalleeTy, FRI->getModule()); - auto oldOpTypes = substConventions.getParameterSILTypes(); - auto newOpTypes = convertConventions.getParameterSILTypes(); + auto context = AI.getFunction()->getTypeExpansionContext(); + auto oldOpTypes = substConventions.getParameterSILTypes(context); + auto newOpTypes = convertConventions.getParameterSILTypes(context); assert(Ops.size() == SubstCalleeTy->getNumParameters() && "Ops and op types must have same size."); @@ -206,10 +209,10 @@ SILCombiner::optimizeApplyOfConvertFunctionInst(FullApplySite AI, bool setNonThrowing = FRI->getFunctionType()->hasErrorResult(); SILInstruction *NAI = Builder.createApply(AI.getLoc(), FRI, SubstitutionMap(), Args, setNonThrowing); - assert(FullApplySite::isa(NAI).getSubstCalleeType() - ->getAllResultsSubstType(AI.getModule()) - == AI.getSubstCalleeType() - ->getAllResultsSubstType(AI.getModule()) && + assert(FullApplySite::isa(NAI).getSubstCalleeType()->getAllResultsSubstType( + AI.getModule(), AI.getFunction()->getTypeExpansionContext()) == + AI.getSubstCalleeType()->getAllResultsSubstType( + AI.getModule(), AI.getFunction()->getTypeExpansionContext()) && "Function types should be the same"); return NAI; } @@ -866,12 +869,11 @@ SILInstruction *SILCombiner::createApplyWithConcreteType( // We need to make sure that we can a) update Apply to use the new args and b) // at least one argument has changed. If no arguments have changed, we need // to return nullptr. Otherwise, we will have an infinite loop. - auto substTy = - Apply.getCallee() - ->getType() - .substGenericArgs(Apply.getModule(), NewCallSubs, - Apply.getFunction()->getTypeExpansionContext()) - .getAs(); + auto context = Apply.getFunction()->getTypeExpansionContext(); + auto substTy = Apply.getCallee() + ->getType() + .substGenericArgs(Apply.getModule(), NewCallSubs, context) + .getAs(); SILFunctionConventions conv(substTy, SILModuleConventions(Apply.getModule())); bool canUpdateArgs = true; @@ -880,7 +882,7 @@ SILInstruction *SILCombiner::createApplyWithConcreteType( // Make sure that *all* the arguments in both the new substitution function // and our vector of new arguments have the same type. canUpdateArgs &= - conv.getSILArgumentType(index) == NewArgs[index]->getType(); + conv.getSILArgumentType(index, context) == NewArgs[index]->getType(); // Make sure that we have changed at least one argument. madeUpdate |= NewArgs[index]->getType() != Apply.getArgument(index)->getType(); diff --git a/lib/SILOptimizer/Transforms/ObjectOutliner.cpp b/lib/SILOptimizer/Transforms/ObjectOutliner.cpp index 1b5bef9ec9194..3deef3a7afe1c 100644 --- a/lib/SILOptimizer/Transforms/ObjectOutliner.cpp +++ b/lib/SILOptimizer/Transforms/ObjectOutliner.cpp @@ -508,8 +508,10 @@ void ObjectOutliner::replaceFindStringCall(ApplyInst *FindStringCall) { if (FTy->getNumParameters() != 3) return; - SILType cacheType = FTy->getParameters()[2].getSILStorageType(*Module, FTy) - .getObjectType(); + SILType cacheType = + FTy->getParameters()[2] + .getSILStorageType(*Module, FTy, TypeExpansionContext::minimal()) + .getObjectType(); NominalTypeDecl *cacheDecl = cacheType.getNominalOrBoundGenericNominal(); if (!cacheDecl) return; diff --git a/lib/SILOptimizer/Transforms/PerformanceInliner.cpp b/lib/SILOptimizer/Transforms/PerformanceInliner.cpp index 7cacee99a4b17..a5acb3643a512 100644 --- a/lib/SILOptimizer/Transforms/PerformanceInliner.cpp +++ b/lib/SILOptimizer/Transforms/PerformanceInliner.cpp @@ -284,8 +284,8 @@ bool SILPerformanceInliner::isProfitableToInline( // Don't inline class methods. if (Callee->hasSelfParam()) { - auto SelfTy = Callee->getLoweredFunctionType() - ->getSelfInstanceType(FuncBuilder.getModule()); + auto SelfTy = Callee->getLoweredFunctionType()->getSelfInstanceType( + FuncBuilder.getModule(), AI.getFunction()->getTypeExpansionContext()); if (SelfTy->mayHaveSuperclass() && Callee->getRepresentation() == SILFunctionTypeRepresentation::Method) isClassMethodAtOsize = true; diff --git a/lib/SILOptimizer/Transforms/SimplifyCFG.cpp b/lib/SILOptimizer/Transforms/SimplifyCFG.cpp index 54e9260f07374..46887a58e5b69 100644 --- a/lib/SILOptimizer/Transforms/SimplifyCFG.cpp +++ b/lib/SILOptimizer/Transforms/SimplifyCFG.cpp @@ -2392,7 +2392,8 @@ bool SimplifyCFG::simplifyTryApplyBlock(TryApplyInst *TAI) { auto CalleeFnTy = CalleeType.castTo(); SILFunctionConventions calleeConv(CalleeFnTy, TAI->getModule()); - auto ResultTy = calleeConv.getSILResultType(); + auto ResultTy = calleeConv.getSILResultType( + TAI->getFunction()->getTypeExpansionContext()); auto OrigResultTy = TAI->getNormalBB()->getArgument(0)->getType(); SILBuilderWithScope Builder(TAI); @@ -2412,15 +2413,15 @@ bool SimplifyCFG::simplifyTryApplyBlock(TryApplyInst *TAI) { Builder.getTypeExpansionContext()); } SILFunctionConventions origConv(OrigFnTy, TAI->getModule()); - + auto context = TAI->getFunction()->getTypeExpansionContext(); SmallVector Args; unsigned numArgs = TAI->getNumArguments(); for (unsigned i = 0; i < numArgs; ++i) { auto Arg = TAI->getArgument(i); // Cast argument if required. std::tie(Arg, std::ignore) = castValueToABICompatibleType( - &Builder, TAI->getLoc(), Arg, origConv.getSILArgumentType(i), - targetConv.getSILArgumentType(i)); + &Builder, TAI->getLoc(), Arg, origConv.getSILArgumentType(i, context), + targetConv.getSILArgumentType(i, context)); Args.push_back(Arg); } diff --git a/lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp b/lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp index b44f36f67b523..6913c3a3c94ee 100644 --- a/lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp +++ b/lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp @@ -197,7 +197,8 @@ static FullApplySite speculateMonomorphicTarget(FullApplySite AI, SILArgument *Arg = Continue->createPhiArgument(AI.getType(), ValueOwnershipKind::Owned); if (!isa(AI)) { - if (AI.getSubstCalleeType()->isNoReturnFunction(F->getModule())) { + if (AI.getSubstCalleeType()->isNoReturnFunction( + F->getModule(), AI.getFunction()->getTypeExpansionContext())) { IdenBuilder.createUnreachable(AI.getLoc()); VirtBuilder.createUnreachable(AI.getLoc()); } else { diff --git a/lib/SILOptimizer/Utils/CastOptimizer.cpp b/lib/SILOptimizer/Utils/CastOptimizer.cpp index d318e92951016..c1c5da4bc3fdc 100644 --- a/lib/SILOptimizer/Utils/CastOptimizer.cpp +++ b/lib/SILOptimizer/Utils/CastOptimizer.cpp @@ -443,12 +443,13 @@ CastOptimizer::optimizeBridgedObjCToSwiftCast(SILDynamicCastInst dynamicCast) { static bool canOptimizeCast(const swift::Type &BridgedTargetTy, swift::SILModule &M, - swift::SILFunctionConventions &substConv) { + swift::SILFunctionConventions &substConv, + TypeExpansionContext context) { // DestTy is the type which we want to convert to SILType DestTy = SILType::getPrimitiveObjectType(BridgedTargetTy->getCanonicalType()); // ConvTy is the return type of the _bridgeToObjectiveCImpl() - auto ConvTy = substConv.getSILResultType().getObjectType(); + auto ConvTy = substConv.getSILResultType(context).getObjectType(); if (ConvTy == DestTy) { // Destination is the same type return true; @@ -640,7 +641,8 @@ CastOptimizer::optimizeBridgedSwiftToObjCCast(SILDynamicCastInst dynamicCast) { // Check that this is a case that the authors of this code thought it could // handle. - if (!canOptimizeCast(BridgedTargetTy, M, substConv)) { + if (!canOptimizeCast(BridgedTargetTy, M, substConv, + F->getTypeExpansionContext())) { return nullptr; } diff --git a/lib/SILOptimizer/Utils/ConstExpr.cpp b/lib/SILOptimizer/Utils/ConstExpr.cpp index f3070fac82cae..9716ec28085fb 100644 --- a/lib/SILOptimizer/Utils/ConstExpr.cpp +++ b/lib/SILOptimizer/Utils/ConstExpr.cpp @@ -1214,11 +1214,13 @@ ConstExprFunctionState::computeCallResult(ApplyInst *apply) { SubstitutionMap calleeSubMap; auto calleeFnType = callee->getLoweredFunctionType(); - assert( - !calleeFnType->hasSelfParam() || - !calleeFnType->getSelfInstanceType(callee->getModule()) - ->getClassOrBoundGenericClass() && - "class methods are not supported"); + assert(!calleeFnType->hasSelfParam() || + !calleeFnType + ->getSelfInstanceType( + callee->getModule(), + apply->getFunction()->getTypeExpansionContext()) + ->getClassOrBoundGenericClass() && + "class methods are not supported"); if (calleeFnType->getInvocationGenericSignature()) { // Get the substitution map of the call. This maps from the callee's space // into the caller's world. Witness methods require additional work to diff --git a/lib/SILOptimizer/Utils/Devirtualize.cpp b/lib/SILOptimizer/Utils/Devirtualize.cpp index 3df6eb70aba75..f07a35cf7d47e 100644 --- a/lib/SILOptimizer/Utils/Devirtualize.cpp +++ b/lib/SILOptimizer/Utils/Devirtualize.cpp @@ -410,8 +410,9 @@ getSubstitutionsForCallee(SILModule &module, CanSILFunctionType baseCalleeType, return SubstitutionMap(); // Add any generic substitutions for the base class. - Type baseSelfType = baseCalleeType->getSelfParameter() - .getArgumentType(module, baseCalleeType); + Type baseSelfType = baseCalleeType->getSelfParameter().getArgumentType( + module, baseCalleeType, + applySite.getFunction()->getTypeExpansionContext()); if (auto metatypeType = baseSelfType->getAs()) baseSelfType = metatypeType->getInstanceType(); @@ -436,8 +437,9 @@ getSubstitutionsForCallee(SILModule &module, CanSILFunctionType baseCalleeType, SubstitutionMap origSubMap = applySite.getSubstitutionMap(); Type calleeSelfType = - applySite.getOrigCalleeType()->getSelfParameter() - .getArgumentType(module, applySite.getOrigCalleeType()); + applySite.getOrigCalleeType()->getSelfParameter().getArgumentType( + module, applySite.getOrigCalleeType(), + applySite.getFunction()->getTypeExpansionContext()); if (auto metatypeType = calleeSelfType->getAs()) calleeSelfType = metatypeType->getInstanceType(); auto *calleeClassDecl = calleeSelfType->getClassOrBoundGenericClass(); @@ -491,7 +493,8 @@ replaceTryApplyInst(SILBuilder &builder, SILLocation loc, TryApplyInst *oldTAI, SILBasicBlock *normalBB = oldTAI->getNormalBB(); SILBasicBlock *resultBB = nullptr; - SILType newResultTy = conv.getSILResultType(); + SILType newResultTy = + conv.getSILResultType(builder.getTypeExpansionContext()); // Does the result value need to be casted? auto oldResultTy = normalBB->getArgument(0)->getType(); @@ -776,7 +779,8 @@ swift::devirtualizeClassMethod(FullApplySite applySite, SmallVector newArgBorrows; auto indirectResultArgIter = applySite.getIndirectSILResults().begin(); - for (auto resultTy : substConv.getIndirectSILResultTypes()) { + for (auto resultTy : substConv.getIndirectSILResultTypes( + applySite.getFunction()->getTypeExpansionContext())) { auto castRes = castValueToABICompatibleType( &builder, loc, *indirectResultArgIter, indirectResultArgIter->getType(), resultTy); @@ -788,7 +792,8 @@ swift::devirtualizeClassMethod(FullApplySite applySite, auto paramArgIter = applySite.getArgumentsWithoutIndirectResults().begin(); // Skip the last parameter, which is `self`. Add it below. for (auto param : substConv.getParameters()) { - auto paramType = substConv.getSILType(param); + auto paramType = + substConv.getSILType(param, builder.getTypeExpansionContext()); SILValue arg = *paramArgIter; if (builder.hasOwnership() && arg->getType().isObject() && arg.getOwnershipKind() == ValueOwnershipKind::Owned @@ -961,8 +966,12 @@ swift::getWitnessMethodSubstitutions(SILModule &module, ApplySite applySite, auto *mod = module.getSwiftModule(); bool isSelfAbstract = - witnessFnTy->getSelfInstanceType(module)->is(); - auto *classWitness = witnessFnTy->getWitnessMethodClass(module); + witnessFnTy + ->getSelfInstanceType( + module, applySite.getFunction()->getTypeExpansionContext()) + ->is(); + auto *classWitness = witnessFnTy->getWitnessMethodClass( + module, applySite.getFunction()->getTypeExpansionContext()); return ::getWitnessMethodSubstitutions(mod, cRef, requirementSig, witnessThunkSig, origSubs, @@ -992,10 +1001,11 @@ devirtualizeWitnessMethod(ApplySite applySite, SILFunction *f, // Figure out the exact bound type of the function to be called by // applying all substitutions. - auto calleeCanType = f->getLoweredFunctionTypeInContext( - TypeExpansionContext(*applySite.getFunction())); - auto substCalleeCanType = calleeCanType->substGenericArgs( - module, subMap, TypeExpansionContext(*applySite.getFunction())); + auto typeExpansionContext = + applySite.getFunction()->getTypeExpansionContext(); + auto calleeCanType = f->getLoweredFunctionTypeInContext(typeExpansionContext); + auto substCalleeCanType = + calleeCanType->substGenericArgs(module, subMap, typeExpansionContext); // Collect arguments from the apply instruction. SmallVector arguments; @@ -1008,7 +1018,8 @@ devirtualizeWitnessMethod(ApplySite applySite, SILFunction *f, unsigned substArgIdx = applySite.getCalleeArgIndexOfFirstAppliedArg(); for (auto arg : applySite.getArguments()) { auto paramInfo = substConv.getSILArgumentConvention(substArgIdx); - auto paramType = substConv.getSILArgumentType(substArgIdx++); + auto paramType = + substConv.getSILArgumentType(substArgIdx++, typeExpansionContext); if (arg->getType() != paramType) { if (argBuilder.hasOwnership() && applySite.getKind() != ApplySiteKind::PartialApplyInst diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp index a11ed7a47e459..88cd53e7c33bc 100644 --- a/lib/SILOptimizer/Utils/Generics.cpp +++ b/lib/SILOptimizer/Utils/Generics.cpp @@ -686,12 +686,14 @@ void ReabstractionInfo::createSubstitutedAndSpecializedTypes() { for (SILResultInfo RI : SubstitutedType->getIndirectFormalResults()) { assert(RI.isFormalIndirect()); - auto ResultTy = substConv.getSILType(RI); + auto ResultTy = substConv.getSILType(RI, getResilienceExpansion()); ResultTy = Callee->mapTypeIntoContext(ResultTy); auto &TL = M.Types.getTypeLowering(ResultTy, getResilienceExpansion()); - if (TL.isLoadable() && !RI.getReturnValueType(M, SubstitutedType)->isVoid() && + if (TL.isLoadable() && + !RI.getReturnValueType(M, SubstitutedType, getResilienceExpansion()) + ->isVoid() && shouldExpand(M, ResultTy)) { Conversions.set(IdxForResult); if (TL.isTrivial()) @@ -708,7 +710,7 @@ void ReabstractionInfo::createSubstitutedAndSpecializedTypes() { auto IdxToInsert = IdxForParam; ++IdxForParam; - auto ParamTy = substConv.getSILType(PI); + auto ParamTy = substConv.getSILType(PI, getResilienceExpansion()); ParamTy = Callee->mapTypeIntoContext(ParamTy); auto &TL = M.Types.getTypeLowering(ParamTy, getResilienceExpansion()); @@ -794,10 +796,10 @@ createSpecializedType(CanSILFunctionType SubstFTy, SILModule &M) const { SmallVector SpecializedResults; SmallVector SpecializedYields; SmallVector SpecializedParams; - + auto context = getResilienceExpansion(); unsigned IndirectResultIdx = 0; for (SILResultInfo RI : SubstFTy->getResults()) { - RI = RI.getUnsubstituted(M, SubstFTy); + RI = RI.getUnsubstituted(M, SubstFTy, context); if (RI.isFormalIndirect()) { bool isTrivial = TrivialArgs.test(IndirectResultIdx); if (isFormalResultConverted(IndirectResultIdx++)) { @@ -816,7 +818,7 @@ createSpecializedType(CanSILFunctionType SubstFTy, SILModule &M) const { } unsigned ParamIdx = 0; for (SILParameterInfo PI : SubstFTy->getParameters()) { - PI = PI.getUnsubstituted(M, SubstFTy); + PI = PI.getUnsubstituted(M, SubstFTy, context); bool isTrivial = TrivialArgs.test(param2ArgIndex(ParamIdx)); if (!isParamConverted(ParamIdx++)) { // No conversion: re-use the original, substituted parameter info. @@ -840,7 +842,7 @@ createSpecializedType(CanSILFunctionType SubstFTy, SILModule &M) const { } for (SILYieldInfo YI : SubstFTy->getYields()) { // For now, always re-use the original, substituted yield info. - SpecializedYields.push_back(YI.getUnsubstituted(M, SubstFTy)); + SpecializedYields.push_back(YI.getUnsubstituted(M, SubstFTy, context)); } auto Signature = SubstFTy->isPolymorphic() @@ -1987,7 +1989,8 @@ static ApplySite replaceWithSpecializedCallee(ApplySite AI, A->isNonThrowing()); if (StoreResultTo) { assert(substConv.useLoweredAddresses()); - if (!CalleeSILSubstFnTy.isNoReturnFunction(Builder.getModule())) { + if (!CalleeSILSubstFnTy.isNoReturnFunction( + Builder.getModule(), Builder.getTypeExpansionContext())) { // Store the direct result to the original result address. fixUsedVoidType(A, Loc, Builder); Builder.createStore(Loc, NewAI, StoreResultTo, @@ -2121,9 +2124,8 @@ SILFunction *ReabstractionThunkGenerator::createThunk() { // Need to store the direct results to the original indirect address. Builder.createStore(Loc, ReturnValue, ReturnValueAddr, StoreOwnershipQualifier::Unqualified); - SILType VoidTy = - OrigPAI->getSubstCalleeType() - ->getDirectFormalResultsType(M); + SILType VoidTy = OrigPAI->getSubstCalleeType()->getDirectFormalResultsType( + M, Builder.getTypeExpansionContext()); assert(VoidTy.isVoid()); ReturnValue = Builder.createTuple(Loc, VoidTy, {}); } @@ -2146,12 +2148,14 @@ SILValue ReabstractionThunkGenerator::createReabstractionThunkApply( SILBasicBlock *ErrorBB = Thunk->createBasicBlock(); Builder.createTryApply(Loc, FRI, Subs, Arguments, NormalBB, ErrorBB); auto *ErrorVal = ErrorBB->createPhiArgument( - SpecializedFunc->mapTypeIntoContext(specConv.getSILErrorType()), + SpecializedFunc->mapTypeIntoContext( + specConv.getSILErrorType(Builder.getTypeExpansionContext())), ValueOwnershipKind::Owned); Builder.setInsertionPoint(ErrorBB); Builder.createThrow(Loc, ErrorVal); SILValue ReturnValue = NormalBB->createPhiArgument( - SpecializedFunc->mapTypeIntoContext(specConv.getSILResultType()), + SpecializedFunc->mapTypeIntoContext( + specConv.getSILResultType(Builder.getTypeExpansionContext())), ValueOwnershipKind::Owned); Builder.setInsertionPoint(NormalBB); return ReturnValue; @@ -2200,8 +2204,8 @@ SILArgument *ReabstractionThunkGenerator::convertReabstractionThunkArguments( // Store the result later. // FIXME: This only handles a single result! Partial specialization could // induce some combination of direct and indirect results. - SILType ResultTy = - SpecializedFunc->mapTypeIntoContext(substConv.getSILType(substRI)); + SILType ResultTy = SpecializedFunc->mapTypeIntoContext( + substConv.getSILType(substRI, Builder.getTypeExpansionContext())); assert(ResultTy.isAddress()); assert(!ReturnValueAddr); ReturnValueAddr = EntryBB->createFunctionArgument(ResultTy); @@ -2222,7 +2226,8 @@ SILArgument *ReabstractionThunkGenerator::convertReabstractionThunkArguments( assert(!specConv.isSILIndirect(SpecType->getParameters()[paramIdx])); // Instead of passing the address, pass the loaded value. SILType ParamTy = SpecializedFunc->mapTypeIntoContext( - substConv.getSILType(SubstType->getParameters()[paramIdx])); + substConv.getSILType(SubstType->getParameters()[paramIdx], + Builder.getTypeExpansionContext())); assert(ParamTy.isAddress()); SILArgument *SpecArg = *SpecArgIter++; SILArgument *NewArg = diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp index 7cb208358bd1f..7a650c6eaf1e1 100644 --- a/lib/Serialization/DeserializeSIL.cpp +++ b/lib/Serialization/DeserializeSIL.cpp @@ -1459,7 +1459,8 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB, SmallVector Args; for (unsigned I = 0, E = ListOfValues.size(); I < E; I++) Args.push_back(getLocalValue(ListOfValues[I], - substConventions.getSILArgumentType(I))); + substConventions.getSILArgumentType( + I, Builder.getTypeExpansionContext()))); SubstitutionMap Substitutions = MF->getSubstitutionMap(NumSubs); if (OpCode == SILInstructionKind::ApplyInst) { @@ -1495,7 +1496,8 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB, SmallVector Args; for (unsigned I = 0, E = ListOfValues.size(); I < E; I++) Args.push_back(getLocalValue(ListOfValues[I], - substConventions.getSILArgumentType(I))); + substConventions.getSILArgumentType( + I, Builder.getTypeExpansionContext()))); SubstitutionMap Substitutions = MF->getSubstitutionMap(NumSubs); ResultVal = Builder.createTryApply(Loc, getLocalValue(ValID, FnTy), @@ -1527,7 +1529,9 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB, unsigned unappliedArgs = numArgs - ListOfValues.size(); for (unsigned I = 0, E = ListOfValues.size(); I < E; I++) Args.push_back(getLocalValue( - ListOfValues[I], fnConv.getSILArgumentType(I + unappliedArgs))); + ListOfValues[I], + fnConv.getSILArgumentType(I + unappliedArgs, + Builder.getTypeExpansionContext()))); auto onStack = closureTy.castTo()->isNoEscape() ? PartialApplyInst::OnStackKind::OnStack : PartialApplyInst::OnStackKind::NotOnStack; diff --git a/test/SILOptimizer/Inputs/opaque_result_types.swift b/test/SILOptimizer/Inputs/opaque_result_types.swift new file mode 100644 index 0000000000000..a5cf05ef5e15b --- /dev/null +++ b/test/SILOptimizer/Inputs/opaque_result_types.swift @@ -0,0 +1,76 @@ +public protocol P { + func myValue() -> Int64 +} +extension Int64: P { + public func myValue() -> Int64 { + return self + } +} +public func bar(_ x: Int64) -> some P { + return x +} +public func foo(_ x: Int64) -> some P { + if x > 0 { + } + return bar(x - 1) +} + +public protocol CP : class { } + +public class C : CP { + public func myValue() -> Int64 { + return 0 + } +} + +public func returnC() -> some CP { + return C() +} + +public protocol P4 { + associatedtype AT + func foo(_ x: Int64) -> AT +} +public struct PA : P4 { + public func foo(_ x: Int64) -> some P { + return Int64(x) + } +} +extension PA { + public func test() { + } +} +public struct Foo { + public var p : Int64 = 1 +} +public struct Test : RandomAccessCollection { + public struct Index : Comparable, Hashable { + public var identifier: AnyHashable? + public var offset: Int + public static func < (lhs: Index, rhs: Index) -> Bool { + return lhs.offset < rhs.offset + } + public func hash(into hasher: inout Hasher) { + } + } + let foos: [Foo] + let ids: [AnyHashable] + func _index(atOffset n: Int) -> Index { + return Index(identifier: ids.isEmpty ? nil : ids[n], offset: n) + } + public var startIndex: Index { + return _index(atOffset: 0) + } + public var endIndex: Index { + return Index(identifier: nil, offset: ids.endIndex) + } + public func index(after i: Index) -> Index { + return _index(atOffset: i.offset + 1) + } + public func index(before i: Index) -> Index { + return _index(atOffset: i.offset - 1) + } + public subscript(i: Index) -> some P { + return foos[i.offset].p + } +} diff --git a/test/SILOptimizer/specialize_opaque_result_types.sil b/test/SILOptimizer/specialize_opaque_result_types.sil new file mode 100644 index 0000000000000..2747fefe6bf72 --- /dev/null +++ b/test/SILOptimizer/specialize_opaque_result_types.sil @@ -0,0 +1,75 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -disable-availability-checking %S/Inputs/opaque_result_types.swift -module-name External -emit-module -emit-module-path %t/External.swiftmodule +// RUN: %target-sil-opt -I %t -enable-sil-verify-all %s -generic-specializer | %FileCheck %s + +// REQUIRES: CPU=x86_64 + +import Builtin +import Swift +import SwiftShims +import External + +sil_stage canonical + +sil @project : $@convention(thin) (@in Test) -> @out IndexingIterator + +sil shared @test : $@convention(thin) (@owned Test) -> () { +bb0(%0 : $Test): + %3 = alloc_stack $Test + store %0 to %3 : $*Test + %5 = alloc_stack $IndexingIterator + %6 = function_ref @project : $@convention(thin) (@in Test) -> @out IndexingIterator + %7 = apply %6(%5, %3) : $@convention(thin) (@in Test) -> @out IndexingIterator + %44 = alloc_stack $Optional + // function_ref protocol witness for IteratorProtocol.next() in conformance IndexingIterator + %45 = function_ref @next : $@convention(witness_method: IteratorProtocol) <τ_0_0 where τ_0_0 : Collection> (@inout IndexingIterator<τ_0_0>) -> @out Optional<τ_0_0.Element> + %46 = apply %45(%44, %5) : $@convention(witness_method: IteratorProtocol) <τ_0_0 where τ_0_0 : Collection> (@inout IndexingIterator<τ_0_0>) -> @out Optional<τ_0_0.Element> + destroy_addr %44: $*Optional + dealloc_stack %44 : $*Optional + destroy_addr %5: $*IndexingIterator + dealloc_stack %5 : $*IndexingIterator + dealloc_stack %3 : $*Test + %41 = tuple () + return %41 : $() +} +// CHECK-LABEL: sil shared @$s4next8External4TestV_Tg5 : $@convention(witness_method: IteratorProtocol) (@inout IndexingIterator) -> Optional +// CHECK: bb0(%0 : $*IndexingIterator): +// CHECK: alloc_stack $Optional +// CHECK: ([[RES:%.*]], %{{.*}}) = begin_apply {{.*}}({{.*}}) : $@yield_once @convention(witness_method: Collection) <τ_0_0 where τ_0_0 : Collection> (@in_guaranteed τ_0_0.Index, @in_guaranteed τ_0_0) -> @yields @in_guaranteed τ_0_0.Element +// CHECK: [[DEST:%.*]] = init_enum_data_addr %1 : $*Optional, #Optional.some!enumelt +// CHECK: copy_addr [[RES]] to [initialization] {{.*}} : $*Int64 +// CHECK: } // end sil function '$s4next8External4TestV_Tg5' + +sil @next : $@convention(witness_method: IteratorProtocol) <τ_0_0 where τ_0_0 : Collection> (@inout IndexingIterator<τ_0_0>) -> @out Optional<τ_0_0.Element> { +bb0(%0 : $*Optional<τ_0_0.Element>, %1 : $*IndexingIterator<τ_0_0>): + %2 = metatype $@thick τ_0_0.Index.Type + %3 = struct_element_addr %1 : $*IndexingIterator<τ_0_0>, #IndexingIterator._position + %4 = alloc_stack $τ_0_0.Index + copy_addr %3 to [initialization] %4 : $*τ_0_0.Index + %6 = struct_element_addr %1 : $*IndexingIterator<τ_0_0>, #IndexingIterator._elements + %20 = alloc_stack $τ_0_0 + copy_addr %6 to [initialization] %20 : $*τ_0_0 + %22 = alloc_stack $τ_0_0.Index + copy_addr %3 to [initialization] %22 : $*τ_0_0.Index + %24 = alloc_stack $τ_0_0 + copy_addr [take] %20 to [initialization] %24 : $*τ_0_0 + %26 = witness_method $τ_0_0, #Collection.subscript!read : (Self) -> (Self.Index) -> () : $@yield_once @convention(witness_method: Collection) <τ_0_0 where τ_0_0 : Collection> (@in_guaranteed τ_0_0.Index, @in_guaranteed τ_0_0) -> @yields @in_guaranteed τ_0_0.Element + + // The specialized begin apply %26 has a result type of t_0_0.Element + // which works out to be an opaque result type whose underlying type is Int64. + // Make sure that the specialized code handles this correctly. + (%27, %28) = begin_apply %26<τ_0_0>(%22, %24) : $@yield_once @convention(witness_method: Collection) <τ_0_0 where τ_0_0 : Collection> (@in_guaranteed τ_0_0.Index, @in_guaranteed τ_0_0) -> @yields @in_guaranteed τ_0_0.Element + + %29 = init_enum_data_addr %0 : $*Optional<τ_0_0.Element>, #Optional.some!enumelt + copy_addr %27 to [initialization] %29 : $*τ_0_0.Element + end_apply %28 + destroy_addr %22 : $*τ_0_0.Index + destroy_addr %24 : $*τ_0_0 + dealloc_stack %24 : $*τ_0_0 + dealloc_stack %22 : $*τ_0_0.Index + dealloc_stack %20 : $*τ_0_0 + destroy_addr %4 : $*τ_0_0.Index + dealloc_stack %4 : $*τ_0_0.Index + %41 = tuple () + return %41 : $() +} From 36f25eeee520f8da166111b41e715118eb6e62e1 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Tue, 5 May 2020 05:59:27 -0700 Subject: [PATCH 2/3] Re-enable test. --- test/SILOptimizer/specialize_opaque_type_archetypes.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/SILOptimizer/specialize_opaque_type_archetypes.swift b/test/SILOptimizer/specialize_opaque_type_archetypes.swift index ad7f8874a0f9e..0236c0817ccbd 100644 --- a/test/SILOptimizer/specialize_opaque_type_archetypes.swift +++ b/test/SILOptimizer/specialize_opaque_type_archetypes.swift @@ -5,8 +5,8 @@ // RUN: %target-swift-frontend -disable-availability-checking %S/Inputs/specialize_opaque_type_archetypes_3.swift -I %t -enable-library-evolution -module-name External2 -Osize -emit-module -o - | %target-sil-opt -module-name External2 | %FileCheck --check-prefix=RESILIENT %s // RUN: %target-swift-frontend -disable-availability-checking -I %t -module-name A -enforce-exclusivity=checked -Osize -emit-sil -sil-verify-all %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize // RUN: %target-swift-frontend -disable-availability-checking -I %t -module-name A -enforce-exclusivity=checked -enable-library-evolution -Osize -emit-sil -sil-verify-all %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize -// See radar for details - rdar://62560867 -// XFAIL: * + + import External import External2 import External3 From b455ac4dafff5ef977465b4ac0d3b2a3faf32f54 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Tue, 5 May 2020 14:36:33 -0700 Subject: [PATCH 3/3] Fix use of SILTypeSubstituter and TypeSubstitutionFn --- lib/SIL/IR/SILFunctionType.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 74f05d3963192..9dfbfe140cc1a 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -3769,11 +3769,18 @@ SILType SILType::subst(SILModule &M, SubstitutionMap subs, if (!hasArchetype() && !hasTypeParameter() && !getASTType()->hasOpaqueArchetype()) return *this; - SILTypeSubstituter STST(M.Types, context, QuerySubstitutionMap{subs}, - LookUpConformanceInSubstitutionMap(subs), - subs.getGenericSignature().getCanonicalSignature(), - false); - return STST.subst(*this); + + // Pass the TypeSubstitutionFn and LookupConformanceFn as arguments so that + // the llvm::function_ref value's scope spans the STST.subst call since + // SILTypeSubstituter captures these functions. + auto result = [&](TypeSubstitutionFn subsFn, + LookupConformanceFn conformancesFn) -> SILType { + SILTypeSubstituter STST(M.Types, context, subsFn, conformancesFn, + subs.getGenericSignature().getCanonicalSignature(), + false); + return STST.subst(*this); + }(QuerySubstitutionMap{subs}, LookUpConformanceInSubstitutionMap(subs)); + return result; } /// Apply a substitution to this polymorphic SILFunctionType so that