@@ -1646,6 +1646,56 @@ void GVNPass::eliminatePartiallyRedundantLoad(
16461646 salvageAndRemoveInstruction (Load);
16471647}
16481648
1649+ // / Merges splited critical edge blocks that originate from the same
1650+ // / predecessor.
1651+ void GVNPass::mergeSplitedCriticalEdges (
1652+ SmallVectorImpl<BasicBlock *> &SplitedCriticalEdges,
1653+ MapVector<BasicBlock *, Value *> &PredLoad) {
1654+ if (SplitedCriticalEdges.size () <= 1 )
1655+ return ;
1656+
1657+ MapVector<BasicBlock *, SmallVector<BasicBlock *, 4 >> PredEdgeMap;
1658+ // Group the splited edge blocks based on their predecessor (Pred).
1659+ // Example: Pred1 -> {Edge1, Edge2}, Pred2 -> {Edge3}
1660+ for (BasicBlock *Edge : SplitedCriticalEdges) {
1661+ // A splited edge block must have exactly one predecessor.
1662+ assert (Edge->getSinglePredecessor () &&
1663+ " Splited edge block should have a single predecessor" );
1664+ auto *Pred = Edge->getSinglePredecessor ();
1665+ PredEdgeMap[Pred].push_back (Edge);
1666+ }
1667+
1668+ // Iterate over the grouped edge blocks to perform the merge.
1669+ for (auto &PredEdgeEl : PredEdgeMap) {
1670+ BasicBlock *Pred = PredEdgeEl.first ;
1671+ SmallVector<BasicBlock *, 4 > &BBs = PredEdgeEl.second ;
1672+ if (BBs.size () <= 1 )
1673+ continue ;
1674+
1675+ // Select the first edge block as the representative block that will
1676+ // remain after merging.
1677+ BasicBlock *MergedBlock = BBs[0 ];
1678+ for (BasicBlock *BB : llvm::drop_begin (BBs)) {
1679+ // Redirect all jumps to this block (BB) from its predecessor (which
1680+ // should only be Pred) to the MergedBlock.
1681+ Instruction *PredTI = Pred->getTerminator ();
1682+ for (unsigned I = 0 , E = PredTI->getNumSuccessors (); I < E; ++I) {
1683+ if (PredTI->getSuccessor (I) == BB) {
1684+ PredTI->setSuccessor (I, MergedBlock);
1685+ LLVM_DEBUG (dbgs () << " Redirected successor in " << Pred->getName ()
1686+ << " from " << BB->getName () << " to "
1687+ << MergedBlock->getName () << " \n " );
1688+ }
1689+ }
1690+ // Remove the block from the SplitedCriticalEdges list as well
1691+ auto it = find (SplitedCriticalEdges, BB);
1692+ SplitedCriticalEdges.erase (it);
1693+ DeleteDeadBlock (BB);
1694+ }
1695+ PredLoad[MergedBlock] = nullptr ;
1696+ }
1697+ }
1698+
16491699bool GVNPass::PerformLoadPRE (LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
16501700 UnavailBlkVect &UnavailableBlocks) {
16511701 // Okay, we have *some* definitions of the value. This means that the value
@@ -1769,9 +1819,10 @@ bool GVNPass::PerformLoadPRE(LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
17691819 }
17701820
17711821 // Decide whether PRE is profitable for this load.
1772- unsigned NumInsertPreds = PredLoads.size () + CriticalEdgePredSplit. size () ;
1822+ unsigned NumInsertPreds = PredLoads.size ();
17731823 unsigned NumUnavailablePreds = NumInsertPreds +
1774- CriticalEdgePredAndLoad.size ();
1824+ CriticalEdgePredAndLoad.size () +
1825+ CriticalEdgePredSplit.size ();
17751826 assert (NumUnavailablePreds != 0 &&
17761827 " Fully available value should already be eliminated!" );
17771828 (void )NumUnavailablePreds;
@@ -1800,14 +1851,36 @@ bool GVNPass::PerformLoadPRE(LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
18001851 return false ;
18011852 }
18021853
1803- // Split critical edges, and update the unavailable predecessors accordingly.
1854+ // Verify that all successors of the predecessor (Pred) are included in the
1855+ // current group (BBs). If Pred has a successor that is not in BBs, merging
1856+ // these blocks could make the Pred -> (block not in BBs) edge critical again.
1857+ // If there is at least one CriticalEdgePredSplit that cannot be merged, it
1858+ // must be rejected because it would require inserting new loads into multiple
1859+ // predecessors.
1860+ if (CriticalEdgePredSplit.size () > 1 - PredLoads.size ()) {
1861+ for (BasicBlock *OrigPred : CriticalEdgePredSplit) {
1862+ auto *PredTI = OrigPred->getTerminator ();
1863+ for (unsigned i = 0 , e = PredTI->getNumSuccessors (); i < e - 1 ; ++i)
1864+ if (PredTI->getSuccessor (i) != PredTI->getSuccessor (i + 1 ))
1865+ return false ;
1866+ }
1867+ }
1868+
1869+ // The edge from Pred to LoadBB is a critical edge will be splitted.
1870+ SmallVector<BasicBlock *, 4 > SplitedCriticalEdges;
18041871 for (BasicBlock *OrigPred : CriticalEdgePredSplit) {
18051872 BasicBlock *NewPred = splitCriticalEdges (OrigPred, LoadBB);
1873+ SplitedCriticalEdges.push_back (NewPred);
18061874 assert (!PredLoads.count (OrigPred) && " Split edges shouldn't be in map!" );
1807- PredLoads[NewPred] = nullptr ;
18081875 LLVM_DEBUG (dbgs () << " Split critical edge " << OrigPred->getName () << " ->"
18091876 << LoadBB->getName () << ' \n ' );
18101877 }
1878+ // Attempts to merge the blocks created by splitting the CriticalEdges. The
1879+ // merged blocks are removed from SplitedCriticalEdges.
1880+ mergeSplitedCriticalEdges (SplitedCriticalEdges, PredLoads);
1881+ // Add the unmerged blocks separately.
1882+ for (auto BB : SplitedCriticalEdges)
1883+ PredLoads[BB] = nullptr ;
18111884
18121885 for (auto &CEP : CriticalEdgePredAndLoad)
18131886 PredLoads[CEP.first ] = nullptr ;
0 commit comments