@@ -285,7 +285,7 @@ class SimplifyCFGOpt {
285285 bool tryToSimplifyUncondBranchWithICmpInIt (ICmpInst *ICI,
286286 IRBuilder<> &Builder);
287287
288- bool hoistCommonCodeFromSuccessors (Instruction *TI, bool EqTermsOnly );
288+ bool hoistCommonCodeFromSuccessors (Instruction *TI, bool AllInstsEqOnly );
289289 bool hoistSuccIdenticalTerminatorToSwitchOrIf (
290290 Instruction *TI, Instruction *I1,
291291 SmallVectorImpl<Instruction *> &OtherSuccTIs);
@@ -1772,13 +1772,84 @@ static bool isSafeCheapLoadStore(const Instruction *I,
17721772 getLoadStoreAlignment (I) < Value::MaximumAlignment;
17731773}
17741774
1775+ namespace {
1776+
1777+ // LockstepReverseIterator - Iterates through instructions
1778+ // in a set of blocks in reverse order from the first non-terminator.
1779+ // For example (assume all blocks have size n):
1780+ // LockstepReverseIterator I([B1, B2, B3]);
1781+ // *I-- = [B1[n], B2[n], B3[n]];
1782+ // *I-- = [B1[n-1], B2[n-1], B3[n-1]];
1783+ // *I-- = [B1[n-2], B2[n-2], B3[n-2]];
1784+ // ...
1785+ class LockstepReverseIterator {
1786+ ArrayRef<BasicBlock *> Blocks;
1787+ SmallVector<Instruction *, 4 > Insts;
1788+ bool Fail;
1789+
1790+ public:
1791+ LockstepReverseIterator (ArrayRef<BasicBlock *> Blocks) : Blocks(Blocks) {
1792+ reset ();
1793+ }
1794+
1795+ void reset () {
1796+ Fail = false ;
1797+ Insts.clear ();
1798+ for (auto *BB : Blocks) {
1799+ Instruction *Inst = BB->getTerminator ();
1800+ for (Inst = Inst->getPrevNode (); Inst && isa<DbgInfoIntrinsic>(Inst);)
1801+ Inst = Inst->getPrevNode ();
1802+ if (!Inst) {
1803+ // Block wasn't big enough.
1804+ Fail = true ;
1805+ return ;
1806+ }
1807+ Insts.push_back (Inst);
1808+ }
1809+ }
1810+
1811+ bool isValid () const { return !Fail; }
1812+
1813+ void operator --() {
1814+ if (Fail)
1815+ return ;
1816+ for (auto *&Inst : Insts) {
1817+ for (Inst = Inst->getPrevNode (); Inst && isa<DbgInfoIntrinsic>(Inst);)
1818+ Inst = Inst->getPrevNode ();
1819+ // Already at beginning of block.
1820+ if (!Inst) {
1821+ Fail = true ;
1822+ return ;
1823+ }
1824+ }
1825+ }
1826+
1827+ void operator ++() {
1828+ if (Fail)
1829+ return ;
1830+ for (auto *&Inst : Insts) {
1831+ for (Inst = Inst->getNextNode (); Inst && isa<DbgInfoIntrinsic>(Inst);)
1832+ Inst = Inst->getNextNode ();
1833+ // Already at end of block.
1834+ if (!Inst) {
1835+ Fail = true ;
1836+ return ;
1837+ }
1838+ }
1839+ }
1840+
1841+ ArrayRef<Instruction *> operator *() const { return Insts; }
1842+ };
1843+
1844+ } // end anonymous namespace
1845+
17751846// / Hoist any common code in the successor blocks up into the block. This
1776- // / function guarantees that BB dominates all successors. If EqTermsOnly is
1777- // / given, only perform hoisting in case both blocks only contain a terminator.
1778- // / In that case, only the original BI will be replaced and selects for PHIs are
1779- // / added.
1847+ // / function guarantees that BB dominates all successors. If AllInstsEqOnly is
1848+ // / given, only perform hoisting in case all successors blocks contain matching
1849+ // / instructions only. In that case, all instructions can be hoisted and the
1850+ // / original branch will be replaced and selects for PHIs are added.
17801851bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors (Instruction *TI,
1781- bool EqTermsOnly ) {
1852+ bool AllInstsEqOnly ) {
17821853 // This does very trivial matching, with limited scanning, to find identical
17831854 // instructions in the two blocks. In particular, we don't want to get into
17841855 // O(N1*N2*...) situations here where Ni are the sizes of these successors. As
@@ -1807,17 +1878,35 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(Instruction *TI,
18071878 SuccIterPairs.push_back (SuccIterPair (SuccItr, 0 ));
18081879 }
18091880
1810- // Check if only hoisting terminators is allowed. This does not add new
1811- // instructions to the hoist location.
1812- if (EqTermsOnly) {
1813- // Skip any debug intrinsics, as they are free to hoist.
1814- for (auto &SuccIter : make_first_range (SuccIterPairs)) {
1815- auto *INonDbg = &*skipDebugIntrinsics (SuccIter);
1816- if (!INonDbg->isTerminator ())
1817- return false ;
1881+ if (AllInstsEqOnly) {
1882+ // Check if all instructions in the successor blocks match. This allows
1883+ // hoisting all instructions and removing the blocks we are hoisting from,
1884+ // so does not add any new instructions.
1885+ SmallVector<BasicBlock *> Succs = to_vector (successors (BB));
1886+ // Check if sizes and terminators of all successors match.
1887+ bool AllSame = none_of (Succs, [&Succs](BasicBlock *Succ) {
1888+ Instruction *Term0 = Succs[0 ]->getTerminator ();
1889+ Instruction *Term = Succ->getTerminator ();
1890+ return !Term->isSameOperationAs (Term0) ||
1891+ !equal (Term->operands (), Term0->operands ()) ||
1892+ Succs[0 ]->size () != Succ->size ();
1893+ });
1894+ if (!AllSame)
1895+ return false ;
1896+ if (AllSame) {
1897+ LockstepReverseIterator LRI (Succs);
1898+ while (LRI.isValid ()) {
1899+ Instruction *I0 = (*LRI)[0 ];
1900+ if (any_of (*LRI, [I0](Instruction *I) {
1901+ return !areIdenticalUpToCommutativity (I0, I);
1902+ })) {
1903+ return false ;
1904+ }
1905+ --LRI;
1906+ }
18181907 }
1819- // Now we know that we only need to hoist debug intrinsics and the
1820- // terminator. Let the loop below handle those 2 cases .
1908+ // Now we know that all instructions in all successors can be hoisted. Let
1909+ // the loop below handle the hoisting .
18211910 }
18221911
18231912 // Count how many instructions were not hoisted so far. There's a limit on how
@@ -2350,81 +2439,6 @@ static void sinkLastInstruction(ArrayRef<BasicBlock*> Blocks) {
23502439 }
23512440}
23522441
2353- namespace {
2354-
2355- // LockstepReverseIterator - Iterates through instructions
2356- // in a set of blocks in reverse order from the first non-terminator.
2357- // For example (assume all blocks have size n):
2358- // LockstepReverseIterator I([B1, B2, B3]);
2359- // *I-- = [B1[n], B2[n], B3[n]];
2360- // *I-- = [B1[n-1], B2[n-1], B3[n-1]];
2361- // *I-- = [B1[n-2], B2[n-2], B3[n-2]];
2362- // ...
2363- class LockstepReverseIterator {
2364- ArrayRef<BasicBlock*> Blocks;
2365- SmallVector<Instruction*,4 > Insts;
2366- bool Fail;
2367-
2368- public:
2369- LockstepReverseIterator (ArrayRef<BasicBlock*> Blocks) : Blocks(Blocks) {
2370- reset ();
2371- }
2372-
2373- void reset () {
2374- Fail = false ;
2375- Insts.clear ();
2376- for (auto *BB : Blocks) {
2377- Instruction *Inst = BB->getTerminator ();
2378- for (Inst = Inst->getPrevNode (); Inst && isa<DbgInfoIntrinsic>(Inst);)
2379- Inst = Inst->getPrevNode ();
2380- if (!Inst) {
2381- // Block wasn't big enough.
2382- Fail = true ;
2383- return ;
2384- }
2385- Insts.push_back (Inst);
2386- }
2387- }
2388-
2389- bool isValid () const {
2390- return !Fail;
2391- }
2392-
2393- void operator --() {
2394- if (Fail)
2395- return ;
2396- for (auto *&Inst : Insts) {
2397- for (Inst = Inst->getPrevNode (); Inst && isa<DbgInfoIntrinsic>(Inst);)
2398- Inst = Inst->getPrevNode ();
2399- // Already at beginning of block.
2400- if (!Inst) {
2401- Fail = true ;
2402- return ;
2403- }
2404- }
2405- }
2406-
2407- void operator ++() {
2408- if (Fail)
2409- return ;
2410- for (auto *&Inst : Insts) {
2411- for (Inst = Inst->getNextNode (); Inst && isa<DbgInfoIntrinsic>(Inst);)
2412- Inst = Inst->getNextNode ();
2413- // Already at end of block.
2414- if (!Inst) {
2415- Fail = true ;
2416- return ;
2417- }
2418- }
2419- }
2420-
2421- ArrayRef<Instruction*> operator * () const {
2422- return Insts;
2423- }
2424- };
2425-
2426- } // end anonymous namespace
2427-
24282442// / Check whether BB's predecessors end with unconditional branches. If it is
24292443// / true, sink any common code from the predecessors to BB.
24302444static bool sinkCommonCodeFromPredecessors (BasicBlock *BB,
0 commit comments