diff --git a/include/swift/SIL/SILFunction.h b/include/swift/SIL/SILFunction.h index e28f04f01cf..e51dd6220e7 100644 --- a/include/swift/SIL/SILFunction.h +++ b/include/swift/SIL/SILFunction.h @@ -70,7 +70,7 @@ public: SILModule &getModule() const { return *ModuleAndLinkage.getPointer(); } SILType getLoweredType() const { return LoweredType; } SILFunctionTypeInfo *getFunctionTypeInfo() const { - return LoweredType.getFunctionTypeInfo(); + return LoweredType.getFunctionTypeInfo(getModule()); } /// Returns the calling convention used by this entry point. diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h index 20e99aa1b7c..a977c64ab70 100644 --- a/include/swift/SIL/SILInstruction.h +++ b/include/swift/SIL/SILInstruction.h @@ -321,17 +321,17 @@ public: ArrayRef Args, SILFunction &F); - bool hasIndirectReturn() const { - return getCallee().getType().getFunctionTypeInfo()->hasIndirectReturn(); + bool hasIndirectReturn(SILModule &M) const { + return getCallee().getType().getFunctionTypeInfo(M)->hasIndirectReturn(); } - SILValue getIndirectReturn() const { - assert(hasIndirectReturn() && "apply inst does not have indirect return!"); + SILValue getIndirectReturn(SILModule &M) const { + assert(hasIndirectReturn(M) && "apply inst does not have indirect return!"); return getArguments().front(); } - OperandValueArrayRef getArgumentsWithoutIndirectReturn() const { - if (hasIndirectReturn()) + OperandValueArrayRef getArgumentsWithoutIndirectReturn(SILModule &M) const { + if (hasIndirectReturn(M)) return getArguments().slice(1); return getArguments(); } diff --git a/include/swift/SIL/SILModule.h b/include/swift/SIL/SILModule.h index caf0a9e48a2..9c31227c882 100644 --- a/include/swift/SIL/SILModule.h +++ b/include/swift/SIL/SILModule.h @@ -35,6 +35,7 @@ namespace swift { class FuncDecl; class SILFunction; class SILTypeList; + class AnyFunctionType; namespace Lowering { class SILGenModule; @@ -68,10 +69,15 @@ private: /// The collection of global variables used in the module. llvm::SetVector globals; - /// AddressOnlyTypeCache - This is a cache that memoizes the result of - /// SILType::isAddressOnly, to avoid recomputing it repeatedly. + /// This is a cache that memoizes the result of SILType::isAddressOnly. llvm::DenseMap AddressOnlyTypeCache; + /// This is a cache that memoizes the result of SILType::getFunctionTypeInfo. + llvm::DenseMap FunctionTypeInfoCache; + + /// Derive the SILFunctionTypeInfo for a type. + SILFunctionTypeInfo *makeFunctionTypeInfo(AnyFunctionType *ft); + // Intentionally marked private so that we need to use 'constructSIL()' // to construct a SILModule. SILModule(ASTContext &TheASTContext); @@ -85,7 +91,6 @@ public: /// getSILTypeList - Get a uniqued pointer to a SIL type list. SILTypeList *getSILTypeList(llvm::ArrayRef Types) const; - /// Types - This converts Swift types to SILTypes. Lowering::TypeConverter Types; diff --git a/include/swift/SIL/SILType.h b/include/swift/SIL/SILType.h index 819967abb4e..73df86b1933 100644 --- a/include/swift/SIL/SILType.h +++ b/include/swift/SIL/SILType.h @@ -34,36 +34,12 @@ namespace Lowering { } // end namespace swift -namespace llvm { - template - class PointerLikeTypeTraits; - - // SILTypeInfo* is always at least eight-byte aligned; make the three tag bits - // available through PointerLikeTypeTraits. - template<> - class PointerLikeTypeTraits { - public: - static inline void *getAsVoidPointer(swift::SILFunctionTypeInfo *I) { - return (void*)I; - } - static inline swift::SILFunctionTypeInfo *getFromVoidPointer(void *P) { - return (swift::SILFunctionTypeInfo*)P; - } - enum { NumLowBitsAvailable = 3 }; - }; -} // end namespace llvm - namespace swift { /// SILType - A Swift type that has been lowered to a SIL representation type. -/// In addition to the Swift type system, SIL adds the following types: -/// -/// - an "address" type that can reference any Swift type (but cannot take the -/// address of an address). *T is the type of an address pointing at T. -/// - uncurried function types. For the function type (T) -> (U) -> (V) -> W, -/// there are uncurried function type levels: -/// (T)(U) -> (V) -> W -/// (T)(U)(V) -> W +/// In addition to the Swift type system, SIL adds "address" types that can +/// reference any Swift type (but cannot take the address of an address). *T +/// is the type of an address pointing at T. /// /// SIL also has the notion of "loadable" vs "address-only" types: loadable /// types have a fixed size and compile-time binary representation and thus @@ -72,9 +48,8 @@ namespace swift { /// indirectly in memory. class SILType { public: - using PointerType = llvm::PointerUnion; // The bool value of the PointerIntPair is the "isAddress" bit. - using ValueType = llvm::PointerIntPair; + using ValueType = llvm::PointerIntPair; private: ValueType value; @@ -85,11 +60,6 @@ private: assert(!ty->is() && "LValueTypes should be eliminated by SIL lowering"); - assert(!ty->is() && - "SIL lowering must produce a SILFunctionTypeInfo for functions"); - } - - SILType(SILFunctionTypeInfo *ti, bool isAddress) : value(ti, isAddress) { } SILType(ValueType value) : value(value) { @@ -100,15 +70,13 @@ private: public: SILType() = default; - /// getPrimitiveType - Form a SILType for a primitive type that does not /// require any special handling (i.e., not a function or aggregate type). static SILType getPrimitiveType(CanType T, bool isAddress) { return SILType(T, isAddress); } - - - bool isNull() const { return value.getPointer().isNull(); } + + bool isNull() const { return bool(value.getPointer()); } explicit operator bool() const { return bool(value.getPointer()); } /// Gets the address type referencing this type, or the type itself if it is @@ -124,7 +92,9 @@ public: } /// Returns the Swift type referenced by this SIL type. - CanType getSwiftRValueType() const; + CanType getSwiftRValueType() const { + return CanType(value.getPointer()); + } /// Returns the Swift type equivalent to this SIL type. If the SIL type is /// an address type, returns an LValueType. @@ -139,9 +109,7 @@ public: /// Gives the SILFunctionTypeInfo for a function type. The type must be /// derived from a Swift FunctionType or PolymorphicFunctionType. - SILFunctionTypeInfo *getFunctionTypeInfo() const { - return value.getPointer().get(); - } + SILFunctionTypeInfo *getFunctionTypeInfo(SILModule &M) const; /// Returns the Swift return type of a function type. /// The SILType must refer to a function type. @@ -250,12 +218,11 @@ inline raw_ostream &operator<<(raw_ostream &OS, SILType T) { return OS; } -/// SILFunctionTypeInfo - SILType for a FunctionType or PolymorphicFunctionType. -/// Specifies the uncurry level and SIL-level calling convention for the -/// function. -class alignas(8) SILFunctionTypeInfo { - // alignas(8) because we need three tag bits on SILFunctionTypeInfo* - // for SILType. +/// Redundant but expensive-to-recompute information about a SIL +/// FunctionType or PolymorphicFunctionType. Contains the details of the +/// SIL-level calling convention for the function, including its exploded +/// input argument types and whether it uses an indirect return argument. +class SILFunctionTypeInfo { CanType swiftType; SILType resultType; unsigned inputTypeCount : 31; @@ -324,15 +291,6 @@ public: } }; -inline CanType SILType::getSwiftRValueType() const { - PointerType p = value.getPointer(); - if (auto *ty = p.dyn_cast()) - return CanType(ty); - if (auto *ti = p.dyn_cast()) - return ti->getSwiftType(); - llvm_unreachable("unknown SILType pointer type"); -} - } // end swift namespace namespace llvm { diff --git a/include/swift/SIL/TypeLowering.h b/include/swift/SIL/TypeLowering.h index 3c3d36ca892..6abe38d00ef 100644 --- a/include/swift/SIL/TypeLowering.h +++ b/include/swift/SIL/TypeLowering.h @@ -189,7 +189,6 @@ class TypeConverter { const TypeLoweringInfo &makeTypeLoweringInfo(CanType t, unsigned uncurryLevel); - SILFunctionTypeInfo *makeInfoForFunctionType(AnyFunctionType *ft); Type makeConstantType(SILConstant constant); diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp index 7b1945149fe..b580a142154 100644 --- a/lib/IRGen/GenFunc.cpp +++ b/lib/IRGen/GenFunc.cpp @@ -1778,7 +1778,8 @@ llvm::Function *irgen::emitFunctionSpecialization(IRGenModule &IGM, // Collect the indirect return address, if present. Address indirectReturn; - SILType retTy = substType.getFunctionTypeInfo()->getSemanticResultType(); + SILType retTy + = substType.getFunctionTypeInfo(*IGM.SILMod)->getSemanticResultType(); TypeInfo const &retTI = IGM.getFragileTypeInfo(retTy); ExplosionSchema schema = retTI.getSchema(explosionLevel); diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index a6f65f0d382..75ba6c3e53e 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -197,7 +197,7 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, SILBasicBlock *entry, Explosion ¶ms, SILType funcTy) { - SILFunctionTypeInfo *funcTI = funcTy.getFunctionTypeInfo(); + SILFunctionTypeInfo *funcTI = funcTy.getFunctionTypeInfo(*IGF.IGM.SILMod); // Map the indirect return if present. ArrayRef args @@ -265,7 +265,7 @@ static void emitEntryPointArgumentsObjCMethodCC(IRGenSILFunction &IGF, SILBasicBlock *entry, Explosion ¶ms, SILType funcTy) { - SILFunctionTypeInfo *funcTI = funcTy.getFunctionTypeInfo(); + SILFunctionTypeInfo *funcTI = funcTy.getFunctionTypeInfo(*IGF.IGM.SILMod); // Map the indirect return if present. ArrayRef args @@ -294,7 +294,7 @@ static void emitEntryPointArgumentsCCC(IRGenSILFunction &IGF, SILBasicBlock *entry, Explosion ¶ms, SILType funcTy) { - SILFunctionTypeInfo *funcTI = funcTy.getFunctionTypeInfo(); + SILFunctionTypeInfo *funcTI = funcTy.getFunctionTypeInfo(*IGF.IGM.SILMod); // Map the indirect return if present. ArrayRef args @@ -697,8 +697,8 @@ static void emitBuiltinApplyInst(IRGenSILFunction &IGF, auto argValues = i->getArguments(); Address indirectResult; - if (i->hasIndirectReturn()) { - indirectResult = IGF.getLoweredAddress(i->getIndirectReturn()); + if (i->hasIndirectReturn(*IGF.IGM.SILMod)) { + indirectResult =IGF.getLoweredAddress(i->getIndirectReturn(*IGF.IGM.SILMod)); argValues = argValues.slice(0, argValues.size() - 1); } @@ -727,7 +727,8 @@ void IRGenSILFunction::visitApplyInst(swift::ApplyInst *i) { } SILType calleeTy = i->getCallee().getType(); - SILType resultTy = calleeTy.getFunctionTypeInfo()->getSemanticResultType(); + SILType resultTy + = calleeTy.getFunctionTypeInfo(*IGM.SILMod)->getSemanticResultType(); CallEmission emission = getCallEmissionForLoweredValue(*this, i->getCallee().getType(), @@ -737,10 +738,10 @@ void IRGenSILFunction::visitApplyInst(swift::ApplyInst *i) { Explosion llArgs(CurExplosionLevel); // Save off the indirect return argument, if any. - OperandValueArrayRef args = i->getArgumentsWithoutIndirectReturn(); + OperandValueArrayRef args = i->getArgumentsWithoutIndirectReturn(*IGM.SILMod); SILValue indirectReturn; - if (i->hasIndirectReturn()) { - indirectReturn = i->getIndirectReturn(); + if (i->hasIndirectReturn(*IGM.SILMod)) { + indirectReturn = i->getIndirectReturn(*IGM.SILMod); } // ObjC message sends need special handling for the 'this' argument. It may diff --git a/lib/SIL/SILGen/OwnershipConventions.cpp b/lib/SIL/SILGen/OwnershipConventions.cpp index a11c82b6f4c..6f3c01003df 100644 --- a/lib/SIL/SILGen/OwnershipConventions.cpp +++ b/lib/SIL/SILGen/OwnershipConventions.cpp @@ -92,9 +92,9 @@ OwnershipConventions OwnershipConventions::get(SILGenFunction &gen, SILType ty) { // Native functions use the default Swift convention. if (!c.isObjC) - return getDefault(ty); + return getDefault(gen, ty); - SILFunctionTypeInfo *ft = ty.getFunctionTypeInfo(); + SILFunctionTypeInfo *ft = ty.getFunctionTypeInfo(gen.SGM.M); // If we have a clang decl associated with the Swift decl, derive its // ownership conventions. @@ -109,8 +109,9 @@ OwnershipConventions OwnershipConventions::get(SILGenFunction &gen, return getForObjCSelectorFamily(getSelectorFamily(c), ft); } -OwnershipConventions OwnershipConventions::getDefault(SILType ty) { - SILFunctionTypeInfo *ft = ty.getFunctionTypeInfo(); +OwnershipConventions OwnershipConventions::getDefault(SILGenFunction &gen, + SILType ty) { + SILFunctionTypeInfo *ft = ty.getFunctionTypeInfo(gen.SGM.M); size_t inputTypeCount = ft->getInputTypes().size(); return { /*calleeConsumed*/ true, diff --git a/lib/SIL/SILGen/OwnershipConventions.h b/lib/SIL/SILGen/OwnershipConventions.h index a7ac83b2a9d..b6d5d02c8b0 100644 --- a/lib/SIL/SILGen/OwnershipConventions.h +++ b/lib/SIL/SILGen/OwnershipConventions.h @@ -73,7 +73,8 @@ public: /// Derive the default Swift ownership conventions for a SILType, which must /// represent a function type. - static OwnershipConventions getDefault(SILType ty); + static OwnershipConventions getDefault(SILGenFunction &gen, + SILType ty); /// True if the callee consumes itself when called. bool isCalleeConsumed() const { return calleeConsumed; } diff --git a/lib/SIL/SILGen/SILGenApply.cpp b/lib/SIL/SILGen/SILGenApply.cpp index ecf54a41aab..e5a23dd9fce 100644 --- a/lib/SIL/SILGen/SILGenApply.cpp +++ b/lib/SIL/SILGen/SILGenApply.cpp @@ -267,7 +267,7 @@ public: case Kind::IndirectValue: assert(level == 0 && "can't curry indirect function"); mv = indirectValue; - ownership = OwnershipConventions::getDefault(mv.getType()); + ownership = OwnershipConventions::getDefault(gen, mv.getType()); break; case Kind::StandaloneFunction: { @@ -317,7 +317,7 @@ public: // FIXME: We currently assume all archetype methods have native ownership // semantics. - ownership = OwnershipConventions::getDefault(method.getType()); + ownership = OwnershipConventions::getDefault(gen, method.getType()); break; } case Kind::ProtocolMethod: { @@ -335,7 +335,7 @@ public: // FIXME: We currently assume all protocol methods have native ownership // semantics. - ownership = OwnershipConventions::getDefault(method.getType()); + ownership = OwnershipConventions::getDefault(gen, method.getType()); break; } } @@ -354,7 +354,7 @@ public: // have changed the function signature. // FIXME: Currently only native methods can be specialized, so always use // default ownership semantics. - ownership = OwnershipConventions::getDefault(specializedUncurriedType); + ownership = OwnershipConventions::getDefault(gen, specializedUncurriedType); } return {mv, ownership}; diff --git a/lib/SIL/SILGen/SILGenDecl.cpp b/lib/SIL/SILGen/SILGenDecl.cpp index b657451a480..f9e6949484c 100644 --- a/lib/SIL/SILGen/SILGenDecl.cpp +++ b/lib/SIL/SILGen/SILGenDecl.cpp @@ -1031,7 +1031,7 @@ void SILGenFunction::emitObjCMethodThunk(SILConstant thunk) { auto ownership = OwnershipConventions::get(*this, thunk, thunkTy); SmallVector args; - SILFunctionTypeInfo *info = thunkTy.getFunctionTypeInfo(); + SILFunctionTypeInfo *info = thunkTy.getFunctionTypeInfo(SGM.M); if (info->hasIndirectReturn()) { args.push_back(new(F.getModule()) SILArgument(info->getIndirectReturnType(), F.begin())); @@ -1067,7 +1067,7 @@ void SILGenFunction::emitObjCMethodThunk(SILConstant thunk) { void SILGenFunction::emitObjCPropertyGetter(SILConstant getter) { SILType thunkTy = SGM.getConstantType(getter); auto ownership = OwnershipConventions::get(*this, getter, thunkTy); - SILFunctionTypeInfo *info = thunkTy.getFunctionTypeInfo(); + SILFunctionTypeInfo *info = thunkTy.getFunctionTypeInfo(SGM.M); SILValue indirectReturn; SILType resultType; @@ -1126,7 +1126,7 @@ void SILGenFunction::emitObjCPropertyGetter(SILConstant getter) { void SILGenFunction::emitObjCPropertySetter(SILConstant setter) { SILType thunkTy = SGM.getConstantType(setter); auto ownership = OwnershipConventions::get(*this, setter, thunkTy); - SILFunctionTypeInfo *info = thunkTy.getFunctionTypeInfo(); + SILFunctionTypeInfo *info = thunkTy.getFunctionTypeInfo(SGM.M); SILValue thisValue = new (F.getModule()) SILArgument(info->getInputTypes()[0], F.begin()); diff --git a/lib/SIL/SILGen/SILGenExpr.cpp b/lib/SIL/SILGen/SILGenExpr.cpp index 0bde970de64..bf40c72f879 100644 --- a/lib/SIL/SILGen/SILGenExpr.cpp +++ b/lib/SIL/SILGen/SILGenExpr.cpp @@ -1782,7 +1782,7 @@ void SILGenFunction::emitCurryThunk(FuncExpr *fe, // Partially apply the next uncurry level and return the result closure. auto toFn = B.createFunctionRef(fe, SGM.getFunction(to)); SILType resultTy - = SGM.getConstantType(from).getFunctionTypeInfo()->getResultType(); + = SGM.getConstantType(from).getFunctionTypeInfo(SGM.M)->getResultType(); auto toClosure = B.createPartialApply(fe, toFn, curriedArgs, resultTy); B.createReturn(fe, toClosure); } diff --git a/lib/SIL/SILModule.cpp b/lib/SIL/SILModule.cpp index a56c31ece03..1cb7ba6e071 100644 --- a/lib/SIL/SILModule.cpp +++ b/lib/SIL/SILModule.cpp @@ -12,6 +12,7 @@ #include "swift/SIL/SILModule.h" #include "swift/SIL/SILValue.h" +#include "swift/SIL/TypeVisitor.h" #include "llvm/ADT/FoldingSet.h" using namespace swift; @@ -85,3 +86,49 @@ SILTypeList *SILModule::getSILTypeList(ArrayRef Types) const { UniqueMap->InsertNode(NewList, InsertPoint); return NewList; } + +namespace { + /// Recursively destructure tuple-type arguments into SIL argument types. + class LoweredFunctionInputTypeVisitor + : public Lowering::TypeVisitor + { + SILModule &M; + SmallVectorImpl &inputTypes; + public: + LoweredFunctionInputTypeVisitor(SILModule &M, + SmallVectorImpl &inputTypes) + : M(M), inputTypes(inputTypes) {} + + void visitType(TypeBase *t) { + inputTypes.push_back(M.Types.getLoweredType(t)); + } + + void visitTupleType(TupleType *tt) { + for (auto &field : tt->getFields()) { + visit(field.getType()->getCanonicalType()); + } + } + }; +} // end anonymous namespace + +SILFunctionTypeInfo *SILModule::makeFunctionTypeInfo(AnyFunctionType *ft) +{ + SmallVector inputTypes; + + // If the result type lowers to an address-only type, add it as an indirect + // return argument. + SILType resultType = Types.getLoweredType(ft->getResult()); + bool hasIndirectReturn = resultType.isAddressOnly(*this); + if (hasIndirectReturn) { + inputTypes.push_back(resultType); + resultType = Types.getEmptyTupleType(); + } + + // Destructure the input tuple type. + LoweredFunctionInputTypeVisitor(*this, inputTypes) + .visit(ft->getInput()->getCanonicalType()); + + return SILFunctionTypeInfo::create(CanType(ft), inputTypes, resultType, + hasIndirectReturn, *this); +} + diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp index 160274f9229..abff3e25c29 100644 --- a/lib/SIL/SILPrinter.cpp +++ b/lib/SIL/SILPrinter.cpp @@ -117,15 +117,6 @@ void SILType::print(raw_ostream &OS) const { // Build up the attributes for a SIL type, if any. llvm::SmallString<64> Attributes; - if (is()) { - auto info = getFunctionTypeInfo(); - - if (info->hasIndirectReturn()) { - if (!Attributes.empty()) Attributes += ", "; - Attributes += "sil_sret"; - } - } - // If we have any attributes, print them out. if (!Attributes.empty()) diff --git a/lib/SIL/SILType.cpp b/lib/SIL/SILType.cpp index 678e295de81..dfc5d6ac6d6 100644 --- a/lib/SIL/SILType.cpp +++ b/lib/SIL/SILType.cpp @@ -16,7 +16,7 @@ #include "swift/AST/Decl.h" using namespace swift; -/// isAddressOnly - True if the type, or the referenced type of an address +/// True if the type, or the referenced type of an address /// type, is address-only. For example, it could be a resilient struct or /// something of unknown size. bool SILType::isAddressOnly(CanType Ty, SILModule &M) { @@ -75,23 +75,34 @@ bool SILType::isAddressOnly(CanType Ty, SILModule &M) { return false; } +SILFunctionTypeInfo *SILType::getFunctionTypeInfo(SILModule &M) const { + AnyFunctionType *ft = cast(getSwiftRValueType()); + + auto found = M.FunctionTypeInfoCache.find(ft); + if (found != M.FunctionTypeInfoCache.end()) + return found->second; + + SILFunctionTypeInfo *info = M.makeFunctionTypeInfo(ft); + M.FunctionTypeInfoCache[ft] = info; + return info; +} SILFunctionTypeInfo *SILFunctionTypeInfo::create(CanType swiftType, - ArrayRef inputTypes, - SILType resultType, - bool hasIndirectReturn, - SILModule &M) { + ArrayRef inputTypes, + SILType resultType, + bool hasIndirectReturn, + SILModule &M) { // We allocate room for an extra unsigned in the uncurriedInputCounts array, // so that we can stuff a leading zero in there and be able to efficiently // return both the begins and ends of each uncurried argument group. void *buffer = M.allocate(sizeof(SILFunctionTypeInfo) + sizeof(SILType)*inputTypes.size(), alignof(SILFunctionTypeInfo)); - SILFunctionTypeInfo *fi = ::new (buffer) SILFunctionTypeInfo( - swiftType, - inputTypes.size(), - resultType, - hasIndirectReturn); + SILFunctionTypeInfo *fi + = ::new (buffer) SILFunctionTypeInfo(swiftType, + inputTypes.size(), + resultType, + hasIndirectReturn); memcpy(fi->getInputTypeBuffer(), inputTypes.data(), sizeof(SILType) * inputTypes.size()); return fi; diff --git a/lib/SIL/TypeLowering.cpp b/lib/SIL/TypeLowering.cpp index 36a33d60d73..b5d7e02861c 100644 --- a/lib/SIL/TypeLowering.cpp +++ b/lib/SIL/TypeLowering.cpp @@ -256,50 +256,6 @@ TypeConverter::~TypeConverter() { } } -namespace { - /// Recursively destructure tuple-type arguments into SIL argument types. - class LoweredFunctionInputTypeVisitor - : public Lowering::TypeVisitor { - TypeConverter &tc; - SmallVectorImpl &inputTypes; - public: - LoweredFunctionInputTypeVisitor(TypeConverter &tc, - SmallVectorImpl &inputTypes) - : tc(tc), inputTypes(inputTypes) {} - - void visitType(TypeBase *t) { - inputTypes.push_back(tc.getLoweredType(t)); - } - - void visitTupleType(TupleType *tt) { - for (auto &field : tt->getFields()) { - visit(field.getType()->getCanonicalType()); - } - } - }; -} // end anonymous namespace - -SILFunctionTypeInfo *TypeConverter::makeInfoForFunctionType(AnyFunctionType *ft) -{ - SmallVector inputTypes; - - // If the result type lowers to an address-only type, add it as an indirect - // return argument. - SILType resultType = getLoweredType(ft->getResult()); - bool hasIndirectReturn = resultType.isAddressOnly(M); - if (hasIndirectReturn) { - inputTypes.push_back(resultType); - resultType = getEmptyTupleType(); - } - - // Destructure the input tuple type. - LoweredFunctionInputTypeVisitor(*this, inputTypes) - .visit(ft->getInput()->getCanonicalType()); - - return SILFunctionTypeInfo::create(CanType(ft), inputTypes, resultType, - hasIndirectReturn, M); -} - const TypeLoweringInfo & TypeConverter::makeTypeLoweringInfo(CanType t, unsigned uncurryLevel) { void *infoBuffer = TypeLoweringInfoBPA.Allocate(); @@ -324,13 +280,14 @@ TypeConverter::makeTypeLoweringInfo(CanType t, unsigned uncurryLevel) { LoadableTypeLoweringInfoVisitor(*theInfo).visit(t); } - // Make a SILFunctionTypeInfo for function types. + // Uncurry function types. if (AnyFunctionType *ft = t->getAs()) { + assert(!addressOnly && "function types should never be address-only"); auto *uncurried = getUncurriedFunctionType(ft, uncurryLevel); - theInfo->loweredType = SILType(makeInfoForFunctionType(uncurried), - /*address=*/ addressOnly); + theInfo->loweredType = SILType(uncurried->getCanonicalType(), + /*address=*/ false); } else { - // Otherwise, create a SILType from just the Swift type. + // Otherwise, the Swift type maps directly to a SILType. assert(uncurryLevel == 0 && "non-function type cannot have an uncurry level"); theInfo->loweredType = SILType(t, /*address=*/ addressOnly); diff --git a/lib/SIL/Verifier.cpp b/lib/SIL/Verifier.cpp index e34d5fcda50..7418e9dea18 100644 --- a/lib/SIL/Verifier.cpp +++ b/lib/SIL/Verifier.cpp @@ -156,7 +156,7 @@ public: require(!calleeTy.isAddress(), "callee of apply cannot be an address"); require(calleeTy.is(), "callee of apply must have concrete function type"); - SILFunctionTypeInfo *ti = calleeTy.getFunctionTypeInfo(); + SILFunctionTypeInfo *ti = calleeTy.getFunctionTypeInfo(F.getModule()); DEBUG(llvm::dbgs() << "function input types:\n"; for (SILType t : ti->getInputTypes()) { @@ -207,8 +207,10 @@ public: require(!appliedTy.castTo()->isThin(), "result of closure cannot have a thin function type"); - SILFunctionTypeInfo *info = calleeTy.getFunctionTypeInfo(); - SILFunctionTypeInfo *resultInfo = appliedTy.getFunctionTypeInfo(); + SILFunctionTypeInfo *info + = calleeTy.getFunctionTypeInfo(F.getModule()); + SILFunctionTypeInfo *resultInfo + = appliedTy.getFunctionTypeInfo(F.getModule()); // The arguments must match the suffix of the original function's input // types. @@ -912,8 +914,9 @@ public: "convert_function cannot change function thinness"); SILFunctionTypeInfo *opTI - = ICI->getOperand().getType().getFunctionTypeInfo(); - SILFunctionTypeInfo *resTI = ICI->getType().getFunctionTypeInfo(); + = ICI->getOperand().getType().getFunctionTypeInfo(F.getModule()); + SILFunctionTypeInfo *resTI + = ICI->getType().getFunctionTypeInfo(F.getModule()); require(opTI->getResultType() == resTI->getResultType(), "result types of convert_function operand and result do no match"); @@ -929,7 +932,7 @@ public: DEBUG(RI->print(llvm::dbgs())); SILFunctionTypeInfo *ti = - F.getLoweredType().getFunctionTypeInfo(); + F.getLoweredType().getFunctionTypeInfo(F.getModule()); SILType functionResultType = ti->getResultType(); SILType instResultType = RI->getOperand().getType(); DEBUG(llvm::dbgs() << "function return type: "; @@ -944,7 +947,7 @@ public: DEBUG(RI->print(llvm::dbgs())); SILFunctionTypeInfo *ti = - F.getLoweredType().getFunctionTypeInfo(); + F.getLoweredType().getFunctionTypeInfo(F.getModule()); SILType functionResultType = ti->getResultType(); SILType instResultType = RI->getOperand().getType(); DEBUG(llvm::dbgs() << "function return type: "; @@ -997,7 +1000,7 @@ public: void verifyEntryPointArguments(SILBasicBlock *entry) { SILType ty = F.getLoweredType(); - SILFunctionTypeInfo *ti = ty.getFunctionTypeInfo(); + SILFunctionTypeInfo *ti = ty.getFunctionTypeInfo(F.getModule()); DEBUG(llvm::dbgs() << "Argument types for entry point BB:\n"; for (auto *arg : make_range(entry->bbarg_begin(), entry->bbarg_end()))