@@ -1012,6 +1012,46 @@ class ExpanderBase {
1012
1012
ManagedValue outerAddr);
1013
1013
};
1014
1014
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
+
1015
1055
// / Given a list of inputs that are suited to the parameters of one
1016
1056
// / function, translate them into a list of outputs that are suited
1017
1057
// / for the parameters of another function, given that the two
@@ -1269,12 +1309,12 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1269
1309
if (innerSubstType.isInOut ()) {
1270
1310
assert (outerSubstType.isInOut ());
1271
1311
auto outerValue = claimNextOuterArg ();
1272
- auto innerLoweredTy = claimNextInnerParam ();
1312
+ auto innerParam = claimNextInnerParam ();
1273
1313
1274
1314
ManagedValue inner =
1275
1315
processInOut (innerOrigType, innerSubstType.getParameterType (),
1276
1316
outerOrigType, outerSubstType.getParameterType (),
1277
- outerValue, innerLoweredTy );
1317
+ outerValue, innerParam );
1278
1318
InnerArgs.push_back (inner);
1279
1319
} else {
1280
1320
process (innerOrigType, innerSubstType.getParameterType (),
@@ -1336,10 +1376,10 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1336
1376
// Okay, we are now working with a single value turning into a
1337
1377
// single value.
1338
1378
auto outerArg = claimNextOuterArg ();
1339
- auto innerParamType = claimNextInnerParam ();
1379
+ auto innerParam = claimNextInnerParam ();
1340
1380
auto innerArg = processSingle (innerOrigType, innerSubstType,
1341
1381
outerOrigType, outerSubstType,
1342
- outerArg, innerParamType );
1382
+ outerArg, innerParam );
1343
1383
InnerArgs.push_back (innerArg);
1344
1384
}
1345
1385
@@ -1350,14 +1390,14 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1350
1390
ManagedValue processToPackParam (
1351
1391
AbstractionPattern innerOrigExpansionType,
1352
1392
AnyFunctionType::CanParamArrayRef innerSubstParams,
1353
- SILParameterInfo innerParam,
1393
+ ParamInfo innerParam,
1354
1394
FunctionInputGenerator &outerParams);
1355
1395
1356
1396
ManagedValue processIntoSingle (AbstractionPattern innerOrigType,
1357
1397
CanType innerSubstType,
1358
1398
AbstractionPattern outerOrigType,
1359
1399
CanType outerSubstType,
1360
- SILParameterInfo innerParam) {
1400
+ ParamInfo innerParam) {
1361
1401
if (outerOrigType.isTuple ()) {
1362
1402
return processTupleIntoSingle (innerOrigType,
1363
1403
innerSubstType,
@@ -1377,7 +1417,7 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1377
1417
CanType innerSubstType,
1378
1418
AbstractionPattern outerOrigType,
1379
1419
CanTupleType outerSubstType,
1380
- SILParameterInfo innerParam) {
1420
+ ParamInfo innerParam) {
1381
1421
// Tuple types are subtypes of their optionals
1382
1422
if (auto innerObjectType = innerSubstType.getOptionalObjectType ()) {
1383
1423
auto innerOrigObjectType = innerOrigType.getOptionalObjectType ();
@@ -1400,11 +1440,14 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1400
1440
assert (innerObjectType->isAny ());
1401
1441
1402
1442
// First, construct the existential.
1443
+ ParamInfo innerAnyParam = getInnerParamInfo (
1444
+ SILParameterInfo (innerObjectType, ParameterConvention::Indirect_In));
1403
1445
auto innerAny =
1404
1446
processAndImplodeIntoAny (innerOrigObjectType,
1405
1447
innerObjectType,
1406
1448
outerOrigType,
1407
- outerSubstType);
1449
+ outerSubstType,
1450
+ innerAnyParam);
1408
1451
1409
1452
// Now, convert it to an optional, using the object type as
1410
1453
// the new outer type.
@@ -1414,12 +1457,11 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1414
1457
}
1415
1458
1416
1459
if (innerSubstType->isAny ()) {
1417
- // We don't need innerParam on this path.
1418
-
1419
1460
return processAndImplodeIntoAny (innerOrigType,
1420
1461
innerSubstType,
1421
1462
outerOrigType,
1422
- outerSubstType);
1463
+ outerSubstType,
1464
+ innerParam);
1423
1465
}
1424
1466
1425
1467
if (auto innerTupleType = dyn_cast<TupleType>(innerSubstType)) {
@@ -1428,20 +1470,27 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1428
1470
assert (innerOrigType.isTypeParameter () &&
1429
1471
" inner is not a tuple and is not opaque?" );
1430
1472
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);
1435
1481
processAndImplodeInto (innerOrigType, innerTupleType,
1436
1482
outerOrigType, outerSubstType,
1437
1483
*innerTemp);
1438
1484
1439
- return innerTemp->getManagedAddress ();
1485
+ ManagedValue innerArg = innerTemp->getManagedAddress ();
1486
+ if (!produceAddress)
1487
+ innerArg = SGF.B .createLoadTake (Loc, innerArg);
1488
+ return innerArg;
1440
1489
} else {
1441
1490
auto innerArg = processAndImplodeIntoValue (
1442
1491
innerOrigType, innerTupleType,
1443
1492
outerOrigType, outerSubstType,
1444
- innerTL. getLoweredType ());
1493
+ innerParam. getType ());
1445
1494
return innerArg;
1446
1495
}
1447
1496
}
@@ -1487,6 +1536,8 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1487
1536
AbstractionPattern innerOrigType,
1488
1537
CanTupleType innerSubstType,
1489
1538
SILType loweredInnerTy) {
1539
+ // FIXME: tuple indexing
1540
+
1490
1541
assert (loweredInnerTy.is <TupleType>());
1491
1542
1492
1543
SmallVector<ManagedValue, 4 > elements;
@@ -1554,43 +1605,50 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1554
1605
CanTupleType innerSubstType,
1555
1606
AbstractionPattern outerOrigType,
1556
1607
CanTupleType outerSubstType,
1557
- SILParameterInfo innerParam) {
1608
+ ParamInfo innerParam) {
1558
1609
assert (innerSubstType->getNumElements () ==
1559
1610
outerSubstType->getNumElements ());
1560
1611
1561
1612
// 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 ();
1565
1615
auto someDecl = SGF.getASTContext ().getOptionalSomeDecl ();
1566
- if (innerLoweredTL.isLoadable () || !SGF.silConv .useLoweredAddresses ()) {
1616
+ bool produceAddress = innerParam.shouldProduceAddress (SGF);
1617
+ if (!produceAddress && !innerSubstType->containsPackExpansionType ()) {
1567
1618
auto payload =
1568
1619
processAndImplodeIntoValue (innerOrigType, innerSubstType,
1569
1620
outerOrigType, outerSubstType,
1570
- innerLoweredTy );
1621
+ innerTupleTy );
1571
1622
1572
1623
return SGF.B .createEnum (Loc, payload, someDecl, innerOptionalTy);
1573
1624
} 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) );
1579
1630
1580
1631
processAndImplodeInto (innerOrigType, innerSubstType,
1581
1632
outerOrigType, outerSubstType,
1582
1633
*tupleTemp);
1583
1634
1584
1635
SGF.B .createInjectEnumAddr (Loc, optionalBuf, someDecl);
1585
1636
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);
1590
1651
}
1591
- if (optionalBuf->getType ().isTrivial (SGF.F ))
1592
- return ManagedValue::forTrivialAddressRValue (optionalBuf);
1593
- return ManagedValue::forBorrowedAddressRValue (optionalBuf);
1594
1652
}
1595
1653
}
1596
1654
@@ -1600,9 +1658,9 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1600
1658
processAndImplodeIntoAny (AbstractionPattern innerOrigType,
1601
1659
CanType innerSubstType,
1602
1660
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 );
1606
1664
1607
1665
auto opaque = AbstractionPattern::getOpaque ();
1608
1666
auto &concreteTL = SGF.getTypeLowering (opaque, outerSubstType);
@@ -1647,6 +1705,8 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1647
1705
assert (outerSubstType->getNumElements () ==
1648
1706
innerSubstType->getNumElements ());
1649
1707
1708
+ // FIXME: tuple indexing
1709
+
1650
1710
for (auto index : indices (innerSubstType.getElementTypes ())) {
1651
1711
process (innerOrigType.getTupleElementType (index),
1652
1712
innerSubstType.getElementType (index),
@@ -1826,31 +1886,28 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1826
1886
AbstractionPattern outerOrigType,
1827
1887
CanType outerSubstType,
1828
1888
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
+ }
1831
1897
1832
- return processSingle (innerOrigType, innerSubstType,
1833
- outerOrigType, outerSubstType,
1834
- outer, innerTy, innerParam.getConvention ());
1835
- }
1898
+ auto innerTy = innerParam.getType ();
1836
1899
1837
- ManagedValue processSingle (AbstractionPattern innerOrigType,
1838
- CanType innerSubstType,
1839
- AbstractionPattern outerOrigType,
1840
- CanType outerSubstType,
1841
- ManagedValue outer,
1842
- SILType innerTy,
1843
- ParameterConvention innerConvention) {
1844
1900
// 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)) {
1847
1904
outer = outer.copyUnmanaged (SGF, Loc);
1848
1905
}
1849
1906
1850
1907
return outer;
1851
1908
}
1852
1909
1853
- switch (innerConvention ) {
1910
+ switch (innerParam. getConvention () ) {
1854
1911
// Direct translation is relatively easy.
1855
1912
case ParameterConvention::Direct_Owned:
1856
1913
case ParameterConvention::Direct_Unowned:
@@ -1885,7 +1942,7 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1885
1942
case ParameterConvention::Pack_Owned:
1886
1943
SGF.SGM .diagnose (Loc, diag::not_implemented,
1887
1944
" reabstraction of pack values" );
1888
- return SGF.emitUndef (resultTy );
1945
+ return SGF.emitUndef (innerTy );
1889
1946
case ParameterConvention::Indirect_Inout:
1890
1947
case ParameterConvention::Pack_Inout:
1891
1948
llvm_unreachable (" inout reabstraction handled elsewhere" );
@@ -1902,8 +1959,8 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1902
1959
AbstractionPattern outerOrigType,
1903
1960
CanType outerSubstType,
1904
1961
ManagedValue outer,
1905
- SILParameterInfo result ) {
1906
- auto resultTy = SGF. getSILType (result, InnerTypesFuncTy );
1962
+ ParamInfo innerParam ) {
1963
+ auto resultTy = innerParam. getType ( );
1907
1964
assert (outer.isLValue ());
1908
1965
if (outer.getType () == resultTy) {
1909
1966
return outer;
@@ -1992,8 +2049,13 @@ class TranslateArguments : public ExpanderBase<TranslateArguments> {
1992
2049
// / is also responsible for adding the inner to inners. This allows
1993
2050
// / readers to easily verify that this is done on all paths. (It'd
1994
2051
// / 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 ());
1997
2059
}
1998
2060
};
1999
2061
@@ -2243,10 +2305,11 @@ getScalarConventionForPackConvention(ParameterConvention conv) {
2243
2305
ManagedValue TranslateArguments::processToPackParam (
2244
2306
AbstractionPattern innerOrigExpansionType,
2245
2307
AnyFunctionType::CanParamArrayRef innerSubstParams,
2246
- SILParameterInfo innerPackParam,
2308
+ ParamInfo innerPackParam,
2247
2309
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 ();
2250
2313
auto innerPackTy = innerTy.castTo <SILPackType>();
2251
2314
assert (innerPackTy->getNumElements () == innerSubstParams.size ());
2252
2315
@@ -2287,7 +2350,7 @@ ManagedValue TranslateArguments::processToPackParam(
2287
2350
if (!outerParam.isOrigPackExpansion ()) {
2288
2351
// Fake up a lowered parameter as if we could pass just this
2289
2352
// component.
2290
- SILParameterInfo innerComponentParam (innerComponentTy. getASTType ( ),
2353
+ ParamInfo innerComponentParam (IndirectSlot (innerComponentTy ),
2291
2354
getScalarConventionForPackConvention (innerPackParam.getConvention ()));
2292
2355
2293
2356
ManagedValue innerArg = processIntoSingle (innerOrigPatternType,
@@ -2366,7 +2429,7 @@ ManagedValue TranslateArguments::processToPackParam(
2366
2429
2367
2430
// Otherwise, claim the next pack component and process it.
2368
2431
} else {
2369
- SILParameterInfo innerComponentParam (innerComponentTy. getASTType ( ),
2432
+ ParamInfo innerComponentParam (IndirectSlot (innerComponentTy ),
2370
2433
getScalarConventionForPackConvention (innerPackParam.getConvention ()));
2371
2434
2372
2435
ManagedValue outer = outerParam.projectPackComponent (SGF, Loc);
0 commit comments