[llvm] r324916 - [LICM] update BlockColors after splitting predecessors
Hans Wennborg via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 19 07:22:19 PST 2018
Merged to 6.0 in r325507.
On Mon, Feb 12, 2018 at 6:56 PM, Jun Bum Lim via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: junbuml
> Date: Mon Feb 12 09:56:55 2018
> New Revision: 324916
>
> URL: http://llvm.org/viewvc/llvm-project?rev=324916&view=rev
> Log:
> [LICM] update BlockColors after splitting predecessors
>
> Update BlockColors after splitting predecessors. Do not allow splitting
> EHPad for sinking when the BlockColors is not empty, so we can
> simply assign predecessor's color to the new block.
>
> Fixes PR36184
>
> Modified:
> llvm/trunk/lib/Transforms/Scalar/LICM.cpp
> llvm/trunk/test/Transforms/LICM/sinking.ll
>
> Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=324916&r1=324915&r2=324916&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Mon Feb 12 09:56:55 2018
> @@ -97,7 +97,7 @@ static bool hoist(Instruction &I, const
> const LoopSafetyInfo *SafetyInfo,
> OptimizationRemarkEmitter *ORE);
> static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT,
> - const Loop *CurLoop, const LoopSafetyInfo *SafetyInfo,
> + const Loop *CurLoop, LoopSafetyInfo *SafetyInfo,
> OptimizationRemarkEmitter *ORE, bool FreeInLoop);
> static bool isSafeToExecuteUnconditionally(Instruction &Inst,
> const DominatorTree *DT,
> @@ -855,10 +855,16 @@ static Instruction *sinkThroughTrivially
> return New;
> }
>
> -static bool canSplitPredecessors(PHINode *PN) {
> +static bool canSplitPredecessors(PHINode *PN, LoopSafetyInfo *SafetyInfo) {
> BasicBlock *BB = PN->getParent();
> if (!BB->canSplitPredecessors())
> return false;
> + // It's not impossible to split EHPad blocks, but if BlockColors already exist
> + // it require updating BlockColors for all offspring blocks accordingly. By
> + // skipping such corner case, we can make updating BlockColors after splitting
> + // predecessor fairly simple.
> + if (!SafetyInfo->BlockColors.empty() && BB->getFirstNonPHI()->isEHPad())
> + return false;
> for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
> BasicBlock *BBPred = *PI;
> if (isa<IndirectBrInst>(BBPred->getTerminator()))
> @@ -868,7 +874,8 @@ static bool canSplitPredecessors(PHINode
> }
>
> static void splitPredecessorsOfLoopExit(PHINode *PN, DominatorTree *DT,
> - LoopInfo *LI, const Loop *CurLoop) {
> + LoopInfo *LI, const Loop *CurLoop,
> + LoopSafetyInfo *SafetyInfo) {
> #ifndef NDEBUG
> SmallVector<BasicBlock *, 32> ExitBlocks;
> CurLoop->getUniqueExitBlocks(ExitBlocks);
> @@ -910,13 +917,21 @@ static void splitPredecessorsOfLoopExit(
> // LE:
> // %p = phi [%p1, %LE.split], [%p2, %LE.split2]
> //
> + auto &BlockColors = SafetyInfo->BlockColors;
> SmallSetVector<BasicBlock *, 8> PredBBs(pred_begin(ExitBB), pred_end(ExitBB));
> while (!PredBBs.empty()) {
> BasicBlock *PredBB = *PredBBs.begin();
> assert(CurLoop->contains(PredBB) &&
> "Expect all predecessors are in the loop");
> - if (PN->getBasicBlockIndex(PredBB) >= 0)
> - SplitBlockPredecessors(ExitBB, PredBB, ".split.loop.exit", DT, LI, true);
> + if (PN->getBasicBlockIndex(PredBB) >= 0) {
> + BasicBlock *NewPred = SplitBlockPredecessors(
> + ExitBB, PredBB, ".split.loop.exit", DT, LI, true);
> + // Since we do not allow splitting EH-block with BlockColors in
> + // canSplitPredecessors(), we can simply assign predecessor's color to
> + // the new block.
> + if (!BlockColors.empty())
> + BlockColors[NewPred] = BlockColors[PredBB];
> + }
> PredBBs.remove(PredBB);
> }
> }
> @@ -927,7 +942,7 @@ static void splitPredecessorsOfLoopExit(
> /// position, and may either delete it or move it to outside of the loop.
> ///
> static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT,
> - const Loop *CurLoop, const LoopSafetyInfo *SafetyInfo,
> + const Loop *CurLoop, LoopSafetyInfo *SafetyInfo,
> OptimizationRemarkEmitter *ORE, bool FreeInLoop) {
> DEBUG(dbgs() << "LICM sinking instruction: " << I << "\n");
> ORE->emit([&]() {
> @@ -975,12 +990,12 @@ static bool sink(Instruction &I, LoopInf
> if (isTriviallyReplacablePHI(*PN, I))
> continue;
>
> - if (!canSplitPredecessors(PN))
> + if (!canSplitPredecessors(PN, SafetyInfo))
> return Changed;
>
> // Split predecessors of the PHI so that we can make users trivially
> // replacable.
> - splitPredecessorsOfLoopExit(PN, DT, LI, CurLoop);
> + splitPredecessorsOfLoopExit(PN, DT, LI, CurLoop, SafetyInfo);
>
> // Should rebuild the iterators, as they may be invalidated by
> // splitPredecessorsOfLoopExit().
>
> Modified: llvm/trunk/test/Transforms/LICM/sinking.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/sinking.ll?rev=324916&r1=324915&r2=324916&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/LICM/sinking.ll (original)
> +++ llvm/trunk/test/Transforms/LICM/sinking.ll Mon Feb 12 09:56:55 2018
> @@ -670,6 +670,67 @@ try.cont:
> ret void
> }
>
> +; The sinkable call should be sunk into an exit block split. After splitting
> +; the exit block, BlockColor for new blocks should be added properly so
> +; that we should be able to access valid ColorVector.
> +;
> +; CHECK-LABEL:@test21_pr36184
> +; CHECK-LABEL: Loop
> +; CHECK-NOT: %sinkableCall
> +; CHECK-LABEL:Out.split.loop.exit
> +; CHECK: %sinkableCall
> +define i32 @test21_pr36184(i8* %P) personality i32 (...)* @__CxxFrameHandler3 {
> +entry:
> + br label %loop.ph
> +
> +loop.ph:
> + br label %Loop
> +
> +Loop:
> + %sinkableCall = call i32 @strlen( i8* %P ) readonly
> + br i1 undef, label %ContLoop, label %Out
> +
> +ContLoop:
> + br i1 undef, label %Loop, label %Out
> +
> +Out:
> + %idx = phi i32 [ %sinkableCall, %Loop ], [0, %ContLoop ]
> + ret i32 %idx
> +}
> +
> +; We do not support splitting a landingpad block if BlockColors is not empty.
> +; CHECK-LABEL: @test22
> +; CHECK-LABEL: while.body2
> +; CHECK-LABEL: %mul
> +; CHECK-NOT: lpadBB.split{{.*}}
> +define void @test22(i1 %b, i32 %v1, i32 %v2) personality i32 (...)* @__CxxFrameHandler3 {
> +entry:
> + br label %while.cond
> +while.cond:
> + br i1 %b, label %try.cont, label %while.body
> +
> +while.body:
> + invoke void @may_throw()
> + to label %while.body2 unwind label %lpadBB
> +
> +while.body2:
> + %v = call i32 @getv()
> + %mul = mul i32 %v, %v2
> + invoke void @may_throw2()
> + to label %while.cond unwind label %lpadBB
> +lpadBB:
> + %.lcssa1 = phi i32 [ 0, %while.body ], [ %mul, %while.body2 ]
> + landingpad { i8*, i32 }
> + catch i8* null
> + br label %lpadBBSucc1
> +
> +lpadBBSucc1:
> + ret void
> +
> +try.cont:
> + ret void
> +}
> +
> declare void @may_throw()
> declare void @may_throw2()
> declare i32 @__CxxFrameHandler3(...)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list