SIL: Plumb TypeExpansionContext through SIL

This commit is contained in:
Arnold Schwaighofer
2019-11-04 11:56:44 -08:00
parent e67b96139d
commit 9ecda0c574
21 changed files with 315 additions and 202 deletions

View File

@@ -293,7 +293,8 @@ public:
///
/// WARNING: This is not a constant time operation because it is implemented
/// in terms of getVarDecl, which requests all BaseType's stored properties.
SILType getType(SILType BaseType, SILModule &M) const;
SILType getType(SILType BaseType, SILModule &M,
TypeExpansionContext context) const;
VarDecl *getVarDecl(SILType BaseType) const {
assert(isValid());
@@ -402,6 +403,7 @@ public:
/// Given a specific SILType, return all first level projections if it is an
/// aggregate.
static void getFirstLevelProjections(SILType V, SILModule &Mod,
TypeExpansionContext context,
llvm::SmallVectorImpl<Projection> &Out);
/// Is this cast which only allows for equality?
@@ -584,6 +586,7 @@ public:
/// is a leaf node in the type tree.
static void expandTypeIntoLeafProjectionPaths(SILType BaseType,
SILModule *Mod,
TypeExpansionContext context,
ProjectionPathList &P);
/// Return true if the given projection paths in \p CPaths does not cover
@@ -626,26 +629,27 @@ public:
SILType getBaseType() const { return BaseType; }
/// Returns the most derived type of the projection path.
SILType getMostDerivedType(SILModule &M) {
SILType getMostDerivedType(SILModule &M, TypeExpansionContext context) {
if (Path.empty())
return getBaseType();
if (MostDerivedType)
return MostDerivedType;
MostDerivedType = getDerivedType(Path.size(), M);
MostDerivedType = getDerivedType(Path.size(), M, context);
return MostDerivedType;
}
/// Returns the ith derived type of the path. This is zero indexed with 0
/// being the base type and n consisting of applying the up to n projections
/// to the base type.
SILType getDerivedType(unsigned i, SILModule &M) const {
SILType getDerivedType(unsigned i, SILModule &M,
TypeExpansionContext context) const {
assert(i <= Path.size());
SILType IterTy = getBaseType();
if (i == 0)
return IterTy;
for (unsigned j : range(i)) {
auto &Proj = Path[j];
IterTy = Proj.getType(IterTy, M);
IterTy = Proj.getType(IterTy, M, context);
}
return IterTy;
}
@@ -671,10 +675,11 @@ public:
const_reverse_iterator rbegin() const { return Path.rbegin(); }
const_reverse_iterator rend() const { return Path.rend(); }
void verify(SILModule &M);
void verify(SILModule &M, TypeExpansionContext context);
raw_ostream &print(raw_ostream &OS, SILModule &M) const;
void dump(SILModule &M) const;
raw_ostream &print(raw_ostream &OS, SILModule &M,
TypeExpansionContext context) const;
void dump(SILModule &M, TypeExpansionContext context) const;
};
/// Returns the hashcode for the new projection path.
@@ -813,9 +818,11 @@ private:
llvm::SmallVectorImpl<ValueNodePair> &Worklist,
SILValue Value);
void createNextLevelChildren(ProjectionTree &Tree);
void createNextLevelChildren(ProjectionTree &Tree, TypeExpansionContext context);
void createNextLevelChildrenForStruct(ProjectionTree &Tree, StructDecl *SD);
void createNextLevelChildrenForStruct(ProjectionTree &Tree,
TypeExpansionContext context,
StructDecl *SD);
void createNextLevelChildrenForTuple(ProjectionTree &Tree, TupleType *TT);
};

View File

@@ -214,7 +214,8 @@ public:
/// Allocate a new argument of type \p Ty and append it to the argument
/// list. Optionally you can pass in a value decl parameter.
SILFunctionArgument *createFunctionArgument(SILType Ty,
const ValueDecl *D = nullptr);
const ValueDecl *D = nullptr,
bool disableEntryBlockVerification = false);
SILFunctionArgument *insertFunctionArgument(unsigned Index, SILType Ty,
ValueOwnershipKind OwnershipKind,

View File

@@ -197,16 +197,23 @@ public:
assert(F && "cannot create this instruction without a function context");
return *F;
}
TypeExpansionContext getTypeExpansionContext() const {
return TypeExpansionContext(getFunction());
}
SILBuilderContext &getBuilderContext() const { return C; }
SILModule &getModule() const { return C.Module; }
ASTContext &getASTContext() const { return getModule().getASTContext(); }
const Lowering::TypeLowering &getTypeLowering(SILType T) const {
auto expansion = ResilienceExpansion::Maximal;
auto expansion = TypeExpansionContext::maximal(getModule().getSwiftModule(),
getModule().isWholeModule());
// If there's no current SILFunction, we're inserting into a global
// variable initializer.
if (F)
expansion = F->getResilienceExpansion();
if (F) {
expansion = TypeExpansionContext(getFunction());
}
return getModule().Types.getTypeLowering(T, expansion);
}
@@ -336,12 +343,11 @@ public:
// Type remapping
//===--------------------------------------------------------------------===//
static SILType
getPartialApplyResultType(SILType Ty, unsigned ArgCount, SILModule &M,
SubstitutionMap subs,
ParameterConvention calleeConvention,
PartialApplyInst::OnStackKind onStack =
PartialApplyInst::OnStackKind::NotOnStack);
static SILType getPartialApplyResultType(
TypeExpansionContext context, SILType Ty, unsigned ArgCount, SILModule &M,
SubstitutionMap subs, ParameterConvention calleeConvention,
PartialApplyInst::OnStackKind onStack =
PartialApplyInst::OnStackKind::NotOnStack);
//===--------------------------------------------------------------------===//
// CFG Manipulation
@@ -574,7 +580,8 @@ public:
FunctionRefBaseInst *createFunctionRefFor(SILLocation Loc, SILFunction *f) {
if (f->isDynamicallyReplaceable())
return createDynamicFunctionRef(Loc, f);
else return createFunctionRef(Loc, f);
else
return createFunctionRef(Loc, f);
}
FunctionRefBaseInst *createFunctionRef(SILLocation Loc, SILFunction *f,
@@ -590,20 +597,20 @@ public:
}
FunctionRefInst *createFunctionRef(SILLocation Loc, SILFunction *f) {
return insert(new (getModule())
FunctionRefInst(getSILDebugLocation(Loc), f));
return insert(new (getModule()) FunctionRefInst(getSILDebugLocation(Loc), f,
getTypeExpansionContext()));
}
DynamicFunctionRefInst *
createDynamicFunctionRef(SILLocation Loc, SILFunction *f) {
return insert(new (getModule()) DynamicFunctionRefInst(
getSILDebugLocation(Loc), f));
getSILDebugLocation(Loc), f, getTypeExpansionContext()));
}
PreviousDynamicFunctionRefInst *
createPreviousDynamicFunctionRef(SILLocation Loc, SILFunction *f) {
return insert(new (getModule()) PreviousDynamicFunctionRefInst(
getSILDebugLocation(Loc), f));
getSILDebugLocation(Loc), f, getTypeExpansionContext()));
}
AllocGlobalInst *createAllocGlobal(SILLocation Loc, SILGlobalVariable *g) {
@@ -611,16 +618,16 @@ public:
AllocGlobalInst(getSILDebugLocation(Loc), g));
}
GlobalAddrInst *createGlobalAddr(SILLocation Loc, SILGlobalVariable *g) {
return insert(new (getModule())
GlobalAddrInst(getSILDebugLocation(Loc), g));
return insert(new (getModule()) GlobalAddrInst(getSILDebugLocation(Loc), g,
getTypeExpansionContext()));
}
GlobalAddrInst *createGlobalAddr(SILLocation Loc, SILType Ty) {
return insert(new (F->getModule())
GlobalAddrInst(getSILDebugLocation(Loc), Ty));
}
GlobalValueInst *createGlobalValue(SILLocation Loc, SILGlobalVariable *g) {
return insert(new (getModule())
GlobalValueInst(getSILDebugLocation(Loc), g));
return insert(new (getModule()) GlobalValueInst(getSILDebugLocation(Loc), g,
getTypeExpansionContext()));
}
IntegerLiteralInst *createIntegerLiteral(IntegerLiteralExpr *E);
@@ -1285,8 +1292,8 @@ public:
UncheckedEnumDataInst *createUncheckedEnumData(SILLocation Loc,
SILValue Operand,
EnumElementDecl *Element) {
SILType EltType =
Operand->getType().getEnumElementType(Element, getModule());
SILType EltType = Operand->getType().getEnumElementType(
Element, getModule(), getTypeExpansionContext());
return createUncheckedEnumData(Loc, Operand, Element, EltType);
}
@@ -1307,8 +1314,8 @@ public:
UncheckedTakeEnumDataAddrInst *
createUncheckedTakeEnumDataAddr(SILLocation Loc, SILValue Operand,
EnumElementDecl *Element) {
SILType EltType =
Operand->getType().getEnumElementType(Element, getModule());
SILType EltType = Operand->getType().getEnumElementType(
Element, getModule(), getTypeExpansionContext());
return createUncheckedTakeEnumDataAddr(Loc, Operand, Element, EltType);
}
@@ -1383,7 +1390,8 @@ public:
StructExtractInst *createStructExtract(SILLocation Loc, SILValue Operand,
VarDecl *Field) {
auto type = Operand->getType().getFieldType(Field, getModule());
auto type = Operand->getType().getFieldType(Field, getModule(),
getTypeExpansionContext());
return createStructExtract(Loc, Operand, Field, type);
}
@@ -1397,7 +1405,8 @@ public:
StructElementAddrInst *
createStructElementAddr(SILLocation Loc, SILValue Operand, VarDecl *Field) {
auto ResultTy = Operand->getType().getFieldType(Field, getModule());
auto ResultTy = Operand->getType().getFieldType(Field, getModule(),
getTypeExpansionContext());
return createStructElementAddr(Loc, Operand, Field, ResultTy);
}
@@ -1408,7 +1417,8 @@ public:
}
RefElementAddrInst *createRefElementAddr(SILLocation Loc, SILValue Operand,
VarDecl *Field) {
auto ResultTy = Operand->getType().getFieldType(Field, getModule());
auto ResultTy = Operand->getType().getFieldType(Field, getModule(),
getTypeExpansionContext());
return createRefElementAddr(Loc, Operand, Field, ResultTy);
}
@@ -2131,7 +2141,8 @@ public:
SILValue emitStructExtract(SILLocation Loc, SILValue Operand,
VarDecl *Field) {
auto type = Operand->getType().getFieldType(Field, getModule());
auto type = Operand->getType().getFieldType(Field, getModule(),
getTypeExpansionContext());
return emitStructExtract(Loc, Operand, Field, type);
}

