1*0a6a1f1dSLionel Sambuc //===---- CGLoopInfo.h - LLVM CodeGen for loop metadata -*- C++ -*---------===// 2*0a6a1f1dSLionel Sambuc // 3*0a6a1f1dSLionel Sambuc // The LLVM Compiler Infrastructure 4*0a6a1f1dSLionel Sambuc // 5*0a6a1f1dSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*0a6a1f1dSLionel Sambuc // License. See LICENSE.TXT for details. 7*0a6a1f1dSLionel Sambuc // 8*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===// 9*0a6a1f1dSLionel Sambuc // 10*0a6a1f1dSLionel Sambuc // This is the internal state used for llvm translation for loop statement 11*0a6a1f1dSLionel Sambuc // metadata. 12*0a6a1f1dSLionel Sambuc // 13*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===// 14*0a6a1f1dSLionel Sambuc 15*0a6a1f1dSLionel Sambuc #ifndef LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H 16*0a6a1f1dSLionel Sambuc #define LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H 17*0a6a1f1dSLionel Sambuc 18*0a6a1f1dSLionel Sambuc #include "llvm/ADT/DenseMap.h" 19*0a6a1f1dSLionel Sambuc #include "llvm/ADT/SmallVector.h" 20*0a6a1f1dSLionel Sambuc #include "llvm/IR/Value.h" 21*0a6a1f1dSLionel Sambuc #include "llvm/Support/Compiler.h" 22*0a6a1f1dSLionel Sambuc 23*0a6a1f1dSLionel Sambuc namespace llvm { 24*0a6a1f1dSLionel Sambuc class BasicBlock; 25*0a6a1f1dSLionel Sambuc class Instruction; 26*0a6a1f1dSLionel Sambuc class MDNode; 27*0a6a1f1dSLionel Sambuc } // end namespace llvm 28*0a6a1f1dSLionel Sambuc 29*0a6a1f1dSLionel Sambuc namespace clang { 30*0a6a1f1dSLionel Sambuc namespace CodeGen { 31*0a6a1f1dSLionel Sambuc 32*0a6a1f1dSLionel Sambuc /// \brief Attributes that may be specified on loops. 33*0a6a1f1dSLionel Sambuc struct LoopAttributes { 34*0a6a1f1dSLionel Sambuc explicit LoopAttributes(bool IsParallel = false); 35*0a6a1f1dSLionel Sambuc void clear(); 36*0a6a1f1dSLionel Sambuc 37*0a6a1f1dSLionel Sambuc /// \brief Generate llvm.loop.parallel metadata for loads and stores. 38*0a6a1f1dSLionel Sambuc bool IsParallel; 39*0a6a1f1dSLionel Sambuc 40*0a6a1f1dSLionel Sambuc /// \brief Values of llvm.loop.vectorize.enable metadata. 41*0a6a1f1dSLionel Sambuc enum LVEnableState { VecUnspecified, VecEnable, VecDisable }; 42*0a6a1f1dSLionel Sambuc 43*0a6a1f1dSLionel Sambuc /// \brief llvm.loop.vectorize.enable 44*0a6a1f1dSLionel Sambuc LVEnableState VectorizerEnable; 45*0a6a1f1dSLionel Sambuc 46*0a6a1f1dSLionel Sambuc /// \brief llvm.loop.vectorize.width 47*0a6a1f1dSLionel Sambuc unsigned VectorizerWidth; 48*0a6a1f1dSLionel Sambuc 49*0a6a1f1dSLionel Sambuc /// \brief llvm.loop.interleave.count 50*0a6a1f1dSLionel Sambuc unsigned VectorizerUnroll; 51*0a6a1f1dSLionel Sambuc }; 52*0a6a1f1dSLionel Sambuc 53*0a6a1f1dSLionel Sambuc /// \brief Information used when generating a structured loop. 54*0a6a1f1dSLionel Sambuc class LoopInfo { 55*0a6a1f1dSLionel Sambuc public: 56*0a6a1f1dSLionel Sambuc /// \brief Construct a new LoopInfo for the loop with entry Header. 57*0a6a1f1dSLionel Sambuc LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs); 58*0a6a1f1dSLionel Sambuc 59*0a6a1f1dSLionel Sambuc /// \brief Get the loop id metadata for this loop. getLoopID()60*0a6a1f1dSLionel Sambuc llvm::MDNode *getLoopID() const { return LoopID; } 61*0a6a1f1dSLionel Sambuc 62*0a6a1f1dSLionel Sambuc /// \brief Get the header block of this loop. getHeader()63*0a6a1f1dSLionel Sambuc llvm::BasicBlock *getHeader() const { return Header; } 64*0a6a1f1dSLionel Sambuc 65*0a6a1f1dSLionel Sambuc /// \brief Get the set of attributes active for this loop. getAttributes()66*0a6a1f1dSLionel Sambuc const LoopAttributes &getAttributes() const { return Attrs; } 67*0a6a1f1dSLionel Sambuc 68*0a6a1f1dSLionel Sambuc private: 69*0a6a1f1dSLionel Sambuc /// \brief Loop ID metadata. 70*0a6a1f1dSLionel Sambuc llvm::MDNode *LoopID; 71*0a6a1f1dSLionel Sambuc /// \brief Header block of this loop. 72*0a6a1f1dSLionel Sambuc llvm::BasicBlock *Header; 73*0a6a1f1dSLionel Sambuc /// \brief The attributes for this loop. 74*0a6a1f1dSLionel Sambuc LoopAttributes Attrs; 75*0a6a1f1dSLionel Sambuc }; 76*0a6a1f1dSLionel Sambuc 77*0a6a1f1dSLionel Sambuc /// \brief A stack of loop information corresponding to loop nesting levels. 78*0a6a1f1dSLionel Sambuc /// This stack can be used to prepare attributes which are applied when a loop 79*0a6a1f1dSLionel Sambuc /// is emitted. 80*0a6a1f1dSLionel Sambuc class LoopInfoStack { 81*0a6a1f1dSLionel Sambuc LoopInfoStack(const LoopInfoStack &) LLVM_DELETED_FUNCTION; 82*0a6a1f1dSLionel Sambuc void operator=(const LoopInfoStack &) LLVM_DELETED_FUNCTION; 83*0a6a1f1dSLionel Sambuc 84*0a6a1f1dSLionel Sambuc public: LoopInfoStack()85*0a6a1f1dSLionel Sambuc LoopInfoStack() {} 86*0a6a1f1dSLionel Sambuc 87*0a6a1f1dSLionel Sambuc /// \brief Begin a new structured loop. The set of staged attributes will be 88*0a6a1f1dSLionel Sambuc /// applied to the loop and then cleared. 89*0a6a1f1dSLionel Sambuc void push(llvm::BasicBlock *Header); 90*0a6a1f1dSLionel Sambuc 91*0a6a1f1dSLionel Sambuc /// \brief End the current loop. 92*0a6a1f1dSLionel Sambuc void pop(); 93*0a6a1f1dSLionel Sambuc 94*0a6a1f1dSLionel Sambuc /// \brief Return the top loop id metadata. getCurLoopID()95*0a6a1f1dSLionel Sambuc llvm::MDNode *getCurLoopID() const { return getInfo().getLoopID(); } 96*0a6a1f1dSLionel Sambuc 97*0a6a1f1dSLionel Sambuc /// \brief Return true if the top loop is parallel. getCurLoopParallel()98*0a6a1f1dSLionel Sambuc bool getCurLoopParallel() const { 99*0a6a1f1dSLionel Sambuc return hasInfo() ? getInfo().getAttributes().IsParallel : false; 100*0a6a1f1dSLionel Sambuc } 101*0a6a1f1dSLionel Sambuc 102*0a6a1f1dSLionel Sambuc /// \brief Function called by the CodeGenFunction when an instruction is 103*0a6a1f1dSLionel Sambuc /// created. 104*0a6a1f1dSLionel Sambuc void InsertHelper(llvm::Instruction *I) const; 105*0a6a1f1dSLionel Sambuc 106*0a6a1f1dSLionel Sambuc /// \brief Set the next pushed loop as parallel. 107*0a6a1f1dSLionel Sambuc void setParallel(bool Enable = true) { StagedAttrs.IsParallel = Enable; } 108*0a6a1f1dSLionel Sambuc 109*0a6a1f1dSLionel Sambuc /// \brief Set the next pushed loop 'vectorizer.enable' 110*0a6a1f1dSLionel Sambuc void setVectorizerEnable(bool Enable = true) { 111*0a6a1f1dSLionel Sambuc StagedAttrs.VectorizerEnable = 112*0a6a1f1dSLionel Sambuc Enable ? LoopAttributes::VecEnable : LoopAttributes::VecDisable; 113*0a6a1f1dSLionel Sambuc } 114*0a6a1f1dSLionel Sambuc 115*0a6a1f1dSLionel Sambuc /// \brief Set the vectorizer width for the next loop pushed. setVectorizerWidth(unsigned W)116*0a6a1f1dSLionel Sambuc void setVectorizerWidth(unsigned W) { StagedAttrs.VectorizerWidth = W; } 117*0a6a1f1dSLionel Sambuc 118*0a6a1f1dSLionel Sambuc /// \brief Set the vectorizer unroll for the next loop pushed. setVectorizerUnroll(unsigned U)119*0a6a1f1dSLionel Sambuc void setVectorizerUnroll(unsigned U) { StagedAttrs.VectorizerUnroll = U; } 120*0a6a1f1dSLionel Sambuc 121*0a6a1f1dSLionel Sambuc private: 122*0a6a1f1dSLionel Sambuc /// \brief Returns true if there is LoopInfo on the stack. hasInfo()123*0a6a1f1dSLionel Sambuc bool hasInfo() const { return !Active.empty(); } 124*0a6a1f1dSLionel Sambuc /// \brief Return the LoopInfo for the current loop. HasInfo should be called 125*0a6a1f1dSLionel Sambuc /// first to ensure LoopInfo is present. getInfo()126*0a6a1f1dSLionel Sambuc const LoopInfo &getInfo() const { return Active.back(); } 127*0a6a1f1dSLionel Sambuc /// \brief The set of attributes that will be applied to the next pushed loop. 128*0a6a1f1dSLionel Sambuc LoopAttributes StagedAttrs; 129*0a6a1f1dSLionel Sambuc /// \brief Stack of active loops. 130*0a6a1f1dSLionel Sambuc llvm::SmallVector<LoopInfo, 4> Active; 131*0a6a1f1dSLionel Sambuc }; 132*0a6a1f1dSLionel Sambuc 133*0a6a1f1dSLionel Sambuc } // end namespace CodeGen 134*0a6a1f1dSLionel Sambuc } // end namespace clang 135*0a6a1f1dSLionel Sambuc 136*0a6a1f1dSLionel Sambuc #endif 137