@@ -1489,6 +1489,9 @@ class AllocOptimize {
1489
1489
bool tryToRemoveDeadAllocation ();
1490
1490
1491
1491
private:
1492
+ Optional<std::pair<SILType, unsigned >>
1493
+ computeAvailableValues (SILValue SrcAddr, SILInstruction *Inst,
1494
+ SmallVectorImpl<AvailableValue> &AvailableValues);
1492
1495
bool promoteLoadCopy (LoadInst *Inst);
1493
1496
bool promoteLoadBorrow (LoadBorrowInst *Inst);
1494
1497
bool promoteCopyAddr (CopyAddrInst *CAI);
@@ -1501,6 +1504,43 @@ class AllocOptimize {
1501
1504
1502
1505
} // end anonymous namespace
1503
1506
1507
+ Optional<std::pair<SILType, unsigned >> AllocOptimize::computeAvailableValues (
1508
+ SILValue SrcAddr, SILInstruction *Inst,
1509
+ SmallVectorImpl<AvailableValue> &AvailableValues) {
1510
+ // If the box has escaped at this instruction, we can't safely promote the
1511
+ // load.
1512
+ if (DataflowContext.hasEscapedAt (Inst))
1513
+ return None;
1514
+
1515
+ SILType LoadTy = SrcAddr->getType ().getObjectType ();
1516
+
1517
+ // If this is a load/copy_addr from a struct field that we want to promote,
1518
+ // compute the access path down to the field so we can determine precise
1519
+ // def/use behavior.
1520
+ unsigned FirstElt = computeSubelement (SrcAddr, TheMemory);
1521
+
1522
+ // If this is a load from within an enum projection, we can't promote it since
1523
+ // we don't track subelements in a type that could be changing.
1524
+ if (FirstElt == ~0U )
1525
+ return None;
1526
+
1527
+ unsigned NumLoadSubElements = getNumSubElements (LoadTy, Module);
1528
+
1529
+ // Set up the bitvector of elements being demanded by the load.
1530
+ SmallBitVector RequiredElts (NumMemorySubElements);
1531
+ RequiredElts.set (FirstElt, FirstElt + NumLoadSubElements);
1532
+
1533
+ AvailableValues.resize (NumMemorySubElements);
1534
+
1535
+ // Find out if we have any available values. If no bits are demanded, we
1536
+ // trivially succeed. This can happen when there is a load of an empty struct.
1537
+ if (NumLoadSubElements != 0 &&
1538
+ !DataflowContext.computeAvailableValues (
1539
+ Inst, FirstElt, NumLoadSubElements, RequiredElts, AvailableValues))
1540
+ return None;
1541
+
1542
+ return std::make_pair (LoadTy, FirstElt);
1543
+ }
1504
1544
1505
1545
// / If we are able to optimize \p Inst, return the source address that
1506
1546
// / instruction is loading from. If we can not optimize \p Inst, then just
@@ -1543,39 +1583,14 @@ bool AllocOptimize::promoteLoadCopy(LoadInst *Inst) {
1543
1583
if (!SrcAddr)
1544
1584
return false ;
1545
1585
1546
- // If the box has escaped at this instruction, we can't safely promote the
1547
- // load.
1548
- if (DataflowContext.hasEscapedAt (Inst))
1549
- return false ;
1550
-
1551
- SILType LoadTy = SrcAddr->getType ().getObjectType ();
1552
-
1553
- // If this is a load/copy_addr from a struct field that we want to promote,
1554
- // compute the access path down to the field so we can determine precise
1555
- // def/use behavior.
1556
- unsigned FirstElt = computeSubelement (SrcAddr, TheMemory);
1557
-
1558
- // If this is a load from within an enum projection, we can't promote it since
1559
- // we don't track subelements in a type that could be changing.
1560
- if (FirstElt == ~0U )
1561
- return false ;
1562
-
1563
- unsigned NumLoadSubElements = getNumSubElements (LoadTy, Module);
1564
-
1565
- // Set up the bitvector of elements being demanded by the load.
1566
- SmallBitVector RequiredElts (NumMemorySubElements);
1567
- RequiredElts.set (FirstElt, FirstElt + NumLoadSubElements);
1568
-
1569
1586
SmallVector<AvailableValue, 8 > AvailableValues;
1570
- AvailableValues.resize (NumMemorySubElements);
1571
-
1572
- // Find out if we have any available values. If no bits are demanded, we
1573
- // trivially succeed. This can happen when there is a load of an empty struct.
1574
- if (NumLoadSubElements != 0 &&
1575
- !DataflowContext.computeAvailableValues (
1576
- Inst, FirstElt, NumLoadSubElements, RequiredElts, AvailableValues))
1587
+ auto Result = computeAvailableValues (SrcAddr, Inst, AvailableValues);
1588
+ if (!Result.hasValue ())
1577
1589
return false ;
1578
1590
1591
+ SILType LoadTy = Result->first ;
1592
+ unsigned FirstElt = Result->second ;
1593
+
1579
1594
// Aggregate together all of the subelements into something that has the same
1580
1595
// type as the load did, and emit smaller loads for any subelements that were
1581
1596
// not available. We are "propagating" a +1 available value from the store
@@ -1625,37 +1640,9 @@ bool AllocOptimize::promoteCopyAddr(CopyAddrInst *Inst) {
1625
1640
if (!SrcAddr)
1626
1641
return false ;
1627
1642
1628
- // If the box has escaped at this instruction, we can't safely promote the
1629
- // load.
1630
- if (DataflowContext.hasEscapedAt (Inst))
1631
- return false ;
1632
-
1633
- SILType LoadTy = SrcAddr->getType ().getObjectType ();
1634
-
1635
- // If this is a load/copy_addr from a struct field that we want to promote,
1636
- // compute the access path down to the field so we can determine precise
1637
- // def/use behavior.
1638
- unsigned FirstElt = computeSubelement (SrcAddr, TheMemory);
1639
-
1640
- // If this is a load from within an enum projection, we can't promote it since
1641
- // we don't track subelements in a type that could be changing.
1642
- if (FirstElt == ~0U )
1643
- return false ;
1644
-
1645
- unsigned NumLoadSubElements = getNumSubElements (LoadTy, Module);
1646
-
1647
- // Set up the bitvector of elements being demanded by the load.
1648
- SmallBitVector RequiredElts (NumMemorySubElements);
1649
- RequiredElts.set (FirstElt, FirstElt+NumLoadSubElements);
1650
-
1651
1643
SmallVector<AvailableValue, 8 > AvailableValues;
1652
- AvailableValues.resize (NumMemorySubElements);
1653
-
1654
- // Find out if we have any available values. If no bits are demanded, we
1655
- // trivially succeed. This can happen when there is a load of an empty struct.
1656
- if (NumLoadSubElements != 0 &&
1657
- !DataflowContext.computeAvailableValues (
1658
- Inst, FirstElt, NumLoadSubElements, RequiredElts, AvailableValues))
1644
+ auto Result = computeAvailableValues (SrcAddr, Inst, AvailableValues);
1645
+ if (!Result.hasValue ())
1659
1646
return false ;
1660
1647
1661
1648
// Ok, we have some available values. If we have a copy_addr, explode it now,
@@ -1687,39 +1674,14 @@ bool AllocOptimize::promoteLoadBorrow(LoadBorrowInst *Inst) {
1687
1674
if (!SrcAddr)
1688
1675
return false ;
1689
1676
1690
- // If the box has escaped at this instruction, we can't safely promote the
1691
- // load.
1692
- if (DataflowContext.hasEscapedAt (Inst))
1693
- return false ;
1694
-
1695
- SILType LoadTy = SrcAddr->getType ().getObjectType ();
1696
-
1697
- // If this is a load/copy_addr from a struct field that we want to promote,
1698
- // compute the access path down to the field so we can determine precise
1699
- // def/use behavior.
1700
- unsigned FirstElt = computeSubelement (SrcAddr, TheMemory);
1701
-
1702
- // If this is a load from within an enum projection, we can't promote it since
1703
- // we don't track subelements in a type that could be changing.
1704
- if (FirstElt == ~0U )
1705
- return false ;
1706
-
1707
- unsigned NumLoadSubElements = getNumSubElements (LoadTy, Module);
1708
-
1709
- // Set up the bitvector of elements being demanded by the load.
1710
- SmallBitVector RequiredElts (NumMemorySubElements);
1711
- RequiredElts.set (FirstElt, FirstElt + NumLoadSubElements);
1712
-
1713
1677
SmallVector<AvailableValue, 8 > AvailableValues;
1714
- AvailableValues.resize (NumMemorySubElements);
1715
-
1716
- // Find out if we have any available values. If no bits are demanded, we
1717
- // trivially succeed. This can happen when there is a load of an empty struct.
1718
- if (NumLoadSubElements != 0 &&
1719
- !DataflowContext.computeAvailableValues (
1720
- Inst, FirstElt, NumLoadSubElements, RequiredElts, AvailableValues))
1678
+ auto Result = computeAvailableValues (SrcAddr, Inst, AvailableValues);
1679
+ if (!Result.hasValue ())
1721
1680
return false ;
1722
1681
1682
+ SILType LoadTy = Result->first ;
1683
+ unsigned FirstElt = Result->second ;
1684
+
1723
1685
// Aggregate together all of the subelements into something that has the same
1724
1686
// type as the load did, and emit smaller loads for any subelements that were
1725
1687
// not available. We are "propagating" a +1 available value from the store
0 commit comments