mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
SIL: Move SILFunctionTypeInfo into a side table.
Generate and cache SILFunctionTypeInfo from Swift types on the fly, and simplify the SILType representation down to a CanType and isAddress bit. Swift SVN r5298
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -321,17 +321,17 @@ public:
|
||||
ArrayRef<SILValue> 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();
|
||||
}
|
||||
|
||||
@@ -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<VarDecl*> 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<TypeBase*, bool> AddressOnlyTypeCache;
|
||||
|
||||
/// This is a cache that memoizes the result of SILType::getFunctionTypeInfo.
|
||||
llvm::DenseMap<AnyFunctionType*, SILFunctionTypeInfo*> 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<SILType> Types) const;
|
||||
|
||||
|
||||
/// Types - This converts Swift types to SILTypes.
|
||||
Lowering::TypeConverter Types;
|
||||
|
||||
|
||||
@@ -34,36 +34,12 @@ namespace Lowering {
|
||||
|
||||
} // end namespace swift
|
||||
|
||||
namespace llvm {
|
||||
template<typename T>
|
||||
class PointerLikeTypeTraits;
|
||||
|
||||
// SILTypeInfo* is always at least eight-byte aligned; make the three tag bits
|
||||
// available through PointerLikeTypeTraits.
|
||||
template<>
|
||||
class PointerLikeTypeTraits<swift::SILFunctionTypeInfo*> {
|
||||
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<TypeBase *, SILFunctionTypeInfo *>;
|
||||
// The bool value of the PointerIntPair is the "isAddress" bit.
|
||||
using ValueType = llvm::PointerIntPair<PointerType, 1, bool>;
|
||||
using ValueType = llvm::PointerIntPair<TypeBase *, 1, bool>;
|
||||
private:
|
||||
ValueType value;
|
||||
|
||||
@@ -85,11 +60,6 @@ private:
|
||||
|
||||
assert(!ty->is<LValueType>() &&
|
||||
"LValueTypes should be eliminated by SIL lowering");
|
||||
assert(!ty->is<AnyFunctionType>() &&
|
||||
"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*>();
|
||||
}
|
||||
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<TypeBase*>())
|
||||
return CanType(ty);
|
||||
if (auto *ti = p.dyn_cast<SILFunctionTypeInfo*>())
|
||||
return ti->getSwiftType();
|
||||
llvm_unreachable("unknown SILType pointer type");
|
||||
}
|
||||
|
||||
} // end swift namespace
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@@ -189,7 +189,6 @@ class TypeConverter {
|
||||
|
||||
const TypeLoweringInfo &makeTypeLoweringInfo(CanType t,
|
||||
unsigned uncurryLevel);
|
||||
SILFunctionTypeInfo *makeInfoForFunctionType(AnyFunctionType *ft);
|
||||
|
||||
Type makeConstantType(SILConstant constant);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<SILArgument*> 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<SILArgument*> 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<SILArgument*> 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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -1031,7 +1031,7 @@ void SILGenFunction::emitObjCMethodThunk(SILConstant thunk) {
|
||||
auto ownership = OwnershipConventions::get(*this, thunk, thunkTy);
|
||||
|
||||
SmallVector<SILValue, 4> 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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<SILType> Types) const {
|
||||
UniqueMap->InsertNode(NewList, InsertPoint);
|
||||
return NewList;
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// Recursively destructure tuple-type arguments into SIL argument types.
|
||||
class LoweredFunctionInputTypeVisitor
|
||||
: public Lowering::TypeVisitor<LoweredFunctionInputTypeVisitor>
|
||||
{
|
||||
SILModule &M;
|
||||
SmallVectorImpl<SILType> &inputTypes;
|
||||
public:
|
||||
LoweredFunctionInputTypeVisitor(SILModule &M,
|
||||
SmallVectorImpl<SILType> &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<SILType, 8> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<AnyFunctionType>()) {
|
||||
auto info = getFunctionTypeInfo();
|
||||
|
||||
if (info->hasIndirectReturn()) {
|
||||
if (!Attributes.empty()) Attributes += ", ";
|
||||
Attributes += "sil_sret";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If we have any attributes, print them out.
|
||||
if (!Attributes.empty())
|
||||
|
||||
@@ -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,6 +75,17 @@ bool SILType::isAddressOnly(CanType Ty, SILModule &M) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SILFunctionTypeInfo *SILType::getFunctionTypeInfo(SILModule &M) const {
|
||||
AnyFunctionType *ft = cast<AnyFunctionType>(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<SILType> inputTypes,
|
||||
@@ -87,8 +98,8 @@ SILFunctionTypeInfo *SILFunctionTypeInfo::create(CanType swiftType,
|
||||
void *buffer = M.allocate(sizeof(SILFunctionTypeInfo)
|
||||
+ sizeof(SILType)*inputTypes.size(),
|
||||
alignof(SILFunctionTypeInfo));
|
||||
SILFunctionTypeInfo *fi = ::new (buffer) SILFunctionTypeInfo(
|
||||
swiftType,
|
||||
SILFunctionTypeInfo *fi
|
||||
= ::new (buffer) SILFunctionTypeInfo(swiftType,
|
||||
inputTypes.size(),
|
||||
resultType,
|
||||
hasIndirectReturn);
|
||||
|
||||
@@ -256,50 +256,6 @@ TypeConverter::~TypeConverter() {
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// Recursively destructure tuple-type arguments into SIL argument types.
|
||||
class LoweredFunctionInputTypeVisitor
|
||||
: public Lowering::TypeVisitor<LoweredFunctionInputTypeVisitor> {
|
||||
TypeConverter &tc;
|
||||
SmallVectorImpl<SILType> &inputTypes;
|
||||
public:
|
||||
LoweredFunctionInputTypeVisitor(TypeConverter &tc,
|
||||
SmallVectorImpl<SILType> &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<SILType, 8> 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<TypeLoweringInfo>();
|
||||
@@ -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<AnyFunctionType>()) {
|
||||
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);
|
||||
|
||||
@@ -156,7 +156,7 @@ public:
|
||||
require(!calleeTy.isAddress(), "callee of apply cannot be an address");
|
||||
require(calleeTy.is<FunctionType>(),
|
||||
"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<FunctionType>()->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()))
|
||||
|
||||
Reference in New Issue
Block a user