Skip to content

Commit acece4c

Browse files
committed
[NFC] Push cleanup management through a few reabstraction utilities
1 parent bdaada6 commit acece4c

File tree

1 file changed

+127
-64
lines changed

1 file changed

+127
-64
lines changed

lib/SILGen/SILGenPoly.cpp

Lines changed: 127 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,46 @@ class ExpanderBase {
10121012
ManagedValue outerAddr);
10131013
};
10141014

1015+
class ParamInfo {
1016+
IndirectSlot slot;
1017+
ParameterConvention convention;
1018+
1019+
public:
1020+
ParamInfo(IndirectSlot slot, ParameterConvention convention)
1021+
: slot(slot), convention(convention) {}
1022+
1023+
SILValue allocate(SILGenFunction &SGF, SILLocation loc) const {
1024+
return slot.allocate(SGF, loc);
1025+
}
1026+
1027+
std::unique_ptr<TemporaryInitialization>
1028+
allocateForInitialization(SILGenFunction &SGF, SILLocation loc) const {
1029+
auto addr = slot.allocate(SGF, loc);
1030+
auto &addrTL = SGF.getTypeLowering(addr->getType());
1031+
return SGF.useBufferAsTemporary(addr, addrTL);
1032+
}
1033+
1034+
SILType getType() const {
1035+
return slot.getType();
1036+
}
1037+
1038+
ParameterConvention getConvention() const {
1039+
return convention;
1040+
}
1041+
1042+
/// Are we expected to generate into a fixed address?
1043+
bool hasAddress() const {
1044+
return slot.hasAddress();
1045+
}
1046+
1047+
/// Are we expected to produce an address?
1048+
bool shouldProduceAddress(SILGenFunction &SGF) const {
1049+
return hasAddress() ||
1050+
(isIndirectFormalParameter(convention) &&
1051+
SGF.silConv.useLoweredAddresses());
1052+
}
1053+
};
1054+
10151055
/// Given a list of inputs that are suited to the parameters of one
10161056
/// function, translate them into a list of outputs that are suited
10171057
/// for the parameters of another function, given that the two
@@ -1269,12 +1309,12 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
12691309
if (innerSubstType.isInOut()) {
12701310
assert(outerSubstType.isInOut());
12711311
auto outerValue = claimNextOuterArg();
1272-
auto innerLoweredTy = claimNextInnerParam();
1312+
auto innerParam = claimNextInnerParam();
12731313

12741314
ManagedValue inner =
12751315
processInOut(innerOrigType, innerSubstType.getParameterType(),
12761316
outerOrigType, outerSubstType.getParameterType(),
1277-
outerValue, innerLoweredTy);
1317+
outerValue, innerParam);
12781318
InnerArgs.push_back(inner);
12791319
} else {
12801320
process(innerOrigType, innerSubstType.getParameterType(),
@@ -1336,10 +1376,10 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
13361376
// Okay, we are now working with a single value turning into a
13371377
// single value.
13381378
auto outerArg = claimNextOuterArg();
1339-
auto innerParamType = claimNextInnerParam();
1379+
auto innerParam = claimNextInnerParam();
13401380
auto innerArg = processSingle(innerOrigType, innerSubstType,
13411381
outerOrigType, outerSubstType,
1342-
outerArg, innerParamType);
1382+
outerArg, innerParam);
13431383
InnerArgs.push_back(innerArg);
13441384
}
13451385

@@ -1350,14 +1390,14 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
13501390
ManagedValue processToPackParam(
13511391
AbstractionPattern innerOrigExpansionType,
13521392
AnyFunctionType::CanParamArrayRef innerSubstParams,
1353-
SILParameterInfo innerParam,
1393+
ParamInfo innerParam,
13541394
FunctionInputGenerator &outerParams);
13551395

