1f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===- llvm/Analysis/IVUsers.h - Induction Variable Users -------*- C++ -*-===// 2f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 3f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// The LLVM Compiler Infrastructure 4f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 5f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file is distributed under the University of Illinois Open Source 6f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// License. See LICENSE.TXT for details. 7f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 8f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===// 9f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 10f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file implements bookkeeping for "interesting" users of expressions 11f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// computed from induction variables. 12f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 13f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===// 14f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 15f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef LLVM_ANALYSIS_IVUSERS_H 16f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define LLVM_ANALYSIS_IVUSERS_H 17f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 18f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Analysis/LoopAnalysisManager.h" 19f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Analysis/LoopPass.h" 20f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Analysis/ScalarEvolutionNormalization.h" 21f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/ValueHandle.h" 22f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 23f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace llvm { 24f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 25f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass AssumptionCache; 26f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass DominatorTree; 27f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass Instruction; 28f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass Value; 29f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass ScalarEvolution; 30f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass SCEV; 31f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass IVUsers; 32f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass DataLayout; 33f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 34f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// IVStrideUse - Keep track of one use of a strided induction variable. 35f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// The Expr member keeps track of the expression, User is the actual user 36f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// instruction of the operand, and 'OperandValToReplace' is the operand of 37f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// the User that is the use. 38f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass IVStrideUse final : public CallbackVH, public ilist_node<IVStrideUse> { 39f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot friend class IVUsers; 40f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 41f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IVStrideUse(IVUsers *P, Instruction* U, Value *O) 42f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : CallbackVH(U), Parent(P), OperandValToReplace(O) { 43f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 44f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 45f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// getUser - Return the user instruction for this use. 46f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Instruction *getUser() const { 47f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return cast<Instruction>(getValPtr()); 48f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 49f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 50f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// setUser - Assign a new user instruction for this use. 51f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setUser(Instruction *NewUser) { 52f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot setValPtr(NewUser); 53f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 54f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 55f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// getOperandValToReplace - Return the Value of the operand in the user 56f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// instruction that this IVStrideUse is representing. 57f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Value *getOperandValToReplace() const { 58f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return OperandValToReplace; 59f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 60f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 61f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// setOperandValToReplace - Assign a new Value as the operand value 62f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// to replace. 63f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setOperandValToReplace(Value *Op) { 64f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot OperandValToReplace = Op; 65f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 66f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 67f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// getPostIncLoops - Return the set of loops for which the expression has 68f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// been adjusted to use post-inc mode. 69f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const PostIncLoopSet &getPostIncLoops() const { 70f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return PostIncLoops; 71f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 72f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 73f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// transformToPostInc - Transform the expression to post-inc form for the 74f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// given loop. 75f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void transformToPostInc(const Loop *L); 76f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 77f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprivate: 78f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Parent - a pointer to the IVUsers that owns this IVStrideUse. 79f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IVUsers *Parent; 80f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 81f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// OperandValToReplace - The Value of the operand in the user instruction 82f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// that this IVStrideUse is representing. 83f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot WeakTrackingVH OperandValToReplace; 84f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 85f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// PostIncLoops - The set of loops for which Expr has been adjusted to 86f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// use post-inc mode. This corresponds with SCEVExpander's post-inc concept. 87f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PostIncLoopSet PostIncLoops; 88f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 89f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Deleted - Implementation of CallbackVH virtual function to 90f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// receive notification when the User is deleted. 91f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void deleted() override; 92f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}; 93f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 94f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass IVUsers { 95f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot friend class IVStrideUse; 96f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Loop *L; 97f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot AssumptionCache *AC; 98f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot LoopInfo *LI; 99f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DominatorTree *DT; 100f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ScalarEvolution *SE; 101f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SmallPtrSet<Instruction*, 16> Processed; 102f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 103f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// IVUses - A list of all tracked IV uses of induction variable expressions 104f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// we are interested in. 105f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ilist<IVStrideUse> IVUses; 106f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 107f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // Ephemeral values used by @llvm.assume in this function. 108f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SmallPtrSet<const Value *, 32> EphValues; 109f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 110f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 111f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IVUsers(Loop *L, AssumptionCache *AC, LoopInfo *LI, DominatorTree *DT, 112f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ScalarEvolution *SE); 113f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 114f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IVUsers(IVUsers &&X) 115f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : L(std::move(X.L)), AC(std::move(X.AC)), DT(std::move(X.DT)), 116f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SE(std::move(X.SE)), Processed(std::move(X.Processed)), 117f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IVUses(std::move(X.IVUses)), EphValues(std::move(X.EphValues)) { 118f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot for (IVStrideUse &U : IVUses) 119f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot U.Parent = this; 120f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 121f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IVUsers(const IVUsers &) = delete; 122f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IVUsers &operator=(IVUsers &&) = delete; 123f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IVUsers &operator=(const IVUsers &) = delete; 124f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 125f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Loop *getLoop() const { return L; } 126f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 127f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// AddUsersIfInteresting - Inspect the specified Instruction. If it is a 128f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// reducible SCEV, recursively add its users to the IVUsesByStride set and 129f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// return true. Otherwise, return false. 130f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool AddUsersIfInteresting(Instruction *I); 131f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 132f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IVStrideUse &AddUser(Instruction *User, Value *Operand); 133f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 134f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// getReplacementExpr - Return a SCEV expression which computes the 135f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// value of the OperandValToReplace of the given IVStrideUse. 136f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const SCEV *getReplacementExpr(const IVStrideUse &IU) const; 137f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 138f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// getExpr - Return the expression for the use. 139f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const SCEV *getExpr(const IVStrideUse &IU) const; 140f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 141f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const SCEV *getStride(const IVStrideUse &IU, const Loop *L) const; 142f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 143f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot typedef ilist<IVStrideUse>::iterator iterator; 144f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot typedef ilist<IVStrideUse>::const_iterator const_iterator; 145f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot iterator begin() { return IVUses.begin(); } 146f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot iterator end() { return IVUses.end(); } 147f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const_iterator begin() const { return IVUses.begin(); } 148f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const_iterator end() const { return IVUses.end(); } 149f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool empty() const { return IVUses.empty(); } 150f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 151f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isIVUserOrOperand(Instruction *Inst) const { 152f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Processed.count(Inst); 153f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 154f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 155f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void releaseMemory(); 156f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 157f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void print(raw_ostream &OS, const Module * = nullptr) const; 158f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 159f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// dump - This method is used for debugging. 160f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void dump() const; 161f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 162f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprotected: 163f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool AddUsersImpl(Instruction *I, SmallPtrSetImpl<Loop*> &SimpleLoopNests); 164f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}; 165f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 166f3014761c955345d6e05491608e73228d014afbandroid-build-team RobotPass *createIVUsersPass(); 167f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 168f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass IVUsersWrapperPass : public LoopPass { 169f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot std::unique_ptr<IVUsers> IU; 170f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 171f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 172f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static char ID; 173f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 174f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IVUsersWrapperPass(); 175f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 176f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IVUsers &getIU() { return *IU; } 177f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const IVUsers &getIU() const { return *IU; } 178f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 179f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void getAnalysisUsage(AnalysisUsage &AU) const override; 180f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 181f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool runOnLoop(Loop *L, LPPassManager &LPM) override; 182f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 183f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void releaseMemory() override; 184f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 185f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void print(raw_ostream &OS, const Module * = nullptr) const override; 186f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}; 187f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 188f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Analysis pass that exposes the \c IVUsers for a loop. 189f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass IVUsersAnalysis : public AnalysisInfoMixin<IVUsersAnalysis> { 190f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot friend AnalysisInfoMixin<IVUsersAnalysis>; 191f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static AnalysisKey Key; 192f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 193f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 194f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot typedef IVUsers Result; 195f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 196f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IVUsers run(Loop &L, LoopAnalysisManager &AM, 197f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot LoopStandardAnalysisResults &AR); 198f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}; 199f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 200f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} 201f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 202f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif 203