void IndVarSimplify::EliminateIVComparisons() { // Look for ICmp users. for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E; ++I) { IVStrideUse &UI = *I; ICmpInst *ICmp = dyn_cast<ICmpInst>(UI.getUser()); if (!ICmp) continue; bool Swapped = UI.getOperandValToReplace() == ICmp->getOperand(1); ICmpInst::Predicate Pred = ICmp->getPredicate(); if (Swapped) Pred = ICmpInst::getSwappedPredicate(Pred); // Get the SCEVs for the ICmp operands. const SCEV *S = IU->getReplacementExpr(UI); const SCEV *X = SE->getSCEV(ICmp->getOperand(!Swapped)); // Simplify unnecessary loops away. const Loop *ICmpLoop = LI->getLoopFor(ICmp->getParent()); S = SE->getSCEVAtScope(S, ICmpLoop); X = SE->getSCEVAtScope(X, ICmpLoop); // If the condition is always true or always false, replace it with // a constant value. if (SE->isKnownPredicate(Pred, S, X)) ICmp->replaceAllUsesWith(ConstantInt::getTrue(ICmp->getContext())); else if (SE->isKnownPredicate(ICmpInst::getInversePredicate(Pred), S, X)) ICmp->replaceAllUsesWith(ConstantInt::getFalse(ICmp->getContext())); else continue; DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n'); DeadInsts.push_back(ICmp); } }
void IndVarSimplify::EliminateIVComparisons() { SmallVector<WeakVH, 16> DeadInsts; // Look for ICmp users. for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E; ++I) { IVStrideUse &UI = *I; ICmpInst *ICmp = dyn_cast<ICmpInst>(UI.getUser()); if (!ICmp) continue; bool Swapped = UI.getOperandValToReplace() == ICmp->getOperand(1); ICmpInst::Predicate Pred = ICmp->getPredicate(); if (Swapped) Pred = ICmpInst::getSwappedPredicate(Pred); // Get the SCEVs for the ICmp operands. const SCEV *S = IU->getReplacementExpr(UI); const SCEV *X = SE->getSCEV(ICmp->getOperand(!Swapped)); // Simplify unnecessary loops away. const Loop *ICmpLoop = LI->getLoopFor(ICmp->getParent()); S = SE->getSCEVAtScope(S, ICmpLoop); X = SE->getSCEVAtScope(X, ICmpLoop); // If the condition is always true or always false, replace it with // a constant value. if (SE->isKnownPredicate(Pred, S, X)) ICmp->replaceAllUsesWith(ConstantInt::getTrue(ICmp->getContext())); else if (SE->isKnownPredicate(ICmpInst::getInversePredicate(Pred), S, X)) ICmp->replaceAllUsesWith(ConstantInt::getFalse(ICmp->getContext())); else continue; DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n'); DeadInsts.push_back(ICmp); } // Now that we're done iterating through lists, clean up any instructions // which are now dead. while (!DeadInsts.empty()) if (Instruction *Inst = dyn_cast_or_null<Instruction>(&*DeadInsts.pop_back_val())) RecursivelyDeleteTriviallyDeadInstructions(Inst); }
/// restrictLoopBound - Op dominates loop body. Op compares an IV based value /// with a loop invariant value. Update loop's lower and upper bound based on /// the loop invariant value. bool LoopIndexSplit::restrictLoopBound(ICmpInst &Op) { bool Sign = Op.isSigned(); Instruction *PHTerm = L->getLoopPreheader()->getTerminator(); if (IVisGT(*ExitCondition) || IVisGE(*ExitCondition)) { BranchInst *EBR = cast<BranchInst>(ExitCondition->getParent()->getTerminator()); ExitCondition->setPredicate(ExitCondition->getInversePredicate()); BasicBlock *T = EBR->getSuccessor(0); EBR->setSuccessor(0, EBR->getSuccessor(1)); EBR->setSuccessor(1, T); } LLVMContext &Context = Op.getContext(); // New upper and lower bounds. Value *NLB = NULL; Value *NUB = NULL; if (Value *V = IVisLT(Op)) { // Restrict upper bound. if (IVisLE(*ExitCondition)) V = getMinusOne(V, Sign, PHTerm, Context); NUB = getMin(V, IVExitValue, Sign, PHTerm); } else if (Value *V = IVisLE(Op)) { // Restrict upper bound. if (IVisLT(*ExitCondition)) V = getPlusOne(V, Sign, PHTerm, Context); NUB = getMin(V, IVExitValue, Sign, PHTerm); } else if (Value *V = IVisGT(Op)) { // Restrict lower bound. V = getPlusOne(V, Sign, PHTerm, Context); NLB = getMax(V, IVStartValue, Sign, PHTerm); } else if (Value *V = IVisGE(Op)) // Restrict lower bound. NLB = getMax(V, IVStartValue, Sign, PHTerm); if (!NLB && !NUB) return false; if (NLB) { unsigned i = IndVar->getBasicBlockIndex(L->getLoopPreheader()); IndVar->setIncomingValue(i, NLB); } if (NUB) { unsigned i = (ExitCondition->getOperand(0) != IVExitValue); ExitCondition->setOperand(i, NUB); } return true; }