@@ -1582,19 +1582,29 @@ hoistLockstepIdenticalDPValues(Instruction *TI, Instruction *I1,
1582
1582
}
1583
1583
}
1584
1584
1585
+ // Hash instructions based on following factors:
1586
+ // 1- Instruction Opcode
1587
+ // 2- Instruction type
1588
+ // 3- Instruction operands
1589
+ llvm::hash_code getHash (Instruction *Instr) {
1590
+ std::vector<Value *> operands (Instr->op_begin (), Instr->op_end ());
1591
+ return llvm::hash_combine (
1592
+ Instr->getOpcode (), Instr->getType (),
1593
+ hash_combine_range (operands.begin (), operands.end ()));
1594
+ }
1595
+
1585
1596
// / Hoist any common code in the successor blocks up into the block. This
1586
1597
// / function guarantees that BB dominates all successors. If EqTermsOnly is
1587
1598
// / given, only perform hoisting in case both blocks only contain a terminator.
1588
1599
// / In that case, only the original BI will be replaced and selects for PHIs are
1589
1600
// / added.
1590
1601
bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors (BasicBlock *BB,
1591
1602
bool EqTermsOnly) {
1592
- // This does very trivial matching, with limited scanning, to find identical
1593
- // instructions in the two blocks. In particular, we don't want to get into
1594
- // O(N1*N2*...) situations here where Ni are the sizes of these successors. As
1595
- // such, we currently just scan for obviously identical instructions in an
1596
- // identical order, possibly separated by the same number of non-identical
1597
- // instructions.
1603
+ // We first sort successors based on the number of instructions each block
1604
+ // holds. Then for each successor we make a hashmap from its instructions,
1605
+ // except for the first successor. After that, we iterate over the
1606
+ // instructions of the first successor. If we find identical instructions from
1607
+ // every other successor, we hoist all of them into the predeccessor.
1598
1608
unsigned int SuccSize = succ_size (BB);
1599
1609
if (SuccSize < 2 )
1600
1610
return false ;
@@ -1608,10 +1618,21 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1608
1618
1609
1619
auto *TI = BB->getTerminator ();
1610
1620
1621
+ SmallVector<BasicBlock *> SuccessorBlocks;
1622
+ for (auto *Succ : successors (BB))
1623
+ SuccessorBlocks.push_back (Succ);
1624
+
1625
+ // Sort successor blocks based on the number of instructions.
1626
+ // This is because we always want to iterate over instructions
1627
+ // of the smallest block.
1628
+ llvm::stable_sort (SuccessorBlocks, [](BasicBlock *BB1, BasicBlock *BB2) {
1629
+ return BB1->sizeWithoutDebug () < BB2->sizeWithoutDebug ();
1630
+ });
1631
+
1611
1632
// The second of pair is a SkipFlags bitmask.
1612
1633
using SuccIterPair = std::pair<BasicBlock::iterator, unsigned >;
1613
1634
SmallVector<SuccIterPair, 8 > SuccIterPairs;
1614
- for (auto *Succ : successors (BB) ) {
1635
+ for (auto *Succ : SuccessorBlocks ) {
1615
1636
BasicBlock::iterator SuccItr = Succ->begin ();
1616
1637
if (isa<PHINode>(*SuccItr))
1617
1638
return false ;
@@ -1645,77 +1666,124 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1645
1666
}
1646
1667
1647
1668
bool Changed = false ;
1669
+ auto *SuccIterPairBegin = SuccIterPairs.begin ();
1670
+ SuccIterPairBegin++;
1671
+ auto OtherSuccIterPairRange =
1672
+ iterator_range (SuccIterPairBegin, SuccIterPairs.end ());
1673
+ auto OtherSuccIterRange = make_first_range (OtherSuccIterPairRange);
1674
+ using InstrFlagPair = std::pair<Instruction *, unsigned >;
1675
+ SmallVector<DenseMap<llvm::hash_code, InstrFlagPair>, 2 > OtherSuccessorsHash;
1676
+
1677
+ for (auto BBItrPair : OtherSuccIterRange) {
1678
+ // Fill the hashmap for every other successor
1679
+ DenseMap<llvm::hash_code, InstrFlagPair> hashMap;
1680
+ unsigned skipFlag = 0 ;
1681
+ Instruction *I = nullptr ;
1682
+ do {
1683
+ I = &*BBItrPair;
1684
+ skipFlag |= skippedInstrFlags (I);
1685
+ hashMap[getHash (I)] = InstrFlagPair (I, skipFlag);
1686
+ BBItrPair++;
1687
+ } while (!I->isTerminator ());
1688
+ OtherSuccessorsHash.push_back (hashMap);
1689
+ }
1648
1690
1691
+ // Keep track of instructions skipped in the first successor
1692
+ unsigned SkipFlagsBB1 = 0 ;
1693
+ bool SameLevelHoist = true ;
1649
1694
for (;;) {
1650
1695
auto *SuccIterPairBegin = SuccIterPairs.begin ();
1651
1696
auto &BB1ItrPair = *SuccIterPairBegin++;
1652
1697
auto OtherSuccIterPairRange =
1653
1698
iterator_range (SuccIterPairBegin, SuccIterPairs.end ());
1654
- auto OtherSuccIterRange = make_first_range (OtherSuccIterPairRange);
1655
-
1656
1699
Instruction *I1 = &*BB1ItrPair.first ;
1657
-
1658
- // Skip debug info if it is not identical.
1659
- bool AllDbgInstsAreIdentical = all_of (OtherSuccIterRange, [I1](auto &Iter) {
1660
- Instruction *I2 = &*Iter;
1661
- return I1->isIdenticalToWhenDefined (I2);
1662
- });
1663
- if (!AllDbgInstsAreIdentical) {
1664
- while (isa<DbgInfoIntrinsic>(I1))
1665
- I1 = &*++BB1ItrPair.first ;
1666
- for (auto &SuccIter : OtherSuccIterRange) {
1667
- Instruction *I2 = &*SuccIter;
1668
- while (isa<DbgInfoIntrinsic>(I2))
1669
- I2 = &*++SuccIter;
1700
+ bool HasIdenticalInst = true ;
1701
+
1702
+ // Check if there are identical instructions in all other successors
1703
+ for (auto &map : OtherSuccessorsHash) {
1704
+ Instruction *I2 = map[getHash (I1)].first ;
1705
+ // We might face with same hash values for different instructions.
1706
+ // If that happens, ignore the instruction.
1707
+ if (!I2 || !I1->isIdenticalTo (I2)) {
1708
+ HasIdenticalInst = false ;
1709
+ break ;
1670
1710
}
1671
1711
}
1672
1712
1673
- bool AllInstsAreIdentical = true ;
1674
- bool HasTerminator = I1->isTerminator ();
1675
- for (auto &SuccIter : OtherSuccIterRange) {
1676
- Instruction *I2 = &*SuccIter;
1677
- HasTerminator |= I2->isTerminator ();
1678
- if (AllInstsAreIdentical && !I1->isIdenticalToWhenDefined (I2))
1679
- AllInstsAreIdentical = false ;
1713
+ if (!HasIdenticalInst) {
1714
+ if (NumSkipped >= HoistCommonSkipLimit)
1715
+ return Changed;
1716
+ SkipFlagsBB1 |= skippedInstrFlags (I1);
1717
+ if (SameLevelHoist) {
1718
+ for (auto &SuccIterPair : OtherSuccIterPairRange) {
1719
+ Instruction *I = &*SuccIterPair.first ++;
1720
+ SuccIterPair.second |= skippedInstrFlags (I);
1721
+ }
1722
+ }
1723
+ NumSkipped++;
1724
+ if (I1->isTerminator ())
1725
+ return Changed;
1726
+ ++BB1ItrPair.first ;
1727
+ continue ;
1680
1728
}
1681
1729
1682
1730
SmallVector<Instruction *, 8 > OtherInsts;
1683
- for (auto &SuccIter : OtherSuccIterRange)
1684
- OtherInsts.push_back (&*SuccIter);
1731
+ if (SameLevelHoist) {
1732
+ for (auto &SuccIterPair : OtherSuccIterPairRange)
1733
+ OtherInsts.push_back (&*(SuccIterPair.first ));
1734
+ } else {
1735
+ for (auto &map : OtherSuccessorsHash)
1736
+ OtherInstrs.push_back (map[getHash (I1)].first );
1737
+ }
1685
1738
1686
1739
// If we are hoisting the terminator instruction, don't move one (making a
1687
1740
// broken BB), instead clone it, and remove BI.
1688
- if (HasTerminator ) {
1741
+ if (I1-> isTerminator () ) {
1689
1742
// Even if BB, which contains only one unreachable instruction, is ignored
1690
1743
// at the beginning of the loop, we can hoist the terminator instruction.
1691
1744
// If any instructions remain in the block, we cannot hoist terminators.
1692
- if (NumSkipped || !AllInstsAreIdentical ) {
1745
+ if (NumSkipped) {
1693
1746
hoistLockstepIdenticalDPValues (TI, I1, OtherInsts);
1694
1747
return Changed;
1695
1748
}
1696
-
1697
- return hoistSuccIdenticalTerminatorToSwitchOrIf (TI, I1, OtherInsts) ||
1698
- Changed;
1749
+ SmallVector<Instruction *, 8 > Insts;
1750
+ for (auto &map : OtherSuccessorsHash) {
1751
+ Instruction *I2 = map[getHash (I1)].first ;
1752
+ // BB holding I2 should only contain the branch instruction
1753
+ auto itr = I2->getParent ()->instructionsWithoutDebug ();
1754
+ if (&*itr.begin () != I2)
1755
+ return Changed;
1756
+ Insts.push_back (I2);
1757
+ }
1758
+ return hoistSuccIdenticalTerminatorToSwitchOrIf (TI, I1, Insts) || Changed;
1699
1759
}
1700
1760
1701
- if (AllInstsAreIdentical) {
1702
- unsigned SkipFlagsBB1 = BB1ItrPair.second ;
1703
- AllInstsAreIdentical =
1704
- isSafeToHoistInstr (I1, SkipFlagsBB1) &&
1705
- all_of (OtherSuccIterPairRange, [=](const auto &Pair) {
1706
- Instruction *I2 = &*Pair.first ;
1707
- unsigned SkipFlagsBB2 = Pair.second ;
1708
- // Even if the instructions are identical, it may not
1709
- // be safe to hoist them if we have skipped over
1710
- // instructions with side effects or their operands
1711
- // weren't hoisted.
1712
- return isSafeToHoistInstr (I2, SkipFlagsBB2) &&
1713
- shouldHoistCommonInstructions (I1, I2, TTI);
1714
- });
1761
+ bool SafeToHoist = isSafeToHoistInstr (I1, SkipFlagsBB1);
1762
+ unsigned index = 0 ;
1763
+ for (auto &SuccIterPair : OtherSuccIterPairRange) {
1764
+ Instruction *I2 = OtherSuccessorsHash[index][getHash (I1)].first ;
1765
+ // If instructions of all successors are at the same level, use the
1766
+ // skipFlag of its BB, i.e., SameLevelHoist. Otherwise, use the skipFlag
1767
+ // that was calculated initially for this instruction in the hashmap
1768
+ if (SameLevelHoist && I2 == (&*(SuccIterPair.first ))) {
1769
+ SafeToHoist = SafeToHoist &&
1770
+ isSafeToHoistInstr (I2, SuccIterPair.second ) &&
1771
+ shouldHoistCommonInstructions (I1, I2, TTI);
1772
+ } else {
1773
+ unsigned skipFlag = OtherSuccessorsHash[index][getHash (I1)].second ;
1774
+ SafeToHoist = SafeToHoist && isSafeToHoistInstr (I2, skipFlag) &&
1775
+ shouldHoistCommonInstructions (I1, I2, TTI);
1776
+ SameLevelHoist = false ;
1777
+ }
1778
+ index++;
1715
1779
}
1716
1780
1717
- if (AllInstsAreIdentical ) {
1781
+ if (SafeToHoist ) {
1718
1782
BB1ItrPair.first ++;
1783
+ if (SameLevelHoist) {
1784
+ for (auto &SuccIterPair : OtherSuccIterPairRange)
1785
+ SuccIterPair.first ++;
1786
+ }
1719
1787
if (isa<DbgInfoIntrinsic>(I1)) {
1720
1788
// The debug location is an integral part of a debug info intrinsic
1721
1789
// and can't be separated from it or replaced. Instead of attempting
@@ -1725,8 +1793,8 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1725
1793
// leave any that were not hoisted behind (by calling moveBefore
1726
1794
// rather than moveBeforePreserving).
1727
1795
I1->moveBefore (TI);
1728
- for (auto &SuccIter : OtherSuccIterRange ) {
1729
- auto *I2 = &*SuccIter++ ;
1796
+ for (auto &map : OtherSuccessorsHash ) {
1797
+ Instruction *I2 = map[ getHash (I1)]. first ;
1730
1798
assert (isa<DbgInfoIntrinsic>(I2));
1731
1799
I2->moveBefore (TI);
1732
1800
}
@@ -1739,8 +1807,8 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1739
1807
// leave any that were not hoisted behind (by calling moveBefore
1740
1808
// rather than moveBeforePreserving).
1741
1809
I1->moveBefore (TI);
1742
- for (auto &SuccIter : OtherSuccIterRange ) {
1743
- Instruction *I2 = &*SuccIter++ ;
1810
+ for (auto &map : OtherSuccessorsHash ) {
1811
+ Instruction *I2 = map[ getHash (I1)]. first ;
1744
1812
assert (I2 != I1);
1745
1813
if (!I2->use_empty ())
1746
1814
I2->replaceAllUsesWith (I1);
@@ -1764,9 +1832,12 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1764
1832
// We are about to skip over a pair of non-identical instructions. Record
1765
1833
// if any have characteristics that would prevent reordering instructions
1766
1834
// across them.
1767
- for (auto &SuccIterPair : SuccIterPairs) {
1768
- Instruction *I = &*SuccIterPair.first ++;
1769
- SuccIterPair.second |= skippedInstrFlags (I);
1835
+ SkipFlagsBB1 |= skippedInstrFlags (I1);
1836
+ if (SameLevelHoist) {
1837
+ for (auto &SuccIterPair : OtherSuccIterPairRange) { // update flags
1838
+ Instruction *I = &*SuccIterPair.first ;
1839
+ SuccIterPair.second |= skippedInstrFlags (I);
1840
+ }
1770
1841
}
1771
1842
++NumSkipped;
1772
1843
}
@@ -1810,7 +1881,6 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf(
1810
1881
Value *BB2V = PN.getIncomingValueForBlock (OtherSuccTI->getParent ());
1811
1882
if (BB1V == BB2V)
1812
1883
continue ;
1813
-
1814
1884
// In the case of an if statement, check for
1815
1885
// passingValueIsAlwaysUndefined here because we would rather eliminate
1816
1886
// undefined control flow then converting it to a select.
@@ -1882,20 +1952,16 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf(
1882
1952
}
1883
1953
}
1884
1954
}
1885
-
1886
1955
SmallVector<DominatorTree::UpdateType, 4 > Updates;
1887
-
1888
1956
// Update any PHI nodes in our new successors.
1889
1957
for (BasicBlock *Succ : successors (BB1)) {
1890
1958
AddPredecessorToBlock (Succ, TIParent, BB1);
1891
1959
if (DTU)
1892
1960
Updates.push_back ({DominatorTree::Insert, TIParent, Succ});
1893
1961
}
1894
-
1895
1962
if (DTU)
1896
1963
for (BasicBlock *Succ : successors (TI))
1897
1964
Updates.push_back ({DominatorTree::Delete, TIParent, Succ});
1898
-
1899
1965
EraseTerminatorAndDCECond (TI);
1900
1966
if (DTU)
1901
1967
DTU->applyUpdates (Updates);
0 commit comments