#include "llvm/Transforms/Scalar/IndVarSimplify.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
#include "llvm/Transforms/Utils/SimplifyIndVar.h"
#include <cassert>
#include <cstdint>
#include <utility>
usingnamespacellvm;
usingnamespacePatternMatch;
#define DEBUG_TYPE …
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 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>
AllowIVWidening("indvars-widen-indvars", cl::Hidden, cl::init(true),
cl::desc("Allow widening of indvars to eliminate s/zext"));
namespace {
class IndVarSimplify { … };
}
static bool ConvertToSInt(const APFloat &APF, int64_t &IntVal) { … }
bool IndVarSimplify::handleFloatingPointIV(Loop *L, PHINode *PN) { … }
bool IndVarSimplify::rewriteNonIntegerIVs(Loop *L) { … }
bool IndVarSimplify::rewriteFirstIterationLoopExitValues(Loop *L) { … }
static void visitIVCast(CastInst *Cast, WideIVInfo &WI,
ScalarEvolution *SE,
const TargetTransformInfo *TTI) { … }
namespace {
class IndVarSimplifyVisitor : public IVVisitor { … };
}
bool IndVarSimplify::simplifyAndExtend(Loop *L,
SCEVExpander &Rewriter,
LoopInfo *LI) { … }
static PHINode *getLoopPhiForCounter(Value *IncV, Loop *L) { … }
static bool isLoopExitTestBasedOn(Value *V, BasicBlock *ExitingBB) { … }
static bool needsLFTR(Loop *L, BasicBlock *ExitingBB) { … }
static bool hasConcreteDefImpl(Value *V, SmallPtrSetImpl<Value*> &Visited,
unsigned Depth) { … }
static bool hasConcreteDef(Value *V) { … }
static bool isLoopCounter(PHINode* Phi, Loop *L,
ScalarEvolution *SE) { … }
static PHINode *FindLoopCounter(Loop *L, BasicBlock *ExitingBB,
const SCEV *BECount,
ScalarEvolution *SE, DominatorTree *DT) { … }
static Value *genLoopLimit(PHINode *IndVar, BasicBlock *ExitingBB,
const SCEV *ExitCount, bool UsePostInc, Loop *L,
SCEVExpander &Rewriter, ScalarEvolution *SE) { … }
bool IndVarSimplify::
linearFunctionTestReplace(Loop *L, BasicBlock *ExitingBB,
const SCEV *ExitCount,
PHINode *IndVar, SCEVExpander &Rewriter) { … }
bool IndVarSimplify::sinkUnusedInvariants(Loop *L) { … }
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) { … }
bool IndVarSimplify::canonicalizeExitCondition(Loop *L) { … }
bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) { … }
bool IndVarSimplify::predicateLoopExits(Loop *L, SCEVExpander &Rewriter) { … }
bool IndVarSimplify::run(Loop *L) { … }
PreservedAnalyses IndVarSimplifyPass::run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR,
LPMUpdater &) { … }