View File

@@ -128,14 +128,15 @@ public:
/// blocks.
///
/// This is used to clone an entire function and should not mutate the
/// original function.
/// original function except if \p replaceOriginalFunctionInPlace is true.
///
/// entryArgs must have a SILValue from the cloned function corresponding to
/// each argument in the original function `F`.
///
/// Cloned instructions are inserted starting at the end of clonedEntryBB.
void cloneFunctionBody(SILFunction *F, SILBasicBlock *clonedEntryBB,
ArrayRef<SILValue> entryArgs);
ArrayRef<SILValue> entryArgs,
bool replaceOriginalFunctionInPlace = false);
/// MARK: Callback utilities used from CRTP extensions during cloning.
/// These should only be called from within an instruction cloning visitor.
@@ -354,8 +355,14 @@ protected:
SILLocation remapLocation(SILLocation Loc) { return Loc; }
const SILDebugScope *remapScope(const SILDebugScope *DS) { return DS; }
SILType remapType(SILType Ty) { return Ty; }
CanType remapASTType(CanType Ty) { return Ty; }
SILType remapType(SILType Ty) {
return Ty;
}
CanType remapASTType(CanType Ty) {
return Ty;
}
ProtocolConformanceRef remapConformance(Type Ty, ProtocolConformanceRef C) {
return C;
}
@@ -612,9 +619,11 @@ void SILCloner<ImplClass>::cloneReachableBlocks(
template <typename ImplClass>
void SILCloner<ImplClass>::cloneFunctionBody(SILFunction *F,
SILBasicBlock *clonedEntryBB,
ArrayRef<SILValue> entryArgs) {
ArrayRef<SILValue> entryArgs,
bool replaceOriginalFunctionInPlace) {
assert(F != clonedEntryBB->getParent() && "Must clone into a new function.");
assert((replaceOriginalFunctionInPlace || F != clonedEntryBB->getParent()) &&
"Must clone into a new function.");
assert(BBMap.empty() && "This API does not allow clients to map blocks.");
assert(ValueMap.empty() && "Stale ValueMap.");
@@ -972,9 +981,9 @@ SILCloner<ImplClass>::visitFunctionRefInst(FunctionRefInst *Inst) {
getOpLocation(Inst->getLoc()), OpFunction));
}
template<typename ImplClass>
void
SILCloner<ImplClass>::visitDynamicFunctionRefInst(DynamicFunctionRefInst *Inst) {
template <typename ImplClass>
void SILCloner<ImplClass>::visitDynamicFunctionRefInst(
DynamicFunctionRefInst *Inst) {
SILFunction *OpFunction =
getOpFunction(Inst->getInitiallyReferencedFunction());
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
@@ -2049,8 +2058,11 @@ SILCloner<ImplClass>::visitWitnessMethodInst(WitnessMethodInst *Inst) {
CanType Ty = conformance.getConcrete()->getType()->getCanonicalType();
if (Ty != newLookupType) {
assert(Ty->isExactSuperclassOf(newLookupType) &&
"Should only create upcasts for sub class.");
assert(
(Ty->isExactSuperclassOf(newLookupType) ||
getBuilder().getModule().Types.getLoweredRValueType(
getBuilder().getTypeExpansionContext(), Ty) == newLookupType) &&
"Should only create upcasts for sub class.");
// We use the super class as the new look up type.
newLookupType = Ty;

View File

@@ -515,6 +515,8 @@ public:
SILType getLoweredLoadableType(Type t) const;
SILType getLoweredType(SILType t) const;
const Lowering::TypeLowering &getTypeLowering(SILType type) const;
bool isTypeABIAccessible(SILType type) const;

View File

@@ -105,7 +105,12 @@ public:
CanSILFunctionType getLoweredFunctionType() const {
return LoweredType.castTo<SILFunctionType>();
}
SILType getLoweredTypeInContext(TypeExpansionContext context) const;
CanSILFunctionType
getLoweredFunctionTypeInContext(TypeExpansionContext context) const {
return getLoweredTypeInContext(context).castTo<SILFunctionType>();
}
StringRef getName() const { return Name; }
void setDeclaration(bool isD) { IsDeclaration = isD; }

View File

@@ -2357,7 +2357,7 @@ class FunctionRefBaseInst : public LiteralInst {
protected:
FunctionRefBaseInst(SILInstructionKind Kind, SILDebugLocation DebugLoc,
SILFunction *F);
SILFunction *F, TypeExpansionContext context);
public:
~FunctionRefBaseInst();
@@ -2416,7 +2416,9 @@ class FunctionRefInst : public FunctionRefBaseInst {
///
/// \param DebugLoc The location of the reference.
/// \param F The function being referenced.
FunctionRefInst(SILDebugLocation DebugLoc, SILFunction *F);
/// \param context The type expansion context of the function reference.
FunctionRefInst(SILDebugLocation DebugLoc, SILFunction *F,
TypeExpansionContext context);
public:
static bool classof(const SILNode *node) {
@@ -2434,7 +2436,9 @@ class DynamicFunctionRefInst : public FunctionRefBaseInst {
///
/// \param DebugLoc The location of the reference.
/// \param F The function being referenced.
DynamicFunctionRefInst(SILDebugLocation DebugLoc, SILFunction *F);
/// \param context The type expansion context of the function reference.
DynamicFunctionRefInst(SILDebugLocation DebugLoc, SILFunction *F,
TypeExpansionContext context);
public:
static bool classof(const SILNode *node) {
@@ -2452,7 +2456,9 @@ class PreviousDynamicFunctionRefInst : public FunctionRefBaseInst {
///
/// \param DebugLoc The location of the reference.
/// \param F The function being referenced.
PreviousDynamicFunctionRefInst(SILDebugLocation DebugLoc, SILFunction *F);
/// \param context The type expansion context of the function reference.
PreviousDynamicFunctionRefInst(SILDebugLocation DebugLoc, SILFunction *F,
TypeExpansionContext context);
public:
static bool classof(const SILNode *node) {
@@ -3117,14 +3123,16 @@ class GlobalAddrInst
GlobalAccessInst> {
friend SILBuilder;
GlobalAddrInst(SILDebugLocation DebugLoc, SILGlobalVariable *Global);
GlobalAddrInst(SILDebugLocation DebugLoc, SILGlobalVariable *Global,
TypeExpansionContext context);
public:
// FIXME: This constructor should be private but is currently used
// in the SILParser.
/// Create a placeholder instruction with an unset global reference.
GlobalAddrInst(SILDebugLocation DebugLoc, SILType Ty)
: InstructionBase(DebugLoc, Ty, nullptr) { }
: InstructionBase(DebugLoc, Ty, nullptr) {}
};
/// Gives the value of a global variable.
@@ -3136,7 +3144,8 @@ class GlobalValueInst
GlobalAccessInst> {
friend SILBuilder;
GlobalValueInst(SILDebugLocation DebugLoc, SILGlobalVariable *Global);
GlobalValueInst(SILDebugLocation DebugLoc, SILGlobalVariable *Global,
TypeExpansionContext context);
};
/// IntegerLiteralInst - Encapsulates an integer constant, as defined originally

View File

@@ -595,7 +595,7 @@ public:
/// Can value operations (copies and destroys) on the given lowered type
/// be performed in this module?
bool isTypeABIAccessible(SILType type,
ResilienceExpansion forExpansion);
TypeExpansionContext forExpansion);
/// Can type metadata for the given formal type be fetched in
/// the given module?

View File

@@ -596,6 +596,8 @@ AbstractionPattern AbstractionPattern::getOptionalObjectType() const {
case Kind::Type:
if (isTypeParameter())
return AbstractionPattern::getOpaque();
if (isa<OpaqueTypeArchetypeType>(getType()))
return AbstractionPattern::getOpaque();
return AbstractionPattern(getGenericSignature(),
::getOptionalObjectType(getType()));

View File

@@ -33,7 +33,8 @@ using namespace swift::Lowering;
CanType TypeConverter::getLoweredTypeOfGlobal(VarDecl *var) {
AbstractionPattern origType = getAbstractionPattern(var);
assert(!origType.isTypeParameter());
return getLoweredRValueType(origType, origType.getType());
return getLoweredRValueType(TypeExpansionContext::minimal(), origType,
origType.getType());
}
AnyFunctionType::Param

View File

@@ -918,7 +918,8 @@ namespace {
auto sourceSomeDecl = Ctx.getOptionalSomeDecl();
SILType loweredSourceObjectType =
source.Value->getType().getEnumElementType(sourceSomeDecl, M);
source.Value->getType().getEnumElementType(
sourceSomeDecl, M, B.getTypeExpansionContext());
// Form the target for the optional object.
EmitSomeState state;
@@ -991,8 +992,8 @@ namespace {
auto someDecl = Ctx.getOptionalSomeDecl();
state.SomeDecl = someDecl;
SILType loweredObjectType =
target.LoweredType.getEnumElementType(someDecl, M);
SILType loweredObjectType = target.LoweredType.getEnumElementType(
someDecl, M, B.getTypeExpansionContext());
if (target.isAddress()) {
SILValue objectAddr =

View File

@@ -374,7 +374,8 @@ void MemoryLocations::initFieldsCounter(Location &loc) {
}
SILModule &module = function->getModule();
for (VarDecl *field : decl->getStoredProperties()) {
loc.updateFieldCounters(ty.getFieldType(field, module), +1);
loc.updateFieldCounters(
ty.getFieldType(field, module, TypeExpansionContext(*function)), +1);
}
return;
}

View File

@@ -177,17 +177,18 @@ Projection::Projection(SingleValueInstruction *I) : Value() {
///
/// WARNING: This is not a constant time operation because it is implemented
/// in terms of getVarDecl, which requests all BaseType's stored properties.
SILType Projection::getType(SILType BaseType, SILModule &M) const {
SILType Projection::getType(SILType BaseType, SILModule &M,
TypeExpansionContext context) const {
assert(isValid());
switch (getKind()) {
case ProjectionKind::Struct:
case ProjectionKind::Class:
return BaseType.getFieldType(getVarDecl(BaseType), M);
return BaseType.getFieldType(getVarDecl(BaseType), M, context);
case ProjectionKind::Enum:
return BaseType.getEnumElementType(getEnumElementDecl(BaseType), M);
return BaseType.getEnumElementType(getEnumElementDecl(BaseType), M, context);
case ProjectionKind::Box:
return getSILBoxFieldType(BaseType.castTo<SILBoxType>(),
M.Types, getIndex());
return getSILBoxFieldType(context, BaseType.castTo<SILBoxType>(), M.Types,
getIndex());
case ProjectionKind::Tuple:
return BaseType.getTupleElementType(getIndex());
case ProjectionKind::Upcast:
@@ -285,18 +286,20 @@ Projection::createAddressProjection(SILBuilder &B, SILLocation Loc,
llvm_unreachable("Unhandled ProjectionKind in switch.");
}
void Projection::getFirstLevelProjections(SILType Ty, SILModule &Mod,
llvm::SmallVectorImpl<Projection> &Out) {
void Projection::getFirstLevelProjections(
SILType Ty, SILModule &Mod, TypeExpansionContext context,
llvm::SmallVectorImpl<Projection> &Out) {
if (auto *S = Ty.getStructOrBoundGenericStruct()) {
unsigned Count = 0;
for (auto *VDecl : S->getStoredProperties()) {
(void) VDecl;
Projection P(ProjectionKind::Struct, Count++);
LLVM_DEBUG(ProjectionPath X(Ty);
assert(X.getMostDerivedType(Mod) == Ty);
assert(X.getMostDerivedType(Mod, context) == Ty);
X.append(P);
assert(X.getMostDerivedType(Mod)==Ty.getFieldType(VDecl, Mod));
X.verify(Mod););
assert(X.getMostDerivedType(Mod, context) ==
Ty.getFieldType(VDecl, Mod, context));
X.verify(Mod, context););
Out.push_back(P);
}
return;
@@ -306,10 +309,11 @@ void Projection::getFirstLevelProjections(SILType Ty, SILModule &Mod,
for (unsigned i = 0, e = TT->getNumElements(); i != e; ++i) {
Projection P(ProjectionKind::Tuple, i);
LLVM_DEBUG(ProjectionPath X(Ty);
assert(X.getMostDerivedType(Mod) == Ty);
assert(X.getMostDerivedType(Mod, context) == Ty);
X.append(P);
assert(X.getMostDerivedType(Mod) == Ty.getTupleElementType(i));
X.verify(Mod););
assert(X.getMostDerivedType(Mod, context) ==
Ty.getTupleElementType(i));
X.verify(Mod, context););
Out.push_back(P);
}
return;
@@ -321,10 +325,11 @@ void Projection::getFirstLevelProjections(SILType Ty, SILModule &Mod,
(void) VDecl;
Projection P(ProjectionKind::Class, Count++);
LLVM_DEBUG(ProjectionPath X(Ty);
assert(X.getMostDerivedType(Mod) == Ty);
assert(X.getMostDerivedType(Mod, context) == Ty);
X.append(P);
assert(X.getMostDerivedType(Mod)==Ty.getFieldType(VDecl, Mod));
X.verify(Mod););
assert(X.getMostDerivedType(Mod, context) ==
Ty.getFieldType(VDecl, Mod, context));
X.verify(Mod, context););
Out.push_back(P);
}
return;
@@ -334,11 +339,10 @@ void Projection::getFirstLevelProjections(SILType Ty, SILModule &Mod,
for (unsigned field : indices(Box->getLayout()->getFields())) {
Projection P(ProjectionKind::Box, field);
LLVM_DEBUG(ProjectionPath X(Ty);
assert(X.getMostDerivedType(Mod) == Ty);
X.append(P);
assert(X.getMostDerivedType(Mod)
== getSILBoxFieldType(Box, Mod.Types, field));
X.verify(Mod););
assert(X.getMostDerivedType(Mod, context) == Ty); X.append(P);
assert(X.getMostDerivedType(Mod, context) ==
getSILBoxFieldType(context, Box, Mod.Types, field));
X.verify(Mod, context););
(void)Box;
Out.push_back(P);
}
@@ -580,12 +584,13 @@ void Projection::print(raw_ostream &os, SILType baseType) const {
os << "<unexpected projection>";
}
raw_ostream &ProjectionPath::print(raw_ostream &os, SILModule &M) const {
raw_ostream &ProjectionPath::print(raw_ostream &os, SILModule &M,
TypeExpansionContext context) const {
os << "Projection Path [";
SILType IterType = getBaseType();
for (const Projection &IterProj : Path) {
SILType BaseType = IterType;
IterType = IterProj.getType(IterType, M);
IterType = IterProj.getType(IterType, M, context);
os << BaseType.getAddressType() << "\n ";
@@ -596,16 +601,16 @@ raw_ostream &ProjectionPath::print(raw_ostream &os, SILModule &M) const {
return os;
}
void ProjectionPath::dump(SILModule &M) const {
print(llvm::dbgs(), M);
void ProjectionPath::dump(SILModule &M, TypeExpansionContext context) const {
print(llvm::dbgs(), M, context);
}
void ProjectionPath::verify(SILModule &M) {
void ProjectionPath::verify(SILModule &M, TypeExpansionContext context) {
#ifndef NDEBUG
SILType IterTy = getBaseType();
assert(IterTy);
for (auto &Proj : Path) {
IterTy = Proj.getType(IterTy, M);
IterTy = Proj.getType(IterTy, M, context);
assert(IterTy);
}
#endif
@@ -613,6 +618,7 @@ void ProjectionPath::verify(SILModule &M) {
void
ProjectionPath::expandTypeIntoLeafProjectionPaths(SILType B, SILModule *Mod,
TypeExpansionContext context,
ProjectionPathList &Paths) {
// Perform a BFS to expand the given type into projectionpath each of
// which contains 1 field from the type.
@@ -626,7 +632,7 @@ ProjectionPath::expandTypeIntoLeafProjectionPaths(SILType B, SILModule *Mod,
// Get the next level projections based on current projection's type.
ProjectionPath PP = Worklist.pop_back_val();
// Get the current type to process.
SILType Ty = PP.getMostDerivedType(*Mod);
SILType Ty = PP.getMostDerivedType(*Mod, context);
LLVM_DEBUG(llvm::dbgs() << "Visiting type: " << Ty << "\n");
@@ -655,7 +661,7 @@ ProjectionPath::expandTypeIntoLeafProjectionPaths(SILType B, SILModule *Mod,
// Get the first level projection of the current type.
Projections.clear();
Projection::getFirstLevelProjections(Ty, *Mod, Projections);
Projection::getFirstLevelProjections(Ty, *Mod, context, Projections);
// Reached the end of the projection tree, this field can not be expanded
// anymore.
@@ -695,11 +701,12 @@ bool ProjectionPath::hasUncoveredNonTrivials(SILType B, const SILFunction &F,
continue;
// Get the current type to process.
SILType Ty = PP.getMostDerivedType(Mod);
SILType Ty = PP.getMostDerivedType(Mod, F.getTypeExpansionContext());
// Get the first level projection of the current type.
llvm::SmallVector<Projection, 4> Projections;
Projection::getFirstLevelProjections(Ty, Mod, Projections);
Projection::getFirstLevelProjections(Ty, Mod, F.getTypeExpansionContext(),
Projections);
// Reached the end of the projection tree, this field can not be expanded
// anymore.
@@ -719,7 +726,8 @@ bool ProjectionPath::hasUncoveredNonTrivials(SILType B, const SILFunction &F,
for (auto &P : Projections) {
ProjectionPath X(B);
X.append(PP);
assert(PP.getMostDerivedType(Mod) == X.getMostDerivedType(Mod));
assert(PP.getMostDerivedType(Mod, F.getTypeExpansionContext()) ==
X.getMostDerivedType(Mod, F.getTypeExpansionContext()));
X.append(P);
Worklist.push_back(X);
}
@@ -728,8 +736,8 @@ bool ProjectionPath::hasUncoveredNonTrivials(SILType B, const SILFunction &F,
// Check whether any path leads to a non-trivial type.
for (auto &X : Paths) {
if (!X.getMostDerivedType(Mod).isTrivial(F))
return true;
if (!X.getMostDerivedType(Mod, F.getTypeExpansionContext()).isTrivial(F))
return true;
}
return false;
}
@@ -937,7 +945,8 @@ processUsersOfValue(ProjectionTree &Tree,
// we have a projection to the next level children, create the next
// level children nodes lazily.
if (!Initialized)
createNextLevelChildren(Tree);
createNextLevelChildren(
Tree, TypeExpansionContext(*projectionInst->getFunction()));
// Look up the Node for this projection add {User, ChildNode} to the
// worklist.
@@ -962,15 +971,14 @@ processUsersOfValue(ProjectionTree &Tree,
}
}
void
ProjectionTreeNode::
createNextLevelChildrenForStruct(ProjectionTree &Tree, StructDecl *SD) {
void ProjectionTreeNode::createNextLevelChildrenForStruct(
ProjectionTree &Tree, TypeExpansionContext context, StructDecl *SD) {
SILModule &Mod = Tree.getModule();
unsigned ChildIndex = 0;
SILType Ty = getType();
for (VarDecl *VD : SD->getStoredProperties()) {
assert(Tree.getNode(Index) == this && "Node is not mapped to itself?");
SILType NodeTy = Ty.getFieldType(VD, Mod);
SILType NodeTy = Ty.getFieldType(VD, Mod, context);
auto *Node = Tree.createChildForStruct(this, NodeTy, VD, ChildIndex++);
LLVM_DEBUG(llvm::dbgs() << " Creating child for: " <<NodeTy << "\n");
LLVM_DEBUG(llvm::dbgs() << " Projection: "
@@ -1000,9 +1008,8 @@ createNextLevelChildrenForTuple(ProjectionTree &Tree, TupleType *TT) {
}
}
void
ProjectionTreeNode::
createNextLevelChildren(ProjectionTree &Tree) {
void ProjectionTreeNode::createNextLevelChildren(ProjectionTree &Tree,
TypeExpansionContext context) {
LLVM_DEBUG(llvm::dbgs() << " Creating children for: " << getType() <<"\n");
if (Initialized) {
LLVM_DEBUG(llvm::dbgs() << " Already initialized! bailing!\n");
@@ -1020,7 +1027,7 @@ createNextLevelChildren(ProjectionTree &Tree) {
if (auto *SD = Ty.getStructOrBoundGenericStruct()) {
LLVM_DEBUG(llvm::dbgs() << " Found a struct!\n");
createNextLevelChildrenForStruct(Tree, SD);
createNextLevelChildrenForStruct(Tree, context, SD);
return;
}

View File

@@ -186,7 +186,7 @@ static bool isTypeMetadataForLayoutAccessible(SILModule &M, SILType type) {
/// ABI-private, we can always at least fetch its metadata and use the
/// value witness table stored there.
bool SILModule::isTypeABIAccessible(SILType type,
ResilienceExpansion forExpansion) {
TypeExpansionContext forExpansion) {
// Fixed-ABI types can have value operations done without metadata.
if (Types.getTypeLowering(type, forExpansion).isFixedABI())
return true;

View File

@@ -142,9 +142,11 @@ void SILBasicBlock::cloneArgumentList(SILBasicBlock *Other) {
}
}
SILFunctionArgument *SILBasicBlock::createFunctionArgument(SILType Ty,
const ValueDecl *D) {
assert(isEntry() && "Function Arguments can only be in the entry block");
SILFunctionArgument *
SILBasicBlock::createFunctionArgument(SILType Ty, const ValueDecl *D,
bool disableEntryBlockVerification) {
assert((disableEntryBlockVerification || isEntry()) &&
"Function Arguments can only be in the entry block");
const SILFunction *Parent = getParent();
auto OwnershipKind = ValueOwnershipKind(
*Parent, Ty,

View File

@@ -49,15 +49,14 @@ TupleInst *SILBuilder::createTuple(SILLocation loc, ArrayRef<SILValue> elts) {
return createTuple(loc, tupleType, elts);
}
SILType SILBuilder::getPartialApplyResultType(SILType origTy, unsigned argCount,
SILModule &M,
SubstitutionMap subs,
ParameterConvention calleeConvention,
PartialApplyInst::OnStackKind onStack) {
SILType SILBuilder::getPartialApplyResultType(
TypeExpansionContext context, SILType origTy, unsigned argCount,
SILModule &M, SubstitutionMap subs, ParameterConvention calleeConvention,
PartialApplyInst::OnStackKind onStack) {
CanSILFunctionType FTI = origTy.castTo<SILFunctionType>();
if (!subs.empty())
FTI = FTI->substGenericArgs(M, subs);
FTI = FTI->substGenericArgs(M, subs, context);
assert(!FTI->isPolymorphic()
&& "must provide substitutions for generic partial_apply");
auto params = FTI->getParameters();
@@ -104,7 +103,8 @@ ProjectBoxInst *SILBuilder::createProjectBox(SILLocation Loc,
SILValue boxOperand,
unsigned index) {
auto boxTy = boxOperand->getType().castTo<SILBoxType>();
auto fieldTy = getSILBoxFieldType(boxTy, getModule().Types, index);
auto fieldTy = getSILBoxFieldType(getTypeExpansionContext(), boxTy,
getModule().Types, index);
return insert(new (getModule()) ProjectBoxInst(
getSILDebugLocation(Loc), boxOperand, index, fieldTy));
@@ -511,11 +511,11 @@ void SILBuilder::addOpenedArchetypeOperands(SILInstruction *I) {
ValueMetatypeInst *SILBuilder::createValueMetatype(SILLocation Loc,
SILType MetatypeTy,
SILValue Base) {
assert(
Base->getType().isLoweringOf(
getModule(), MetatypeTy.castTo<MetatypeType>().getInstanceType()) &&
"value_metatype result must be formal metatype of the lowered operand "
"type");
assert(Base->getType().isLoweringOf(
getTypeExpansionContext(), getModule(),
MetatypeTy.castTo<MetatypeType>().getInstanceType()) &&
"value_metatype result must be formal metatype of the lowered operand "
"type");
return insert(new (getModule()) ValueMetatypeInst(getSILDebugLocation(Loc),
MetatypeTy, Base));
}
@@ -541,7 +541,8 @@ void SILBuilder::emitDestructureValueOperation(
// In non qualified ownership SIL, drop back to using projection code.
SmallVector<Projection, 16> projections;
Projection::getFirstLevelProjections(v->getType(), getModule(), projections);
Projection::getFirstLevelProjections(v->getType(), getModule(),
getTypeExpansionContext(), projections);
llvm::transform(projections, std::back_inserter(results),
[&](const Projection &p) -> SILValue {
return p.createObjectProjection(*this, loc, v).get();
@@ -562,7 +563,8 @@ void SILBuilder::emitDestructureAddressOperation(
}
SmallVector<Projection, 16> projections;
Projection::getFirstLevelProjections(v->getType(), getModule(), projections);
Projection::getFirstLevelProjections(v->getType(), getModule(),
getTypeExpansionContext(), projections);
llvm::transform(projections, std::back_inserter(results),
[&](const Projection &p) -> SILValue {
return p.createAddressProjection(*this, loc, v).get();

View File

@@ -261,6 +261,9 @@ const TypeLowering &SILFunction::getTypeLowering(SILType type) const {
return getModule().Types.getTypeLowering(type, TypeExpansionContext(*this));
}
SILType SILFunction::getLoweredType(SILType t) const {
return getTypeLowering(t).getLoweredType().getCategoryType(t.getCategory());
}
bool SILFunction::isTypeABIAccessible(SILType type) const {
return getModule().isTypeABIAccessible(type, TypeExpansionContext(*this));
}

View File

@@ -107,7 +107,8 @@ SILFunctionBuilder::getOrCreateFunction(SILLocation loc, SILDeclRef constant,
ForDefinition_t forDefinition,
ProfileCounter entryCount) {
auto nameTmp = constant.mangle();
auto constantType = mod.Types.getConstantFunctionType(constant);
auto constantType = mod.Types.getConstantFunctionType(
TypeExpansionContext::minimal(), constant);
SILLinkage linkage = constant.getLinkage(forDefinition);
if (auto fn = mod.lookUpFunction(nameTmp)) {

View File

@@ -310,3 +310,14 @@ swift::getVariableOfStaticInitializer(SILFunction *InitFunc,
return nullptr;
return GVar;
}
SILType
SILGlobalVariable::getLoweredTypeInContext(TypeExpansionContext context) const {
auto ty = getLoweredType();
if (!ty.getASTType()->hasOpaqueArchetype() ||
!context.shouldLookThroughOpaqueTypeArchetypes())
return ty;
auto resultTy =
getModule().Types.getTypeLowering(ty, context).getLoweredType();
return resultTy.getCategoryType(ty.getCategory());
}

View File

@@ -285,7 +285,9 @@ AllocBoxInst *AllocBoxInst::create(SILDebugLocation Loc,
}
SILType AllocBoxInst::getAddressType() const {
return getSILBoxFieldType(getBoxType(), getModule().Types, 0).getAddressType();
return getSILBoxFieldType(TypeExpansionContext(*this->getFunction()),
getBoxType(), getModule().Types, 0)
.getAddressType();
}
VarDecl *AllocBoxInst::getDecl() const {
@@ -416,8 +418,8 @@ ApplyInst::create(SILDebugLocation Loc, SILValue Callee, SubstitutionMap Subs,
Optional<SILModuleConventions> ModuleConventions,
SILFunction &F, SILOpenedArchetypesState &OpenedArchetypes,
const GenericSpecializationInformation *SpecializationInfo) {
SILType SubstCalleeSILTy =
Callee->getType().substGenericArgs(F.getModule(), Subs);
SILType SubstCalleeSILTy = Callee->getType().substGenericArgs(
F.getModule(), Subs, F.getTypeExpansionContext());
auto SubstCalleeTy = SubstCalleeSILTy.getAs<SILFunctionType>();
SILFunctionConventions Conv(SubstCalleeTy,
ModuleConventions.hasValue()
@@ -462,8 +464,8 @@ BeginApplyInst::create(SILDebugLocation loc, SILValue callee,
SILFunction &F,
SILOpenedArchetypesState &openedArchetypes,
const GenericSpecializationInformation *specializationInfo) {
SILType substCalleeSILType =
callee->getType().substGenericArgs(F.getModule(), subs);
SILType substCalleeSILType = callee->getType().substGenericArgs(
F.getModule(), subs, F.getTypeExpansionContext());
auto substCalleeType = substCalleeSILType.castTo<SILFunctionType>();
SILFunctionConventions conv(substCalleeType,
@@ -553,10 +555,11 @@ PartialApplyInst *PartialApplyInst::create(
SILOpenedArchetypesState &OpenedArchetypes,
const GenericSpecializationInformation *SpecializationInfo,
OnStackKind onStack) {
SILType SubstCalleeTy =
Callee->getType().substGenericArgs(F.getModule(), Subs);
SILType SubstCalleeTy = Callee->getType().substGenericArgs(
F.getModule(), Subs, F.getTypeExpansionContext());
SILType ClosureType = SILBuilder::getPartialApplyResultType(
SubstCalleeTy, Args.size(), F.getModule(), {}, CalleeConvention, onStack);
F.getTypeExpansionContext(), SubstCalleeTy, Args.size(), F.getModule(), {},
CalleeConvention, onStack);
SmallVector<SILValue, 32> TypeDependentOperands;
collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, F,
@@ -591,8 +594,8 @@ TryApplyInst *TryApplyInst::create(
ArrayRef<SILValue> args, SILBasicBlock *normalBB, SILBasicBlock *errorBB,
SILFunction &F, SILOpenedArchetypesState &openedArchetypes,
const GenericSpecializationInformation *specializationInfo) {
SILType substCalleeTy =
callee->getType().substGenericArgs(F.getModule(), subs);
SILType substCalleeTy = callee->getType().substGenericArgs(
F.getModule(), subs, F.getTypeExpansionContext());
SmallVector<SILValue, 32> typeDependentOperands;
collectTypeDependentOperands(typeDependentOperands, openedArchetypes, F,
@@ -608,8 +611,9 @@ TryApplyInst *TryApplyInst::create(
FunctionRefBaseInst::FunctionRefBaseInst(SILInstructionKind Kind,
SILDebugLocation DebugLoc,
SILFunction *F)
: LiteralInst(Kind, DebugLoc, F->getLoweredType()), f(F) {
SILFunction *F,
TypeExpansionContext context)
: LiteralInst(Kind, DebugLoc, F->getLoweredTypeInContext(context)), f(F) {
F->incrementRefCount();
}
@@ -624,21 +628,25 @@ FunctionRefBaseInst::~FunctionRefBaseInst() {
getInitiallyReferencedFunction()->decrementRefCount();
}
FunctionRefInst::FunctionRefInst(SILDebugLocation Loc, SILFunction *F)
: FunctionRefBaseInst(SILInstructionKind::FunctionRefInst, Loc, F) {
FunctionRefInst::FunctionRefInst(SILDebugLocation Loc, SILFunction *F,
TypeExpansionContext context)
: FunctionRefBaseInst(SILInstructionKind::FunctionRefInst, Loc, F,
context) {
assert(!F->isDynamicallyReplaceable());
}
DynamicFunctionRefInst::DynamicFunctionRefInst(SILDebugLocation Loc,
SILFunction *F)
: FunctionRefBaseInst(SILInstructionKind::DynamicFunctionRefInst, Loc, F) {
SILFunction *F,
TypeExpansionContext context)
: FunctionRefBaseInst(SILInstructionKind::DynamicFunctionRefInst, Loc, F,
context) {
assert(F->isDynamicallyReplaceable());
}
PreviousDynamicFunctionRefInst::PreviousDynamicFunctionRefInst(
SILDebugLocation Loc, SILFunction *F)
SILDebugLocation Loc, SILFunction *F, TypeExpansionContext context)
: FunctionRefBaseInst(SILInstructionKind::PreviousDynamicFunctionRefInst,
Loc, F) {
Loc, F, context) {
assert(!F->isDynamicallyReplaceable());
}
@@ -648,16 +656,19 @@ AllocGlobalInst::AllocGlobalInst(SILDebugLocation Loc,
Global(Global) {}
GlobalAddrInst::GlobalAddrInst(SILDebugLocation DebugLoc,
SILGlobalVariable *Global)
: InstructionBase(DebugLoc, Global->getLoweredType().getAddressType(),
SILGlobalVariable *Global,
TypeExpansionContext context)
: InstructionBase(DebugLoc,
Global->getLoweredTypeInContext(context).getAddressType(),
Global) {}
GlobalValueInst::GlobalValueInst(SILDebugLocation DebugLoc,
SILGlobalVariable *Global)
: InstructionBase(DebugLoc, Global->getLoweredType().getObjectType(),
SILGlobalVariable *Global,
TypeExpansionContext context)
: InstructionBase(DebugLoc,
Global->getLoweredTypeInContext(context).getObjectType(),
Global) {}
const IntrinsicInfo &BuiltinInst::getIntrinsicInfo() const {
return getModule().getIntrinsicInfo(getName());
}
@@ -1087,7 +1098,8 @@ bool StructExtractInst::isTrivialFieldOfOneRCIDStruct() const {
// Otherwise check if we have a non-trivial type. If we don't have one,
// continue.
if (StructTy.getFieldType(D, F->getModule()).isTrivial(*F))
if (StructTy.getFieldType(D, F->getModule(), TypeExpansionContext(*F))
.isTrivial(*F))
continue;
// Ok, this type is non-trivial. If we have not seen a non-trivial field
@@ -1132,7 +1144,8 @@ bool StructExtractInst::isFieldOnlyNonTrivialField() const {
// Ok, we have a field that is not equal to the field we are
// extracting. If that field is trivial, we do not care about
// it... continue.
if (StructTy.getFieldType(D, F->getModule()).isTrivial(*F))
if (StructTy.getFieldType(D, F->getModule(), TypeExpansionContext(*F))
.isTrivial(*F))
continue;
// We have found a non trivial member that is not the member we are
@@ -2450,11 +2463,12 @@ static void computeAggregateFirstLevelSubtypeInfo(
// TODO: Create an iterator for accessing first level projections to eliminate
// this SmallVector.
llvm::SmallVector<Projection, 8> Projections;
Projection::getFirstLevelProjections(OpType, M, Projections);
Projection::getFirstLevelProjections(OpType, M, F.getTypeExpansionContext(),
Projections);
auto OpOwnershipKind = Operand.getOwnershipKind();
for (auto &P : Projections) {
SILType ProjType = P.getType(OpType, M);
SILType ProjType = P.getType(OpType, M, F.getTypeExpansionContext());
Types.emplace_back(ProjType);
OwnershipKinds.emplace_back(
OpOwnershipKind.getProjectedOwnershipKind(F, ProjType));

View File

@@ -134,14 +134,15 @@ void verifyKeyPathComponent(SILModule &M,
bool forPropertyDescriptor,
bool hasIndices) {
auto &C = M.getASTContext();
auto typeExpansionContext =
TypeExpansionContext::noOpaqueTypeArchetypesSubstitution(expansion);
auto opaque = AbstractionPattern::getOpaque();
auto loweredBaseTy =
M.Types.getLoweredType(opaque, baseTy, expansion);
M.Types.getLoweredType(opaque, baseTy, typeExpansionContext);
auto componentTy = component.getComponentType().subst(patternSubs)
->getCanonicalType();
auto loweredComponentTy =
M.Types.getLoweredType(opaque, componentTy, expansion);
M.Types.getLoweredType(opaque, componentTy, typeExpansionContext);
auto checkIndexEqualsAndHash = [&]{
if (!component.getSubscriptIndices().empty()) {
@@ -153,7 +154,7 @@ void verifyKeyPathComponent(SILModule &M,
"operator");
auto substEqualsType = equals->getLoweredFunctionType()
->substGenericArgs(M, patternSubs);
->substGenericArgs(M, patternSubs, TypeExpansionContext::minimal());
require(substEqualsType->getParameters().size() == 2,
"must have two arguments");
@@ -186,7 +187,7 @@ void verifyKeyPathComponent(SILModule &M,
"operator");
auto substHashType = hash->getLoweredFunctionType()
->substGenericArgs(M, patternSubs);
->substGenericArgs(M, patternSubs, TypeExpansionContext::minimal());
require(substHashType->getParameters().size() == 1,
"must have two arguments");
@@ -234,7 +235,8 @@ void verifyKeyPathComponent(SILModule &M,
require(property->hasStorage(), "property must be stored");
require(!property->isResilient(M.getSwiftModule(), expansion),
"cannot access storage of resilient property");
auto propertyTy = loweredBaseTy.getFieldType(property, M);
auto propertyTy =
loweredBaseTy.getFieldType(property, M, typeExpansionContext);
require(propertyTy.getObjectType()
== loweredComponentTy.getObjectType(),
"component type should match the maximal abstraction of the "
@@ -269,8 +271,8 @@ void verifyKeyPathComponent(SILModule &M,
"less visible getters");
}
auto substGetterType = getter->getLoweredFunctionType()
->substGenericArgs(M, patternSubs);
auto substGetterType = getter->getLoweredFunctionType()->substGenericArgs(
M, patternSubs, TypeExpansionContext::minimal());
require(substGetterType->getRepresentation() ==
SILFunctionTypeRepresentation::Thin,
"getter should be a thin function");
@@ -317,7 +319,7 @@ void verifyKeyPathComponent(SILModule &M,
}
auto substSetterType = setter->getLoweredFunctionType()
->substGenericArgs(M, patternSubs);
->substGenericArgs(M, patternSubs, TypeExpansionContext::minimal());
require(substSetterType->getRepresentation() ==
SILFunctionTypeRepresentation::Thin,
@@ -366,8 +368,9 @@ void verifyKeyPathComponent(SILModule &M,
require(contextType == operands[opIndex].get()->getType(),
"operand must match type required by pattern");
SILType loweredType = index.LoweredType;
require(loweredType.isLoweringOf(M, index.FormalType),
"pattern index formal type doesn't match lowered type");
require(
loweredType.isLoweringOf(typeExpansionContext, M, index.FormalType),
"pattern index formal type doesn't match lowered type");
}
checkIndexEqualsAndHash();
@@ -1301,7 +1304,7 @@ public:
}
// Apply the substitutions.
return fnTy->substGenericArgs(F.getModule(), subs);
return fnTy->substGenericArgs(F.getModule(), subs, F.getTypeExpansionContext());
}
/// Check that for each opened archetype or dynamic self type in substitutions
@@ -1743,7 +1746,8 @@ public:
void checkGlobalAccessInst(GlobalAccessInst *GAI) {
SILGlobalVariable *RefG = GAI->getReferencedGlobal();
require(GAI->getType().getObjectType() == RefG->getLoweredType(),
require(GAI->getType().getObjectType() ==
RefG->getLoweredTypeInContext(F.getTypeExpansionContext()),
"global_addr/value must be the type of the variable it references");
if (auto *VD = RefG->getDecl()) {
require(!VD->isResilient(F.getModule().getSwiftModule(),
@@ -2324,7 +2328,8 @@ public:
"project_box operand should be a value");
auto boxTy = I->getOperand()->getType().getAs<SILBoxType>();
require(boxTy, "project_box operand should be a @box type");
require(I->getType() == getSILBoxFieldType(boxTy, F.getModule().Types,
require(I->getType() == getSILBoxFieldType(F.getTypeExpansionContext(), boxTy,
F.getModule().Types,
I->getFieldIndex()),
"project_box result should be address of boxed type");
@@ -2393,7 +2398,8 @@ public:
"number of struct operands does not match number of stored "
"member variables of struct");
SILType loweredType = structTy.getFieldType(field, F.getModule());
SILType loweredType =
structTy.getFieldType(field, F.getModule(), F.getTypeExpansionContext());
if (SI->getModule().getStage() != SILStage::Lowered) {
require((*opi)->getType() == loweredType,
"struct operand type does not match field type");
@@ -2415,8 +2421,8 @@ public:
if (UI->getElement()->hasAssociatedValues()) {
require(UI->getOperand()->getType().isObject(),
"EnumInst operand must be an object");
SILType caseTy = UI->getType().getEnumElementType(UI->getElement(),
F.getModule());
SILType caseTy = UI->getType().getEnumElementType(
UI->getElement(), F.getModule(), F.getTypeExpansionContext());
if (UI->getModule().getStage() != SILStage::Lowered) {
require(caseTy == UI->getOperand()->getType(),
"EnumInst operand type does not match type of case");
@@ -2436,9 +2442,8 @@ public:
require(UI->getType().isAddress(),
"InitEnumDataAddrInst must produce an address");
SILType caseTy =
UI->getOperand()->getType().getEnumElementType(UI->getElement(),
F.getModule());
SILType caseTy = UI->getOperand()->getType().getEnumElementType(
UI->getElement(), F.getModule(), F.getTypeExpansionContext());
if (UI->getModule().getStage() != SILStage::Lowered) {
requireSameType(
@@ -2459,9 +2464,8 @@ public:
require(UI->getType().isObject(),
"UncheckedEnumData must produce an address");
SILType caseTy =
UI->getOperand()->getType().getEnumElementType(UI->getElement(),
F.getModule());
SILType caseTy = UI->getOperand()->getType().getEnumElementType(
UI->getElement(), F.getModule(), F.getTypeExpansionContext());
if (UI->getModule().getStage() != SILStage::Lowered) {
require(caseTy == UI->getType(),
@@ -2481,9 +2485,8 @@ public:
require(UI->getType().isAddress(),
"UncheckedTakeEnumDataAddrInst must produce an address");
SILType caseTy =
UI->getOperand()->getType().getEnumElementType(UI->getElement(),
F.getModule());
SILType caseTy = UI->getOperand()->getType().getEnumElementType(
UI->getElement(), F.getModule(), F.getTypeExpansionContext());
if (UI->getModule().getStage() != SILStage::Lowered) {
require(caseTy == UI->getType(), "UncheckedTakeEnumDataAddrInst result "
@@ -2519,7 +2522,8 @@ public:
// Is a SIL type a potential lowering of a formal type?
bool isLoweringOf(SILType loweredType, CanType formalType) {
return loweredType.isLoweringOf(F.getModule(), formalType);
return loweredType.isLoweringOf(F.getTypeExpansionContext(), F.getModule(),
formalType);
}
void checkMetatypeInst(MetatypeInst *MI) {
@@ -2609,9 +2613,9 @@ public:
require(AI->getType().isObject(),
"result of alloc_box must be an object");
for (unsigned field : indices(AI->getBoxType()->getLayout()->getFields())) {
verifyOpenedArchetype(AI,
getSILBoxFieldLoweredType(AI->getBoxType(), F.getModule().Types,
field));
verifyOpenedArchetype(AI, getSILBoxFieldLoweredType(
F.getTypeExpansionContext(), AI->getBoxType(),
F.getModule().Types, field));
}
// An alloc_box with a mark_uninitialized user can not have any other users.
@@ -2705,8 +2709,8 @@ public:
"struct_extract field is not a member of the struct");
if (EI->getModule().getStage() != SILStage::Lowered) {
SILType loweredFieldTy =
operandTy.getFieldType(EI->getField(), F.getModule());
SILType loweredFieldTy = operandTy.getFieldType(
EI->getField(), F.getModule(), F.getTypeExpansionContext());
require(loweredFieldTy == EI->getType(),
"result of struct_extract does not match type of field");
}
@@ -2751,8 +2755,8 @@ public:
"struct_element_addr field is not a member of the struct");
if (EI->getModule().getStage() != SILStage::Lowered) {
SILType loweredFieldTy =
operandTy.getFieldType(EI->getField(), F.getModule());
SILType loweredFieldTy = operandTy.getFieldType(
EI->getField(), F.getModule(), F.getTypeExpansionContext());
require(loweredFieldTy == EI->getType(),
"result of struct_element_addr does not match type of field");
}
@@ -2777,8 +2781,8 @@ public:
"ref_element_addr field must be a member of the class");
if (EI->getModule().getStage() != SILStage::Lowered) {
SILType loweredFieldTy =
operandTy.getFieldType(EI->getField(), F.getModule());
SILType loweredFieldTy = operandTy.getFieldType(
EI->getField(), F.getModule(), F.getTypeExpansionContext());
require(loweredFieldTy == EI->getType(),
"result of ref_element_addr does not match type of field");
}
@@ -2876,7 +2880,8 @@ public:
// The type of the dynamic method must match the usual type of the method,
// but with the more opaque Self type.
auto constantInfo = F.getModule().Types.getConstantInfo(method);
auto constantInfo =
F.getModule().Types.getConstantInfo(F.getTypeExpansionContext(), method);
auto methodTy = constantInfo.SILFnType;
assert(!methodTy->isCoroutine());
@@ -2884,7 +2889,8 @@ public:
// Map interface types to archetypes.
if (auto *env = F.getModule().Types.getConstantGenericEnvironment(method)) {
auto subs = env->getForwardingSubstitutionMap();
methodTy = methodTy->substGenericArgs(F.getModule(), subs);
methodTy = methodTy->substGenericArgs(F.getModule(), subs,
F.getTypeExpansionContext());
}
assert(!methodTy->isPolymorphic());
@@ -2954,7 +2960,8 @@ public:
void checkClassMethodInst(ClassMethodInst *CMI) {
auto member = CMI->getMember();
auto overrideTy = TC.getConstantOverrideType(member);
auto overrideTy =
TC.getConstantOverrideType(F.getTypeExpansionContext(), member);
if (CMI->getModule().getStage() != SILStage::Lowered) {
requireSameType(
CMI->getType(), SILType::getPrimitiveObjectType(overrideTy),
@@ -2982,7 +2989,8 @@ public:
void checkSuperMethodInst(SuperMethodInst *CMI) {
auto member = CMI->getMember();
auto overrideTy = TC.getConstantOverrideType(member);
auto overrideTy =
TC.getConstantOverrideType(F.getTypeExpansionContext(), member);
if (CMI->getModule().getStage() != SILStage::Lowered) {
requireSameType(
CMI->getType(), SILType::getPrimitiveObjectType(overrideTy),
@@ -3033,7 +3041,8 @@ public:
operandInstanceType = metatypeType.getInstanceType();
if (operandInstanceType.getClassOrBoundGenericClass()) {
auto overrideTy = TC.getConstantOverrideType(member);
auto overrideTy =
TC.getConstantOverrideType(F.getTypeExpansionContext(), member);
requireSameType(
OMI->getType(), SILType::getPrimitiveObjectType(overrideTy),
"result type of objc_method must match abstracted type of method");
@@ -3058,7 +3067,8 @@ public:
void checkObjCSuperMethodInst(ObjCSuperMethodInst *OMI) {
auto member = OMI->getMember();
auto overrideTy = TC.getConstantOverrideType(member);
auto overrideTy =
TC.getConstantOverrideType(F.getTypeExpansionContext(), member);
if (OMI->getModule().getStage() != SILStage::Lowered) {
requireSameType(
OMI->getType(), SILType::getPrimitiveObjectType(overrideTy),
@@ -3901,7 +3911,9 @@ public:
LLVM_DEBUG(RI->print(llvm::dbgs()));
SILType functionResultType =
F.mapTypeIntoContext(fnConv.getSILResultType());
F.getLoweredType(
F.mapTypeIntoContext(fnConv.getSILResultType()).getASTType())
.getCategoryType(fnConv.getSILResultType().getCategory());
SILType instResultType = RI->getOperand()->getType();
LLVM_DEBUG(llvm::dbgs() << "function return type: ";
functionResultType.dump();
@@ -3914,11 +3926,15 @@ public:
void checkThrowInst(ThrowInst *TI) {
LLVM_DEBUG(TI->print(llvm::dbgs()));
CanSILFunctionType fnType = F.getLoweredFunctionType();
CanSILFunctionType fnType =
F.getLoweredFunctionTypeInContext(F.getTypeExpansionContext());
require(fnType->hasErrorResult(),
"throw in function that doesn't have an error result");
SILType functionResultType = F.mapTypeIntoContext(fnConv.getSILErrorType());
SILType functionResultType =
F.getLoweredType(
F.mapTypeIntoContext(fnConv.getSILErrorType()).getASTType())
.getCategoryType(fnConv.getSILErrorType().getCategory());
SILType instResultType = TI->getOperand()->getType();
LLVM_DEBUG(llvm::dbgs() << "function error result type: ";
functionResultType.dump();
@@ -3934,7 +3950,8 @@ public:
}
void checkYieldInst(YieldInst *YI) {
CanSILFunctionType fnType = F.getLoweredFunctionType();
CanSILFunctionType fnType =
F.getLoweredFunctionTypeInContext(F.getTypeExpansionContext());
require(fnType->isCoroutine(),
"yield in non-coroutine function");
@@ -4134,7 +4151,8 @@ public:
}
if (dest->getArguments().size() == 1) {
SILType eltArgTy = uTy.getEnumElementType(elt, F.getModule());
SILType eltArgTy = uTy.getEnumElementType(elt, F.getModule(),
F.getTypeExpansionContext());
SILType bbArgTy = dest->getArguments()[0]->getType();
if (F.getModule().getStage() != SILStage::Lowered) {
// During the lowered stage, a function type might have different
@@ -4540,7 +4558,9 @@ public:
auto mappedTy = F.mapTypeIntoContext(ty);
SILArgument *bbarg = *argI;
++argI;
if (bbarg->getType() != mappedTy) {
if (bbarg->getType() != mappedTy &&
bbarg->getType() != F.getLoweredType(mappedTy.getASTType())
.getCategoryType(mappedTy.getCategory())) {
llvm::errs() << what << " type mismatch!\n";
llvm::errs() << " argument: "; bbarg->dump();
llvm::errs() << " expected: "; mappedTy.dump();
@@ -5145,7 +5165,8 @@ void SILVTable::verify(const SILModule &M) const {
for (auto &entry : getEntries()) {
// All vtable entries must be decls in a class context.
assert(entry.Method.hasDecl() && "vtable entry is not a decl");
auto baseInfo = M.Types.getConstantInfo(entry.Method);
auto baseInfo =
M.Types.getConstantInfo(TypeExpansionContext::minimal(), entry.Method);
ValueDecl *decl = entry.Method.getDecl();
assert((!isa<AccessorDecl>(decl)