From 90b71c2f3dd4e75690caba8697e956ad9723d746 Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Tue, 31 Oct 2017 22:56:16 +0000 Subject: [PATCH] [SimplifyIndVar] Inline makIVComparisonInvariant to eleminate code duplication [NFC] This formulation might be slightly slower since I eagerly compute the cheap replacements. If anyone sees this having a compile time impact, let me know and I'll use lazy population instead. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317048 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/SimplifyIndVar.cpp | 80 +++++++++---------------- 1 file changed, 29 insertions(+), 51 deletions(-) diff --git a/lib/Transforms/Utils/SimplifyIndVar.cpp b/lib/Transforms/Utils/SimplifyIndVar.cpp index 43c209bf1aa..66e63351822 100644 --- a/lib/Transforms/Utils/SimplifyIndVar.cpp +++ b/lib/Transforms/Utils/SimplifyIndVar.cpp @@ -83,12 +83,6 @@ namespace { bool eliminateOverflowIntrinsic(CallInst *CI); bool eliminateIVUser(Instruction *UseInst, Instruction *IVOperand); - bool isCheapLoopInvariantPredicate(ICmpInst::Predicate Pred, - const SCEV *LHS, const SCEV *RHS, const Loop *L, - const SmallDenseMap &FreeExpansions, - ICmpInst::Predicate &InvariantPred, - Value *&LHSV, Value *& RHSV); - bool makeIVComparisonInvariant(ICmpInst *ICmp, Value *IVOperand); void eliminateIVComparison(ICmpInst *ICmp, Value *IVOperand); void simplifyIVRemainder(BinaryOperator *Rem, Value *IVOperand, bool IsSigned); @@ -98,6 +92,16 @@ namespace { bool eliminateSDiv(BinaryOperator *SDiv); bool strengthenOverflowingOperation(BinaryOperator *OBO, Value *IVOperand); bool strengthenRightShift(BinaryOperator *BO, Value *IVOperand); + + + private: + // Wrapped around ScalarEvolution::isLoopInvariantPredicate which returns + // true only when a free expansion is available. + bool isCheapLoopInvariantPredicate(ICmpInst::Predicate Pred, + const SCEV *LHS, const SCEV *RHS, const Loop *L, + const SmallDenseMap &FreeExpansions, + ICmpInst::Predicate &InvariantPred, + Value *&LHSV, Value *& RHSV); }; } @@ -187,10 +191,12 @@ bool SimplifyIndvar::isCheapLoopInvariantPredicate(ICmpInst::Predicate Pred, return (LHSV && RHSV); } -bool SimplifyIndvar::makeIVComparisonInvariant(ICmpInst *ICmp, - Value *IVOperand) { +/// SimplifyIVUsers helper for eliminating useless +/// comparisons against an induction variable. +void SimplifyIndvar::eliminateIVComparison(ICmpInst *ICmp, Value *IVOperand) { unsigned IVOperIdx = 0; ICmpInst::Predicate Pred = ICmp->getPredicate(); + ICmpInst::Predicate OriginalPred = Pred; if (IVOperand != ICmp->getOperand(0)) { // Swapped assert(IVOperand == ICmp->getOperand(1) && "Can't find IVOperand"); @@ -204,57 +210,23 @@ bool SimplifyIndvar::makeIVComparisonInvariant(ICmpInst *ICmp, const SCEV *S = SE->getSCEVAtScope(ICmp->getOperand(IVOperIdx), ICmpLoop); const SCEV *X = SE->getSCEVAtScope(ICmp->getOperand(1 - IVOperIdx), ICmpLoop); - auto *PN = dyn_cast(IVOperand); - if (!PN) - return false; - SmallDenseMap CheapExpansions; CheapExpansions[S] = ICmp->getOperand(IVOperIdx); CheapExpansions[X] = ICmp->getOperand(1 - IVOperIdx); // TODO: Support multiple entry loops? (We currently bail out of these in // the IndVarSimplify pass) - if (auto *BB = L->getLoopPredecessor()) { - Value *Incoming = PN->getIncomingValueForBlock(BB); - const SCEV *IncomingS = SE->getSCEV(Incoming); - CheapExpansions[IncomingS] = Incoming; - } + auto *PN = dyn_cast(IVOperand); + if (PN) + if (auto *BB = L->getLoopPredecessor()) { + Value *Incoming = PN->getIncomingValueForBlock(BB); + const SCEV *IncomingS = SE->getSCEV(Incoming); + CheapExpansions[IncomingS] = Incoming; + } ICmpInst::Predicate NewPred; Value *NewLHS = nullptr, *NewRHS = nullptr; - if (!isCheapLoopInvariantPredicate(Pred, S, X, L, CheapExpansions, - NewPred, NewLHS, NewRHS)) - return false; - - assert(NewLHS && NewRHS); - - DEBUG(dbgs() << "INDVARS: Simplified comparison: " << *ICmp << '\n'); - ICmp->setPredicate(NewPred); - ICmp->setOperand(0, NewLHS); - ICmp->setOperand(1, NewRHS); - return true; -} - -/// SimplifyIVUsers helper for eliminating useless -/// comparisons against an induction variable. -void SimplifyIndvar::eliminateIVComparison(ICmpInst *ICmp, Value *IVOperand) { - unsigned IVOperIdx = 0; - ICmpInst::Predicate Pred = ICmp->getPredicate(); - ICmpInst::Predicate OriginalPred = Pred; - if (IVOperand != ICmp->getOperand(0)) { - // Swapped - assert(IVOperand == ICmp->getOperand(1) && "Can't find IVOperand"); - IVOperIdx = 1; - Pred = ICmpInst::getSwappedPredicate(Pred); - } - - // Get the SCEVs for the ICmp operands (in the specific context of the - // current loop) - const Loop *ICmpLoop = LI->getLoopFor(ICmp->getParent()); - const SCEV *S = SE->getSCEVAtScope(ICmp->getOperand(IVOperIdx), ICmpLoop); - const SCEV *X = SE->getSCEVAtScope(ICmp->getOperand(1 - IVOperIdx), ICmpLoop); - // If the condition is always true or always false, replace it with // a constant value. if (SE->isKnownPredicate(Pred, S, X)) { @@ -265,8 +237,14 @@ void SimplifyIndvar::eliminateIVComparison(ICmpInst *ICmp, Value *IVOperand) { ICmp->replaceAllUsesWith(ConstantInt::getFalse(ICmp->getContext())); DeadInsts.emplace_back(ICmp); DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n'); - } else if (makeIVComparisonInvariant(ICmp, IVOperand)) { - // fallthrough to end of function + } else if (PN && + isCheapLoopInvariantPredicate(Pred, S, X, L, CheapExpansions, + NewPred, NewLHS, NewRHS)) { + DEBUG(dbgs() << "INDVARS: Simplified comparison: " << *ICmp << '\n'); + ICmp->setPredicate(NewPred); + assert(NewLHS && NewRHS); + ICmp->setOperand(0, NewLHS); + ICmp->setOperand(1, NewRHS); } else if (ICmpInst::isSigned(OriginalPred) && SE->isKnownNonNegative(S) && SE->isKnownNonNegative(X)) { // If we were unable to make anything above, all we can is to canonicalize -- 2.40.0