-//===---------------------------------------------------------------------===//
-// rewriteFirstIterationLoopExitValues: Rewrite loop exit values if we know
-// they will exit at the first iteration.
-//===---------------------------------------------------------------------===//
-
-/// Check to see if this loop has loop invariant conditions which lead to loop
-/// exits. If so, we know that if the exit path is taken, it is at the first
-/// loop iteration. This lets us predict exit values of PHI nodes that live in
-/// loop header.
-void IndVarSimplify::rewriteFirstIterationLoopExitValues(Loop *L) {
- // Verify the input to the pass is already in LCSSA form.
- assert(L->isLCSSAForm(*DT));
-
- SmallVector<BasicBlock *, 8> ExitBlocks;
- L->getUniqueExitBlocks(ExitBlocks);
-
- for (auto *ExitBB : ExitBlocks) {
- BasicBlock::iterator begin = ExitBB->begin();
- // If there are no more PHI nodes in this exit block, then no more
- // values defined inside the loop are used on this path.
- while (auto *PN = dyn_cast<PHINode>(begin++)) {
- for (unsigned IncomingValIdx = 0, e = PN->getNumIncomingValues();
- IncomingValIdx != e; ++IncomingValIdx) {
- auto *IncomingBB = PN->getIncomingBlock(IncomingValIdx);
- if (!L->contains(IncomingBB))
- continue;
-
- // Get condition that leads to the exit path.
- auto *TermInst = IncomingBB->getTerminator();
-
- Value *Cond = nullptr;
- if (auto *BI = dyn_cast<BranchInst>(TermInst)) {
- // Must be a conditional branch, otherwise the block
- // should not be in the loop.
- Cond = BI->getCondition();
- } else if (auto *SI = dyn_cast<SwitchInst>(TermInst))
- Cond = SI->getCondition();
-
- // All non-instructions are loop-invariant.
- if (isa<Instruction>(Cond) && !L->isLoopInvariant(Cond))
- continue;
-
- auto *ExitVal =
- dyn_cast<PHINode>(PN->getIncomingValue(IncomingValIdx));
-
- // Only deal with PHIs.
- if (!ExitVal)
- continue;
-
- // If ExitVal is a PHI on the loop header, then we know its
- // value along this exit because the exit can only be taken
- // on the first iteration.
- auto *LoopPreheader = L->getLoopPreheader();
- assert(LoopPreheader && "Invalid loop");
- if (ExitVal->getBasicBlockIndex(LoopPreheader) != -1) {
- assert(ExitVal->getParent() == L->getHeader() &&
- "ExitVal must be in loop header");
- PN->setIncomingValue(IncomingValIdx,
- ExitVal->getIncomingValueForBlock(LoopPreheader));
- }
- }
- }
- }
-}
-