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