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