clang  8.0.0svn
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  const llvm::DebugLoc &StartLoc,
24  const llvm::DebugLoc &EndLoc) {
25 
26  if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 &&
27  Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 &&
28  Attrs.UnrollAndJamCount == 0 &&
32  Attrs.DistributeEnable == LoopAttributes::Unspecified && !StartLoc &&
33  !EndLoc)
34  return nullptr;
35 
37  // Reserve operand 0 for loop id self reference.
38  auto TempNode = MDNode::getTemporary(Ctx, None);
39  Args.push_back(TempNode.get());
40 
41  // If we have a valid start debug location for the loop, add it.
42  if (StartLoc) {
43  Args.push_back(StartLoc.getAsMDNode());
44 
45  // If we also have a valid end debug location for the loop, add it.
46  if (EndLoc)
47  Args.push_back(EndLoc.getAsMDNode());
48  }
49 
50  // Setting vectorize.width
51  if (Attrs.VectorizeWidth > 0) {
52  Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.width"),
53  ConstantAsMetadata::get(ConstantInt::get(
54  Type::getInt32Ty(Ctx), Attrs.VectorizeWidth))};
55  Args.push_back(MDNode::get(Ctx, Vals));
56  }
57 
58  // Setting interleave.count
59  if (Attrs.InterleaveCount > 0) {
60  Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.interleave.count"),
61  ConstantAsMetadata::get(ConstantInt::get(
62  Type::getInt32Ty(Ctx), Attrs.InterleaveCount))};
63  Args.push_back(MDNode::get(Ctx, Vals));
64  }
65 
66  // Setting unroll.count
67  if (Attrs.UnrollCount > 0) {
68  Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll.count"),
69  ConstantAsMetadata::get(ConstantInt::get(
70  Type::getInt32Ty(Ctx), Attrs.UnrollCount))};
71  Args.push_back(MDNode::get(Ctx, Vals));
72  }
73 
74  // Setting unroll_and_jam.count
75  if (Attrs.UnrollAndJamCount > 0) {
76  Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll_and_jam.count"),
77  ConstantAsMetadata::get(ConstantInt::get(
78  Type::getInt32Ty(Ctx), Attrs.UnrollAndJamCount))};
79  Args.push_back(MDNode::get(Ctx, Vals));
80  }
81 
82  // Setting vectorize.enable
84  Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.enable"),
85  ConstantAsMetadata::get(ConstantInt::get(
86  Type::getInt1Ty(Ctx), (Attrs.VectorizeEnable ==
88  Args.push_back(MDNode::get(Ctx, Vals));
89  }
90 
91  // Setting unroll.full or unroll.disable
93  std::string Name;
95  Name = "llvm.loop.unroll.enable";
96  else if (Attrs.UnrollEnable == LoopAttributes::Full)
97  Name = "llvm.loop.unroll.full";
98  else
99  Name = "llvm.loop.unroll.disable";
100  Metadata *Vals[] = {MDString::get(Ctx, Name)};
101  Args.push_back(MDNode::get(Ctx, Vals));
102  }
103 
104  // Setting unroll_and_jam.full or unroll_and_jam.disable
106  std::string Name;
108  Name = "llvm.loop.unroll_and_jam.enable";
109  else if (Attrs.UnrollAndJamEnable == LoopAttributes::Full)
110  Name = "llvm.loop.unroll_and_jam.full";
111  else
112  Name = "llvm.loop.unroll_and_jam.disable";
113  Metadata *Vals[] = {MDString::get(Ctx, Name)};
114  Args.push_back(MDNode::get(Ctx, Vals));
115  }
116 
118  Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.distribute.enable"),
119  ConstantAsMetadata::get(ConstantInt::get(
120  Type::getInt1Ty(Ctx), (Attrs.DistributeEnable ==
122  Args.push_back(MDNode::get(Ctx, Vals));
123  }
124 
125  // Set the first operand to itself.
126  MDNode *LoopID = MDNode::get(Ctx, Args);
127  LoopID->replaceOperandWith(0, LoopID);
128  return LoopID;
129 }
130 
132  : IsParallel(IsParallel), VectorizeEnable(LoopAttributes::Unspecified),
133  UnrollEnable(LoopAttributes::Unspecified),
134  UnrollAndJamEnable(LoopAttributes::Unspecified), VectorizeWidth(0),
135  InterleaveCount(0), UnrollCount(0), UnrollAndJamCount(0),
136  DistributeEnable(LoopAttributes::Unspecified) {}
137 
139  IsParallel = false;
140  VectorizeWidth = 0;
141  InterleaveCount = 0;
142  UnrollCount = 0;
143  UnrollAndJamCount = 0;
148 }
149 
150 LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
151  const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
152  : LoopID(nullptr), Header(Header), Attrs(Attrs) {
153  LoopID = createMetadata(Header->getContext(), Attrs, StartLoc, EndLoc);
154 }
155 
156 void LoopInfoStack::push(BasicBlock *Header, const llvm::DebugLoc &StartLoc,
157  const llvm::DebugLoc &EndLoc) {
158  Active.push_back(LoopInfo(Header, StagedAttrs, StartLoc, EndLoc));
159  // Clear the attributes so nested loops do not inherit them.
160  StagedAttrs.clear();
161 }
162 
163 void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
165  const llvm::DebugLoc &StartLoc,
166  const llvm::DebugLoc &EndLoc) {
167 
168  // Identify loop hint attributes from Attrs.
169  for (const auto *Attr : Attrs) {
170  const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr);
171  const OpenCLUnrollHintAttr *OpenCLHint =
172  dyn_cast<OpenCLUnrollHintAttr>(Attr);
173 
174  // Skip non loop hint attributes
175  if (!LH && !OpenCLHint) {
176  continue;
177  }
178 
179  LoopHintAttr::OptionType Option = LoopHintAttr::Unroll;
180  LoopHintAttr::LoopHintState State = LoopHintAttr::Disable;
181  unsigned ValueInt = 1;
182  // Translate opencl_unroll_hint attribute argument to
183  // equivalent LoopHintAttr enums.
184  // OpenCL v2.0 s6.11.5:
185  // 0 - full unroll (no argument).
186  // 1 - disable unroll.
187  // other positive integer n - unroll by n.
188  if (OpenCLHint) {
189  ValueInt = OpenCLHint->getUnrollHint();
190  if (ValueInt == 0) {
191  State = LoopHintAttr::Full;
192  } else if (ValueInt != 1) {
193  Option = LoopHintAttr::UnrollCount;
194  State = LoopHintAttr::Numeric;
195  }
196  } else if (LH) {
197  auto *ValueExpr = LH->getValue();
198  if (ValueExpr) {
199  llvm::APSInt ValueAPS = ValueExpr->EvaluateKnownConstInt(Ctx);
200  ValueInt = ValueAPS.getSExtValue();
201  }
202 
203  Option = LH->getOption();
204  State = LH->getState();
205  }
206  switch (State) {
207  case LoopHintAttr::Disable:
208  switch (Option) {
209  case LoopHintAttr::Vectorize:
210  // Disable vectorization by specifying a width of 1.
211  setVectorizeWidth(1);
212  break;
213  case LoopHintAttr::Interleave:
214  // Disable interleaving by speciyfing a count of 1.
215  setInterleaveCount(1);
216  break;
217  case LoopHintAttr::Unroll:
218  setUnrollState(LoopAttributes::Disable);
219  break;
220  case LoopHintAttr::UnrollAndJam:
221  setUnrollAndJamState(LoopAttributes::Disable);
222  break;
223  case LoopHintAttr::Distribute:
224  setDistributeState(false);
225  break;
226  case LoopHintAttr::UnrollCount:
227  case LoopHintAttr::UnrollAndJamCount:
228  case LoopHintAttr::VectorizeWidth:
229  case LoopHintAttr::InterleaveCount:
230  llvm_unreachable("Options cannot be disabled.");
231  break;
232  }
233  break;
234  case LoopHintAttr::Enable:
235  switch (Option) {
236  case LoopHintAttr::Vectorize:
237  case LoopHintAttr::Interleave:
238  setVectorizeEnable(true);
239  break;
240  case LoopHintAttr::Unroll:
241  setUnrollState(LoopAttributes::Enable);
242  break;
243  case LoopHintAttr::UnrollAndJam:
244  setUnrollAndJamState(LoopAttributes::Enable);
245  break;
246  case LoopHintAttr::Distribute:
247  setDistributeState(true);
248  break;
249  case LoopHintAttr::UnrollCount:
250  case LoopHintAttr::UnrollAndJamCount:
251  case LoopHintAttr::VectorizeWidth:
252  case LoopHintAttr::InterleaveCount:
253  llvm_unreachable("Options cannot enabled.");
254  break;
255  }
256  break;
257  case LoopHintAttr::AssumeSafety:
258  switch (Option) {
259  case LoopHintAttr::Vectorize:
260  case LoopHintAttr::Interleave:
261  // Apply "llvm.mem.parallel_loop_access" metadata to load/stores.
262  setParallel(true);
263  setVectorizeEnable(true);
264  break;
265  case LoopHintAttr::Unroll:
266  case LoopHintAttr::UnrollAndJam:
267  case LoopHintAttr::UnrollCount:
268  case LoopHintAttr::UnrollAndJamCount:
269  case LoopHintAttr::VectorizeWidth:
270  case LoopHintAttr::InterleaveCount:
271  case LoopHintAttr::Distribute:
272  llvm_unreachable("Options cannot be used to assume mem safety.");
273  break;
274  }
275  break;
276  case LoopHintAttr::Full:
277  switch (Option) {
278  case LoopHintAttr::Unroll:
279  setUnrollState(LoopAttributes::Full);
280  break;
281  case LoopHintAttr::UnrollAndJam:
282  setUnrollAndJamState(LoopAttributes::Full);
283  break;
284  case LoopHintAttr::Vectorize:
285  case LoopHintAttr::Interleave:
286  case LoopHintAttr::UnrollCount:
287  case LoopHintAttr::UnrollAndJamCount:
288  case LoopHintAttr::VectorizeWidth:
289  case LoopHintAttr::InterleaveCount:
290  case LoopHintAttr::Distribute:
291  llvm_unreachable("Options cannot be used with 'full' hint.");
292  break;
293  }
294  break;
295  case LoopHintAttr::Numeric:
296  switch (Option) {
297  case LoopHintAttr::VectorizeWidth:
298  setVectorizeWidth(ValueInt);
299  break;
300  case LoopHintAttr::InterleaveCount:
301  setInterleaveCount(ValueInt);
302  break;
303  case LoopHintAttr::UnrollCount:
304  setUnrollCount(ValueInt);
305  break;
306  case LoopHintAttr::UnrollAndJamCount:
307  setUnrollAndJamCount(ValueInt);
308  break;
309  case LoopHintAttr::Unroll:
310  case LoopHintAttr::UnrollAndJam:
311  case LoopHintAttr::Vectorize:
312  case LoopHintAttr::Interleave:
313  case LoopHintAttr::Distribute:
314  llvm_unreachable("Options cannot be assigned a value.");
315  break;
316  }
317  break;
318  }
319  }
320 
321  /// Stage the attributes.
322  push(Header, StartLoc, EndLoc);
323 }
324 
326  assert(!Active.empty() && "No active loops to pop");
327  Active.pop_back();
328 }
329 
330 void LoopInfoStack::InsertHelper(Instruction *I) const {
331  if (!hasInfo())
332  return;
333 
334  const LoopInfo &L = getInfo();
335  if (!L.getLoopID())
336  return;
337 
338  if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) {
339  for (unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i)
340  if (TI->getSuccessor(i) == L.getHeader()) {
341  TI->setMetadata(llvm::LLVMContext::MD_loop, L.getLoopID());
342  break;
343  }
344  return;
345  }
346 
347  if (I->mayReadOrWriteMemory()) {
348  SmallVector<Metadata *, 2> ParallelLoopIDs;
349  for (const LoopInfo &AL : Active)
350  if (AL.getAttributes().IsParallel)
351  ParallelLoopIDs.push_back(AL.getLoopID());
352 
353  MDNode *ParallelMD = nullptr;
354  if (ParallelLoopIDs.size() == 1)
355  ParallelMD = cast<MDNode>(ParallelLoopIDs[0]);
356  else if (ParallelLoopIDs.size() >= 2)
357  ParallelMD = MDNode::get(I->getContext(), ParallelLoopIDs);
358  I->setMetadata("llvm.mem.parallel_loop_access", ParallelMD);
359  }
360 }
Defines the clang::ASTContext interface.
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Definition: Dominators.h:30
Attributes that may be specified on loops.
Definition: CGLoopInfo.h:36
unsigned UnrollAndJamCount
llvm.unroll.
Definition: CGLoopInfo.h:65
Information used when generating a structured loop.
Definition: CGLoopInfo.h:72
LoopAttributes(bool IsParallel=false)
Definition: CGLoopInfo.cpp:131
LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
Construct a new LoopInfo for the loop with entry Header.
Definition: CGLoopInfo.cpp:150
LVEnableState UnrollEnable
Value for llvm.loop.unroll.* metadata (enable, disable, or full).
Definition: CGLoopInfo.h:50
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
LineState State
unsigned InterleaveCount
Value for llvm.loop.interleave.count metadata.
Definition: CGLoopInfo.h:59
LVEnableState VectorizeEnable
Value for llvm.loop.vectorize.enable metadata.
Definition: CGLoopInfo.h:47
void pop()
End the current loop.
Definition: CGLoopInfo.cpp:325
Whether values of this type can be null is (explicitly) unspecified.
LVEnableState UnrollAndJamEnable
Value for llvm.loop.unroll_and_jam.* metadata (enable, disable, or full).
Definition: CGLoopInfo.h:53
void InsertHelper(llvm::Instruction *I) const
Function called by the CodeGenFunction when an instruction is created.
Definition: CGLoopInfo.cpp:330
bool IsParallel
Generate llvm.loop.parallel metadata for loads and stores.
Definition: CGLoopInfo.h:41
unsigned UnrollCount
llvm.unroll.
Definition: CGLoopInfo.h:62
LVEnableState DistributeEnable
Value for llvm.loop.distribute.enable metadata.
Definition: CGLoopInfo.h:68
llvm::MDNode * getLoopID() const
Get the loop id metadata for this loop.
Definition: CGLoopInfo.h:79
static MDNode * createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
Definition: CGLoopInfo.cpp:22
void push(llvm::BasicBlock *Header, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
Begin a new structured loop.
static const TypeInfo & getInfo(unsigned id)
Definition: Types.cpp:34
unsigned VectorizeWidth
Value for llvm.loop.vectorize.width metadata.
Definition: CGLoopInfo.h:56
llvm::BasicBlock * getHeader() const
Get the header block of this loop.
Definition: CGLoopInfo.h:82
Attr - This represents one attribute.
Definition: Attr.h:43