34 #define DEBUG_TYPE "iv-users"
38 "Induction Variable Users",
false,
true)
59 if (AR->getLoop() == L)
60 return AR->isAffine() ||
71 if (
const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
72 bool AnyInterestingYet =
false;
76 if (AnyInterestingYet)
78 AnyInterestingYet =
true;
80 return AnyInterestingYet;
92 Loop *NearestLoop =
nullptr;
97 if (DomLoop && DomLoop->
getHeader() == DomBB) {
102 if (SimpleLoopNests.
count(DomLoop))
107 NearestLoop = DomLoop;
111 SimpleLoopNests.
insert(NearestLoop);
124 if (!Processed.insert(I).second)
145 if (EphValues.count(I))
159 if (!UniqueUsers.
insert(User).second)
163 if (isa<PHINode>(User) && Processed.count(User))
171 unsigned OperandNo = U.getOperandNo();
173 UseBB =
PHI->getIncomingBlock(ValNo);
184 bool AddUserToIVUsers =
false;
186 if (isa<PHINode>(User) || Processed.count(User) ||
188 DEBUG(
dbgs() <<
"FOUND USER in other loop: " << *User <<
'\n'
189 <<
" OF SCEV: " << *ISE <<
'\n');
190 AddUserToIVUsers =
true;
192 }
else if (Processed.count(User) || !
AddUsersImpl(User, SimpleLoopNests)) {
193 DEBUG(
dbgs() <<
"FOUND USER: " << *User <<
'\n'
194 <<
" OF SCEV: " << *ISE <<
'\n');
195 AddUserToIVUsers =
true;
198 if (AddUserToIVUsers) {
204 const SCEV *OriginalISE = ISE;
214 if (OriginalISE != ISE) {
215 const SCEV *DenormalizedISE =
217 NewUse.PostIncLoops, *SE, *DT);
221 if (OriginalISE != DenormalizedISE) {
222 DEBUG(
dbgs() <<
" DISCARDING (NORMALIZATION ISN'T INVERTIBLE): "
229 dbgs() <<
" NORMALIZED TO: " << *ISE <<
'\n');
245 IVUses.push_back(
new IVStrideUse(
this, User, Operand));
246 return IVUses.back();
265 AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
267 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
268 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
269 SE = &getAnalysis<ScalarEvolution>();
285 OS <<
"IV Users for loop ";
286 L->
getHeader()->printAsOperand(OS,
false);
288 OS <<
" with backedge-taken count "
294 E = IVUses.end(); UI != E; ++UI) {
296 UI->getOperandValToReplace()->printAsOperand(OS,
false);
299 I = UI->PostIncLoops.begin(),
300 E = UI->PostIncLoops.end();
I != E; ++
I) {
301 OS <<
" (post-inc with loop ";
302 (*I)->getHeader()->printAsOperand(OS,
false);
307 UI->getUser()->print(OS);
309 OS <<
"Printing <null> User";
314 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
320 void IVUsers::releaseMemory() {
342 if (AR->getLoop() == L)
347 if (
const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
360 return AR->getStepRecurrence(*SE);
368 void IVStrideUse::deleted() {
370 Parent->Processed.erase(this->
getUser());
371 Parent->IVUses.erase(
this);
Pass interface - Implemented by all 'passes'.
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...
A Module instance is used to store all the information related to an LLVM module. ...
Pass * createIVUsersPass()
ScalarEvolution - This class is 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.
An immutable pass that tracks lazily created AssumptionCache objects.
void print(raw_ostream &OS, const Module *=nullptr) const override
print - Print out the internal state of the pass.
LoopT * getLoopFor(const BlockT *BB) const
getLoopFor - 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.
void initializeIVUsersPass(PassRegistry &)
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
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
uint64_t getTypeSizeInBits(Type *Ty) const
getTypeSizeInBits - Return the size in bits of the specified type, for which isSCEVable must return t...
bool isLoopSimplifyForm() const
isLoopSimplifyForm - Return true if the Loop is in the form that the LoopSimplify form transforms loo...
SCEVAddRecExpr - 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.
Instruction * getUser() const
getUser - Return the user instruction for this use.
NormalizeAutodetect - Detect post-inc opportunities on new expressions, update the given loop set...
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
bool isSCEVable(Type *Ty) const
isSCEVable - 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.
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)
getSCEVAtScope - Return a SCEV expression for the specified value at the specified scope in the progr...
Represent the analysis usage information of a pass.
bool contains(const LoopT *L) const
contains - Return true if the specified loop is contained within in this loop.
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
SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
DomTreeNodeBase< NodeT > * getIDom() const
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.
SCEVAddExpr - This node represents an addition of some number of SCEVs.
void setPreservesAll()
Set by analyses that do not transform their input at all.
void dump() const
dump - This method is used for debugging.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
SCEV - This class represents an analyzed expression in the program.
bool isLegalInteger(unsigned Width) const
Returns true if the specified type is known to be a native integer type supported by the CPU...
void transformToPostInc(const Loop *L)
transformToPostInc - Transform the expression to post-inc form for the given loop.
INITIALIZE_PASS_BEGIN(IVUsers,"iv-users","Induction Variable Users", false, true) INITIALIZE_PASS_END(IVUsers
const SCEV * getBackedgeTakenCount(const Loop *L)
getBackedgeTakenCount - If the specified loop has a predictable backedge-taken count, return it, otherwise return a SCEVCouldNotCompute object.
static const SCEVAddRecExpr * findAddRecForLoop(const SCEV *S, const Loop *L)
LLVM Value Representation.
const SCEV * getSCEV(Value *V)
getSCEV - Return a SCEV expression for the full generality of the specified expression.
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.
bool isSafeToSpeculativelyExecute(const Value *V, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
isSafeToSpeculativelyExecute - Return true if the instruction does not have any effects besides calcu...
Legacy analysis pass which computes a DominatorTree.
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)
hasLoopInvariantBackedgeTakenCount - Return true if the specified loop has an analyzable loop-invaria...
const BasicBlock * getParent() const