@@ -97,7 +97,7 @@ static bool hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
9797 const LoopSafetyInfo *SafetyInfo,
9898 OptimizationRemarkEmitter *ORE);
9999static bool sink (Instruction &I, LoopInfo *LI, DominatorTree *DT,
100- const Loop *CurLoop, const LoopSafetyInfo *SafetyInfo,
100+ const Loop *CurLoop, LoopSafetyInfo *SafetyInfo,
101101 OptimizationRemarkEmitter *ORE, bool FreeInLoop);
102102static bool isSafeToExecuteUnconditionally (Instruction &Inst,
103103 const DominatorTree *DT,
@@ -855,10 +855,16 @@ static Instruction *sinkThroughTriviallyReplacablePHI(
855855 return New;
856856}
857857
858- static bool canSplitPredecessors (PHINode *PN) {
858+ static bool canSplitPredecessors (PHINode *PN, LoopSafetyInfo *SafetyInfo ) {
859859 BasicBlock *BB = PN->getParent ();
860860 if (!BB->canSplitPredecessors ())
861861 return false ;
862+ // FIXME: it's not impossible to split LandingPad blocks, but if BlockColors
863+ // already exist it require updating BlockColors for all offspring blocks
864+ // accordingly. By skipping such corner case, we can make updating BlockColors
865+ // after splitting predecessor fairly simple.
866+ if (!SafetyInfo->BlockColors .empty () && BB->getFirstNonPHI ()->isEHPad ())
867+ return false ;
862868 for (pred_iterator PI = pred_begin (BB), E = pred_end (BB); PI != E; ++PI) {
863869 BasicBlock *BBPred = *PI;
864870 if (isa<IndirectBrInst>(BBPred->getTerminator ()))
@@ -868,7 +874,8 @@ static bool canSplitPredecessors(PHINode *PN) {
868874}
869875
870876static void splitPredecessorsOfLoopExit (PHINode *PN, DominatorTree *DT,
871- LoopInfo *LI, const Loop *CurLoop) {
877+ LoopInfo *LI, const Loop *CurLoop,
878+ LoopSafetyInfo *SafetyInfo) {
872879#ifndef NDEBUG
873880 SmallVector<BasicBlock *, 32 > ExitBlocks;
874881 CurLoop->getUniqueExitBlocks (ExitBlocks);
@@ -910,13 +917,21 @@ static void splitPredecessorsOfLoopExit(PHINode *PN, DominatorTree *DT,
910917 // LE:
911918 // %p = phi [%p1, %LE.split], [%p2, %LE.split2]
912919 //
920+ auto &BlockColors = SafetyInfo->BlockColors ;
913921 SmallSetVector<BasicBlock *, 8 > PredBBs (pred_begin (ExitBB), pred_end (ExitBB));
914922 while (!PredBBs.empty ()) {
915923 BasicBlock *PredBB = *PredBBs.begin ();
916924 assert (CurLoop->contains (PredBB) &&
917925 " Expect all predecessors are in the loop" );
918- if (PN->getBasicBlockIndex (PredBB) >= 0 )
919- SplitBlockPredecessors (ExitBB, PredBB, " .split.loop.exit" , DT, LI, true );
926+ if (PN->getBasicBlockIndex (PredBB) >= 0 ) {
927+ BasicBlock *NewPred = SplitBlockPredecessors (
928+ ExitBB, PredBB, " .split.loop.exit" , DT, LI, true );
929+ // Since we do not allow splitting EH-block with BlockColors in
930+ // canSplitPredecessors(), we can simply assign predecessor's color to
931+ // the new block.
932+ if (!BlockColors.empty ())
933+ BlockColors[NewPred] = BlockColors[PredBB];
934+ }
920935 PredBBs.remove (PredBB);
921936 }
922937}
@@ -927,7 +942,7 @@ static void splitPredecessorsOfLoopExit(PHINode *PN, DominatorTree *DT,
927942// / position, and may either delete it or move it to outside of the loop.
928943// /
929944static bool sink (Instruction &I, LoopInfo *LI, DominatorTree *DT,
930- const Loop *CurLoop, const LoopSafetyInfo *SafetyInfo,
945+ const Loop *CurLoop, LoopSafetyInfo *SafetyInfo,
931946 OptimizationRemarkEmitter *ORE, bool FreeInLoop) {
932947 DEBUG (dbgs () << " LICM sinking instruction: " << I << " \n " );
933948 ORE->emit ([&]() {
@@ -975,12 +990,12 @@ static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT,
975990 if (isTriviallyReplacablePHI (*PN, I))
976991 continue ;
977992
978- if (!canSplitPredecessors (PN))
993+ if (!canSplitPredecessors (PN, SafetyInfo ))
979994 return Changed;
980995
981996 // Split predecessors of the PHI so that we can make users trivially
982997 // replacable.
983- splitPredecessorsOfLoopExit (PN, DT, LI, CurLoop);
998+ splitPredecessorsOfLoopExit (PN, DT, LI, CurLoop, SafetyInfo );
984999
9851000 // Should rebuild the iterators, as they may be invalidated by
9861001 // splitPredecessorsOfLoopExit().
0 commit comments