| //===---- CGLoopInfo.h - LLVM CodeGen for loop metadata -*- C++ -*---------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This is the internal state used for llvm translation for loop statement |
| // metadata. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef CLANG_CODEGEN_CGLOOPINFO_H |
| #define CLANG_CODEGEN_CGLOOPINFO_H |
| |
| #include "llvm/ADT/DenseMap.h" |
| #include "llvm/ADT/SmallVector.h" |
| #include "llvm/IR/Value.h" |
| #include "llvm/Support/Compiler.h" |
| |
| namespace llvm { |
| class BasicBlock; |
| class Instruction; |
| class MDNode; |
| } // end namespace llvm |
| |
| namespace clang { |
| namespace CodeGen { |
| |
| /// \brief Attributes that may be specified on loops. |
| struct LoopAttributes { |
| explicit LoopAttributes(bool IsParallel = false); |
| void clear(); |
| |
| /// \brief Generate llvm.loop.parallel metadata for loads and stores. |
| bool IsParallel; |
| |
| /// \brief Values of llvm.loop.vectorize.enable metadata. |
| enum LVEnableState { VecUnspecified, VecEnable, VecDisable }; |
| |
| /// \brief llvm.loop.vectorize.enable |
| LVEnableState VectorizerEnable; |
| |
| /// \brief llvm.loop.vectorize.width |
| unsigned VectorizerWidth; |
| |
| /// \brief llvm.loop.interleave.count |
| unsigned VectorizerUnroll; |
| }; |
| |
| /// \brief Information used when generating a structured loop. |
| class LoopInfo { |
| public: |
| /// \brief Construct a new LoopInfo for the loop with entry Header. |
| LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs); |
| |
| /// \brief Get the loop id metadata for this loop. |
| llvm::MDNode *getLoopID() const { return LoopID; } |
| |
| /// \brief Get the header block of this loop. |
| llvm::BasicBlock *getHeader() const { return Header; } |
| |
| /// \brief Get the set of attributes active for this loop. |
| const LoopAttributes &getAttributes() const { return Attrs; } |
| |
| private: |
| /// \brief Loop ID metadata. |
| llvm::MDNode *LoopID; |
| /// \brief Header block of this loop. |
| llvm::BasicBlock *Header; |
| /// \brief The attributes for this loop. |
| LoopAttributes Attrs; |
| }; |
| |
| /// \brief A stack of loop information corresponding to loop nesting levels. |
| /// This stack can be used to prepare attributes which are applied when a loop |
| /// is emitted. |
| class LoopInfoStack { |
| LoopInfoStack(const LoopInfoStack &) LLVM_DELETED_FUNCTION; |
| void operator=(const LoopInfoStack &) LLVM_DELETED_FUNCTION; |
| |
| public: |
| LoopInfoStack() {} |
| |
| /// \brief Begin a new structured loop. The set of staged attributes will be |
| /// applied to the loop and then cleared. |
| void push(llvm::BasicBlock *Header); |
| |
| /// \brief End the current loop. |
| void pop(); |
| |
| /// \brief Return the top loop id metadata. |
| llvm::MDNode *getCurLoopID() const { return getInfo().getLoopID(); } |
| |
| /// \brief Return true if the top loop is parallel. |
| bool getCurLoopParallel() const { |
| return hasInfo() ? getInfo().getAttributes().IsParallel : false; |
| } |
| |
| /// \brief Function called by the CodeGenFunction when an instruction is |
| /// created. |
| void InsertHelper(llvm::Instruction *I) const; |
| |
| /// \brief Set the next pushed loop as parallel. |
| void setParallel(bool Enable = true) { StagedAttrs.IsParallel = Enable; } |
| |
| /// \brief Set the next pushed loop 'vectorizer.enable' |
| void setVectorizerEnable(bool Enable = true) { |
| StagedAttrs.VectorizerEnable = |
| Enable ? LoopAttributes::VecEnable : LoopAttributes::VecDisable; |
| } |
| |
| /// \brief Set the vectorizer width for the next loop pushed. |
| void setVectorizerWidth(unsigned W) { StagedAttrs.VectorizerWidth = W; } |
| |
| /// \brief Set the vectorizer unroll for the next loop pushed. |
| void setVectorizerUnroll(unsigned U) { StagedAttrs.VectorizerUnroll = U; } |
| |
| private: |
| /// \brief Returns true if there is LoopInfo on the stack. |
| bool hasInfo() const { return !Active.empty(); } |
| /// \brief Return the LoopInfo for the current loop. HasInfo should be called |
| /// first to ensure LoopInfo is present. |
| const LoopInfo &getInfo() const { return Active.back(); } |
| /// \brief The set of attributes that will be applied to the next pushed loop. |
| LoopAttributes StagedAttrs; |
| /// \brief Stack of active loops. |
| llvm::SmallVector<LoopInfo, 4> Active; |
| }; |
| |
| } // end namespace CodeGen |
| } // end namespace clang |
| |
| #endif // CLANG_CODEGEN_CGLOOPINFO_H |