@@ -1604,10 +1604,7 @@ void TempRValueOptPass::run() {
1604
1604
++II;
1605
1605
1606
1606
// Remove identity copies which are a result of this optimization.
1607
- if (CopyInst && CopyInst->getSrc () == CopyInst->getDest () &&
1608
- // Identity copies cannot take the source. This check is just here
1609
- // to be on the safe side.
1610
- !CopyInst->isTakeOfSrc ()) {
1607
+ if (CopyInst && CopyInst->getSrc () == CopyInst->getDest ()) {
1611
1608
// This is either the CopyInst which just got optimized or it is a
1612
1609
// follow-up from an earlier iteration, where another copy_addr copied
1613
1610
// the temporary back to the source location.
@@ -1725,9 +1722,8 @@ bool TempRValueOptPass::collectLoads(
1725
1722
1726
1723
case SILInstructionKind::CopyAddrInst: {
1727
1724
// copy_addr which read from the temporary are like loads.
1728
- // TODO: Handle copy_addr [take]. But this doesn't seem to be important.
1729
1725
auto *copyFromTmp = cast<CopyAddrInst>(user);
1730
- if (copyFromTmp->getDest () == address || copyFromTmp-> isTakeOfSrc () ) {
1726
+ if (copyFromTmp->getDest () == address) {
1731
1727
LLVM_DEBUG (llvm::dbgs () << " Temp written or taken" << *user);
1732
1728
return false ;
1733
1729
}
@@ -1774,7 +1770,7 @@ bool TempRValueOptPass::checkNoSourceModification(CopyAddrInst *copyInst,
1774
1770
1775
1771
// / Tries to perform the temporary rvalue copy elimination for \p copyInst
1776
1772
bool TempRValueOptPass::tryOptimizeCopyIntoTemp (CopyAddrInst *copyInst) {
1777
- if (copyInst-> isTakeOfSrc () || !copyInst->isInitializationOfDest ())
1773
+ if (!copyInst->isInitializationOfDest ())
1778
1774
return false ;
1779
1775
1780
1776
auto *tempObj = dyn_cast<AllocStackInst>(copyInst->getDest ());
@@ -1818,10 +1814,25 @@ bool TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
1818
1814
SILInstruction *user = use->getUser ();
1819
1815
switch (user->getKind ()) {
1820
1816
case SILInstructionKind::DestroyAddrInst:
1817
+ if (copyInst->isTakeOfSrc ()) {
1818
+ use->set (copyInst->getSrc ());
1819
+ } else {
1820
+ user->eraseFromParent ();
1821
+ }
1822
+ break ;
1821
1823
case SILInstructionKind::DeallocStackInst:
1822
1824
user->eraseFromParent ();
1823
1825
break ;
1824
- case SILInstructionKind::CopyAddrInst:
1826
+ case SILInstructionKind::CopyAddrInst: {
1827
+ auto *CAI = cast<CopyAddrInst>(user);
1828
+ if (CAI != copyInst) {
1829
+ assert (CAI->getSrc () == tempObj);
1830
+ if (CAI->isTakeOfSrc () && !copyInst->isTakeOfSrc ())
1831
+ CAI->setIsTakeOfSrc (IsNotTake);
1832
+ }
1833
+ use->set (copyInst->getSrc ());
1834
+ break ;
1835
+ }
1825
1836
case SILInstructionKind::StructElementAddrInst:
1826
1837
case SILInstructionKind::TupleElementAddrInst:
1827
1838
case SILInstructionKind::LoadInst:
0 commit comments