@@ -1618,27 +1618,39 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1618
1618
1619
1619
auto *TI = BB->getTerminator ();
1620
1620
1621
- SmallVector<BasicBlock *> SuccessorBlocks;
1622
- for (auto *Succ : successors (BB))
1623
- SuccessorBlocks.push_back (Succ);
1621
+ SmallVector<BasicBlock *, 8 > SuccessorBBs;
1622
+ for (auto *Succ : successors (BB)) {
1623
+ BasicBlock::iterator SuccItr = Succ->begin ();
1624
+ // If we find an unreachable instruction at the beginning of a basic block,
1625
+ // we can still hoist instructions from the rest of the basic blocks.
1626
+ if (isa<UnreachableInst>(*SuccItr))
1627
+ continue ;
1628
+ SuccessorBBs.push_back (Succ);
1629
+ }
1624
1630
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
+ // Find the smallest BB because we always want to iterate over instructions
1632
+ // of the smallest Successor.
1633
+ auto *SmallestBB = *std::min_element (SuccessorBBs.begin (), SuccessorBBs.end (),
1634
+ [](BasicBlock *BB1, BasicBlock *BB2) {
1635
+ return BB1->size () < BB2->size ();
1636
+ });
1637
+ std::iter_swap (
1638
+ SuccessorBBs.begin (),
1639
+ std::find (SuccessorBBs.begin (), SuccessorBBs.end (), SmallestBB));
1631
1640
1632
1641
// The second of pair is a SkipFlags bitmask.
1633
1642
using SuccIterPair = std::pair<BasicBlock::iterator, unsigned >;
1634
1643
SmallVector<SuccIterPair, 8 > SuccIterPairs;
1635
- for (auto *Succ : SuccessorBlocks ) {
1644
+ for (auto *Succ : SuccessorBBs ) {
1636
1645
BasicBlock::iterator SuccItr = Succ->begin ();
1637
1646
if (isa<PHINode>(*SuccItr))
1638
1647
return false ;
1639
1648
SuccIterPairs.push_back (SuccIterPair (SuccItr, 0 ));
1640
1649
}
1641
1650
1651
+ if (SuccIterPairs.size () < 2 )
1652
+ return false ;
1653
+
1642
1654
// Check if only hoisting terminators is allowed. This does not add new
1643
1655
// instructions to the hoist location.
1644
1656
if (EqTermsOnly) {
@@ -1656,14 +1668,6 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1656
1668
// many instructions we skip, serving as a compilation time control as well as
1657
1669
// preventing excessive increase of life ranges.
1658
1670
unsigned NumSkipped = 0 ;
1659
- // If we find an unreachable instruction at the beginning of a basic block, we
1660
- // can still hoist instructions from the rest of the basic blocks.
1661
- if (SuccIterPairs.size () > 2 ) {
1662
- erase_if (SuccIterPairs,
1663
- [](const auto &Pair) { return isa<UnreachableInst>(Pair.first ); });
1664
- if (SuccIterPairs.size () < 2 )
1665
- return false ;
1666
- }
1667
1671
1668
1672
bool Changed = false ;
1669
1673
auto *SuccIterPairBegin = SuccIterPairs.begin ();
@@ -1697,14 +1701,25 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1697
1701
auto OtherSuccIterPairRange =
1698
1702
iterator_range (SuccIterPairBegin, SuccIterPairs.end ());
1699
1703
Instruction *I1 = &*BB1ItrPair.first ;
1704
+
1705
+ // Skip debug info if it is not identical.
1706
+ bool IdenticalDebugs = all_of (OtherSuccIterRange, [I1](auto &Iter) {
1707
+ Instruction *I2 = &*Iter;
1708
+ return I1->isIdenticalToWhenDefined (I2);
1709
+ });
1710
+ if (!IdenticalDebugs) {
1711
+ while (isa<DbgInfoIntrinsic>(I1))
1712
+ I1 = &*++BB1ItrPair.first ;
1713
+ }
1714
+
1700
1715
bool HasIdenticalInst = true ;
1701
1716
1702
1717
// Check if there are identical instructions in all other successors
1703
1718
for (auto &map : OtherSuccessorsHash) {
1704
1719
Instruction *I2 = map[getHash (I1)].first ;
1705
1720
// We might face with same hash values for different instructions.
1706
1721
// If that happens, ignore the instruction.
1707
- if (!I2 || !I1->isIdenticalTo (I2)) {
1722
+ if (!I2 || !I1->isIdenticalToWhenDefined (I2)) {
1708
1723
HasIdenticalInst = false ;
1709
1724
break ;
1710
1725
}
@@ -1720,7 +1735,7 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1720
1735
SuccIterPair.second |= skippedInstrFlags (I);
1721
1736
}
1722
1737
}
1723
- NumSkipped++ ;
1738
+ ++NumSkipped ;
1724
1739
if (I1->isTerminator ())
1725
1740
return Changed;
1726
1741
++BB1ItrPair.first ;
@@ -1733,7 +1748,7 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1733
1748
OtherInsts.push_back (&*(SuccIterPair.first ));
1734
1749
} else {
1735
1750
for (auto &map : OtherSuccessorsHash)
1736
- OtherInstrs .push_back (map[getHash (I1)].first );
1751
+ OtherInsts .push_back (map[getHash (I1)].first );
1737
1752
}
1738
1753
1739
1754
// If we are hoisting the terminator instruction, don't move one (making a
@@ -1810,13 +1825,38 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1810
1825
for (auto &map : OtherSuccessorsHash) {
1811
1826
Instruction *I2 = map[getHash (I1)].first ;
1812
1827
assert (I2 != I1);
1813
- if (!I2->use_empty ())
1828
+ // Update hashcode of all instructions using I2
1829
+ if (!I2->use_empty ()) {
1830
+ SmallVector<llvm::hash_code, 8 > PrevHashCodes;
1831
+ SmallVector<llvm::Instruction *, 8 > PrevUsers;
1832
+ // Once the uses of I1 are replaced, the hash value computed for
1833
+ // those users are not valid anymore so we gather users and then
1834
+ // recompute the hash codes for them. We need to do this only for
1835
+ // the instructions located in the same block as I2 because we
1836
+ // initially only hashed those instructions.
1837
+ for (auto *user : I2->users ()) {
1838
+ if (auto *I = dyn_cast<Instruction>(user)) {
1839
+ if (I->getParent () != I2->getParent ())
1840
+ continue ;
1841
+ PrevHashCodes.push_back (getHash (I));
1842
+ PrevUsers.push_back (I);
1843
+ }
1844
+ }
1814
1845
I2->replaceAllUsesWith (I1);
1846
+ unsigned index = 0 ;
1847
+ for (auto &PrevHash : PrevHashCodes) {
1848
+ auto NewHash = getHash (PrevUsers[index]);
1849
+ map.insert ({NewHash, map[PrevHash]});
1850
+ map.erase (PrevHash);
1851
+ index++;
1852
+ }
1853
+ }
1815
1854
I1->andIRFlags (I2);
1816
1855
combineMetadataForCSE (I1, I2, true );
1817
1856
// I1 and I2 are being combined into a single instruction. Its debug
1818
1857
// location is the merged locations of the original instructions.
1819
1858
I1->applyMergedLocation (I1->getDebugLoc (), I2->getDebugLoc ());
1859
+ map.erase (getHash (I1));
1820
1860
I2->eraseFromParent ();
1821
1861
}
1822
1862
}
@@ -1832,10 +1872,11 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1832
1872
// We are about to skip over a pair of non-identical instructions. Record
1833
1873
// if any have characteristics that would prevent reordering instructions
1834
1874
// across them.
1875
+ BB1ItrPair.first ++;
1835
1876
SkipFlagsBB1 |= skippedInstrFlags (I1);
1836
1877
if (SameLevelHoist) {
1837
1878
for (auto &SuccIterPair : OtherSuccIterPairRange) { // update flags
1838
- Instruction *I = &*SuccIterPair.first ;
1879
+ Instruction *I = &*SuccIterPair.first ++ ;
1839
1880
SuccIterPair.second |= skippedInstrFlags (I);
1840
1881
}
1841
1882
}
@@ -1857,11 +1898,8 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf(
1857
1898
// Use only for an if statement.
1858
1899
auto *I2 = *OtherSuccTIs.begin ();
1859
1900
auto *BB2 = I2->getParent ();
1860
- if (BI) {
1901
+ if (BI)
1861
1902
assert (OtherSuccTIs.size () == 1 );
1862
- assert (BI->getSuccessor (0 ) == I1->getParent ());
1863
- assert (BI->getSuccessor (1 ) == I2->getParent ());
1864
- }
1865
1903
1866
1904
// In the case of an if statement, we try to hoist an invoke.
1867
1905
// FIXME: Can we define a safety predicate for CallBr?
@@ -1881,6 +1919,7 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf(
1881
1919
Value *BB2V = PN.getIncomingValueForBlock (OtherSuccTI->getParent ());
1882
1920
if (BB1V == BB2V)
1883
1921
continue ;
1922
+
1884
1923
// In the case of an if statement, check for
1885
1924
// passingValueIsAlwaysUndefined here because we would rather eliminate
1886
1925
// undefined control flow then converting it to a select.
@@ -1952,16 +1991,20 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf(
1952
1991
}
1953
1992
}
1954
1993
}
1994
+
1955
1995
SmallVector<DominatorTree::UpdateType, 4 > Updates;
1996
+
1956
1997
// Update any PHI nodes in our new successors.
1957
1998
for (BasicBlock *Succ : successors (BB1)) {
1958
1999
AddPredecessorToBlock (Succ, TIParent, BB1);
1959
2000
if (DTU)
1960
2001
Updates.push_back ({DominatorTree::Insert, TIParent, Succ});
1961
2002
}
2003
+
1962
2004
if (DTU)
1963
2005
for (BasicBlock *Succ : successors (TI))
1964
2006
Updates.push_back ({DominatorTree::Delete, TIParent, Succ});
2007
+
1965
2008
EraseTerminatorAndDCECond (TI);
1966
2009
if (DTU)
1967
2010
DTU->applyUpdates (Updates);
@@ -3713,7 +3756,7 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
3713
3756
// Change the PHI node into a select instruction.
3714
3757
Value *TrueVal = PN->getIncomingValueForBlock (IfTrue);
3715
3758
Value *FalseVal = PN->getIncomingValueForBlock (IfFalse);
3716
-
3759
+
3717
3760
Value *Sel = Builder.CreateSelect (IfCond, TrueVal, FalseVal, " " , DomBI);
3718
3761
PN->replaceAllUsesWith (Sel);
3719
3762
Sel->takeName (PN);
0 commit comments