23 #include "llvm/Config/llvm-config.h" 36 #define DEBUG_TYPE "iv-users" 47 "Induction Variable Users",
false,
true)
66 if (AR->getLoop() == L)
67 return AR->isAffine() ||
79 bool AnyInterestingYet =
false;
80 for (
const auto *
Op :
Add->operands())
82 if (AnyInterestingYet)
84 AnyInterestingYet =
true;
86 return AnyInterestingYet;
98 Loop *NearestLoop =
nullptr;
100 Rung; Rung = Rung->
getIDom()) {
103 if (DomLoop && DomLoop->
getHeader() == DomBB) {
108 if (SimpleLoopNests.
count(DomLoop))
113 NearestLoop = DomLoop;
117 SimpleLoopNests.
insert(NearestLoop);
174 if (!Processed.insert(I).second)
177 if (!SE->isSCEVable(I->
getType()))
195 if (EphValues.count(I))
199 const SCEV *ISE = SE->getSCEV(I);
209 if (!UniqueUsers.
insert(User).second)
213 if (isa<PHINode>(User) && Processed.count(User))
220 if (
PHINode *PHI = dyn_cast<PHINode>(User)) {
221 unsigned OperandNo = U.getOperandNo();
223 UseBB = PHI->getIncomingBlock(ValNo);
234 bool AddUserToIVUsers =
false;
235 if (LI->getLoopFor(User->
getParent()) != L) {
236 if (isa<PHINode>(User) || Processed.count(User) ||
237 !AddUsersImpl(User, SimpleLoopNests)) {
238 LLVM_DEBUG(
dbgs() <<
"FOUND USER in other loop: " << *User <<
'\n' 239 <<
" OF SCEV: " << *ISE <<
'\n');
240 AddUserToIVUsers =
true;
242 }
else if (Processed.count(User) || !AddUsersImpl(User, SimpleLoopNests)) {
244 <<
" OF SCEV: " << *ISE <<
'\n');
245 AddUserToIVUsers =
true;
248 if (AddUserToIVUsers) {
254 const SCEV *OriginalISE = ISE;
257 auto *L = AR->getLoop();
260 NewUse.PostIncLoops.
insert(L);
270 if (OriginalISE != ISE) {
271 const SCEV *DenormalizedISE =
276 if (OriginalISE != DenormalizedISE) {
278 <<
" DISCARDING (NORMALIZATION ISN'T INVERTIBLE): " 285 <<
" NORMALIZED TO: " << *ISE <<
'\n');
297 return AddUsersImpl(I, SimpleLoopNests);
301 IVUses.push_back(
new IVStrideUse(
this, User, Operand));
302 return IVUses.back();
307 : L(L), AC(AC), LI(LI), DT(DT), SE(SE), IVUses() {
320 OS <<
"IV Users for loop ";
329 IVUse.getOperandValToReplace()->printAsOperand(OS,
false);
331 for (
auto PostIncLoop : IVUse.PostIncLoops) {
332 OS <<
" (post-inc with loop ";
333 PostIncLoop->getHeader()->printAsOperand(OS,
false);
338 IVUse.getUser()->print(OS);
340 OS <<
"Printing <null> User";
345 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 367 auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
369 auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
370 auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
371 auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
373 IU.reset(
new IVUsers(L, AC, LI, DT, SE));
397 if (AR->getLoop() == L)
403 for (
const auto *
Op :
Add->operands())
414 return AR->getStepRecurrence(*SE);
419 PostIncLoops.insert(L);
422 void IVStrideUse::deleted() {
424 Parent->Processed.erase(this->getUser());
425 Parent->IVUses.erase(
this);
Pass interface - Implemented by all 'passes'.
static void collectEphemeralValues(const Loop *L, AssumptionCache *AC, SmallPtrSetImpl< const Value *> &EphValues)
Collect a loop's ephemeral values (those used only by an assume or similar intrinsics in the loop)...
bool runOnLoop(Loop *L, LPPassManager &LPM) override
A parsed version of the target data layout string in and methods for querying it. ...
bool AddUsersImpl(Instruction *I, SmallPtrSetImpl< Loop *> &SimpleLoopNests)
AddUsersImpl - Inspect the specified instruction.
iterator_range< use_iterator > uses()
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static bool IVUseShouldUsePostIncValue(Instruction *User, Value *Operand, const Loop *L, DominatorTree *DT)
IVUseShouldUsePostIncValue - We have discovered a "User" of an IV expression and now we need to decid...
const SCEV * getReplacementExpr(const IVStrideUse &IU) const
getReplacementExpr - Return a SCEV expression which computes the value of the OperandValToReplace of ...
This class represents lattice values for constants.
A Module instance is used to store all the information related to an LLVM module. ...
const SCEV * normalizeForPostIncUse(const SCEV *S, const PostIncLoopSet &Loops, ScalarEvolution &SE)
Normalize S to be post-increment for all loops present in Loops.
Pass * createIVUsersPass()
The main scalar evolution driver.
void initializeIVUsersWrapperPassPass(PassRegistry &)
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
block Block Frequency true
iv Induction Variable Users
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
iterator begin()
Instruction iterator methods.
bool AddUsersIfInteresting(Instruction *I)
AddUsersIfInteresting - Inspect the specified Instruction.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
static bool isSimplifiedLoopNest(BasicBlock *BB, const DominatorTree *DT, const LoopInfo *LI, SmallPtrSetImpl< Loop *> &SimpleLoopNests)
Return true if all loop headers that dominate this block are in simplified form.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
A Use represents the edge between a Value definition and its users.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
BlockT * getHeader() const
void print(raw_ostream &OS, const Module *=nullptr) const
Type * getType() const
All values are typed, get the type of this value.
This node represents a polynomial recurrence on the trip count of the specified loop.
This header provides classes for managing per-loop analyses.
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
const SCEV * normalizeForPostIncUseIf(const SCEV *S, NormalizePredTy Pred, ScalarEvolution &SE)
Normalize S for all add recurrence sub-expressions for which Pred returns true.
const SCEV * getStride(const IVStrideUse &IU, const Loop *L) const
LLVM Basic Block Representation.
IVUsers run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR)
DomTreeNodeBase * getIDom() const
This file contains the declarations for the subclasses of Constant, which represent the different fla...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
Represent the analysis usage information of a pass.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
const PostIncLoopSet & getPostIncLoops() const
getPostIncLoops - Return the set of loops for which the expression has been adjusted to use post-inc ...
static unsigned getIncomingValueNumForOperand(unsigned i)
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
static bool isInteresting(const SCEV *S, const Instruction *I, const Loop *L, ScalarEvolution *SE, LoopInfo *LI)
isInteresting - Test whether the given expression is "interesting" when used by the given expression...
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
Iterator for intrusive lists based on ilist_node.
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
Module.h This file contains the declarations for the Module class.
bool isLegalInteger(uint64_t Width) const
Returns true if the specified type is known to be a native integer type supported by the CPU...
unsigned getNumIncomingValues() const
Return the number of incoming edges.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
This node represents an addition of some number of SCEVs.
void setPreservesAll()
Set by analyses that do not transform their input at all.
uint64_t getTypeSizeInBits(Type *Ty) const
Size examples:
bool isLoopSimplifyForm() const
Return true if the Loop is in the form that the LoopSimplify form transforms loops to...
IVUsers(Loop *L, AssumptionCache *AC, LoopInfo *LI, DominatorTree *DT, ScalarEvolution *SE)
MCExpr const & getExpr(MCExpr const &Expr)
This class represents an analyzed expression in the program.
Represents a single loop in the control flow graph.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getOperandValToReplace() const
getOperandValToReplace - Return the Value of the operand in the user instruction that this IVStrideUs...
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void dump() const
dump - This method is used for debugging.
const SCEV * getExpr(const IVStrideUse &IU) const
getExpr - Return the expression for the use.
void transformToPostInc(const Loop *L)
transformToPostInc - Transform the expression to post-inc form for the given loop.
INITIALIZE_PASS_BEGIN(IVUsersWrapperPass, "iv-users", "Induction Variable Users", false, true) INITIALIZE_PASS_END(IVUsersWrapperPass
const SCEV * getBackedgeTakenCount(const Loop *L)
If the specified loop has a predictable backedge-taken count, return it, otherwise return a SCEVCould...
bool isSafeToSpeculativelyExecute(const Value *V, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr)
Return true if the instruction does not have any effects besides calculating the result and does not ...
static const SCEVAddRecExpr * findAddRecForLoop(const SCEV *S, const Loop *L)
const SCEV * denormalizeForPostIncUse(const SCEV *S, const PostIncLoopSet &Loops, ScalarEvolution &SE)
Denormalize S to be post-increment for all loops present in Loops.
LLVM Value Representation.
IVStrideUse - Keep track of one use of a strided induction variable.
This class implements an extremely fast bulk output stream that can only output to a stream...
The legacy pass manager's analysis pass to compute loop information.
A container for analyses that lazily runs them and caches their results.
Legacy analysis pass which computes a DominatorTree.
IVStrideUse & AddUser(Instruction *User, Value *Operand)
bool hasLoopInvariantBackedgeTakenCount(const Loop *L)
Return true if the specified loop has an analyzable loop-invariant backedge-taken count...
A special type used by analysis passes to provide an address that identifies that particular analysis...
void print(raw_ostream &OS, const Module *=nullptr) const override
print - Print out the internal state of the pass.
const BasicBlock * getParent() const