@@ -1562,27 +1562,39 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1562
1562
1563
1563
auto *TI = BB->getTerminator ();
1564
1564
1565
- SmallVector<BasicBlock *> SuccessorBlocks;
1566
- for (auto *Succ : successors (BB))
1567
- SuccessorBlocks.push_back (Succ);
1565
+ SmallVector<BasicBlock *, 8 > SuccessorBBs;
1566
+ for (auto *Succ : successors (BB)) {
1567
+ BasicBlock::iterator SuccItr = Succ->begin ();
1568
+ // If we find an unreachable instruction at the beginning of a basic block,
1569
+ // we can still hoist instructions from the rest of the basic blocks.
1570
+ if (isa<UnreachableInst>(*SuccItr))
1571
+ continue ;
1572
+ SuccessorBBs.push_back (Succ);
1573
+ }
1568
1574
1569
- // Sort successor blocks based on the number of instructions.
1570
- // This is because we always want to iterate over instructions
1571
- // of the smallest block.
1572
- llvm::stable_sort (SuccessorBlocks, [](BasicBlock *BB1, BasicBlock *BB2) {
1573
- return BB1->sizeWithoutDebug () < BB2->sizeWithoutDebug ();
1574
- });
1575
+ // Find the smallest BB because we always want to iterate over instructions
1576
+ // of the smallest Successor.
1577
+ auto *SmallestBB = *std::min_element (SuccessorBBs.begin (), SuccessorBBs.end (),
1578
+ [](BasicBlock *BB1, BasicBlock *BB2) {
1579
+ return BB1->size () < BB2->size ();
1580
+ });
1581
+ std::iter_swap (
1582
+ SuccessorBBs.begin (),
1583
+ std::find (SuccessorBBs.begin (), SuccessorBBs.end (), SmallestBB));
1575
1584
1576
1585
// The second of pair is a SkipFlags bitmask.
1577
1586
using SuccIterPair = std::pair<BasicBlock::iterator, unsigned >;
1578
1587
SmallVector<SuccIterPair, 8 > SuccIterPairs;
1579
- for (auto *Succ : SuccessorBlocks ) {
1588
+ for (auto *Succ : SuccessorBBs ) {
1580
1589
BasicBlock::iterator SuccItr = Succ->begin ();
1581
1590
if (isa<PHINode>(*SuccItr))
1582
1591
return false ;
1583
1592
SuccIterPairs.push_back (SuccIterPair (SuccItr, 0 ));
1584
1593
}
1585
1594
1595
+ if (SuccIterPairs.size () < 2 )
1596
+ return false ;
1597
+
1586
1598
// Check if only hoisting terminators is allowed. This does not add new
1587
1599
// instructions to the hoist location.
1588
1600
if (EqTermsOnly) {
@@ -1600,14 +1612,6 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1600
1612
// many instructions we skip, serving as a compilation time control as well as
1601
1613
// preventing excessive increase of life ranges.
1602
1614
unsigned NumSkipped = 0 ;
1603
- // If we find an unreachable instruction at the beginning of a basic block, we
1604
- // can still hoist instructions from the rest of the basic blocks.
1605
- if (SuccIterPairs.size () > 2 ) {
1606
- erase_if (SuccIterPairs,
1607
- [](const auto &Pair) { return isa<UnreachableInst>(Pair.first ); });
1608
- if (SuccIterPairs.size () < 2 )
1609
- return false ;
1610
- }
1611
1615
1612
1616
bool Changed = false ;
1613
1617
auto *SuccIterPairBegin = SuccIterPairs.begin ();
@@ -1642,14 +1646,25 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1642
1646
iterator_range (SuccIterPairBegin, SuccIterPairs.end ());
1643
1647
Instruction *I1 = &*BB1ItrPair.first ;
1644
1648
auto *BB1 = I1->getParent ();
1649
+
1650
+ // Skip debug info if it is not identical.
1651
+ bool IdenticalDebugs = all_of (OtherSuccIterRange, [I1](auto &Iter) {
1652
+ Instruction *I2 = &*Iter;
1653
+ return I1->isIdenticalToWhenDefined (I2);
1654
+ });
1655
+ if (!IdenticalDebugs) {
1656
+ while (isa<DbgInfoIntrinsic>(I1))
1657
+ I1 = &*++BB1ItrPair.first ;
1658
+ }
1659
+
1645
1660
bool HasIdenticalInst = true ;
1646
1661
1647
1662
// Check if there are identical instructions in all other successors
1648
1663
for (auto &map : OtherSuccessorsHash) {
1649
1664
Instruction *I2 = map[getHash (I1)].first ;
1650
1665
// We might face with same hash values for different instructions.
1651
1666
// If that happens, ignore the instruction.
1652
- if (!I2 || !I1->isIdenticalTo (I2)) {
1667
+ if (!I2 || !I1->isIdenticalToWhenDefined (I2)) {
1653
1668
HasIdenticalInst = false ;
1654
1669
break ;
1655
1670
}
@@ -1665,7 +1680,7 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1665
1680
SuccIterPair.second |= skippedInstrFlags (I);
1666
1681
}
1667
1682
}
1668
- NumSkipped++ ;
1683
+ ++NumSkipped ;
1669
1684
if (I1->isTerminator ())
1670
1685
return Changed;
1671
1686
++BB1ItrPair.first ;
@@ -1737,13 +1752,38 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1737
1752
for (auto &map : OtherSuccessorsHash) {
1738
1753
Instruction *I2 = map[getHash (I1)].first ;
1739
1754
assert (I2 != I1);
1740
- if (!I2->use_empty ())
1755
+ // Update hashcode of all instructions using I2
1756
+ if (!I2->use_empty ()) {
1757
+ SmallVector<llvm::hash_code, 8 > PrevHashCodes;
1758
+ SmallVector<llvm::Instruction *, 8 > PrevUsers;
1759
+ // Once the uses of I1 are replaced, the hash value computed for
1760
+ // those users are not valid anymore so we gather users and then
1761
+ // recompute the hash codes for them. We need to do this only for
1762
+ // the instructions located in the same block as I2 because we
1763
+ // initially only hashed those instructions.
1764
+ for (auto *user : I2->users ()) {
1765
+ if (auto *I = dyn_cast<Instruction>(user)) {
1766
+ if (I->getParent () != I2->getParent ())
1767
+ continue ;
1768
+ PrevHashCodes.push_back (getHash (I));
1769
+ PrevUsers.push_back (I);
1770
+ }
1771
+ }
1741
1772
I2->replaceAllUsesWith (I1);
1773
+ unsigned index = 0 ;
1774
+ for (auto &PrevHash : PrevHashCodes) {
1775
+ auto NewHash = getHash (PrevUsers[index]);
1776
+ std::swap (map[NewHash], map[PrevHash]);
1777
+ map.erase (PrevHash);
1778
+ index++;
1779
+ }
1780
+ }
1742
1781
I1->andIRFlags (I2);
1743
1782
combineMetadataForCSE (I1, I2, true );
1744
1783
// I1 and I2 are being combined into a single instruction. Its debug
1745
1784
// location is the merged locations of the original instructions.
1746
1785
I1->applyMergedLocation (I1->getDebugLoc (), I2->getDebugLoc ());
1786
+ map.erase (getHash (I1));
1747
1787
I2->eraseFromParent ();
1748
1788
}
1749
1789
}
@@ -1757,10 +1797,11 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1757
1797
// We are about to skip over a pair of non-identical instructions. Record
1758
1798
// if any have characteristics that would prevent reordering instructions
1759
1799
// across them.
1800
+ BB1ItrPair.first ++;
1760
1801
SkipFlagsBB1 |= skippedInstrFlags (I1);
1761
1802
if (SameLevelHoist) {
1762
1803
for (auto &SuccIterPair : OtherSuccIterPairRange) { // update flags
1763
- Instruction *I = &*SuccIterPair.first ;
1804
+ Instruction *I = &*SuccIterPair.first ++ ;
1764
1805
SuccIterPair.second |= skippedInstrFlags (I);
1765
1806
}
1766
1807
}
@@ -1874,16 +1915,20 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf(
1874
1915
}
1875
1916
}
1876
1917
}
1918
+
1877
1919
SmallVector<DominatorTree::UpdateType, 4 > Updates;
1920
+
1878
1921
// Update any PHI nodes in our new successors.
1879
1922
for (BasicBlock *Succ : successors (BB1)) {
1880
1923
AddPredecessorToBlock (Succ, TIParent, BB1);
1881
1924
if (DTU)
1882
1925
Updates.push_back ({DominatorTree::Insert, TIParent, Succ});
1883
1926
}
1927
+
1884
1928
if (DTU)
1885
1929
for (BasicBlock *Succ : successors (TI))
1886
1930
Updates.push_back ({DominatorTree::Delete, TIParent, Succ});
1931
+
1887
1932
EraseTerminatorAndDCECond (TI);
1888
1933
if (DTU)
1889
1934
DTU->applyUpdates (Updates);
@@ -3631,7 +3676,6 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
3631
3676
// Change the PHI node into a select instruction.
3632
3677
Value *TrueVal = PN->getIncomingValueForBlock (IfTrue);
3633
3678
Value *FalseVal = PN->getIncomingValueForBlock (IfFalse);
3634
-
3635
3679
Value *Sel = Builder.CreateSelect (IfCond, TrueVal, FalseVal, " " , DomBI);
3636
3680
PN->replaceAllUsesWith (Sel);
3637
3681
Sel->takeName (PN);
0 commit comments