clang  3.9.0
CGLoopInfo.cpp
Go to the documentation of this file.
1 //===---- CGLoopInfo.cpp - LLVM CodeGen for loop metadata -*- C++ -*-------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "CGLoopInfo.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/AST/Attr.h"
13 #include "clang/Sema/LoopHint.h"
14 #include "llvm/IR/BasicBlock.h"
15 #include "llvm/IR/Constants.h"
16 #include "llvm/IR/InstrTypes.h"
17 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/Metadata.h"
19 using namespace clang::CodeGen;
20 using namespace llvm;
21 
22 static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs,
23  llvm::DebugLoc Location) {
24 
25  if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 &&
26  Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 &&
30  !Location)
31  return nullptr;
32 
34  // Reserve operand 0 for loop id self reference.
35  auto TempNode = MDNode::getTemporary(Ctx, None);
36  Args.push_back(TempNode.get());
37 
38  // If we have a valid debug location for the loop, add it.
39  if (Location)
40  Args.push_back(Location.getAsMDNode());
41 
42  // Setting vectorize.width
43  if (Attrs.VectorizeWidth > 0) {
44  Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.width"),
45  ConstantAsMetadata::get(ConstantInt::get(
46  Type::getInt32Ty(Ctx), Attrs.VectorizeWidth))};
47  Args.push_back(MDNode::get(Ctx, Vals));
48  }
49 
50  // Setting interleave.count
51  if (Attrs.InterleaveCount > 0) {
52  Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.interleave.count"),
53  ConstantAsMetadata::get(ConstantInt::get(
54  Type::getInt32Ty(Ctx), Attrs.InterleaveCount))};
55  Args.push_back(MDNode::get(Ctx, Vals));
56  }
57 
58  // Setting interleave.count
59  if (Attrs.UnrollCount > 0) {
60  Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll.count"),
61  ConstantAsMetadata::get(ConstantInt::get(
62  Type::getInt32Ty(Ctx), Attrs.UnrollCount))};
63  Args.push_back(MDNode::get(Ctx, Vals));
64  }
65 
66  // Setting vectorize.enable
68  Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.enable"),
69  ConstantAsMetadata::get(ConstantInt::get(
70  Type::getInt1Ty(Ctx), (Attrs.VectorizeEnable ==
72  Args.push_back(MDNode::get(Ctx, Vals));
73  }
74 
75  // Setting unroll.full or unroll.disable
77  std::string Name;
79  Name = "llvm.loop.unroll.enable";
80  else if (Attrs.UnrollEnable == LoopAttributes::Full)
81  Name = "llvm.loop.unroll.full";
82  else
83  Name = "llvm.loop.unroll.disable";
84  Metadata *Vals[] = {MDString::get(Ctx, Name)};
85  Args.push_back(MDNode::get(Ctx, Vals));
86  }
87 
89  Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.distribute.enable"),
90  ConstantAsMetadata::get(ConstantInt::get(
91  Type::getInt1Ty(Ctx), (Attrs.DistributeEnable ==
93  Args.push_back(MDNode::get(Ctx, Vals));
94  }
95 
96  // Set the first operand to itself.
97  MDNode *LoopID = MDNode::get(Ctx, Args);
98  LoopID->replaceOperandWith(0, LoopID);
99  return LoopID;
100 }
101 
103  : IsParallel(IsParallel), VectorizeEnable(LoopAttributes::Unspecified),
104  UnrollEnable(LoopAttributes::Unspecified), VectorizeWidth(0),
105  InterleaveCount(0), UnrollCount(0),
106  DistributeEnable(LoopAttributes::Unspecified) {}
107 
109  IsParallel = false;
110  VectorizeWidth = 0;
111  InterleaveCount = 0;
112  UnrollCount = 0;
115 }
116 
117 LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
118  llvm::DebugLoc Location)
119  : LoopID(nullptr), Header(Header), Attrs(Attrs) {
120  LoopID = createMetadata(Header->getContext(), Attrs, Location);
121 }
122 
123 void LoopInfoStack::push(BasicBlock *Header, llvm::DebugLoc Location) {
124  Active.push_back(LoopInfo(Header, StagedAttrs, Location));
125  // Clear the attributes so nested loops do not inherit them.
126  StagedAttrs.clear();
127 }
128 
129 void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
131  llvm::DebugLoc Location) {
132 
133  // Identify loop hint attributes from Attrs.
134  for (const auto *Attr : Attrs) {
135  const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr);
136  const OpenCLUnrollHintAttr *OpenCLHint =
137  dyn_cast<OpenCLUnrollHintAttr>(Attr);
138 
139  // Skip non loop hint attributes
140  if (!LH && !OpenCLHint) {
141  continue;
142  }
143 
144  LoopHintAttr::OptionType Option = LoopHintAttr::Unroll;
145  LoopHintAttr::LoopHintState State = LoopHintAttr::Disable;
146  unsigned ValueInt = 1;
147  // Translate opencl_unroll_hint attribute argument to
148  // equivalent LoopHintAttr enums.
149  // OpenCL v2.0 s6.11.5:
150  // 0 - full unroll (no argument).
151  // 1 - disable unroll.
152  // other positive integer n - unroll by n.
153  if (OpenCLHint) {
154  ValueInt = OpenCLHint->getUnrollHint();
155  if (ValueInt == 0) {
156  State = LoopHintAttr::Full;
157  } else if (ValueInt != 1) {
158  Option = LoopHintAttr::UnrollCount;
159  State = LoopHintAttr::Numeric;
160  }
161  } else if (LH) {
162  auto *ValueExpr = LH->getValue();
163  if (ValueExpr) {
164  llvm::APSInt ValueAPS = ValueExpr->EvaluateKnownConstInt(Ctx);
165  ValueInt = ValueAPS.getSExtValue();
166  }
167 
168  Option = LH->getOption();
169  State = LH->getState();
170  }
171  switch (State) {
172  case LoopHintAttr::Disable:
173  switch (Option) {
174  case LoopHintAttr::Vectorize:
175  // Disable vectorization by specifying a width of 1.
177  break;
178  case LoopHintAttr::Interleave:
179  // Disable interleaving by speciyfing a count of 1.
181  break;
182  case LoopHintAttr::Unroll:
184  break;
185  case LoopHintAttr::Distribute:
186  setDistributeState(false);
187  break;
188  case LoopHintAttr::UnrollCount:
189  case LoopHintAttr::VectorizeWidth:
190  case LoopHintAttr::InterleaveCount:
191  llvm_unreachable("Options cannot be disabled.");
192  break;
193  }
194  break;
195  case LoopHintAttr::Enable:
196  switch (Option) {
197  case LoopHintAttr::Vectorize:
198  case LoopHintAttr::Interleave:
199  setVectorizeEnable(true);
200  break;
201  case LoopHintAttr::Unroll:
203  break;
204  case LoopHintAttr::Distribute:
205  setDistributeState(true);
206  break;
207  case LoopHintAttr::UnrollCount:
208  case LoopHintAttr::VectorizeWidth:
209  case LoopHintAttr::InterleaveCount:
210  llvm_unreachable("Options cannot enabled.");
211  break;
212  }
213  break;
214  case LoopHintAttr::AssumeSafety:
215  switch (Option) {
216  case LoopHintAttr::Vectorize:
217  case LoopHintAttr::Interleave:
218  // Apply "llvm.mem.parallel_loop_access" metadata to load/stores.
219  setParallel(true);
220  setVectorizeEnable(true);
221  break;
222  case LoopHintAttr::Unroll:
223  case LoopHintAttr::UnrollCount:
224  case LoopHintAttr::VectorizeWidth:
225  case LoopHintAttr::InterleaveCount:
226  case LoopHintAttr::Distribute:
227  llvm_unreachable("Options cannot be used to assume mem safety.");
228  break;
229  }
230  break;
231  case LoopHintAttr::Full:
232  switch (Option) {
233  case LoopHintAttr::Unroll:
235  break;
236  case LoopHintAttr::Vectorize:
237  case LoopHintAttr::Interleave:
238  case LoopHintAttr::UnrollCount:
239  case LoopHintAttr::VectorizeWidth:
240  case LoopHintAttr::InterleaveCount:
241  case LoopHintAttr::Distribute:
242  llvm_unreachable("Options cannot be used with 'full' hint.");
243  break;
244  }
245  break;
246  case LoopHintAttr::Numeric:
247  switch (Option) {
248  case LoopHintAttr::VectorizeWidth:
249  setVectorizeWidth(ValueInt);
250  break;
251  case LoopHintAttr::InterleaveCount:
252  setInterleaveCount(ValueInt);
253  break;
254  case LoopHintAttr::UnrollCount:
255  setUnrollCount(ValueInt);
256  break;
257  case LoopHintAttr::Unroll:
258  case LoopHintAttr::Vectorize:
259  case LoopHintAttr::Interleave:
260  case LoopHintAttr::Distribute:
261  llvm_unreachable("Options cannot be assigned a value.");
262  break;
263  }
264  break;
265  }
266  }
267 
268  /// Stage the attributes.
269  push(Header, Location);
270 }
271 
273  assert(!Active.empty() && "No active loops to pop");
274  Active.pop_back();
275 }
276 
277 void LoopInfoStack::InsertHelper(Instruction *I) const {
278  if (!hasInfo())
279  return;
280 
281  const LoopInfo &L = getInfo();
282  if (!L.getLoopID())
283  return;
284 
285  if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) {
286  for (unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i)
287  if (TI->getSuccessor(i) == L.getHeader()) {
288  TI->setMetadata(llvm::LLVMContext::MD_loop, L.getLoopID());
289  break;
290  }
291  return;
292  }
293 
294  if (L.getAttributes().IsParallel && I->mayReadOrWriteMemory())
295  I->setMetadata("llvm.mem.parallel_loop_access", L.getLoopID());
296 }
Defines the clang::ASTContext interface.
void setUnrollCount(unsigned C)
Set the unroll count for the next loop pushed.
Definition: CGLoopInfo.h:154
void push(llvm::BasicBlock *Header, llvm::DebugLoc Location=llvm::DebugLoc())
Begin a new structured loop.
Attributes that may be specified on loops.
Definition: CGLoopInfo.h:37
Information used when generating a structured loop.
Definition: CGLoopInfo.h:67
LoopAttributes(bool IsParallel=false)
Definition: CGLoopInfo.cpp:102
LVEnableState UnrollEnable
Value for llvm.loop.unroll.* metadata (enable, disable, or full).
Definition: CGLoopInfo.h:51
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Definition: Type.h:4549
llvm::BasicBlock * getHeader() const
Get the header block of this loop.
Definition: CGLoopInfo.h:77
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:92
LineState State
unsigned InterleaveCount
Value for llvm.loop.interleave.count metadata.
Definition: CGLoopInfo.h:57
static MDNode * createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs, llvm::DebugLoc Location)
Definition: CGLoopInfo.cpp:22
LVEnableState VectorizeEnable
Value for llvm.loop.vectorize.enable metadata.
Definition: CGLoopInfo.h:48
void pop()
End the current loop.
Definition: CGLoopInfo.cpp:272
Whether values of this type can be null is (explicitly) unspecified.
void setVectorizeWidth(unsigned W)
Set the vectorize width for the next loop pushed.
Definition: CGLoopInfo.h:148
detail::InMemoryDirectory::const_iterator I
llvm::MDNode * getLoopID() const
Get the loop id metadata for this loop.
Definition: CGLoopInfo.h:74
bool IsParallel
Generate llvm.loop.parallel metadata for loads and stores.
Definition: CGLoopInfo.h:42
void setInterleaveCount(unsigned C)
Set the interleave count for the next loop pushed.
Definition: CGLoopInfo.h:151
unsigned UnrollCount
llvm.unroll.
Definition: CGLoopInfo.h:60
void setParallel(bool Enable=true)
Set the next pushed loop as parallel.
Definition: CGLoopInfo.h:128
LVEnableState DistributeEnable
Value for llvm.loop.distribute.enable metadata.
Definition: CGLoopInfo.h:63
void setDistributeState(bool Enable=true)
Set the next pushed loop as a distribution candidate.
Definition: CGLoopInfo.h:137
LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs, llvm::DebugLoc Location)
Construct a new LoopInfo for the loop with entry Header.
Definition: CGLoopInfo.cpp:117
void InsertHelper(llvm::Instruction *I) const
Function called by the CodeGenFunction when an instruction is created.
Definition: CGLoopInfo.cpp:277
const LoopAttributes & getAttributes() const
Get the set of attributes active for this loop.
Definition: CGLoopInfo.h:80
void setUnrollState(const LoopAttributes::LVEnableState &State)
Set the next pushed loop unroll state.
Definition: CGLoopInfo.h:143
void setVectorizeEnable(bool Enable=true)
Set the next pushed loop 'vectorize.enable'.
Definition: CGLoopInfo.h:131
unsigned VectorizeWidth
Value for llvm.loop.vectorize.width metadata.
Definition: CGLoopInfo.h:54
Attr - This represents one attribute.
Definition: Attr.h:45