@@ -1580,6 +1580,56 @@ void GVNPass::eliminatePartiallyRedundantLoad(
15801580 });
15811581}
15821582
1583+ // / Merges splited critical edge blocks that originate from the same
1584+ // / predecessor.
1585+ void GVNPass::mergeSplitedCriticalEdges (
1586+ SmallVectorImpl<BasicBlock *> &SplitedCriticalEdges,
1587+ MapVector<BasicBlock *, Value *> &PredLoad) {
1588+ if (SplitedCriticalEdges.size () <= 1 )
1589+ return ;
1590+
1591+ MapVector<BasicBlock *, SmallVector<BasicBlock *, 4 >> PredEdgeMap;
1592+ // Group the splited edge blocks based on their predecessor (Pred).
1593+ // Example: Pred1 -> {Edge1, Edge2}, Pred2 -> {Edge3}
1594+ for (BasicBlock *Edge : SplitedCriticalEdges) {
1595+ // A splited edge block must have exactly one predecessor.
1596+ assert (Edge->getSinglePredecessor () &&
1597+ " Splited edge block should have a single predecessor" );
1598+ auto *Pred = Edge->getSinglePredecessor ();
1599+ PredEdgeMap[Pred].push_back (Edge);
1600+ }
1601+
1602+ // Iterate over the grouped edge blocks to perform the merge.
1603+ for (auto &PredEdgeEl : PredEdgeMap) {
1604+ BasicBlock *Pred = PredEdgeEl.first ;
1605+ SmallVector<BasicBlock *, 4 > &BBs = PredEdgeEl.second ;
1606+ if (BBs.size () <= 1 )
1607+ continue ;
1608+
1609+ // Select the first edge block as the representative block that will
1610+ // remain after merging.
1611+ BasicBlock *MergedBlock = BBs[0 ];
1612+ for (BasicBlock *BB : llvm::drop_begin (BBs)) {
1613+ // Redirect all jumps to this block (BB) from its predecessor (which
1614+ // should only be Pred) to the MergedBlock.
1615+ Instruction *PredTI = Pred->getTerminator ();
1616+ for (unsigned I = 0 , E = PredTI->getNumSuccessors (); I < E; ++I) {
1617+ if (PredTI->getSuccessor (I) == BB) {
1618+ PredTI->setSuccessor (I, MergedBlock);
1619+ LLVM_DEBUG (dbgs () << " Redirected successor in " << Pred->getName ()
1620+ << " from " << BB->getName () << " to "
1621+ << MergedBlock->getName () << " \n " );
1622+ }
1623+ }
1624+ // Remove the block from the SplitedCriticalEdges list as well
1625+ auto it = find (SplitedCriticalEdges, BB);
1626+ SplitedCriticalEdges.erase (it);
1627+ DeleteDeadBlock (BB);
1628+ }
1629+ PredLoad[MergedBlock] = nullptr ;
1630+ }
1631+ }
1632+
15831633bool GVNPass::PerformLoadPRE (LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
15841634 UnavailBlkVect &UnavailableBlocks) {
15851635 // Okay, we have *some* definitions of the value. This means that the value
@@ -1703,9 +1753,10 @@ bool GVNPass::PerformLoadPRE(LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
17031753 }
17041754
17051755 // Decide whether PRE is profitable for this load.
1706- unsigned NumInsertPreds = PredLoads.size () + CriticalEdgePredSplit. size () ;
1756+ unsigned NumInsertPreds = PredLoads.size ();
17071757 unsigned NumUnavailablePreds = NumInsertPreds +
1708- CriticalEdgePredAndLoad.size ();
1758+ CriticalEdgePredAndLoad.size () +
1759+ CriticalEdgePredSplit.size ();
17091760 assert (NumUnavailablePreds != 0 &&
17101761 " Fully available value should already be eliminated!" );
17111762 (void )NumUnavailablePreds;
@@ -1734,14 +1785,36 @@ bool GVNPass::PerformLoadPRE(LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
17341785 return false ;
17351786 }
17361787
1737- // Split critical edges, and update the unavailable predecessors accordingly.
1788+ // Verify that all successors of the predecessor (Pred) are included in the
1789+ // current group (BBs). If Pred has a successor that is not in BBs, merging
1790+ // these blocks could make the Pred -> (block not in BBs) edge critical again.
1791+ // If there is at least one CriticalEdgePredSplit that cannot be merged, it
1792+ // must be rejected because it would require inserting new loads into multiple
1793+ // predecessors.
1794+ if (CriticalEdgePredSplit.size () > 1 - PredLoads.size ()) {
1795+ for (BasicBlock *OrigPred : CriticalEdgePredSplit) {
1796+ auto *PredTI = OrigPred->getTerminator ();
1797+ for (unsigned i = 0 , e = PredTI->getNumSuccessors (); i < e - 1 ; ++i)
1798+ if (PredTI->getSuccessor (i) != PredTI->getSuccessor (i + 1 ))
1799+ return false ;
1800+ }
1801+ }
1802+
1803+ // The edge from Pred to LoadBB is a critical edge will be splitted.
1804+ SmallVector<BasicBlock *, 4 > SplitedCriticalEdges;
17381805 for (BasicBlock *OrigPred : CriticalEdgePredSplit) {
17391806 BasicBlock *NewPred = splitCriticalEdges (OrigPred, LoadBB);
1807+ SplitedCriticalEdges.push_back (NewPred);
17401808 assert (!PredLoads.count (OrigPred) && " Split edges shouldn't be in map!" );
1741- PredLoads[NewPred] = nullptr ;
17421809 LLVM_DEBUG (dbgs () << " Split critical edge " << OrigPred->getName () << " ->"
17431810 << LoadBB->getName () << ' \n ' );
17441811 }
1812+ // Attempts to merge the blocks created by splitting the CriticalEdges. The
1813+ // merged blocks are removed from SplitedCriticalEdges.
1814+ mergeSplitedCriticalEdges (SplitedCriticalEdges, PredLoads);
1815+ // Add the unmerged blocks separately.
1816+ for (auto BB : SplitedCriticalEdges)
1817+ PredLoads[BB] = nullptr ;
17451818
17461819 for (auto &CEP : CriticalEdgePredAndLoad)
17471820 PredLoads[CEP.first ] = nullptr ;
0 commit comments