1*67e74705SXin Li //===---- CGLoopInfo.h - LLVM CodeGen for loop metadata -*- C++ -*---------===// 2*67e74705SXin Li // 3*67e74705SXin Li // The LLVM Compiler Infrastructure 4*67e74705SXin Li // 5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source 6*67e74705SXin Li // License. See LICENSE.TXT for details. 7*67e74705SXin Li // 8*67e74705SXin Li //===----------------------------------------------------------------------===// 9*67e74705SXin Li // 10*67e74705SXin Li // This is the internal state used for llvm translation for loop statement 11*67e74705SXin Li // metadata. 12*67e74705SXin Li // 13*67e74705SXin Li //===----------------------------------------------------------------------===// 14*67e74705SXin Li 15*67e74705SXin Li #ifndef LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H 16*67e74705SXin Li #define LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H 17*67e74705SXin Li 18*67e74705SXin Li #include "llvm/ADT/ArrayRef.h" 19*67e74705SXin Li #include "llvm/ADT/DenseMap.h" 20*67e74705SXin Li #include "llvm/ADT/SmallVector.h" 21*67e74705SXin Li #include "llvm/IR/DebugLoc.h" 22*67e74705SXin Li #include "llvm/IR/Value.h" 23*67e74705SXin Li #include "llvm/Support/Compiler.h" 24*67e74705SXin Li 25*67e74705SXin Li namespace llvm { 26*67e74705SXin Li class BasicBlock; 27*67e74705SXin Li class Instruction; 28*67e74705SXin Li class MDNode; 29*67e74705SXin Li } // end namespace llvm 30*67e74705SXin Li 31*67e74705SXin Li namespace clang { 32*67e74705SXin Li class Attr; 33*67e74705SXin Li class ASTContext; 34*67e74705SXin Li namespace CodeGen { 35*67e74705SXin Li 36*67e74705SXin Li /// \brief Attributes that may be specified on loops. 37*67e74705SXin Li struct LoopAttributes { 38*67e74705SXin Li explicit LoopAttributes(bool IsParallel = false); 39*67e74705SXin Li void clear(); 40*67e74705SXin Li 41*67e74705SXin Li /// \brief Generate llvm.loop.parallel metadata for loads and stores. 42*67e74705SXin Li bool IsParallel; 43*67e74705SXin Li 44*67e74705SXin Li /// \brief State of loop vectorization or unrolling. 45*67e74705SXin Li enum LVEnableState { Unspecified, Enable, Disable, Full }; 46*67e74705SXin Li 47*67e74705SXin Li /// \brief Value for llvm.loop.vectorize.enable metadata. 48*67e74705SXin Li LVEnableState VectorizeEnable; 49*67e74705SXin Li 50*67e74705SXin Li /// \brief Value for llvm.loop.unroll.* metadata (enable, disable, or full). 51*67e74705SXin Li LVEnableState UnrollEnable; 52*67e74705SXin Li 53*67e74705SXin Li /// \brief Value for llvm.loop.vectorize.width metadata. 54*67e74705SXin Li unsigned VectorizeWidth; 55*67e74705SXin Li 56*67e74705SXin Li /// \brief Value for llvm.loop.interleave.count metadata. 57*67e74705SXin Li unsigned InterleaveCount; 58*67e74705SXin Li 59*67e74705SXin Li /// \brief llvm.unroll. 60*67e74705SXin Li unsigned UnrollCount; 61*67e74705SXin Li 62*67e74705SXin Li /// \brief Value for llvm.loop.distribute.enable metadata. 63*67e74705SXin Li LVEnableState DistributeEnable; 64*67e74705SXin Li }; 65*67e74705SXin Li 66*67e74705SXin Li /// \brief Information used when generating a structured loop. 67*67e74705SXin Li class LoopInfo { 68*67e74705SXin Li public: 69*67e74705SXin Li /// \brief Construct a new LoopInfo for the loop with entry Header. 70*67e74705SXin Li LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs, 71*67e74705SXin Li llvm::DebugLoc Location); 72*67e74705SXin Li 73*67e74705SXin Li /// \brief Get the loop id metadata for this loop. getLoopID()74*67e74705SXin Li llvm::MDNode *getLoopID() const { return LoopID; } 75*67e74705SXin Li 76*67e74705SXin Li /// \brief Get the header block of this loop. getHeader()77*67e74705SXin Li llvm::BasicBlock *getHeader() const { return Header; } 78*67e74705SXin Li 79*67e74705SXin Li /// \brief Get the set of attributes active for this loop. getAttributes()80*67e74705SXin Li const LoopAttributes &getAttributes() const { return Attrs; } 81*67e74705SXin Li 82*67e74705SXin Li private: 83*67e74705SXin Li /// \brief Loop ID metadata. 84*67e74705SXin Li llvm::MDNode *LoopID; 85*67e74705SXin Li /// \brief Header block of this loop. 86*67e74705SXin Li llvm::BasicBlock *Header; 87*67e74705SXin Li /// \brief The attributes for this loop. 88*67e74705SXin Li LoopAttributes Attrs; 89*67e74705SXin Li }; 90*67e74705SXin Li 91*67e74705SXin Li /// \brief A stack of loop information corresponding to loop nesting levels. 92*67e74705SXin Li /// This stack can be used to prepare attributes which are applied when a loop 93*67e74705SXin Li /// is emitted. 94*67e74705SXin Li class LoopInfoStack { 95*67e74705SXin Li LoopInfoStack(const LoopInfoStack &) = delete; 96*67e74705SXin Li void operator=(const LoopInfoStack &) = delete; 97*67e74705SXin Li 98*67e74705SXin Li public: LoopInfoStack()99*67e74705SXin Li LoopInfoStack() {} 100*67e74705SXin Li 101*67e74705SXin Li /// \brief Begin a new structured loop. The set of staged attributes will be 102*67e74705SXin Li /// applied to the loop and then cleared. 103*67e74705SXin Li void push(llvm::BasicBlock *Header, 104*67e74705SXin Li llvm::DebugLoc Location = llvm::DebugLoc()); 105*67e74705SXin Li 106*67e74705SXin Li /// \brief Begin a new structured loop. Stage attributes from the Attrs list. 107*67e74705SXin Li /// The staged attributes are applied to the loop and then cleared. 108*67e74705SXin Li void push(llvm::BasicBlock *Header, clang::ASTContext &Ctx, 109*67e74705SXin Li llvm::ArrayRef<const Attr *> Attrs, 110*67e74705SXin Li llvm::DebugLoc Location = llvm::DebugLoc()); 111*67e74705SXin Li 112*67e74705SXin Li /// \brief End the current loop. 113*67e74705SXin Li void pop(); 114*67e74705SXin Li 115*67e74705SXin Li /// \brief Return the top loop id metadata. getCurLoopID()116*67e74705SXin Li llvm::MDNode *getCurLoopID() const { return getInfo().getLoopID(); } 117*67e74705SXin Li 118*67e74705SXin Li /// \brief Return true if the top loop is parallel. getCurLoopParallel()119*67e74705SXin Li bool getCurLoopParallel() const { 120*67e74705SXin Li return hasInfo() ? getInfo().getAttributes().IsParallel : false; 121*67e74705SXin Li } 122*67e74705SXin Li 123*67e74705SXin Li /// \brief Function called by the CodeGenFunction when an instruction is 124*67e74705SXin Li /// created. 125*67e74705SXin Li void InsertHelper(llvm::Instruction *I) const; 126*67e74705SXin Li 127*67e74705SXin Li /// \brief Set the next pushed loop as parallel. 128*67e74705SXin Li void setParallel(bool Enable = true) { StagedAttrs.IsParallel = Enable; } 129*67e74705SXin Li 130*67e74705SXin Li /// \brief Set the next pushed loop 'vectorize.enable' 131*67e74705SXin Li void setVectorizeEnable(bool Enable = true) { 132*67e74705SXin Li StagedAttrs.VectorizeEnable = 133*67e74705SXin Li Enable ? LoopAttributes::Enable : LoopAttributes::Disable; 134*67e74705SXin Li } 135*67e74705SXin Li 136*67e74705SXin Li /// \brief Set the next pushed loop as a distribution candidate. 137*67e74705SXin Li void setDistributeState(bool Enable = true) { 138*67e74705SXin Li StagedAttrs.DistributeEnable = 139*67e74705SXin Li Enable ? LoopAttributes::Enable : LoopAttributes::Disable; 140*67e74705SXin Li } 141*67e74705SXin Li 142*67e74705SXin Li /// \brief Set the next pushed loop unroll state. setUnrollState(const LoopAttributes::LVEnableState & State)143*67e74705SXin Li void setUnrollState(const LoopAttributes::LVEnableState &State) { 144*67e74705SXin Li StagedAttrs.UnrollEnable = State; 145*67e74705SXin Li } 146*67e74705SXin Li 147*67e74705SXin Li /// \brief Set the vectorize width for the next loop pushed. setVectorizeWidth(unsigned W)148*67e74705SXin Li void setVectorizeWidth(unsigned W) { StagedAttrs.VectorizeWidth = W; } 149*67e74705SXin Li 150*67e74705SXin Li /// \brief Set the interleave count for the next loop pushed. setInterleaveCount(unsigned C)151*67e74705SXin Li void setInterleaveCount(unsigned C) { StagedAttrs.InterleaveCount = C; } 152*67e74705SXin Li 153*67e74705SXin Li /// \brief Set the unroll count for the next loop pushed. setUnrollCount(unsigned C)154*67e74705SXin Li void setUnrollCount(unsigned C) { StagedAttrs.UnrollCount = C; } 155*67e74705SXin Li 156*67e74705SXin Li private: 157*67e74705SXin Li /// \brief Returns true if there is LoopInfo on the stack. hasInfo()158*67e74705SXin Li bool hasInfo() const { return !Active.empty(); } 159*67e74705SXin Li /// \brief Return the LoopInfo for the current loop. HasInfo should be called 160*67e74705SXin Li /// first to ensure LoopInfo is present. getInfo()161*67e74705SXin Li const LoopInfo &getInfo() const { return Active.back(); } 162*67e74705SXin Li /// \brief The set of attributes that will be applied to the next pushed loop. 163*67e74705SXin Li LoopAttributes StagedAttrs; 164*67e74705SXin Li /// \brief Stack of active loops. 165*67e74705SXin Li llvm::SmallVector<LoopInfo, 4> Active; 166*67e74705SXin Li }; 167*67e74705SXin Li 168*67e74705SXin Li } // end namespace CodeGen 169*67e74705SXin Li } // end namespace clang 170*67e74705SXin Li 171*67e74705SXin Li #endif 172