mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Revert "SILGen: Emit literal closures at the abstraction level of their context. [take 2]" (#39228)
This commit is contained in:
@@ -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> ¶meters)
|
||||
: 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.
|
||||
|
||||
Reference in New Issue
Block a user