LLVM: lib/Transforms/Scalar/IndVarSimplify.cpp File Reference (original) (raw)
Go to the source code of this file.
| Classes | |
|---|---|
| struct | FloatingPointIV |
| Represents a floating-point induction variable pattern that may be convertible to integer form. More... | |
| struct | IntegerIV |
| Represents the integer values for a converted IV. More... |
| Macros | |
|---|---|
| #define | DEBUG_TYPE "indvars" |
| Functions | |
|---|---|
| STATISTIC (NumWidened, "Number of indvars widened") | |
| STATISTIC (NumReplaced, "Number of exit values replaced") | |
| STATISTIC (NumLFTR, "Number of loop exit tests replaced") | |
| STATISTIC (NumElimExt, "Number of IV sign/zero extends eliminated") | |
| STATISTIC (NumElimIV, "Number of congruent IVs eliminated") | |
| static bool | ConvertToSInt (const APFloat &APF, int64_t &IntVal) |
| Convert APF to an integer, if possible. | |
| static bool | isRepresentableAsExactInteger (const APFloat &FPVal, int64_t IntVal) |
| Ensure we stay within the bounds of fp values that can be represented as integers without gaps, which are 2^24 and 2^53 for IEEE-754 single and double precision respectively (both on negative and positive side). | |
| static CmpInst::Predicate | getIntegerPredicate (CmpInst::Predicate FPPred) |
| static std::optional< FloatingPointIV > | maybeFloatingPointRecurrence (Loop *L, PHINode *PN) |
| Analyze a PN to determine whether it represents a simple floating-point induction variable, with constant fp init, increment, and exit values. | |
| static std::optional< IntegerIV > | tryConvertToIntegerIV (const FloatingPointIV &FPIV) |
| Ensure that the floating-point IV can be converted to a semantics-preserving signed 32-bit integer IV. | |
| static void | canonicalizeToIntegerIV (Loop *L, PHINode *PN, const FloatingPointIV &FPIV, const IntegerIV &IIV, const TargetLibraryInfo *TLI, std::unique_ptr< MemorySSAUpdater > &MSSAU) |
| Rewrite the floating-point IV as an integer IV. | |
| static void | visitIVCast (CastInst *Cast, WideIVInfo &WI, ScalarEvolution *SE, const TargetTransformInfo *TTI) |
| Update information about the induction variable that is extended by this sign or zero extend operation. | |
| static PHINode * | getLoopPhiForCounter (Value *IncV, Loop *L) |
| Given an Value which is hoped to be part of an add recurance in the given loop, return the associated Phi node if so. | |
| static bool | isLoopExitTestBasedOn (Value *V, BasicBlock *ExitingBB) |
| Whether the current loop exit test is based on this value. | |
| static bool | needsLFTR (Loop *L, BasicBlock *ExitingBB) |
| linearFunctionTestReplace policy. | |
| static bool | hasConcreteDefImpl (Value *V, SmallPtrSetImpl< Value * > &Visited, unsigned Depth) |
| Recursive helper for hasConcreteDef(). | |
| static bool | hasConcreteDef (Value *V) |
| Return true if the given value is concrete. | |
| static bool | isLoopCounter (PHINode *Phi, Loop *L, ScalarEvolution *SE) |
| Return true if the given phi is a "counter" in L. | |
| static PHINode * | FindLoopCounter (Loop *L, BasicBlock *ExitingBB, const SCEV *BECount, ScalarEvolution *SE, DominatorTree *DT) |
| Search the loop header for a loop counter (anadd rec w/step of one) suitable for use by LFTR. | |
| static Value * | genLoopLimit (PHINode *IndVar, BasicBlock *ExitingBB, const SCEV *ExitCount, bool UsePostInc, Loop *L, SCEVExpander &Rewriter, ScalarEvolution *SE) |
| Insert an IR expression which computes the value held by the IV IndVar (which must be an loop counter w/unit stride) after the backedge of loop L is taken ExitCount times. | |
| static void | replaceExitCond (BranchInst *BI, Value *NewCond, SmallVectorImpl< WeakTrackingVH > &DeadInsts) |
| static Constant * | createFoldedExitCond (const Loop *L, BasicBlock *ExitingBB, bool IsTaken) |
| static void | foldExit (const Loop *L, BasicBlock *ExitingBB, bool IsTaken, SmallVectorImpl< WeakTrackingVH > &DeadInsts) |
| static void | replaceLoopPHINodesWithPreheaderValues (LoopInfo *LI, Loop *L, SmallVectorImpl< WeakTrackingVH > &DeadInsts, ScalarEvolution &SE) |
| static Value * | createInvariantCond (const Loop *L, BasicBlock *ExitingBB, const ScalarEvolution::LoopInvariantPredicate &LIP, SCEVExpander &Rewriter) |
| static std::optional< Value * > | createReplacement (ICmpInst *ICmp, const Loop *L, BasicBlock *ExitingBB, const SCEV *MaxIter, bool Inverted, bool SkipLastIter, ScalarEvolution *SE, SCEVExpander &Rewriter) |
| static bool | optimizeLoopExitWithUnknownExitCount (const Loop *L, BranchInst *BI, BasicBlock *ExitingBB, const SCEV *MaxIter, bool SkipLastIter, ScalarEvolution *SE, SCEVExpander &Rewriter, SmallVectorImpl< WeakTrackingVH > &DeadInsts) |
| static bool | crashingBBWithoutEffect (const BasicBlock &BB) |
| Variables | |
|---|---|
| static cl::opt< ReplaceExitVal > | ReplaceExitValue ("replexitval", cl::Hidden, cl::init(OnlyCheapRepl), cl::desc("Choose the strategy to replace exit value in IndVarSimplify"), cl::values(clEnumValN(NeverRepl, "never", "never replace exit value"), clEnumValN(OnlyCheapRepl, "cheap", "only replace exit value when the cost is cheap"), clEnumValN(UnusedIndVarInLoop, "unusedindvarinloop", "only replace exit value when it is an unused " "induction variable in the loop and has cheap replacement cost"), clEnumValN(NoHardUse, "noharduse", "only replace exit values when loop def likely dead"), clEnumValN(AlwaysRepl, "always", "always replace exit value whenever possible"))) |
| static cl::opt< bool > | UsePostIncrementRanges ("indvars-post-increment-ranges", cl::Hidden, cl::desc("Use post increment control-dependent ranges in IndVarSimplify"), cl::init(true)) |
| static cl::opt< bool > | DisableLFTR ("disable-lftr", cl::Hidden, cl::init(false), cl::desc("Disable Linear Function Test Replace optimization")) |
| static cl::opt< bool > | LoopPredication ("indvars-predicate-loops", cl::Hidden, cl::init(true), cl::desc("Predicate conditions in read only loops")) |
| static cl::opt< bool > | LoopPredicationTraps ("indvars-predicate-loop-traps", cl::Hidden, cl::init(true), cl::desc("Predicate conditions that trap in loops with only local writes")) |
| static cl::opt< bool > | AllowIVWidening ("indvars-widen-indvars", cl::Hidden, cl::init(true), cl::desc("Allow widening of indvars to eliminate s/zext")) |
◆ DEBUG_TYPE
#define DEBUG_TYPE "indvars"
◆ canonicalizeToIntegerIV()
Rewrite the floating-point IV as an integer IV.
Definition at line 425 of file IndVarSimplify.cpp.
References llvm::PHINode::addIncoming(), llvm::cast(), FloatingPointIV::Compare, llvm::PHINode::Create(), llvm::dbgs(), IntegerIV::ExitValue, llvm::PoisonValue::get(), llvm::Value::getContext(), llvm::Instruction::getDebugLoc(), llvm::PHINode::getIncomingBlock(), llvm::PHINode::getIncomingValue(), llvm::Type::getInt32Ty(), llvm::ilist_node_impl< OptionsT >::getIterator(), llvm::Value::getName(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::CmpInst::getPredicateName(), llvm::ConstantInt::getSigned(), llvm::Value::getType(), IntegerIV::IncrValue, IntegerIV::InitValue, llvm::Int32Ty, LLVM_DEBUG, IntegerIV::NewPred, llvm::RecursivelyDeleteTriviallyDeadInstructions(), llvm::Value::replaceAllUsesWith(), llvm::Instruction::setDebugLoc(), llvm::Value::takeName(), and llvm::Instruction::user_back().
◆ ConvertToSInt()
◆ crashingBBWithoutEffect()
◆ createFoldedExitCond()
◆ createInvariantCond()
◆ createReplacement()
Definition at line 1353 of file IndVarSimplify.cpp.
References llvm::cast(), createFoldedExitCond(), createInvariantCond(), llvm::dyn_cast(), llvm::ScalarEvolution::evaluatePredicateAt(), llvm::ICmpInst::getCmpPredicate(), llvm::ICmpInst::getInverseCmpPredicate(), llvm::ScalarEvolution::getLoopInvariantExitCondDuringFirstIterations(), llvm::ScalarEvolution::getMinusOne(), llvm::ScalarEvolution::getMinusSCEV(), llvm::ScalarEvolution::getOne(), llvm::User::getOperand(), llvm::ScalarEvolution::getSCEVAtScope(), llvm::BasicBlock::getTerminator(), llvm::ScalarEvolution::getTruncateExpr(), llvm::SCEV::getType(), llvm::ScalarEvolution::getTypeSizeInBits(), llvm::ScalarEvolution::getUMinFromMismatchedTypes(), llvm::ScalarEvolution::getZeroExtendExpr(), llvm::CmpInst::ICMP_ULE, llvm::ScalarEvolution::isKnownPredicateAt(), LHS, RHS, and llvm::UMin.
Referenced by optimizeLoopExitWithUnknownExitCount().
◆ FindLoopCounter()
Search the loop header for a loop counter (anadd rec w/step of one) suitable for use by LFTR.
If multiple counters are available, select the "best" one based profitable heuristics.
BECount may be an i8* pointer type. The pointer difference is already valid count without scaling the address stride, so it remains a pointer expression as far as SCEV is concerned.
Definition at line 939 of file IndVarSimplify.cpp.
References assert(), llvm::cast(), Cond, DL, llvm::ScalarEvolution::getSCEV(), llvm::BasicBlock::getTerminator(), llvm::SCEV::getType(), llvm::Value::getType(), llvm::ScalarEvolution::getTypeSizeInBits(), hasConcreteDef(), I, llvm::isa(), llvm::isAlmostDeadIV(), isLoopCounter(), isLoopExitTestBasedOn(), llvm::SCEV::isZero(), and llvm::mustExecuteUBIfPoisonOnPathTo().
◆ foldExit()
◆ genLoopLimit()
Insert an IR expression which computes the value held by the IV IndVar (which must be an loop counter w/unit stride) after the backedge of loop L is taken ExitCount times.
Definition at line 1019 of file IndVarSimplify.cpp.
References assert(), llvm::cast(), llvm::SCEVAddRecExpr::evaluateAtIteration(), llvm::SCEVAddRecExpr::getPostIncExpr(), llvm::ScalarEvolution::getSCEV(), llvm::SCEVAddRecExpr::getStart(), llvm::SCEVAddRecExpr::getStepRecurrence(), llvm::BasicBlock::getTerminator(), llvm::ScalarEvolution::getTruncateExpr(), llvm::SCEV::getType(), llvm::SCEVAddRecExpr::getType(), llvm::Value::getType(), llvm::ScalarEvolution::getTypeSizeInBits(), llvm::isa(), llvm::Type::isIntegerTy(), isLoopCounter(), llvm::ScalarEvolution::isLoopInvariant(), and llvm::SCEV::isOne().
◆ getIntegerPredicate()
Definition at line 235 of file IndVarSimplify.cpp.
References llvm::CmpInst::BAD_ICMP_PREDICATE, llvm::CmpInst::FCMP_OEQ, llvm::CmpInst::FCMP_OGE, llvm::CmpInst::FCMP_OGT, llvm::CmpInst::FCMP_OLE, llvm::CmpInst::FCMP_OLT, llvm::CmpInst::FCMP_ONE, llvm::CmpInst::FCMP_UEQ, llvm::CmpInst::FCMP_UGE, llvm::CmpInst::FCMP_UGT, llvm::CmpInst::FCMP_ULE, llvm::CmpInst::FCMP_ULT, llvm::CmpInst::FCMP_UNE, llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, llvm::CmpInst::ICMP_SGE, llvm::CmpInst::ICMP_SGT, llvm::CmpInst::ICMP_SLE, and llvm::CmpInst::ICMP_SLT.
Referenced by tryConvertToIntegerIV().
◆ getLoopPhiForCounter()
◆ hasConcreteDef()
◆ hasConcreteDefImpl()
◆ isLoopCounter()
Return true if the given phi is a "counter" in L.
A counter is an add recurance (of integer or pointer type) with an arbitrary start, and a step of 1. Note that L must have exactly one latch.
Definition at line 914 of file IndVarSimplify.cpp.
References assert(), getLoopPhiForCounter(), llvm::ScalarEvolution::getSCEV(), llvm::isa(), llvm::ScalarEvolution::isSCEVable(), llvm::SCEVPatternMatch::m_SCEV(), llvm::SCEVPatternMatch::m_scev_AffineAddRec(), llvm::SCEVPatternMatch::m_scev_One(), llvm::SCEVPatternMatch::m_SpecificLoop(), and llvm::SCEVPatternMatch::match().
Referenced by FindLoopCounter(), and genLoopLimit().
◆ isLoopExitTestBasedOn()
◆ isRepresentableAsExactInteger()
◆ maybeFloatingPointRecurrence()
◆ needsLFTR()
linearFunctionTestReplace policy.
Return true unless we can show that the current exit test is already sufficiently canonical.
Definition at line 822 of file IndVarSimplify.cpp.
References assert(), llvm::cast(), Cond, llvm::dyn_cast(), llvm::BranchInst::getCondition(), getLoopPhiForCounter(), llvm::BasicBlock::getTerminator(), llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, LHS, RHS, and std::swap().
◆ optimizeLoopExitWithUnknownExitCount()
Definition at line 1410 of file IndVarSimplify.cpp.
References assert(), Changed, llvm::ScalarEvolution::computeExitLimitFromCond(), llvm::SmallPtrSetImpl< PtrType >::count(), createReplacement(), llvm::dbgs(), llvm::dyn_cast(), llvm::SmallVectorTemplateCommon< T, typename >::empty(), llvm::SmallPtrSetImpl< PtrType >::erase(), llvm::BranchInst::getCondition(), llvm::ScalarEvolution::getExitCount(), llvm::Value::getName(), llvm::ScalarEvolution::getNoopOrZeroExtend(), llvm::BranchInst::getSuccessor(), llvm::SCEV::getType(), llvm::ScalarEvolution::getWiderType(), llvm::Value::hasOneUse(), llvm::SmallPtrSetImpl< PtrType >::insert(), llvm::isa(), LHS, LLVM_DEBUG, llvm::PatternMatch::m_LogicalAnd(), llvm::PatternMatch::m_LogicalOr(), llvm::PatternMatch::m_Value(), llvm::SCEVPatternMatch::match(), llvm::SmallVectorImpl< T >::pop_back_val(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::Value::replaceAllUsesWith(), RHS, llvm::SmallPtrSetImplBase::size(), llvm::SmallVectorTemplateCommon< T, typename >::size(), and llvm::ScalarEvolution::SymbolicMaximum.
◆ replaceExitCond()
◆ replaceLoopPHINodesWithPreheaderValues()
Definition at line 1295 of file IndVarSimplify.cpp.
References assert(), llvm::cast(), llvm::SmallVectorImpl< T >::emplace_back(), llvm::SmallVectorTemplateCommon< T, typename >::empty(), llvm::ScalarEvolution::forgetValue(), llvm::PHINode::getIncomingValueForBlock(), I, llvm::SmallPtrSetImpl< PtrType >::insert(), llvm::SmallVectorImpl< T >::pop_back_val(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::Value::replaceAllUsesWith(), llvm::LoopInfo::replacementPreservesLCSSAForm(), llvm::simplifyInstruction(), and llvm::Value::users().
◆ STATISTIC() [1/5]
| STATISTIC | ( | NumElimExt | , |
|---|---|---|---|
| "Number of IV sign/zero extends eliminated" | ) |
◆ STATISTIC() [2/5]
| STATISTIC | ( | NumElimIV | , |
|---|---|---|---|
| "Number of congruent IVs eliminated" | ) |
◆ STATISTIC() [3/5]
| STATISTIC | ( | NumLFTR | , |
|---|---|---|---|
| "Number of loop exit tests replaced" | ) |
◆ STATISTIC() [4/5]
| STATISTIC | ( | NumReplaced | , |
|---|---|---|---|
| "Number of exit values replaced" | ) |
◆ STATISTIC() [5/5]
| STATISTIC | ( | NumWidened | , |
|---|---|---|---|
| "Number of indvars widened" | ) |
◆ tryConvertToIntegerIV()
Ensure that the floating-point IV can be converted to a semantics-preserving signed 32-bit integer IV.
Returns a IntegerIV struct if possible, std::nullopt otherwise.
Definition at line 333 of file IndVarSimplify.cpp.
References llvm::CmpInst::BAD_ICMP_PREDICATE, FloatingPointIV::Compare, ConvertToSInt(), FloatingPointIV::ExitValue, getIntegerPredicate(), llvm::CmpInst::getPredicate(), llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, llvm::CmpInst::ICMP_SGE, llvm::CmpInst::ICMP_SGT, llvm::CmpInst::ICMP_SLE, llvm::CmpInst::ICMP_SLT, FloatingPointIV::IncrValue, FloatingPointIV::InitValue, llvm::isInt(), isRepresentableAsExactInteger(), and Range.
◆ visitIVCast()
◆ AllowIVWidening
| cl::opt< bool > AllowIVWidening("indvars-widen-indvars", cl::Hidden, cl::init(true), cl::desc("Allow widening of indvars to eliminate s/zext")) ( "indvars-widen-indvars" , cl::Hidden , cl::init(true) , cl::desc("Allow widening of indvars to eliminate s/zext") ) | static |
|---|
◆ DisableLFTR
| cl::opt< bool > DisableLFTR("disable-lftr", cl::Hidden, cl::init(false), cl::desc("Disable Linear Function Test Replace optimization")) ( "disable-lftr" , cl::Hidden , cl::init(false) , cl::desc("Disable Linear Function Test Replace optimization") ) | static |
|---|
◆ LoopPredication
| cl::opt< bool > LoopPredication("indvars-predicate-loops", cl::Hidden, cl::init(true), cl::desc("Predicate conditions in read only loops")) ( "indvars-predicate-loops" , cl::Hidden , cl::init(true) , cl::desc("Predicate conditions in read only loops") ) | static |
|---|
◆ LoopPredicationTraps
| cl::opt< bool > LoopPredicationTraps("indvars-predicate-loop-traps", cl::Hidden, cl::init(true), cl::desc("Predicate conditions that trap in loops with only local writes")) ( "indvars-predicate-loop-traps" , cl::Hidden , cl::init(true) , cl::desc("Predicate conditions that trap in loops with only local writes") ) | static |
|---|
◆ ReplaceExitValue
| cl::opt< ReplaceExitVal > ReplaceExitValue("replexitval", cl::Hidden, cl::init(OnlyCheapRepl), cl::desc("Choose the strategy to replace exit value in IndVarSimplify"), cl::values( clEnumValN(NeverRepl, "never", "never replace exit value"), clEnumValN(OnlyCheapRepl, "cheap", "only replace exit value when the cost is cheap"), clEnumValN( UnusedIndVarInLoop, "unusedindvarinloop", "only replace exit value when it is an unused " "induction variable in the loop and has cheap replacement cost"), clEnumValN(NoHardUse, "noharduse", "only replace exit values when loop def likely dead"), clEnumValN(AlwaysRepl, "always", "always replace exit value whenever possible"))) ( "replexitval" , cl::Hidden , cl::init(OnlyCheapRepl) , cl::desc("Choose the strategy to replace exit value in IndVarSimplify") , cl::values( clEnumValN(NeverRepl, "never", "never replace exit value"), clEnumValN(OnlyCheapRepl, "cheap", "only replace exit value when the cost is cheap"), clEnumValN( UnusedIndVarInLoop, "unusedindvarinloop", "only replace exit value when it is an unused " "induction variable in the loop and has cheap replacement cost"), clEnumValN(NoHardUse, "noharduse", "only replace exit values when loop def likely dead"), clEnumValN(AlwaysRepl, "always", "always replace exit value whenever possible")) ) | static |
|---|
◆ UsePostIncrementRanges
| cl::opt< bool > UsePostIncrementRanges("indvars-post-increment-ranges", cl::Hidden, cl::desc("Use post increment control-dependent ranges in IndVarSimplify"), cl::init(true)) ( "indvars-post-increment-ranges" , cl::Hidden , cl::desc("Use post increment control-dependent ranges in IndVarSimplify") , cl::init(true) ) | static |
|---|