Skip to content

Commit

Permalink
[LCSSA][LICM] When LCSSA inserts a PHI node into the unwind destinati…
Browse files Browse the repository at this point in the history
…on of a detach within a loop, ensure that that PHI node inherits the correct value from the detached.rethrow predecessor. Update LICM to avoid splitting the detach and detached.rethrow predecessors of the unwind destination of a detach in a loop.
  • Loading branch information
neboat committed Feb 17, 2021
1 parent d71e4c7 commit 3baa4ce
Show file tree
Hide file tree
Showing 3 changed files with 2,793 additions and 3 deletions.
14 changes: 13 additions & 1 deletion llvm/lib/Transforms/Scalar/LICM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1516,6 +1516,11 @@ static void splitPredecessorsOfLoopExit(PHINode *PN, DominatorTree *DT,
CurLoop->getUniqueExitBlocks(ExitBlocks);
SmallPtrSet<BasicBlock *, 32> ExitBlockSet(ExitBlocks.begin(),
ExitBlocks.end());

// Get the Tapir task exits for the current loop, in order to check for users
// contained in those task exits.
SmallPtrSet<BasicBlock *, 4> CurLoopTaskExits;
CurLoop->getTaskExits(CurLoopTaskExits);
#endif
BasicBlock *ExitBB = PN->getParent();
assert(ExitBlockSet.count(ExitBB) && "Expect the PHI is in an exit block.");
Expand Down Expand Up @@ -1556,8 +1561,15 @@ static void splitPredecessorsOfLoopExit(PHINode *PN, DominatorTree *DT,
SmallSetVector<BasicBlock *, 8> PredBBs(pred_begin(ExitBB), pred_end(ExitBB));
while (!PredBBs.empty()) {
BasicBlock *PredBB = *PredBBs.begin();
assert(CurLoop->contains(PredBB) &&
assert((CurLoop->contains(PredBB) || CurLoopTaskExits.count(PredBB)) &&
"Expect all predecessors are in the loop");
// Don't split loop-exit predecessor blocks terminated by a detach or
// detached.rethrow.
if (isa<DetachInst>(PredBB->getTerminator()) ||
isDetachedRethrow(PredBB->getTerminator())) {
PredBBs.remove(PredBB);
continue;
}
if (PN->getBasicBlockIndex(PredBB) >= 0) {
BasicBlock *NewPred = SplitBlockPredecessors(
ExitBB, PredBB, ".split.loop.exit", DT, LI, MSSAU, true);
Expand Down
11 changes: 9 additions & 2 deletions llvm/lib/Transforms/Utils/LCSSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
// instructions within the same loops, computing the exit blocks is
// expensive, and we're not mutating the loop structure.
SmallDenseMap<Loop*, SmallVector<BasicBlock *,1>> LoopExitBlocks;
// Similarly, cache the Loop TaskExits across this loop.
SmallDenseMap<Loop*, SmallPtrSet<BasicBlock *,1>> LoopTaskExits;

while (!Worklist.empty()) {
UsesToRewrite.clear();
Expand All @@ -104,13 +106,18 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
if (ExitBlocks.empty())
continue;

if (!LoopTaskExits.count(L))
L->getTaskExits(LoopTaskExits[L]);
assert(LoopTaskExits.count(L));
const SmallPtrSetImpl<BasicBlock *> &TaskExits = LoopTaskExits[L];

for (Use &U : I->uses()) {
Instruction *User = cast<Instruction>(U.getUser());
BasicBlock *UserBB = User->getParent();
if (auto *PN = dyn_cast<PHINode>(User))
UserBB = PN->getIncomingBlock(U);

if (InstBB != UserBB && !L->contains(UserBB))
if (InstBB != UserBB && !L->contains(UserBB) && !TaskExits.count(UserBB))
UsesToRewrite.push_back(&U);
}

Expand Down Expand Up @@ -163,7 +170,7 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
// If the exit block has a predecessor not within the loop, arrange for
// the incoming value use corresponding to that predecessor to be
// rewritten in terms of a different LCSSA PHI.
if (!L->contains(Pred))
if (!L->contains(Pred) && !TaskExits.count(Pred))
UsesToRewrite.push_back(
&PN->getOperandUse(PN->getOperandNumForIncomingValue(
PN->getNumIncomingValues() - 1)));
Expand Down
Loading

0 comments on commit 3baa4ce

Please sign in to comment.