Clang Project

clang_source_code/lib/CodeGen/CGLoopInfo.h
1//===---- CGLoopInfo.h - LLVM CodeGen for loop metadata -*- C++ -*---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This is the internal state used for llvm translation for loop statement
10// metadata.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H
15#define LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H
16
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/IR/DebugLoc.h"
20#include "llvm/IR/Value.h"
21#include "llvm/Support/Compiler.h"
22
23namespace llvm {
24class BasicBlock;
25class Instruction;
26class MDNode;
27// end namespace llvm
28
29namespace clang {
30class Attr;
31class ASTContext;
32namespace CodeGen {
33
34/// Attributes that may be specified on loops.
35struct LoopAttributes {
36  explicit LoopAttributes(bool IsParallel = false);
37  void clear();
38
39  /// Generate llvm.loop.parallel metadata for loads and stores.
40  bool IsParallel;
41
42  /// State of loop vectorization or unrolling.
43  enum LVEnableState { UnspecifiedEnableDisableFull };
44
45  /// Value for llvm.loop.vectorize.enable metadata.
46  LVEnableState VectorizeEnable;
47
48  /// Value for llvm.loop.unroll.* metadata (enable, disable, or full).
49  LVEnableState UnrollEnable;
50
51  /// Value for llvm.loop.unroll_and_jam.* metadata (enable, disable, or full).
52  LVEnableState UnrollAndJamEnable;
53
54  /// Value for llvm.loop.vectorize.width metadata.
55  unsigned VectorizeWidth;
56
57  /// Value for llvm.loop.interleave.count metadata.
58  unsigned InterleaveCount;
59
60  /// llvm.unroll.
61  unsigned UnrollCount;
62
63  /// llvm.unroll.
64  unsigned UnrollAndJamCount;
65
66  /// Value for llvm.loop.distribute.enable metadata.
67  LVEnableState DistributeEnable;
68
69  /// Value for llvm.loop.pipeline.disable metadata.
70  bool PipelineDisabled;
71
72  /// Value for llvm.loop.pipeline.iicount metadata.
73  unsigned PipelineInitiationInterval;
74};
75
76/// Information used when generating a structured loop.
77class LoopInfo {
78public:
79  /// Construct a new LoopInfo for the loop with entry Header.
80  LoopInfo(llvm::BasicBlock *Headerconst LoopAttributes &Attrs,
81           const llvm::DebugLoc &StartLocconst llvm::DebugLoc &EndLoc);
82
83  /// Get the loop id metadata for this loop.
84  llvm::MDNode *getLoopID() const { return LoopID; }
85
86  /// Get the header block of this loop.
87  llvm::BasicBlock *getHeader() const { return Header; }
88
89  /// Get the set of attributes active for this loop.
90  const LoopAttributes &getAttributes() const { return Attrs; }
91
92  /// Return this loop's access group or nullptr if it does not have one.
93  llvm::MDNode *getAccessGroup() const { return AccGroup; }
94
95private:
96  /// Loop ID metadata.
97  llvm::MDNode *LoopID;
98  /// Header block of this loop.
99  llvm::BasicBlock *Header;
100  /// The attributes for this loop.
101  LoopAttributes Attrs;
102  /// The access group for memory accesses parallel to this loop.
103  llvm::MDNode *AccGroup = nullptr;
104};
105
106/// A stack of loop information corresponding to loop nesting levels.
107/// This stack can be used to prepare attributes which are applied when a loop
108/// is emitted.
109class LoopInfoStack {
110  LoopInfoStack(const LoopInfoStack &) = delete;
111  void operator=(const LoopInfoStack &) = delete;
112
113public:
114  LoopInfoStack() {}
115
116  /// Begin a new structured loop. The set of staged attributes will be
117  /// applied to the loop and then cleared.
118  void push(llvm::BasicBlock *Headerconst llvm::DebugLoc &StartLoc,
119            const llvm::DebugLoc &EndLoc);
120
121  /// Begin a new structured loop. Stage attributes from the Attrs list.
122  /// The staged attributes are applied to the loop and then cleared.
123  void push(llvm::BasicBlock *Headerclang::ASTContext &Ctx,
124            llvm::ArrayRef<const Attr *> Attrsconst llvm::DebugLoc &StartLoc,
125            const llvm::DebugLoc &EndLoc);
126
127  /// End the current loop.
128  void pop();
129
130  /// Return the top loop id metadata.
131  llvm::MDNode *getCurLoopID() const { return getInfo().getLoopID(); }
132
133  /// Return true if the top loop is parallel.
134  bool getCurLoopParallel() const {
135    return hasInfo() ? getInfo().getAttributes().IsParallel : false;
136  }
137
138  /// Function called by the CodeGenFunction when an instruction is
139  /// created.
140  void InsertHelper(llvm::Instruction *Iconst;
141
142  /// Set the next pushed loop as parallel.
143  void setParallel(bool Enable = true) { StagedAttrs.IsParallel = Enable; }
144
145  /// Set the next pushed loop 'vectorize.enable'
146  void setVectorizeEnable(bool Enable = true) {
147    StagedAttrs.VectorizeEnable =
148        Enable ? LoopAttributes::Enable : LoopAttributes::Disable;
149  }
150
151  /// Set the next pushed loop as a distribution candidate.
152  void setDistributeState(bool Enable = true) {
153    StagedAttrs.DistributeEnable =
154        Enable ? LoopAttributes::Enable : LoopAttributes::Disable;
155  }
156
157  /// Set the next pushed loop unroll state.
158  void setUnrollState(const LoopAttributes::LVEnableState &State) {
159    StagedAttrs.UnrollEnable = State;
160  }
161
162  /// Set the next pushed loop unroll_and_jam state.
163  void setUnrollAndJamState(const LoopAttributes::LVEnableState &State) {
164    StagedAttrs.UnrollAndJamEnable = State;
165  }
166
167  /// Set the vectorize width for the next loop pushed.
168  void setVectorizeWidth(unsigned W) { StagedAttrs.VectorizeWidth = W; }
169
170  /// Set the interleave count for the next loop pushed.
171  void setInterleaveCount(unsigned C) { StagedAttrs.InterleaveCount = C; }
172
173  /// Set the unroll count for the next loop pushed.
174  void setUnrollCount(unsigned C) { StagedAttrs.UnrollCount = C; }
175
176  /// \brief Set the unroll count for the next loop pushed.
177  void setUnrollAndJamCount(unsigned C) { StagedAttrs.UnrollAndJamCount = C; }
178
179  /// Set the pipeline disabled state.
180  void setPipelineDisabled(bool S) { StagedAttrs.PipelineDisabled = S; }
181
182  /// Set the pipeline initiation interval.
183  void setPipelineInitiationInterval(unsigned C) {
184    StagedAttrs.PipelineInitiationInterval = C;
185  }
186
187private:
188  /// Returns true if there is LoopInfo on the stack.
189  bool hasInfo() const { return !Active.empty(); }
190  /// Return the LoopInfo for the current loop. HasInfo should be called
191  /// first to ensure LoopInfo is present.
192  const LoopInfo &getInfo() const { return Active.back(); }
193  /// The set of attributes that will be applied to the next pushed loop.
194  LoopAttributes StagedAttrs;
195  /// Stack of active loops.
196  llvm::SmallVector<LoopInfo4Active;
197};
198
199// end namespace CodeGen
200// end namespace clang
201
202#endif
203
clang::CodeGen::LoopAttributes::clear
clang::CodeGen::LoopAttributes::IsParallel
clang::CodeGen::LoopAttributes::LVEnableState
clang::CodeGen::LoopAttributes::VectorizeEnable
clang::CodeGen::LoopAttributes::UnrollEnable
clang::CodeGen::LoopAttributes::UnrollAndJamEnable
clang::CodeGen::LoopAttributes::VectorizeWidth
clang::CodeGen::LoopAttributes::InterleaveCount
clang::CodeGen::LoopAttributes::UnrollCount
clang::CodeGen::LoopAttributes::UnrollAndJamCount
clang::CodeGen::LoopAttributes::DistributeEnable
clang::CodeGen::LoopAttributes::PipelineDisabled
clang::CodeGen::LoopAttributes::PipelineInitiationInterval
clang::CodeGen::LoopInfo::getLoopID
clang::CodeGen::LoopInfo::getHeader
clang::CodeGen::LoopInfo::getAttributes
clang::CodeGen::LoopInfo::getAccessGroup
clang::CodeGen::LoopInfo::LoopID
clang::CodeGen::LoopInfo::Header
clang::CodeGen::LoopInfo::Attrs
clang::CodeGen::LoopInfo::AccGroup
clang::CodeGen::LoopInfoStack::push
clang::CodeGen::LoopInfoStack::push
clang::CodeGen::LoopInfoStack::pop
clang::CodeGen::LoopInfoStack::getCurLoopID
clang::CodeGen::LoopInfoStack::getCurLoopParallel
clang::CodeGen::LoopInfoStack::InsertHelper
clang::CodeGen::LoopInfoStack::setParallel
clang::CodeGen::LoopInfoStack::setVectorizeEnable
clang::CodeGen::LoopInfoStack::setDistributeState
clang::CodeGen::LoopInfoStack::setUnrollState
clang::CodeGen::LoopInfoStack::setUnrollAndJamState
clang::CodeGen::LoopInfoStack::setVectorizeWidth
clang::CodeGen::LoopInfoStack::setInterleaveCount
clang::CodeGen::LoopInfoStack::setUnrollCount
clang::CodeGen::LoopInfoStack::setUnrollAndJamCount
clang::CodeGen::LoopInfoStack::setPipelineDisabled
clang::CodeGen::LoopInfoStack::setPipelineInitiationInterval
clang::CodeGen::LoopInfoStack::hasInfo
clang::CodeGen::LoopInfoStack::getInfo
clang::CodeGen::LoopInfoStack::StagedAttrs
clang::CodeGen::LoopInfoStack::Active
clang::CodeGen::LoopInfoStack::push