@@ -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 ();
@@ -1704,7 +1708,7 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1704
1708
Instruction *I2 = map[getHash (I1)].first ;
1705
1709
// We might face with same hash values for different instructions.
1706
1710
// If that happens, ignore the instruction.
1707
- if (!I2 || !I1->isIdenticalTo (I2)) {
1711
+ if (!I2 || !I1->isIdenticalToWhenDefined (I2)) {
1708
1712
HasIdenticalInst = false ;
1709
1713
break ;
1710
1714
}
@@ -1720,7 +1724,7 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1720
1724
SuccIterPair.second |= skippedInstrFlags (I);
1721
1725
}
1722
1726
}
1723
- NumSkipped++ ;
1727
+ ++NumSkipped ;
1724
1728
if (I1->isTerminator ())
1725
1729
return Changed;
1726
1730
++BB1ItrPair.first ;
@@ -1810,13 +1814,38 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1810
1814
for (auto &map : OtherSuccessorsHash) {
1811
1815
Instruction *I2 = map[getHash (I1)].first ;
1812
1816
assert (I2 != I1);
1813
- if (!I2->use_empty ())
1817
+ // Update hashcode of all instructions using I2
1818
+ if (!I2->use_empty ()) {
1819
+ SmallVector<llvm::hash_code, 8 > PrevHashCodes;
1820
+ SmallVector<llvm::Instruction *, 8 > PrevUsers;
1821
+ // Once the uses of I1 are replaced, the hash value computed for
1822
+ // those users are not valid anymore so we gather users and then
1823
+ // recompute the hash codes for them. We need to do this only for
1824
+ // the instructions located in the same block as I2 because we
1825
+ // initially only hashed those instructions.
1826
+ for (auto *user : I2->users ()) {
1827
+ if (auto *I = dyn_cast<Instruction>(user)) {
1828
+ if (I->getParent () != I2->getParent ())
1829
+ continue ;
1830
+ PrevHashCodes.push_back (getHash (I));
1831
+ PrevUsers.push_back (I);
1832
+ }
1833
+ }
1814
1834
I2->replaceAllUsesWith (I1);
1835
+ unsigned index = 0 ;
1836
+ for (auto &PrevHash : PrevHashCodes) {
1837
+ auto NewHash = getHash (PrevUsers[index]);
1838
+ std::swap (map[NewHash], map[PrevHash]);
1839
+ map.erase (PrevHash);
1840
+ index++;
1841
+ }
1842
+ }
1815
1843
I1->andIRFlags (I2);
1816
1844
combineMetadataForCSE (I1, I2, true );
1817
1845
// I1 and I2 are being combined into a single instruction. Its debug
1818
1846
// location is the merged locations of the original instructions.
1819
1847
I1->applyMergedLocation (I1->getDebugLoc (), I2->getDebugLoc ());
1848
+ map.erase (getHash (I1));
1820
1849
I2->eraseFromParent ();
1821
1850
}
1822
1851
}
@@ -1832,10 +1861,11 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
1832
1861
// We are about to skip over a pair of non-identical instructions. Record
1833
1862
// if any have characteristics that would prevent reordering instructions
1834
1863
// across them.
1864
+ BB1ItrPair.first ++;
1835
1865
SkipFlagsBB1 |= skippedInstrFlags (I1);
1836
1866
if (SameLevelHoist) {
1837
1867
for (auto &SuccIterPair : OtherSuccIterPairRange) { // update flags
1838
- Instruction *I = &*SuccIterPair.first ;
1868
+ Instruction *I = &*SuccIterPair.first ++ ;
1839
1869
SuccIterPair.second |= skippedInstrFlags (I);
1840
1870
}
1841
1871
}
@@ -1952,16 +1982,20 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf(
1952
1982
}
1953
1983
}
1954
1984
}
1985
+
1955
1986
SmallVector<DominatorTree::UpdateType, 4 > Updates;
1987
+
1956
1988
// Update any PHI nodes in our new successors.
1957
1989
for (BasicBlock *Succ : successors (BB1)) {
1958
1990
AddPredecessorToBlock (Succ, TIParent, BB1);
1959
1991
if (DTU)
1960
1992
Updates.push_back ({DominatorTree::Insert, TIParent, Succ});
1961
1993
}
1994
+
1962
1995
if (DTU)
1963
1996
for (BasicBlock *Succ : successors (TI))
1964
1997
Updates.push_back ({DominatorTree::Delete, TIParent, Succ});
1998
+
1965
1999
EraseTerminatorAndDCECond (TI);
1966
2000
if (DTU)
1967
2001
DTU->applyUpdates (Updates);
@@ -3713,7 +3747,6 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
3713
3747
// Change the PHI node into a select instruction.
3714
3748
Value *TrueVal = PN->getIncomingValueForBlock (IfTrue);
3715
3749
Value *FalseVal = PN->getIncomingValueForBlock (IfFalse);
3716
-
3717
3750
Value *Sel = Builder.CreateSelect (IfCond, TrueVal, FalseVal, " " , DomBI);
3718
3751
PN->replaceAllUsesWith (Sel);
3719
3752
Sel->takeName (PN);
0 commit comments