CGLoopInfo.h revision 344779
155714Skris//===---- CGLoopInfo.h - LLVM CodeGen for loop metadata -*- C++ -*---------===// 255714Skris// 355714Skris// The LLVM Compiler Infrastructure 455714Skris// 555714Skris// This file is distributed under the University of Illinois Open Source 655714Skris// License. See LICENSE.TXT for details. 755714Skris// 8280304Sjkim//===----------------------------------------------------------------------===// 955714Skris// 1055714Skris// This is the internal state used for llvm translation for loop statement 1155714Skris// metadata. 1255714Skris// 1355714Skris//===----------------------------------------------------------------------===// 1455714Skris 15280304Sjkim#ifndef LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H 1655714Skris#define LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H 1755714Skris 1855714Skris#include "llvm/ADT/ArrayRef.h" 1955714Skris#include "llvm/ADT/SmallVector.h" 2055714Skris#include "llvm/IR/DebugLoc.h" 2155714Skris#include "llvm/IR/Value.h" 22280304Sjkim#include "llvm/Support/Compiler.h" 2355714Skris 2455714Skrisnamespace llvm { 2555714Skrisclass BasicBlock; 2655714Skrisclass Instruction; 2755714Skrisclass MDNode; 2855714Skris} // end namespace llvm 2955714Skris 3055714Skrisnamespace clang { 3155714Skrisclass Attr; 3255714Skrisclass ASTContext; 3355714Skrisnamespace CodeGen { 3455714Skris 3555714Skris/// Attributes that may be specified on loops. 3655714Skrisstruct LoopAttributes { 37280304Sjkim explicit LoopAttributes(bool IsParallel = false); 3855714Skris void clear(); 3955714Skris 40280304Sjkim /// Generate llvm.loop.parallel metadata for loads and stores. 4155714Skris bool IsParallel; 4255714Skris 4355714Skris /// State of loop vectorization or unrolling. 4455714Skris enum LVEnableState { Unspecified, Enable, Disable, Full }; 4555714Skris 4655714Skris /// Value for llvm.loop.vectorize.enable metadata. 4755714Skris LVEnableState VectorizeEnable; 4855714Skris 4955714Skris /// Value for llvm.loop.unroll.* metadata (enable, disable, or full). 5055714Skris LVEnableState UnrollEnable; 5155714Skris 52280304Sjkim /// Value for llvm.loop.unroll_and_jam.* metadata (enable, disable, or full). 5355714Skris LVEnableState UnrollAndJamEnable; 5455714Skris 5555714Skris /// Value for llvm.loop.vectorize.width metadata. 5655714Skris unsigned VectorizeWidth; 5755714Skris 5855714Skris /// Value for llvm.loop.interleave.count metadata. 5955714Skris unsigned InterleaveCount; 6055714Skris 6155714Skris /// llvm.unroll. 6255714Skris unsigned UnrollCount; 63280304Sjkim 6455714Skris /// llvm.unroll. 6555714Skris unsigned UnrollAndJamCount; 6655714Skris 67111147Snectar /// Value for llvm.loop.distribute.enable metadata. 6855714Skris LVEnableState DistributeEnable; 6955714Skris 7055714Skris /// Value for llvm.loop.pipeline.disable metadata. 7155714Skris bool PipelineDisabled; 72280304Sjkim 73280304Sjkim /// Value for llvm.loop.pipeline.iicount metadata. 74280304Sjkim unsigned PipelineInitiationInterval; 7555714Skris}; 76280304Sjkim 77280304Sjkim/// Information used when generating a structured loop. 78280304Sjkimclass LoopInfo { 79280304Sjkimpublic: 80280304Sjkim /// Construct a new LoopInfo for the loop with entry Header. 81280304Sjkim LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs, 82280304Sjkim const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc); 83280304Sjkim 84280304Sjkim /// Get the loop id metadata for this loop. 85280304Sjkim llvm::MDNode *getLoopID() const { return LoopID; } 86280304Sjkim 87280304Sjkim /// Get the header block of this loop. 88280304Sjkim llvm::BasicBlock *getHeader() const { return Header; } 89280304Sjkim 90280304Sjkim /// Get the set of attributes active for this loop. 91280304Sjkim const LoopAttributes &getAttributes() const { return Attrs; } 92280304Sjkim 9355714Skris /// Return this loop's access group or nullptr if it does not have one. 9455714Skris llvm::MDNode *getAccessGroup() const { return AccGroup; } 95280304Sjkim 96280304Sjkimprivate: 97280304Sjkim /// Loop ID metadata. 98280304Sjkim llvm::MDNode *LoopID; 99280304Sjkim /// Header block of this loop. 100280304Sjkim llvm::BasicBlock *Header; 10155714Skris /// The attributes for this loop. 102280304Sjkim LoopAttributes Attrs; 103280304Sjkim /// The access group for memory accesses parallel to this loop. 104280304Sjkim llvm::MDNode *AccGroup = nullptr; 105280304Sjkim}; 106280304Sjkim 107280304Sjkim/// A stack of loop information corresponding to loop nesting levels. 108280304Sjkim/// This stack can be used to prepare attributes which are applied when a loop 109280304Sjkim/// is emitted. 110280304Sjkimclass LoopInfoStack { 111280304Sjkim LoopInfoStack(const LoopInfoStack &) = delete; 112280304Sjkim void operator=(const LoopInfoStack &) = delete; 11355714Skris 11455714Skrispublic: 115280304Sjkim LoopInfoStack() {} 116280304Sjkim 11755714Skris /// Begin a new structured loop. The set of staged attributes will be 118280304Sjkim /// applied to the loop and then cleared. 119280304Sjkim void push(llvm::BasicBlock *Header, const llvm::DebugLoc &StartLoc, 120280304Sjkim const llvm::DebugLoc &EndLoc); 121280304Sjkim 122 /// Begin a new structured loop. Stage attributes from the Attrs list. 123 /// The staged attributes are applied to the loop and then cleared. 124 void push(llvm::BasicBlock *Header, clang::ASTContext &Ctx, 125 llvm::ArrayRef<const Attr *> Attrs, const llvm::DebugLoc &StartLoc, 126 const llvm::DebugLoc &EndLoc); 127 128 /// End the current loop. 129 void pop(); 130 131 /// Return the top loop id metadata. 132 llvm::MDNode *getCurLoopID() const { return getInfo().getLoopID(); } 133 134 /// Return true if the top loop is parallel. 135 bool getCurLoopParallel() const { 136 return hasInfo() ? getInfo().getAttributes().IsParallel : false; 137 } 138 139 /// Function called by the CodeGenFunction when an instruction is 140 /// created. 141 void InsertHelper(llvm::Instruction *I) const; 142 143 /// Set the next pushed loop as parallel. 144 void setParallel(bool Enable = true) { StagedAttrs.IsParallel = Enable; } 145 146 /// Set the next pushed loop 'vectorize.enable' 147 void setVectorizeEnable(bool Enable = true) { 148 StagedAttrs.VectorizeEnable = 149 Enable ? LoopAttributes::Enable : LoopAttributes::Disable; 150 } 151 152 /// Set the next pushed loop as a distribution candidate. 153 void setDistributeState(bool Enable = true) { 154 StagedAttrs.DistributeEnable = 155 Enable ? LoopAttributes::Enable : LoopAttributes::Disable; 156 } 157 158 /// Set the next pushed loop unroll state. 159 void setUnrollState(const LoopAttributes::LVEnableState &State) { 160 StagedAttrs.UnrollEnable = State; 161 } 162 163 /// Set the next pushed loop unroll_and_jam state. 164 void setUnrollAndJamState(const LoopAttributes::LVEnableState &State) { 165 StagedAttrs.UnrollAndJamEnable = State; 166 } 167 168 /// Set the vectorize width for the next loop pushed. 169 void setVectorizeWidth(unsigned W) { StagedAttrs.VectorizeWidth = W; } 170 171 /// Set the interleave count for the next loop pushed. 172 void setInterleaveCount(unsigned C) { StagedAttrs.InterleaveCount = C; } 173 174 /// Set the unroll count for the next loop pushed. 175 void setUnrollCount(unsigned C) { StagedAttrs.UnrollCount = C; } 176 177 /// \brief Set the unroll count for the next loop pushed. 178 void setUnrollAndJamCount(unsigned C) { StagedAttrs.UnrollAndJamCount = C; } 179 180 /// Set the pipeline disabled state. 181 void setPipelineDisabled(bool S) { StagedAttrs.PipelineDisabled = S; } 182 183 /// Set the pipeline initiation interval. 184 void setPipelineInitiationInterval(unsigned C) { 185 StagedAttrs.PipelineInitiationInterval = C; 186 } 187 188private: 189 /// Returns true if there is LoopInfo on the stack. 190 bool hasInfo() const { return !Active.empty(); } 191 /// Return the LoopInfo for the current loop. HasInfo should be called 192 /// first to ensure LoopInfo is present. 193 const LoopInfo &getInfo() const { return Active.back(); } 194 /// The set of attributes that will be applied to the next pushed loop. 195 LoopAttributes StagedAttrs; 196 /// Stack of active loops. 197 llvm::SmallVector<LoopInfo, 4> Active; 198}; 199 200} // end namespace CodeGen 201} // end namespace clang 202 203#endif 204