Revert "SILGen: Emit literal closures at the abstraction level of their context. [take 2]" (#39228)

This commit is contained in:
Joe Groff
2021-09-09 09:53:43 -07:00
committed by GitHub
parent 0829f5b30c
commit 3abe16f40f
34 changed files with 158 additions and 528 deletions

View File

@@ -40,8 +40,7 @@ SILValue SILGenFunction::emitSelfDecl(VarDecl *selfDecl) {
namespace {
class EmitBBArguments : public CanTypeVisitor<EmitBBArguments,
/*RetTy*/ ManagedValue,
/*ArgTys...*/ AbstractionPattern>
/*RetTy*/ ManagedValue>
{
public:
SILGenFunction &SGF;
@@ -55,11 +54,11 @@ public:
ArrayRef<SILParameterInfo> &parameters)
: SGF(sgf), parent(parent), loc(l), fnTy(fnTy), parameters(parameters) {}
ManagedValue visitType(CanType t, AbstractionPattern orig) {
return visitType(t, orig, /*isInOut=*/false);
ManagedValue visitType(CanType t) {
return visitType(t, /*isInOut=*/false);
}
ManagedValue visitType(CanType t, AbstractionPattern orig, bool isInOut) {
ManagedValue visitType(CanType t, bool isInOut) {
// The calling convention always uses minimal resilience expansion but
// inside the function we lower/expand types in context of the current
// function.
@@ -68,9 +67,8 @@ public:
SGF.SGM.Types.getLoweredType(t, TypeExpansionContext::minimal());
argType = argType.getCategoryType(argTypeConv.getCategory());
if (isInOut
|| orig.getParameterConvention(SGF.SGM.Types) == AbstractionPattern::Indirect)
argType = argType.getCategoryType(SILValueCategory::Address);
if (isInOut)
argType = SILType::getPrimitiveAddressType(argType.getASTType());
// Pop the next parameter info.
auto parameterInfo = parameters.front();
@@ -81,18 +79,18 @@ public:
ManagedValue mv = SGF.B.createInputFunctionArgument(
paramType, loc.getAsASTNode<ValueDecl>());
// This is a hack to deal with the fact that Self.Type comes in as a static
// metatype, but we have to downcast it to a dynamic Self metatype to get
// the right semantics.
if (argType != paramType) {
if (auto argMetaTy = argType.getAs<MetatypeType>()) {
if (auto argSelfTy = dyn_cast<DynamicSelfType>(argMetaTy.getInstanceType())) {
assert(argSelfTy.getSelfType()
== paramType.castTo<MetatypeType>().getInstanceType());
mv = SGF.B.createUncheckedBitCast(loc, mv, argType);
}
}
// This is a hack to deal with the fact that Self.Type comes in as a
// static metatype, but we have to downcast it to a dynamic Self
// metatype to get the right semantics.
assert(
cast<DynamicSelfType>(
argType.castTo<MetatypeType>().getInstanceType())
.getSelfType()
== paramType.castTo<MetatypeType>().getInstanceType());
mv = SGF.B.createUncheckedBitCast(loc, mv, argType);
}
if (isInOut)
return mv;
@@ -103,12 +101,6 @@ public:
mv = SGF.B.createLoadTake(loc, mv);
else
mv = SGF.B.createLoadBorrow(loc, mv);
argType = argType.getObjectType();
}
if (argType != paramType) {
// Reabstract the value if necessary.
mv = SGF.emitOrigToSubstValue(loc, mv, orig, t);
}
// If the value is a (possibly optional) ObjC block passed into the entry
@@ -127,20 +119,15 @@ public:
return mv;
}
ManagedValue visitTupleType(CanTupleType t, AbstractionPattern orig) {
// Only destructure if the abstraction pattern is also a tuple.
if (!orig.isTuple())
return visitType(t, orig);
ManagedValue visitTupleType(CanTupleType t) {
SmallVector<ManagedValue, 4> elements;
auto &tl = SGF.SGM.Types.getTypeLowering(t, SGF.getTypeExpansionContext());
bool canBeGuaranteed = tl.isLoadable();
// Collect the exploded elements.
for (unsigned i = 0, e = orig.getNumTupleElements(); i < e; ++i) {
auto elt = visit(t.getElementType(i),
orig.getTupleElementType(i));
for (auto fieldType : t.getElementTypes()) {
auto elt = visit(fieldType);
// If we can't borrow one of the elements as a guaranteed parameter, then
// we have to +1 the tuple.
if (elt.hasCleanup())
@@ -204,16 +191,11 @@ struct ArgumentInitHelper {
ArrayRef<SILParameterInfo> parameters;
uint16_t ArgNo = 0;
Optional<AbstractionPattern> OrigFnType;
ArgumentInitHelper(SILGenFunction &SGF, SILFunction &f,
Optional<AbstractionPattern> origFnType)
ArgumentInitHelper(SILGenFunction &SGF, SILFunction &f)
: SGF(SGF), f(f), initB(SGF.B),
parameters(
f.getLoweredFunctionTypeInContext(SGF.B.getTypeExpansionContext())
->getParameters()),
OrigFnType(origFnType)
{}
->getParameters()) {}
unsigned getNumArgs() const { return ArgNo; }
@@ -227,12 +209,9 @@ struct ArgumentInitHelper {
f.getLoweredFunctionType(), parameters);
// Note: inouts of tuples are not exploded, so we bypass visit().
AbstractionPattern origTy = OrigFnType
? OrigFnType->getFunctionParamType(ArgNo - 1)
: AbstractionPattern(canTy);
if (isInOut)
return argEmitter.visitType(canTy, origTy, /*isInOut=*/true);
return argEmitter.visit(canTy, origTy);
return argEmitter.visitType(canTy, /*isInOut=*/true);
return argEmitter.visit(canTy);
}
/// Create a SILArgument and store its value into the given Initialization,
@@ -434,10 +413,9 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
DeclContext *DC,
Type resultType,
bool throws,
SourceLoc throwsLoc,
Optional<AbstractionPattern> origClosureType) {
SourceLoc throwsLoc) {
uint16_t ArgNo = emitBasicProlog(paramList, selfParam, resultType,
DC, throws, throwsLoc, origClosureType);
DC, throws, throwsLoc);
// Emit the capture argument variables. These are placed last because they
// become the first curry level of the SIL function.
@@ -782,40 +760,28 @@ SILValue SILGenFunction::emitGetCurrentExecutor(SILLocation loc) {
SubstitutionMap(), { });
}
static void emitIndirectResultParameters(SILGenFunction &SGF,
Type resultType,
AbstractionPattern origResultType,
static void emitIndirectResultParameters(SILGenFunction &SGF, Type resultType,
DeclContext *DC) {
// Expand tuples.
if (origResultType.isTuple()) {
auto tupleType = resultType->castTo<TupleType>();
for (unsigned i = 0, e = origResultType.getNumTupleElements(); i < e; ++i) {
emitIndirectResultParameters(SGF, tupleType->getElementType(i),
origResultType.getTupleElementType(i),
DC);
if (auto tupleType = resultType->getAs<TupleType>()) {
for (auto eltType : tupleType->getElementTypes()) {
emitIndirectResultParameters(SGF, eltType, DC);
}
return;
}
// If the return type is address-only, emit the indirect return argument.
auto &resultTI =
SGF.SGM.Types.getTypeLowering(origResultType,
DC->mapTypeIntoContext(resultType),
SGF.getTypeExpansionContext());
// The calling convention always uses minimal resilience expansion.
auto &resultTI =
SGF.SGM.Types.getTypeLowering(DC->mapTypeIntoContext(resultType),
SGF.getTypeExpansionContext());
auto &resultTIConv = SGF.SGM.Types.getTypeLowering(
DC->mapTypeIntoContext(resultType), TypeExpansionContext::minimal());
auto resultConvType = resultTIConv.getLoweredType();
// And the abstraction pattern may force an indirect return even if the
// concrete type wouldn't normally be returned indirectly.
if (!SILModuleConventions::isReturnedIndirectlyInSIL(resultConvType,
SGF.SGM.M))
if (!SILModuleConventions(SGF.SGM.M).useLoweredAddresses()
|| origResultType.getResultConvention(SGF.SGM.Types) != AbstractionPattern::Indirect) {
return;
if (!SILModuleConventions::isReturnedIndirectlyInSIL(
resultTIConv.getLoweredType(), SGF.SGM.M)) {
return;
}
auto &ctx = SGF.getASTContext();
auto var = new (ctx) ParamDecl(SourceLoc(), SourceLoc(),
@@ -830,25 +796,19 @@ static void emitIndirectResultParameters(SILGenFunction &SGF,
}
uint16_t SILGenFunction::emitBasicProlog(ParameterList *paramList,
ParamDecl *selfParam,
Type resultType,
DeclContext *DC,
bool throws,
SourceLoc throwsLoc,
Optional<AbstractionPattern> origClosureType) {
ParamDecl *selfParam,
Type resultType,
DeclContext *DC,
bool throws,
SourceLoc throwsLoc) {
// Create the indirect result parameters.
auto genericSig = DC->getGenericSignatureOfContext();
resultType = resultType->getCanonicalType(genericSig);
AbstractionPattern origResultType = origClosureType
? origClosureType->getFunctionResultType()
: AbstractionPattern(genericSig.getCanonicalSignature(),
CanType(resultType));
emitIndirectResultParameters(*this, resultType, origResultType, DC);
emitIndirectResultParameters(*this, resultType, DC);
// Emit the argument variables in calling convention order.
ArgumentInitHelper emitter(*this, F, origClosureType);
ArgumentInitHelper emitter(*this, F);
// Add the SILArguments and use them to initialize the local argument
// values.