@@ -1526,6 +1526,62 @@ static bool shouldHoistCommonInstructions(Instruction *I1, Instruction *I2,
1526
1526
return true ;
1527
1527
}
1528
1528
1529
+ // / Hoists DPValues from \p I1 and \p OtherInstrs that are identical in
1530
+ // / lock-step to \p TI. This matches how dbg.* intrinsics are hoisting in
1531
+ // / hoistCommonCodeFromSuccessors. e.g. The input:
1532
+ // / I1 DPVs: { x, z },
1533
+ // / OtherInsts: { I2 DPVs: { x, y, z } }
1534
+ // / would result in hoisting only DPValue x.
1535
+ static void
1536
+ hoistLockstepIdenticalDPValues (Instruction *TI, Instruction *I1,
1537
+ SmallVectorImpl<Instruction *> &OtherInsts) {
1538
+ if (!I1->hasDbgValues ())
1539
+ return ;
1540
+ using CurrentAndEndIt =
1541
+ std::pair<DPValue::self_iterator, DPValue::self_iterator>;
1542
+ // Vector of {Current, End} iterators.
1543
+ SmallVector<CurrentAndEndIt> Itrs;
1544
+ Itrs.reserve (OtherInsts.size () + 1 );
1545
+ // Helper lambdas for lock-step checks:
1546
+ // Return true if this Current == End.
1547
+ auto atEnd = [](const CurrentAndEndIt &Pair) {
1548
+ return Pair.first == Pair.second ;
1549
+ };
1550
+ // Return true if all Current are identical.
1551
+ auto allIdentical = [](const SmallVector<CurrentAndEndIt> &Itrs) {
1552
+ return all_of (make_first_range (ArrayRef (Itrs).drop_front ()),
1553
+ [&](DPValue::self_iterator I) {
1554
+ return Itrs[0 ].first ->isIdenticalToWhenDefined (*I);
1555
+ });
1556
+ };
1557
+
1558
+ // Collect the iterators.
1559
+ Itrs.push_back (
1560
+ {I1->getDbgValueRange ().begin (), I1->getDbgValueRange ().end ()});
1561
+ for (Instruction *Other : OtherInsts) {
1562
+ if (!Other->hasDbgValues ())
1563
+ return ;
1564
+ Itrs.push_back (
1565
+ {Other->getDbgValueRange ().begin (), Other->getDbgValueRange ().end ()});
1566
+ }
1567
+
1568
+ // Iterate in lock-step until any of the DPValue lists are exausted. If
1569
+ // the lock-step DPValues are identical, hoist all of them to TI.
1570
+ // This replicates the dbg.* intrinsic behaviour in
1571
+ // hoistCommonCodeFromSuccessors.
1572
+ while (none_of (Itrs, atEnd)) {
1573
+ bool HoistDPVs = allIdentical (Itrs);
1574
+ for (CurrentAndEndIt &Pair : Itrs) {
1575
+ // Increment Current iterator now as we may be about to move the DPValue.
1576
+ DPValue &DPV = *Pair.first ++;
1577
+ if (HoistDPVs) {
1578
+ DPV.removeFromParent ();
1579
+ TI->getParent ()->insertDPValueBefore (&DPV, TI->getIterator ());
1580
+ }
1581
+ }
1582
+ }
1583
+ }
1584
+
1529
1585
// / Hoist any common code in the successor blocks up into the block. This
1530
1586
// / function guarantees that BB dominates all successors. If EqTermsOnly is
1531
1587
// / given, only perform hoisting in case both blocks only contain a terminator.
@@ -1598,7 +1654,6 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1598
1654
auto OtherSuccIterRange = make_first_range (OtherSuccIterPairRange);
1599
1655
1600
1656
Instruction *I1 = &*BB1ItrPair.first ;
1601
- auto *BB1 = I1->getParent ();
1602
1657
1603
1658
// Skip debug info if it is not identical.
1604
1659
bool AllDbgInstsAreIdentical = all_of (OtherSuccIterRange, [I1](auto &Iter) {
@@ -1624,18 +1679,23 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1624
1679
AllInstsAreIdentical = false ;
1625
1680
}
1626
1681
1682
+ SmallVector<Instruction *, 8 > OtherInsts;
1683
+ for (auto &SuccIter : OtherSuccIterRange)
1684
+ OtherInsts.push_back (&*SuccIter);
1685
+
1627
1686
// If we are hoisting the terminator instruction, don't move one (making a
1628
1687
// broken BB), instead clone it, and remove BI.
1629
1688
if (HasTerminator) {
1630
1689
// Even if BB, which contains only one unreachable instruction, is ignored
1631
1690
// at the beginning of the loop, we can hoist the terminator instruction.
1632
1691
// If any instructions remain in the block, we cannot hoist terminators.
1633
- if (NumSkipped || !AllInstsAreIdentical)
1692
+ if (NumSkipped || !AllInstsAreIdentical) {
1693
+ hoistLockstepIdenticalDPValues (TI, I1, OtherInsts);
1634
1694
return Changed;
1635
- SmallVector<Instruction *, 8 > Insts;
1636
- for ( auto &SuccIter : OtherSuccIterRange)
1637
- Insts. push_back (&*SuccIter);
1638
- return hoistSuccIdenticalTerminatorToSwitchOrIf (TI, I1, Insts) || Changed;
1695
+ }
1696
+
1697
+ return hoistSuccIdenticalTerminatorToSwitchOrIf (TI, I1, OtherInsts) ||
1698
+ Changed;
1639
1699
}
1640
1700
1641
1701
if (AllInstsAreIdentical) {
@@ -1660,18 +1720,25 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1660
1720
// The debug location is an integral part of a debug info intrinsic
1661
1721
// and can't be separated from it or replaced. Instead of attempting
1662
1722
// to merge locations, simply hoist both copies of the intrinsic.
1663
- I1->moveBeforePreserving (TI);
1723
+ hoistLockstepIdenticalDPValues (TI, I1, OtherInsts);
1724
+ // We've just hoisted DPValues; move I1 after them (before TI) and
1725
+ // leave any that were not hoisted behind (by calling moveBefore
1726
+ // rather than moveBeforePreserving).
1727
+ I1->moveBefore (TI);
1664
1728
for (auto &SuccIter : OtherSuccIterRange) {
1665
1729
auto *I2 = &*SuccIter++;
1666
1730
assert (isa<DbgInfoIntrinsic>(I2));
1667
- I2->moveBeforePreserving (TI);
1731
+ I2->moveBefore (TI);
1668
1732
}
1669
1733
} else {
1670
1734
// For a normal instruction, we just move one to right before the
1671
1735
// branch, then replace all uses of the other with the first. Finally,
1672
1736
// we remove the now redundant second instruction.
1673
- I1->moveBeforePreserving (TI);
1674
- BB->splice (TI->getIterator (), BB1, I1->getIterator ());
1737
+ hoistLockstepIdenticalDPValues (TI, I1, OtherInsts);
1738
+ // We've just hoisted DPValues; move I1 after them (before TI) and
1739
+ // leave any that were not hoisted behind (by calling moveBefore
1740
+ // rather than moveBeforePreserving).
1741
+ I1->moveBefore (TI);
1675
1742
for (auto &SuccIter : OtherSuccIterRange) {
1676
1743
Instruction *I2 = &*SuccIter++;
1677
1744
assert (I2 != I1);
@@ -1690,8 +1757,10 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1690
1757
Changed = true ;
1691
1758
NumHoistCommonInstrs += SuccIterPairs.size ();
1692
1759
} else {
1693
- if (NumSkipped >= HoistCommonSkipLimit)
1760
+ if (NumSkipped >= HoistCommonSkipLimit) {
1761
+ hoistLockstepIdenticalDPValues (TI, I1, OtherInsts);
1694
1762
return Changed;
1763
+ }
1695
1764
// We are about to skip over a pair of non-identical instructions. Record
1696
1765
// if any have characteristics that would prevent reordering instructions
1697
1766
// across them.
@@ -1752,7 +1821,10 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf(
1752
1821
}
1753
1822
}
1754
1823
1755
- // Okay, it is safe to hoist the terminator.
1824
+ // Hoist DPValues attached to the terminator to match dbg.* intrinsic hoisting
1825
+ // behaviour in hoistCommonCodeFromSuccessors.
1826
+ hoistLockstepIdenticalDPValues (TI, I1, OtherSuccTIs);
1827
+ // Clone the terminator and hoist it into the pred, without any debug info.
1756
1828
Instruction *NT = I1->clone ();
1757
1829
NT->insertInto (TIParent, TI->getIterator ());
1758
1830
if (!NT->getType ()->isVoidTy ()) {
0 commit comments