13561396
ManagedValue processIntoSingle(AbstractionPattern innerOrigType,
13571397
CanType innerSubstType,
13581398
AbstractionPattern outerOrigType,
13591399
CanType outerSubstType,
1360-
SILParameterInfo innerParam) {
1400+
ParamInfo innerParam) {
13611401
if (outerOrigType.isTuple()) {
13621402
return processTupleIntoSingle(innerOrigType,
13631403
innerSubstType,
@@ -1377,7 +1417,7 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
13771417
CanType innerSubstType,
13781418
AbstractionPattern outerOrigType,
13791419
CanTupleType outerSubstType,
1380-
SILParameterInfo innerParam) {
1420+
ParamInfo innerParam) {
13811421
// Tuple types are subtypes of their optionals
13821422
if (auto innerObjectType = innerSubstType.getOptionalObjectType()) {
13831423
auto innerOrigObjectType = innerOrigType.getOptionalObjectType();
@@ -1400,11 +1440,14 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
14001440
assert(innerObjectType->isAny());
14011441

14021442
// First, construct the existential.
1443+
ParamInfo innerAnyParam = getInnerParamInfo(
1444+
SILParameterInfo(innerObjectType, ParameterConvention::Indirect_In));
14031445
auto innerAny =
14041446
processAndImplodeIntoAny(innerOrigObjectType,
14051447
innerObjectType,
14061448
outerOrigType,
1407-
outerSubstType);
1449+
outerSubstType,
1450+
innerAnyParam);
14081451

14091452
// Now, convert it to an optional, using the object type as
14101453
// the new outer type.
@@ -1414,12 +1457,11 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
14141457
}
14151458

14161459
if (innerSubstType->isAny()) {
1417-
// We don't need innerParam on this path.
1418-
14191460
return processAndImplodeIntoAny(innerOrigType,
14201461
innerSubstType,
14211462
outerOrigType,
1422-
outerSubstType);
1463+
outerSubstType,
1464+
innerParam);
14231465
}
14241466

14251467
if (auto innerTupleType = dyn_cast<TupleType>(innerSubstType)) {
@@ -1428,20 +1470,27 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
14281470
assert(innerOrigType.isTypeParameter() &&
14291471
"inner is not a tuple and is not opaque?");
14301472

1431-
auto innerTy = SGF.getSILType(innerParam, InnerTypesFuncTy);
1432-
auto &innerTL = SGF.getTypeLowering(innerTy);
1433-
if (SGF.silConv.useLoweredAddresses()) {
1434-
auto innerTemp = SGF.emitTemporary(Loc, innerTL);
1473+
// As usual, we need to allocate if we're emitting into a fixed
1474+
// address or if the parameter convention requires an address.
1475+
// We also need to use this pattern if the substituted tuple type
1476+
// contains a pack expansion because we can't use the scalar
1477+
// instruction to produce such a tuple.
1478+
bool produceAddress = innerParam.shouldProduceAddress(SGF);
1479+
if (produceAddress || innerTupleType->containsPackExpansionType()) {
1480+
auto innerTemp = innerParam.allocateForInitialization(SGF, Loc);
14351481
processAndImplodeInto(innerOrigType, innerTupleType,
14361482
outerOrigType, outerSubstType,
14371483
*innerTemp);
14381484

1439-
return innerTemp->getManagedAddress();
1485+
ManagedValue innerArg = innerTemp->getManagedAddress();
1486+
if (!produceAddress)
1487+
innerArg = SGF.B.createLoadTake(Loc, innerArg);
1488+
return innerArg;
14401489
} else {
14411490
auto innerArg = processAndImplodeIntoValue(
14421491
innerOrigType, innerTupleType,
14431492
outerOrigType, outerSubstType,
1444-
innerTL.getLoweredType());
1493+
innerParam.getType());
14451494
return innerArg;
14461495
}
14471496
}
@@ -1487,6 +1536,8 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
14871536
AbstractionPattern innerOrigType,
14881537
CanTupleType innerSubstType,
14891538
SILType loweredInnerTy) {
1539+
// FIXME: tuple indexing
1540+
14901541
assert(loweredInnerTy.is<TupleType>());
14911542

14921543
SmallVector<ManagedValue, 4> elements;
@@ -1554,43 +1605,50 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
15541605
CanTupleType innerSubstType,
15551606
AbstractionPattern outerOrigType,
15561607
CanTupleType outerSubstType,
1557-
SILParameterInfo innerParam) {
1608+
ParamInfo innerParam) {
15581609
assert(innerSubstType->getNumElements() ==
15591610
outerSubstType->getNumElements());
15601611

15611612
// Collect the tuple elements.
1562-
auto &innerLoweredTL = SGF.getTypeLowering(innerOrigType, innerSubstType);
1563-
auto innerLoweredTy = innerLoweredTL.getLoweredType();
1564-
auto innerOptionalTy = SGF.getSILType(innerParam, InnerTypesFuncTy);
1613+
auto innerOptionalTy = innerParam.getType();
1614+
auto innerTupleTy = innerOptionalTy.getOptionalObjectType();
15651615
auto someDecl = SGF.getASTContext().getOptionalSomeDecl();
1566-
if (innerLoweredTL.isLoadable() || !SGF.silConv.useLoweredAddresses()) {
1616+
bool produceAddress = innerParam.shouldProduceAddress(SGF);
1617+
if (!produceAddress && !innerSubstType->containsPackExpansionType()) {
15671618
auto payload =
15681619
processAndImplodeIntoValue(innerOrigType, innerSubstType,
15691620
outerOrigType, outerSubstType,
1570-
innerLoweredTy);
1621+
innerTupleTy);
15711622

15721623
return SGF.B.createEnum(Loc, payload, someDecl, innerOptionalTy);
15731624
} else {
1574-
auto optionalBuf = SGF.emitTemporaryAllocation(Loc, innerOptionalTy);
1575-
auto tupleBuf = SGF.B.createInitEnumDataAddr(Loc, optionalBuf, someDecl,
1576-
innerLoweredTy);
1577-
1578-
auto tupleTemp = SGF.useBufferAsTemporary(tupleBuf, innerLoweredTL);
1625+
auto optionalBuf = innerParam.allocate(SGF, Loc);
1626+
auto tupleBuf =
1627+
SGF.B.createInitEnumDataAddr(Loc, optionalBuf, someDecl, innerTupleTy);
1628+
auto tupleTemp =
1629+
SGF.useBufferAsTemporary(tupleBuf, SGF.getTypeLowering(innerTupleTy));
15791630

15801631
processAndImplodeInto(innerOrigType, innerSubstType,
15811632
outerOrigType, outerSubstType,
15821633
*tupleTemp);
15831634

15841635
SGF.B.createInjectEnumAddr(Loc, optionalBuf, someDecl);
15851636

1586-
auto payload = tupleTemp->getManagedAddress();
1587-
if (payload.hasCleanup()) {
1588-
payload.forward(SGF);
1589-
return SGF.emitManagedBufferWithCleanup(optionalBuf);
1637+
auto innerPayload = tupleTemp->getManagedAddress();
1638+
if (innerPayload.hasCleanup()) {
1639+
innerPayload.forward(SGF);
1640+
auto optionalAddr = SGF.emitManagedBufferWithCleanup(optionalBuf);
1641+
if (produceAddress) return optionalAddr;
1642+
return SGF.B.createLoadTake(Loc, optionalAddr);
1643+
} else if (optionalBuf->getType().isTrivial(SGF.F)) {
1644+
auto optionalAddr = ManagedValue::forTrivialAddressRValue(optionalBuf);
1645+
if (produceAddress) return optionalAddr;
1646+
return SGF.B.createLoadTrivial(Loc, optionalAddr);
1647+
} else {
1648+
auto optionalAddr = ManagedValue::forBorrowedAddressRValue(optionalBuf);
1649+
if (produceAddress) return optionalAddr;
1650+
return SGF.B.createLoadBorrow(Loc, optionalAddr);
15901651
}
1591-
if (optionalBuf->getType().isTrivial(SGF.F))
1592-
return ManagedValue::forTrivialAddressRValue(optionalBuf);
1593-
return ManagedValue::forBorrowedAddressRValue(optionalBuf);
15941652
}
15951653
}
15961654

@@ -1600,9 +1658,9 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
16001658
processAndImplodeIntoAny(AbstractionPattern innerOrigType,
16011659
CanType innerSubstType,
16021660
AbstractionPattern outerOrigType,
1603-
CanTupleType outerSubstType) {
1604-
auto existentialTy = SGF.getLoweredType(innerOrigType, innerSubstType);
1605-
auto existentialBuf = SGF.emitTemporaryAllocation(Loc, existentialTy);
1661+
CanTupleType outerSubstType,
1662+
ParamInfo innerParam) {
1663+
auto existentialBuf = innerParam.allocate(SGF, Loc);
16061664

16071665
auto opaque = AbstractionPattern::getOpaque();
16081666
auto &concreteTL = SGF.getTypeLowering(opaque, outerSubstType);
@@ -1647,6 +1705,8 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
16471705
assert(outerSubstType->getNumElements() ==
16481706
innerSubstType->getNumElements());
16491707

1708+
// FIXME: tuple indexing
1709+
16501710
for (auto index : indices(innerSubstType.getElementTypes())) {
16511711
process(innerOrigType.getTupleElementType(index),
16521712
innerSubstType.getElementType(index),
@@ -1826,31 +1886,28 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
18261886
AbstractionPattern outerOrigType,
18271887
CanType outerSubstType,
18281888
ManagedValue outer,
1829-
SILParameterInfo innerParam) {
1830-
auto innerTy = SGF.getSILType(innerParam, InnerTypesFuncTy);
1889+
ParamInfo innerParam) {
1890+
if (innerParam.hasAddress()) {
1891+
auto innerTemp = innerParam.allocateForInitialization(SGF, Loc);
1892+
processSingleInto(innerOrigType, innerSubstType,
1893+
outerOrigType, outerSubstType,
1894+
outer, innerParam.getType(), *innerTemp);
1895+
return innerTemp->getManagedAddress();
1896+
}
18311897

1832-
return processSingle(innerOrigType, innerSubstType,
1833-
outerOrigType, outerSubstType,
1834-
outer, innerTy, innerParam.getConvention());
1835-
}
1898+
auto innerTy = innerParam.getType();
18361899

1837-
ManagedValue processSingle(AbstractionPattern innerOrigType,
1838-
CanType innerSubstType,
1839-
AbstractionPattern outerOrigType,
1840-
CanType outerSubstType,
1841-
ManagedValue outer,
1842-
SILType innerTy,
1843-
ParameterConvention innerConvention) {
18441900
// Easy case: we want to pass exactly this value.
1845-
if (outer.getType() == innerTy) {
1846-
if (isConsumedParameter(innerConvention) && !outer.isPlusOne(SGF)) {
1901+
if (outer.getType() == innerParam.getType()) {
1902+
if (isConsumedParameter(innerParam.getConvention()) &&
1903+
!outer.isPlusOne(SGF)) {
18471904
outer = outer.copyUnmanaged(SGF, Loc);
18481905
}
18491906

18501907
return outer;
18511908
}
18521909

1853-
switch (innerConvention) {
1910+
switch (innerParam.getConvention()) {
18541911
// Direct translation is relatively easy.
18551912
case ParameterConvention::Direct_Owned:
18561913
case ParameterConvention::Direct_Unowned:
@@ -1885,7 +1942,7 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
18851942
case ParameterConvention::Pack_Owned:
18861943
SGF.SGM.diagnose(Loc, diag::not_implemented,
18871944
"reabstraction of pack values");
1888-
return SGF.emitUndef(resultTy);
1945+
return SGF.emitUndef(innerTy);
18891946
case ParameterConvention::Indirect_Inout:
18901947
case ParameterConvention::Pack_Inout:
18911948
llvm_unreachable("inout reabstraction handled elsewhere");
@@ -1902,8 +1959,8 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
19021959
AbstractionPattern outerOrigType,
19031960
CanType outerSubstType,
19041961
ManagedValue outer,
1905-
SILParameterInfo result) {
1906-
auto resultTy = SGF.getSILType(result, InnerTypesFuncTy);
1962+
ParamInfo innerParam) {
1963+
auto resultTy = innerParam.getType();
19071964
assert(outer.isLValue());
19081965
if (outer.getType() == resultTy) {
19091966
return outer;
@@ -1992,8 +2049,13 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
19922049
/// is also responsible for adding the inner to inners. This allows
19932050
/// readers to easily verify that this is done on all paths. (It'd
19942051
/// sure be nice if we had better language mode for that, though.)
1995-
SILParameterInfo claimNextInnerParam() {
1996-
return claimNext(InnerTypes);
2052+
ParamInfo claimNextInnerParam() {
2053+
return getInnerParamInfo(claimNext(InnerTypes));
2054+
}
2055+
2056+
ParamInfo getInnerParamInfo(SILParameterInfo innerParam) {
2057+
auto innerTy = SGF.getSILType(innerParam, InnerTypesFuncTy);
2058+
return ParamInfo(IndirectSlot(innerTy), innerParam.getConvention());
19972059
}
19982060
};
19992061

@@ -2243,10 +2305,11 @@ getScalarConventionForPackConvention(ParameterConvention conv) {
22432305
ManagedValue TranslateArguments::processToPackParam(
22442306
AbstractionPattern innerOrigExpansionType,
22452307
AnyFunctionType::CanParamArrayRef innerSubstParams,
2246-
SILParameterInfo innerPackParam,
2308+
ParamInfo innerPackParam,
22472309
FunctionInputGenerator &outerParam) {
2248-
assert(innerPackParam.isPack());
2249-
auto innerTy = SGF.getSILType(innerPackParam, InnerTypesFuncTy);
2310+
assert(isPackParameter(innerPackParam.getConvention()));
2311+
assert(!innerPackParam.hasAddress());
2312+
auto innerTy = innerPackParam.getType();
22502313
auto innerPackTy = innerTy.castTo<SILPackType>();
22512314
assert(innerPackTy->getNumElements() == innerSubstParams.size());
22522315

@@ -2287,7 +2350,7 @@ ManagedValue TranslateArguments::processToPackParam(
22872350
if (!outerParam.isOrigPackExpansion()) {
22882351
// Fake up a lowered parameter as if we could pass just this
22892352
// component.
2290-
SILParameterInfo innerComponentParam(innerComponentTy.getASTType(),
2353+
ParamInfo innerComponentParam(IndirectSlot(innerComponentTy),
22912354
getScalarConventionForPackConvention(innerPackParam.getConvention()));
22922355

22932356
ManagedValue innerArg = processIntoSingle(innerOrigPatternType,
@@ -2366,7 +2429,7 @@ ManagedValue TranslateArguments::processToPackParam(
23662429

23672430
// Otherwise, claim the next pack component and process it.
23682431
} else {
2369-
SILParameterInfo innerComponentParam(innerComponentTy.getASTType(),
2432+
ParamInfo innerComponentParam(IndirectSlot(innerComponentTy),
23702433
getScalarConventionForPackConvention(innerPackParam.getConvention()));
23712434

23722435
ManagedValue outer = outerParam.projectPackComponent(SGF, Loc);

0 commit comments

Comments
 (0)