Skip to content

Commit 533d41d

Browse files
committed
SIL: Compute lowered local captures of SILDeclRefs and not AnyFunctionRefs
Unfortuantely this commit is bigger than I would like but I couldn't think of any reasonable ways to split it up. The general idea here is that capture computation is now done for a SILDeclRef and not an AnyFunctionRef. This allows SIL to represent the captures of a default argument generator.
1 parent b8642b0 commit 533d41d

File tree

11 files changed

+175
-151
lines changed

11 files changed

+175
-151
lines changed

include/swift/SIL/TypeLowering.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ class TypeConverter {
689689

690690
llvm::DenseMap<OverrideKey, SILConstantInfo *> ConstantOverrideTypes;
691691

692-
llvm::DenseMap<AnyFunctionRef, CaptureInfo> LoweredCaptures;
692+
llvm::DenseMap<SILDeclRef, CaptureInfo> LoweredCaptures;
693693

694694
/// Cache of loadable SILType to number of (estimated) fields
695695
///
@@ -896,11 +896,6 @@ class TypeConverter {
896896
SILType getEmptyTupleType() {
897897
return SILType::getPrimitiveObjectType(TupleType::getEmpty(Context));
898898
}
899-
900-
/// Get a function type curried with its capture context.
901-
CanAnyFunctionType getFunctionInterfaceTypeWithCaptures(
902-
CanAnyFunctionType funcType,
903-
AnyFunctionRef closure);
904899

905900
/// Describes what we're trying to compute a bridged type for.
906901
///
@@ -972,10 +967,10 @@ class TypeConverter {
972967
CanType get##BridgedType##Type();
973968
#include "swift/SIL/BridgedTypes.def"
974969

975-
/// Get the capture list from a closure, with transitive function captures
976-
/// flattened.
977-
CaptureInfo getLoweredLocalCaptures(AnyFunctionRef fn);
978-
bool hasLoweredLocalCaptures(AnyFunctionRef fn);
970+
/// Get the capture list for a function or default argument, with transitive
971+
/// function captures flattened.
972+
CaptureInfo getLoweredLocalCaptures(SILDeclRef fn);
973+
bool hasLoweredLocalCaptures(SILDeclRef fn);
979974

980975
enum class ABIDifference : uint8_t {
981976
// No ABI differences, function can be trivially bitcast to result type.

lib/SIL/SILFunctionType.cpp

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ static std::pair<AbstractionPattern, CanType> updateResultTypeForForeignError(
715715
/// If we ever add that ability, it will be a different capture list
716716
/// from the function to which the argument is attached.
717717
static void
718-
lowerCaptureContextParameters(TypeConverter &TC, AnyFunctionRef function,
718+
lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
719719
CanGenericSignature genericSig,
720720
ResilienceExpansion expansion,
721721
SmallVectorImpl<SILParameterInfo> &inputs) {
@@ -725,8 +725,7 @@ lowerCaptureContextParameters(TypeConverter &TC, AnyFunctionRef function,
725725
// canonicalize references to the generic parameters that may appear in
726726
// non-canonical types in that context. We need the original generic
727727
// signature from the AST for that.
728-
auto origGenericSig = function.getGenericSignature();
729-
728+
auto origGenericSig = function.getAnyFunctionRef()->getGenericSignature();
730729
auto loweredCaptures = TC.getLoweredLocalCaptures(function);
731730

732731
for (auto capture : loweredCaptures.getCaptures()) {
@@ -999,18 +998,12 @@ static CanSILFunctionType getSILFunctionType(
999998
yields, coroutineKind);
1000999

10011000
// Lower the capture context parameters, if any.
1002-
//
1003-
// *NOTE* Currently default arg generators can not capture anything.
1004-
// If we ever add that ability, it will be a different capture list
1005-
// from the function to which the argument is attached.
1006-
if (constant && !constant->isDefaultArgGenerator()) {
1007-
if (auto function = constant->getAnyFunctionRef()) {
1008-
auto expansion = ResilienceExpansion::Maximal;
1009-
if (constant->isSerialized())
1010-
expansion = ResilienceExpansion::Minimal;
1011-
lowerCaptureContextParameters(TC, *function, genericSig, expansion,
1012-
inputs);
1013-
}
1001+
if (constant && constant->getAnyFunctionRef()) {
1002+
auto expansion = ResilienceExpansion::Maximal;
1003+
if (constant->isSerialized())
1004+
expansion = ResilienceExpansion::Minimal;
1005+
lowerCaptureContextParameters(TC, *constant, genericSig, expansion,
1006+
inputs);
10141007
}
10151008

10161009
auto calleeConvention = ParameterConvention::Direct_Unowned;

lib/SIL/TypeLowering.cpp

Lines changed: 87 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,31 +1728,27 @@ getTypeLoweringForExpansion(TypeKey key,
17281728
}
17291729

17301730
static GenericSignature *
1731-
getEffectiveGenericSignature(DeclContext *dc) {
1732-
if (auto sig = dc->getGenericSignatureOfContext()) {
1733-
if (sig->areAllParamsConcrete())
1734-
return nullptr;
1735-
return sig;
1736-
}
1731+
getEffectiveGenericSignature(DeclContext *dc,
1732+
CaptureInfo captureInfo) {
1733+
if (dc->getParent()->isLocalContext() &&
1734+
!captureInfo.hasGenericParamCaptures())
1735+
return nullptr;
17371736

1738-
return nullptr;
1737+
return dc->getGenericSignatureOfContext();
17391738
}
17401739

17411740
static GenericSignature *
17421741
getEffectiveGenericSignature(AnyFunctionRef fn,
17431742
CaptureInfo captureInfo) {
1744-
auto dc = fn.getAsDeclContext();
1745-
1746-
if (dc->getParent()->isLocalContext() &&
1747-
!captureInfo.hasGenericParamCaptures())
1748-
return nullptr;
1749-
1750-
return getEffectiveGenericSignature(dc);
1743+
return getEffectiveGenericSignature(fn.getAsDeclContext(), captureInfo);
17511744
}
17521745

17531746
static CanGenericSignature
17541747
getCanonicalSignatureOrNull(GenericSignature *sig) {
1755-
return sig ? sig->getCanonicalSignature() : nullptr;
1748+
if (!sig || sig->areAllParamsConcrete())
1749+
return nullptr;
1750+
1751+
return sig->getCanonicalSignature();
17561752
}
17571753

17581754
/// Get the type of a global variable accessor function, () -> RawPointer.
@@ -1763,7 +1759,6 @@ static CanAnyFunctionType getGlobalAccessorType(CanType varType) {
17631759

17641760
/// Get the type of a default argument generator, () -> T.
17651761
static CanAnyFunctionType getDefaultArgGeneratorInterfaceType(
1766-
TypeConverter &TC,
17671762
SILDeclRef c) {
17681763
auto *vd = c.getDecl();
17691764
auto resultTy = getParameterAt(vd,
@@ -1785,7 +1780,15 @@ static CanAnyFunctionType getDefaultArgGeneratorInterfaceType(
17851780
}
17861781

17871782
// Get the generic signature from the surrounding context.
1788-
auto sig = TC.getConstantGenericSignature(c);
1783+
auto *sig = vd->getInnermostDeclContext()->getGenericSignatureOfContext();
1784+
if (auto *afd = dyn_cast<AbstractFunctionDecl>(vd)) {
1785+
auto *param = getParameterAt(afd, c.defaultArgIndex);
1786+
if (param->getDefaultValue()) {
1787+
auto &captureInfo = param->getDefaultArgumentCaptureInfo();
1788+
sig = getEffectiveGenericSignature(afd, captureInfo);
1789+
}
1790+
}
1791+
17891792
return CanAnyFunctionType::get(getCanonicalSignatureOrNull(sig),
17901793
{}, canResultTy);
17911794
}
@@ -1806,7 +1809,7 @@ static CanAnyFunctionType getStoredPropertyInitializerInterfaceType(
18061809
resultTy = originalProperty->getValueInterfaceType()->getCanonicalType();
18071810
}
18081811

1809-
auto sig = getEffectiveGenericSignature(DC);
1812+
auto sig = DC->getGenericSignatureOfContext();
18101813

18111814
return CanAnyFunctionType::get(getCanonicalSignatureOrNull(sig),
18121815
{}, resultTy);
@@ -1837,7 +1840,7 @@ static CanAnyFunctionType getDestructorInterfaceType(DestructorDecl *dd,
18371840
: C.TheNativeObjectType);
18381841
CanType methodTy = CanFunctionType::get({}, resultTy);
18391842

1840-
auto sig = getEffectiveGenericSignature(dd);
1843+
auto sig = dd->getGenericSignatureOfContext();
18411844
FunctionType::Param args[] = {FunctionType::Param(classType)};
18421845
return CanAnyFunctionType::get(getCanonicalSignatureOrNull(sig),
18431846
llvm::makeArrayRef(args),
@@ -1862,22 +1865,24 @@ static CanAnyFunctionType getIVarInitDestroyerInterfaceType(ClassDecl *cd,
18621865
: SILFunctionTypeRepresentation::Method);
18631866

18641867
resultType = CanFunctionType::get({}, resultType, extInfo);
1865-
auto sig = getEffectiveGenericSignature(cd);
1868+
auto sig = cd->getGenericSignature();
18661869
FunctionType::Param args[] = {FunctionType::Param(classType)};
18671870
return CanAnyFunctionType::get(getCanonicalSignatureOrNull(sig),
18681871
llvm::makeArrayRef(args),
18691872
resultType, extInfo);
18701873
}
18711874

1872-
CanAnyFunctionType
1873-
TypeConverter::getFunctionInterfaceTypeWithCaptures(CanAnyFunctionType funcType,
1874-
AnyFunctionRef theClosure) {
1875+
static CanAnyFunctionType
1876+
getFunctionInterfaceTypeWithCaptures(TypeConverter &TC,
1877+
CanAnyFunctionType funcType,
1878+
SILDeclRef constant) {
18751879
// Get transitive closure of value captured by this function, and any
18761880
// captured functions.
1877-
auto captureInfo = getLoweredLocalCaptures(theClosure);
1881+
auto captureInfo = TC.getLoweredLocalCaptures(constant);
18781882

18791883
// Capture generic parameters from the enclosing context if necessary.
1880-
auto *genericSig = getEffectiveGenericSignature(theClosure, captureInfo);
1884+
auto closure = *constant.getAnyFunctionRef();
1885+
auto *genericSig = getEffectiveGenericSignature(closure, captureInfo);
18811886

18821887
auto innerExtInfo = AnyFunctionType::ExtInfo(FunctionType::Representation::Thin,
18831888
funcType->throws());
@@ -1897,25 +1902,22 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
18971902

18981903
switch (c.kind) {
18991904
case SILDeclRef::Kind::Func: {
1905+
CanAnyFunctionType funcTy;
19001906
if (auto *ACE = c.loc.dyn_cast<AbstractClosureExpr *>()) {
19011907
// FIXME: Closures could have an interface type computed by Sema.
1902-
auto funcTy = cast<AnyFunctionType>(ACE->getType()->getCanonicalType());
19031908
funcTy = cast<AnyFunctionType>(
1904-
funcTy->mapTypeOutOfContext()
1905-
->getCanonicalType());
1906-
return getFunctionInterfaceTypeWithCaptures(funcTy, ACE);
1909+
ACE->getType()->mapTypeOutOfContext()->getCanonicalType());
1910+
} else {
1911+
funcTy = cast<AnyFunctionType>(
1912+
vd->getInterfaceType()->getCanonicalType());
19071913
}
1908-
1909-
FuncDecl *func = cast<FuncDecl>(vd);
1910-
auto funcTy = cast<AnyFunctionType>(
1911-
func->getInterfaceType()->getCanonicalType());
1912-
return getFunctionInterfaceTypeWithCaptures(funcTy, func);
1914+
return getFunctionInterfaceTypeWithCaptures(*this, funcTy, c);
19131915
}
19141916

19151917
case SILDeclRef::Kind::EnumElement: {
19161918
auto funcTy = cast<AnyFunctionType>(
1917-
vd->getInterfaceType()->getCanonicalType());
1918-
auto sig = getEffectiveGenericSignature(vd->getDeclContext());
1919+
vd->getInterfaceType()->getCanonicalType());
1920+
auto sig = vd->getDeclContext()->getGenericSignatureOfContext();
19191921
return CanAnyFunctionType::get(getCanonicalSignatureOrNull(sig),
19201922
funcTy->getParams(),
19211923
funcTy.getResult(),
@@ -1926,14 +1928,14 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
19261928
auto *cd = cast<ConstructorDecl>(vd);
19271929
auto funcTy = cast<AnyFunctionType>(
19281930
cd->getInterfaceType()->getCanonicalType());
1929-
return getFunctionInterfaceTypeWithCaptures(funcTy, cd);
1931+
return getFunctionInterfaceTypeWithCaptures(*this, funcTy, c);
19301932
}
19311933

19321934
case SILDeclRef::Kind::Initializer: {
19331935
auto *cd = cast<ConstructorDecl>(vd);
19341936
auto funcTy = cast<AnyFunctionType>(
19351937
cd->getInitializerInterfaceType()->getCanonicalType());
1936-
return getFunctionInterfaceTypeWithCaptures(funcTy, cd);
1938+
return getFunctionInterfaceTypeWithCaptures(*this, funcTy, c);
19371939
}
19381940

19391941
case SILDeclRef::Kind::Destroyer:
@@ -1949,7 +1951,7 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
19491951
return getGlobalAccessorType(var->getInterfaceType()->getCanonicalType());
19501952
}
19511953
case SILDeclRef::Kind::DefaultArgGenerator:
1952-
return getDefaultArgGeneratorInterfaceType(*this, c);
1954+
return getDefaultArgGeneratorInterfaceType(c);
19531955
case SILDeclRef::Kind::StoredPropertyInitializer:
19541956
return getStoredPropertyInitializerInterfaceType(cast<VarDecl>(vd));
19551957
case SILDeclRef::Kind::IVarInitializer:
@@ -1969,43 +1971,28 @@ TypeConverter::getConstantGenericSignature(SILDeclRef c) {
19691971

19701972
/// Get the function generic params, including outer params.
19711973
switch (c.kind) {
1972-
case SILDeclRef::Kind::Func: {
1973-
if (auto *ACE = c.getAbstractClosureExpr()) {
1974-
auto captureInfo = getLoweredLocalCaptures(ACE);
1975-
return getEffectiveGenericSignature(ACE, captureInfo);
1976-
}
1977-
FuncDecl *func = cast<FuncDecl>(vd);
1978-
auto captureInfo = getLoweredLocalCaptures(func);
1979-
return getEffectiveGenericSignature(func, captureInfo);
1980-
}
1981-
case SILDeclRef::Kind::EnumElement: {
1982-
auto eltDecl = cast<EnumElementDecl>(vd);
1983-
return getEffectiveGenericSignature(eltDecl->getDeclContext());
1984-
}
1974+
case SILDeclRef::Kind::Func:
19851975
case SILDeclRef::Kind::Allocator:
19861976
case SILDeclRef::Kind::Initializer:
19871977
case SILDeclRef::Kind::Destroyer:
19881978
case SILDeclRef::Kind::Deallocator: {
1989-
auto *afd = cast<AbstractFunctionDecl>(vd);
1990-
auto captureInfo = getLoweredLocalCaptures(afd);
1991-
return getEffectiveGenericSignature(afd, captureInfo);
1979+
auto captureInfo = getLoweredLocalCaptures(c);
1980+
return getEffectiveGenericSignature(
1981+
*c.getAnyFunctionRef(), captureInfo);
19921982
}
1993-
case SILDeclRef::Kind::GlobalAccessor:
1994-
return getEffectiveGenericSignature(vd->getDeclContext());
19951983
case SILDeclRef::Kind::IVarInitializer:
19961984
case SILDeclRef::Kind::IVarDestroyer:
1997-
return getEffectiveGenericSignature(cast<ClassDecl>(vd));
1998-
case SILDeclRef::Kind::DefaultArgGenerator:
1985+
return cast<ClassDecl>(vd)->getGenericSignature();
1986+
case SILDeclRef::Kind::DefaultArgGenerator: {
19991987
// Use the generic environment of the original function.
2000-
if (auto *afd = dyn_cast<AbstractFunctionDecl>(c.getDecl())) {
2001-
auto captureInfo = getLoweredLocalCaptures(afd);
2002-
return getEffectiveGenericSignature(afd, captureInfo);
2003-
}
1988+
auto captureInfo = getLoweredLocalCaptures(c);
20041989
return getEffectiveGenericSignature(
2005-
c.getDecl()->getInnermostDeclContext());
1990+
vd->getInnermostDeclContext(), captureInfo);
1991+
}
1992+
case SILDeclRef::Kind::EnumElement:
1993+
case SILDeclRef::Kind::GlobalAccessor:
20061994
case SILDeclRef::Kind::StoredPropertyInitializer:
2007-
// Use the generic environment of the containing type.
2008-
return getEffectiveGenericSignature(c.getDecl()->getDeclContext());
1995+
return vd->getDeclContext()->getGenericSignatureOfContext();
20091996
}
20101997

20111998
llvm_unreachable("Unhandled SILDeclRefKind in switch.");
@@ -2107,12 +2094,16 @@ getAnyFunctionRefFromCapture(CapturedValue capture) {
21072094
}
21082095

21092096
bool
2110-
TypeConverter::hasLoweredLocalCaptures(AnyFunctionRef fn) {
2097+
TypeConverter::hasLoweredLocalCaptures(SILDeclRef fn) {
21112098
return !getLoweredLocalCaptures(fn).getCaptures().empty();
21122099
}
21132100

21142101
CaptureInfo
2115-
TypeConverter::getLoweredLocalCaptures(AnyFunctionRef fn) {
2102+
TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
2103+
fn.isForeign = 0;
2104+
fn.isCurried = 0;
2105+
fn.isDirectReference = 0;
2106+
21162107
// See if we've cached the lowered capture list for this function.
21172108
auto found = LoweredCaptures.find(fn);
21182109
if (found != LoweredCaptures.end())
@@ -2132,6 +2123,7 @@ TypeConverter::getLoweredLocalCaptures(AnyFunctionRef fn) {
21322123

21332124
std::function<void (const CaptureInfo &captureInfo)> collectCaptures;
21342125
std::function<void (AnyFunctionRef)> collectFunctionCaptures;
2126+
std::function<void (SILDeclRef)> collectConstantCaptures;
21352127

21362128
collectCaptures = [&](const CaptureInfo &captureInfo) {
21372129
if (captureInfo.hasGenericParamCaptures())
@@ -2262,7 +2254,10 @@ TypeConverter::getLoweredLocalCaptures(AnyFunctionRef fn) {
22622254

22632255
collectCaptures(curFn.getCaptureInfo());
22642256

2265-
// Also visit default argument captures.
2257+
// A function's captures also include its default arguments, because
2258+
// when we reference a function we don't track which default arguments
2259+
// are referenced too.
2260+
//
22662261
// FIXME: This should be more fine-grained -- we should only need the
22672262
// captures for default arguments that are actually referenced.
22682263
if (auto *AFD = curFn.getAbstractFunctionDecl()) {
@@ -2272,7 +2267,27 @@ TypeConverter::getLoweredLocalCaptures(AnyFunctionRef fn) {
22722267
}
22732268
}
22742269
};
2275-
collectFunctionCaptures(fn);
2270+
2271+
collectConstantCaptures = [&](SILDeclRef curFn) {
2272+
if (curFn.isDefaultArgGenerator()) {
2273+
if (auto *afd = dyn_cast<AbstractFunctionDecl>(curFn.getDecl())) {
2274+
auto *param = getParameterAt(afd, curFn.defaultArgIndex);
2275+
if (param->getDefaultValue())
2276+
collectCaptures(param->getDefaultArgumentCaptureInfo());
2277+
return;
2278+
}
2279+
2280+
if (curFn.getDecl()->getInnermostDeclContext()
2281+
->getGenericSignatureOfContext())
2282+
capturesGenericParams = true;
2283+
2284+
return;
2285+
}
2286+
2287+
collectFunctionCaptures(*curFn.getAnyFunctionRef());
2288+
};
2289+
2290+
collectConstantCaptures(fn);
22762291

22772292
SmallVector<CapturedValue, 4> resultingCaptures;
22782293
for (auto capturePair : captures) {
@@ -2518,7 +2533,7 @@ TypeConverter::getInterfaceBoxTypeForCapture(ValueDecl *captured,
25182533
bool isMutable) {
25192534
auto &C = M.getASTContext();
25202535
auto signature = getCanonicalSignatureOrNull(
2521-
getEffectiveGenericSignature(captured->getDeclContext()));
2536+
captured->getDeclContext()->getGenericSignatureOfContext());
25222537

25232538
// If the type is not dependent at all, we can form a concrete box layout.
25242539
// We don't need to capture the generic environment.
@@ -2606,7 +2621,7 @@ CanSILBoxType TypeConverter::getBoxTypeForEnumElement(SILType enumType,
26062621
Context.getLazyResolver()->resolveDeclSignature(elt);
26072622

26082623
auto boxSignature = getCanonicalSignatureOrNull(
2609-
getEffectiveGenericSignature(enumDecl));
2624+
enumDecl->getGenericSignature());
26102625

26112626
if (boxSignature == CanGenericSignature()) {
26122627
auto eltIntfTy = elt->getArgumentInterfaceType();

0 commit comments

Comments
 (0)