35 #define DEBUG_TYPE "iv-users"
46 "Induction Variable Users",
false,
true)
65 if (AR->getLoop() ==
L)
66 return AR->isAffine() ||
78 bool AnyInterestingYet =
false;
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);
130 if (!Processed.insert(I).second)
151 if (EphValues.count(I))
165 if (!UniqueUsers.
insert(User).second)
169 if (isa<PHINode>(User) && Processed.count(User))
176 if (
PHINode *PHI = dyn_cast<PHINode>(User)) {
177 unsigned OperandNo = U.getOperandNo();
179 UseBB = PHI->getIncomingBlock(ValNo);
190 bool AddUserToIVUsers =
false;
192 if (isa<PHINode>(User) || Processed.count(User) ||
194 DEBUG(
dbgs() <<
"FOUND USER in other loop: " << *User <<
'\n'
195 <<
" OF SCEV: " << *ISE <<
'\n');
196 AddUserToIVUsers =
true;
198 }
else if (Processed.count(User) || !
AddUsersImpl(User, SimpleLoopNests)) {
199 DEBUG(
dbgs() <<
"FOUND USER: " << *User <<
'\n'
200 <<
" OF SCEV: " << *ISE <<
'\n');
201 AddUserToIVUsers =
true;
204 if (AddUserToIVUsers) {
210 const SCEV *OriginalISE = ISE;
220 if (OriginalISE != ISE) {
221 const SCEV *DenormalizedISE =
223 NewUse.PostIncLoops, *SE, *DT);
227 if (OriginalISE != DenormalizedISE) {
228 DEBUG(
dbgs() <<
" DISCARDING (NORMALIZATION ISN'T INVERTIBLE): "
235 dbgs() <<
" NORMALIZED TO: " << *ISE <<
'\n');
251 IVUses.push_back(
new IVStrideUse(
this, User, Operand));
252 return IVUses.back();
257 : L(L), AC(AC), LI(LI), DT(DT), SE(SE), IVUses() {
270 OS <<
"IV Users for loop ";
271 L->
getHeader()->printAsOperand(OS,
false);
279 IVUse.getOperandValToReplace()->printAsOperand(OS,
false);
281 for (
auto PostIncLoop : IVUse.PostIncLoops) {
282 OS <<
" (post-inc with loop ";
283 PostIncLoop->getHeader()->printAsOperand(OS,
false);
288 IVUse.getUser()->print(OS);
290 OS <<
"Printing <null> User";
295 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
317 auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
319 auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
320 auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
321 auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
323 IU.reset(
new IVUsers(L, AC, LI, DT, SE));
350 if (AR->getLoop() ==
L)
368 return AR->getStepRecurrence(*SE);
376 void IVStrideUse::deleted() {
378 Parent->Processed.erase(this->
getUser());
379 Parent->IVUses.erase(
this);
Pass interface - Implemented by all 'passes'.
bool runOnLoop(Loop *L, LPPassManager &LPM) override
const SCEV * getExpr(const IVStrideUse &IU) const
getExpr - Return the expression for the use.
A parsed version of the target data layout string in and methods for querying it. ...
iterator_range< use_iterator > uses()
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
const PostIncLoopSet & getPostIncLoops() const
getPostIncLoops - Return the set of loops for which the expression has been adjusted to use post-inc ...
const SCEV * TransformForPostIncUse(TransformKind Kind, const SCEV *S, Instruction *User, Value *OperandValToReplace, PostIncLoopSet &Loops, ScalarEvolution &SE, DominatorTree &DT)
TransformForPostIncUse - Transform the given expression according to the given transformation kind...
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
A Module instance is used to store all the information related to an LLVM module. ...
Pass * createIVUsersPass()
The main scalar evolution driver.
Denormalize - Perform the inverse transform on the expression with the given loop set...
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void initializeIVUsersWrapperPassPass(PassRegistry &)
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of .assume calls within a function.
void print(raw_ostream &OS, const Module *=nullptr) const
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
iv Induction Variable Users
BlockT * getHeader() const
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool AddUsersIfInteresting(Instruction *I)
AddUsersIfInteresting - Inspect the specified Instruction.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
const SCEV * getStride(const IVStrideUse &IU, const Loop *L) const
A Use represents the edge between a Value definition and its users.
const SCEV *const * op_iterator
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
uint64_t getTypeSizeInBits(Type *Ty) const
Return the size in bits of the specified type, for which isSCEVable must return true.
bool isLoopSimplifyForm() const
Return true if the Loop is in the form that the LoopSimplify form transforms loops to...
This node represents a polynomial recurrence on the trip count of the specified loop.
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.
Base class for the actual dominator tree node.
This header provides classes for managing per-loop analyses.
Instruction * getUser() const
getUser - Return the user instruction for this use.
void dump() const
dump - This method is used for debugging.
NormalizeAutodetect - Detect post-inc opportunities on new expressions, update the given loop set...
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...
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
bool AddUsersImpl(Instruction *I, SmallPtrSetImpl< Loop * > &SimpleLoopNests)
AddUsersImpl - Inspect the specified instruction.
LLVM Basic Block Representation.
IVUsers run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Normalize - Normalize according to the given loops.
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 * getReplacementExpr(const IVStrideUse &IU) const
getReplacementExpr - Return a SCEV expression which computes the value of the OperandValToReplace of ...
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.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
static unsigned getIncomingValueNumForOperand(unsigned i)
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...
iv Induction Variable false
Iterator for intrusive lists based on ilist_node.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Value * getOperandValToReplace() const
getOperandValToReplace - Return the Value of the operand in the user instruction that this IVStrideUs...
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
This node represents an addition of some number of SCEVs.
void setPreservesAll()
Set by analyses that do not transform their input at all.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
IVUsers(Loop *L, AssumptionCache *AC, LoopInfo *LI, DominatorTree *DT, ScalarEvolution *SE)
This class represents an analyzed expression in the program.
Represents a single loop in the control flow graph.
void transformToPostInc(const Loop *L)
transformToPostInc - Transform the expression to post-inc form for the given loop.
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)
LLVM Value Representation.
const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
INITIALIZE_PASS_BEGIN(IVUsersWrapperPass,"iv-users","Induction Variable Users", false, true) INITIALIZE_PASS_END(IVUsersWrapperPass
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.
bool isLegalInteger(uint64_t Width) const
Returns true if the specified type is known to be a native integer type supported by the CPU...
DomTreeNodeBase< NodeT > * getNode(NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
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)...
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...
const BasicBlock * getParent() const
void print(raw_ostream &OS, const Module *=nullptr) const override
print - Print out the internal state of the pass.