blob: aabbb9518f98c95c26d7492845617f874e44f8c0 [file] [log] [blame]
Alexander Musman515ad8c2014-05-22 08:54:05 +00001//===---- CGLoopInfo.cpp - LLVM CodeGen for loop metadata -*- C++ -*-------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Alexander Musman515ad8c2014-05-22 08:54:05 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "CGLoopInfo.h"
Tyler Nowicki54c020d2015-07-27 20:10:20 +000010#include "clang/AST/ASTContext.h"
Tyler Nowicki9d268e12015-06-11 23:23:17 +000011#include "clang/AST/Attr.h"
Alexander Musman515ad8c2014-05-22 08:54:05 +000012#include "llvm/IR/BasicBlock.h"
Chandler Carruth4aaaaab2018-10-18 08:16:20 +000013#include "llvm/IR/CFG.h"
Alexander Musman515ad8c2014-05-22 08:54:05 +000014#include "llvm/IR/Constants.h"
15#include "llvm/IR/InstrTypes.h"
16#include "llvm/IR/Instructions.h"
17#include "llvm/IR/Metadata.h"
Tyler Nowicki4e8e9002015-06-08 23:27:35 +000018using namespace clang::CodeGen;
Alexander Musman515ad8c2014-05-22 08:54:05 +000019using namespace llvm;
20
Hal Finkelc07e19b2016-05-25 21:53:24 +000021static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs,
Benjamin Kramer81cb4b72016-11-24 16:01:20 +000022 const llvm::DebugLoc &StartLoc,
Michael Kruse05351372018-12-20 21:24:54 +000023 const llvm::DebugLoc &EndLoc, MDNode *&AccGroup) {
Alexander Musman515ad8c2014-05-22 08:54:05 +000024
Tyler Nowickida46d0e2015-07-14 23:03:09 +000025 if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 &&
Tyler Nowicki54c020d2015-07-27 20:10:20 +000026 Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 &&
Aaron Ballman9bdf5152019-01-04 17:20:00 +000027 Attrs.UnrollAndJamCount == 0 && !Attrs.PipelineDisabled &&
28 Attrs.PipelineInitiationInterval == 0 &&
Tyler Nowicki54c020d2015-07-27 20:10:20 +000029 Attrs.VectorizeEnable == LoopAttributes::Unspecified &&
Hal Finkelc07e19b2016-05-25 21:53:24 +000030 Attrs.UnrollEnable == LoopAttributes::Unspecified &&
David Greenc8e39242018-08-01 14:36:12 +000031 Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified &&
32 Attrs.DistributeEnable == LoopAttributes::Unspecified && !StartLoc &&
33 !EndLoc)
Alexander Musman515ad8c2014-05-22 08:54:05 +000034 return nullptr;
35
Duncan P. N. Exon Smithfb494912014-12-09 18:39:32 +000036 SmallVector<Metadata *, 4> Args;
Alexander Musman515ad8c2014-05-22 08:54:05 +000037 // Reserve operand 0 for loop id self reference.
Duncan P. N. Exon Smith7fd74ac2015-01-19 21:30:48 +000038 auto TempNode = MDNode::getTemporary(Ctx, None);
39 Args.push_back(TempNode.get());
Alexander Musman515ad8c2014-05-22 08:54:05 +000040
Amara Emerson652795d2016-11-10 14:44:30 +000041 // 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 }
Hal Finkelc07e19b2016-05-25 21:53:24 +000049
Tyler Nowickida46d0e2015-07-14 23:03:09 +000050 // Setting vectorize.width
51 if (Attrs.VectorizeWidth > 0) {
Duncan P. N. Exon Smithfb494912014-12-09 18:39:32 +000052 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.width"),
53 ConstantAsMetadata::get(ConstantInt::get(
Tyler Nowickida46d0e2015-07-14 23:03:09 +000054 Type::getInt32Ty(Ctx), Attrs.VectorizeWidth))};
Alexander Musman515ad8c2014-05-22 08:54:05 +000055 Args.push_back(MDNode::get(Ctx, Vals));
56 }
57
Tyler Nowickida46d0e2015-07-14 23:03:09 +000058 // Setting interleave.count
59 if (Attrs.InterleaveCount > 0) {
Duncan P. N. Exon Smithfb494912014-12-09 18:39:32 +000060 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.interleave.count"),
61 ConstantAsMetadata::get(ConstantInt::get(
Tyler Nowickida46d0e2015-07-14 23:03:09 +000062 Type::getInt32Ty(Ctx), Attrs.InterleaveCount))};
Alexander Musman515ad8c2014-05-22 08:54:05 +000063 Args.push_back(MDNode::get(Ctx, Vals));
64 }
65
David Greenc8e39242018-08-01 14:36:12 +000066 // Setting unroll.count
Tyler Nowicki54c020d2015-07-27 20:10:20 +000067 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
David Greenc8e39242018-08-01 14:36:12 +000074 // 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
Tyler Nowickida46d0e2015-07-14 23:03:09 +000082 // Setting vectorize.enable
83 if (Attrs.VectorizeEnable != LoopAttributes::Unspecified) {
84 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.enable"),
85 ConstantAsMetadata::get(ConstantInt::get(
86 Type::getInt1Ty(Ctx), (Attrs.VectorizeEnable ==
87 LoopAttributes::Enable)))};
Alexander Musman515ad8c2014-05-22 08:54:05 +000088 Args.push_back(MDNode::get(Ctx, Vals));
89 }
90
Tyler Nowicki54c020d2015-07-27 20:10:20 +000091 // Setting unroll.full or unroll.disable
92 if (Attrs.UnrollEnable != LoopAttributes::Unspecified) {
Mark Heffernan397a98d2015-08-10 17:29:39 +000093 std::string Name;
94 if (Attrs.UnrollEnable == LoopAttributes::Enable)
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)};
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000101 Args.push_back(MDNode::get(Ctx, Vals));
102 }
103
David Greenc8e39242018-08-01 14:36:12 +0000104 // Setting unroll_and_jam.full or unroll_and_jam.disable
105 if (Attrs.UnrollAndJamEnable != LoopAttributes::Unspecified) {
106 std::string Name;
107 if (Attrs.UnrollAndJamEnable == LoopAttributes::Enable)
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
Adam Nemet2de463e2016-06-14 12:04:26 +0000117 if (Attrs.DistributeEnable != LoopAttributes::Unspecified) {
118 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.distribute.enable"),
119 ConstantAsMetadata::get(ConstantInt::get(
120 Type::getInt1Ty(Ctx), (Attrs.DistributeEnable ==
121 LoopAttributes::Enable)))};
122 Args.push_back(MDNode::get(Ctx, Vals));
123 }
124
Michael Kruse05351372018-12-20 21:24:54 +0000125 if (Attrs.IsParallel) {
126 AccGroup = MDNode::getDistinct(Ctx, {});
127 Args.push_back(MDNode::get(
128 Ctx, {MDString::get(Ctx, "llvm.loop.parallel_accesses"), AccGroup}));
129 }
130
Aaron Ballman9bdf5152019-01-04 17:20:00 +0000131 if (Attrs.PipelineDisabled) {
132 Metadata *Vals[] = {
133 MDString::get(Ctx, "llvm.loop.pipeline.disable"),
134 ConstantAsMetadata::get(ConstantInt::get(
135 Type::getInt1Ty(Ctx), (Attrs.PipelineDisabled == true)))};
136 Args.push_back(MDNode::get(Ctx, Vals));
137 }
138
139 if (Attrs.PipelineInitiationInterval > 0) {
140 Metadata *Vals[] = {
141 MDString::get(Ctx, "llvm.loop.pipeline.initiationinterval"),
142 ConstantAsMetadata::get(ConstantInt::get(
143 Type::getInt32Ty(Ctx), Attrs.PipelineInitiationInterval))};
144 Args.push_back(MDNode::get(Ctx, Vals));
145 }
146
Alexander Musman515ad8c2014-05-22 08:54:05 +0000147 // Set the first operand to itself.
Duncan P. N. Exon Smithfb494912014-12-09 18:39:32 +0000148 MDNode *LoopID = MDNode::get(Ctx, Args);
Alexander Musman515ad8c2014-05-22 08:54:05 +0000149 LoopID->replaceOperandWith(0, LoopID);
Alexander Musman515ad8c2014-05-22 08:54:05 +0000150 return LoopID;
151}
152
153LoopAttributes::LoopAttributes(bool IsParallel)
Tyler Nowickida46d0e2015-07-14 23:03:09 +0000154 : IsParallel(IsParallel), VectorizeEnable(LoopAttributes::Unspecified),
David Greenc8e39242018-08-01 14:36:12 +0000155 UnrollEnable(LoopAttributes::Unspecified),
156 UnrollAndJamEnable(LoopAttributes::Unspecified), VectorizeWidth(0),
157 InterleaveCount(0), UnrollCount(0), UnrollAndJamCount(0),
Aaron Ballman9bdf5152019-01-04 17:20:00 +0000158 DistributeEnable(LoopAttributes::Unspecified), PipelineDisabled(false),
159 PipelineInitiationInterval(0) {}
Alexander Musman515ad8c2014-05-22 08:54:05 +0000160
161void LoopAttributes::clear() {
162 IsParallel = false;
Tyler Nowickida46d0e2015-07-14 23:03:09 +0000163 VectorizeWidth = 0;
164 InterleaveCount = 0;
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000165 UnrollCount = 0;
David Greenc8e39242018-08-01 14:36:12 +0000166 UnrollAndJamCount = 0;
Tyler Nowickida46d0e2015-07-14 23:03:09 +0000167 VectorizeEnable = LoopAttributes::Unspecified;
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000168 UnrollEnable = LoopAttributes::Unspecified;
David Greenc8e39242018-08-01 14:36:12 +0000169 UnrollAndJamEnable = LoopAttributes::Unspecified;
Adam Nemet9c848592016-08-24 04:31:56 +0000170 DistributeEnable = LoopAttributes::Unspecified;
Aaron Ballman9bdf5152019-01-04 17:20:00 +0000171 PipelineDisabled = false;
172 PipelineInitiationInterval = 0;
Alexander Musman515ad8c2014-05-22 08:54:05 +0000173}
174
Hal Finkelc07e19b2016-05-25 21:53:24 +0000175LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
Benjamin Kramer81cb4b72016-11-24 16:01:20 +0000176 const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
Alexander Musman515ad8c2014-05-22 08:54:05 +0000177 : LoopID(nullptr), Header(Header), Attrs(Attrs) {
Michael Kruse05351372018-12-20 21:24:54 +0000178 LoopID =
179 createMetadata(Header->getContext(), Attrs, StartLoc, EndLoc, AccGroup);
Alexander Musman515ad8c2014-05-22 08:54:05 +0000180}
181
Benjamin Kramer81cb4b72016-11-24 16:01:20 +0000182void LoopInfoStack::push(BasicBlock *Header, const llvm::DebugLoc &StartLoc,
183 const llvm::DebugLoc &EndLoc) {
Amara Emerson652795d2016-11-10 14:44:30 +0000184 Active.push_back(LoopInfo(Header, StagedAttrs, StartLoc, EndLoc));
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000185 // Clear the attributes so nested loops do not inherit them.
186 StagedAttrs.clear();
187}
188
189void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
Hal Finkelc07e19b2016-05-25 21:53:24 +0000190 ArrayRef<const clang::Attr *> Attrs,
Benjamin Kramer81cb4b72016-11-24 16:01:20 +0000191 const llvm::DebugLoc &StartLoc,
192 const llvm::DebugLoc &EndLoc) {
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000193
194 // Identify loop hint attributes from Attrs.
Tyler Nowicki9d268e12015-06-11 23:23:17 +0000195 for (const auto *Attr : Attrs) {
196 const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr);
Anastasia Stulova6bdbcbb2016-02-19 18:30:11 +0000197 const OpenCLUnrollHintAttr *OpenCLHint =
198 dyn_cast<OpenCLUnrollHintAttr>(Attr);
Tyler Nowicki9d268e12015-06-11 23:23:17 +0000199
200 // Skip non loop hint attributes
Anastasia Stulova6bdbcbb2016-02-19 18:30:11 +0000201 if (!LH && !OpenCLHint) {
Tyler Nowicki9d268e12015-06-11 23:23:17 +0000202 continue;
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000203 }
204
Anastasia Stulova6bdbcbb2016-02-19 18:30:11 +0000205 LoopHintAttr::OptionType Option = LoopHintAttr::Unroll;
206 LoopHintAttr::LoopHintState State = LoopHintAttr::Disable;
207 unsigned ValueInt = 1;
208 // Translate opencl_unroll_hint attribute argument to
209 // equivalent LoopHintAttr enums.
Fangrui Song6907ce22018-07-30 19:24:48 +0000210 // OpenCL v2.0 s6.11.5:
Anastasia Stulova6bdbcbb2016-02-19 18:30:11 +0000211 // 0 - full unroll (no argument).
212 // 1 - disable unroll.
213 // other positive integer n - unroll by n.
214 if (OpenCLHint) {
215 ValueInt = OpenCLHint->getUnrollHint();
216 if (ValueInt == 0) {
217 State = LoopHintAttr::Full;
218 } else if (ValueInt != 1) {
219 Option = LoopHintAttr::UnrollCount;
220 State = LoopHintAttr::Numeric;
221 }
222 } else if (LH) {
223 auto *ValueExpr = LH->getValue();
224 if (ValueExpr) {
225 llvm::APSInt ValueAPS = ValueExpr->EvaluateKnownConstInt(Ctx);
226 ValueInt = ValueAPS.getSExtValue();
227 }
228
229 Option = LH->getOption();
230 State = LH->getState();
231 }
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000232 switch (State) {
233 case LoopHintAttr::Disable:
234 switch (Option) {
235 case LoopHintAttr::Vectorize:
236 // Disable vectorization by specifying a width of 1.
237 setVectorizeWidth(1);
238 break;
239 case LoopHintAttr::Interleave:
240 // Disable interleaving by speciyfing a count of 1.
241 setInterleaveCount(1);
242 break;
243 case LoopHintAttr::Unroll:
Mark Heffernan397a98d2015-08-10 17:29:39 +0000244 setUnrollState(LoopAttributes::Disable);
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000245 break;
David Greenc8e39242018-08-01 14:36:12 +0000246 case LoopHintAttr::UnrollAndJam:
247 setUnrollAndJamState(LoopAttributes::Disable);
248 break;
Adam Nemet2de463e2016-06-14 12:04:26 +0000249 case LoopHintAttr::Distribute:
250 setDistributeState(false);
251 break;
Aaron Ballman9bdf5152019-01-04 17:20:00 +0000252 case LoopHintAttr::PipelineDisabled:
253 setPipelineDisabled(true);
254 break;
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000255 case LoopHintAttr::UnrollCount:
David Greenc8e39242018-08-01 14:36:12 +0000256 case LoopHintAttr::UnrollAndJamCount:
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000257 case LoopHintAttr::VectorizeWidth:
258 case LoopHintAttr::InterleaveCount:
Aaron Ballman9bdf5152019-01-04 17:20:00 +0000259 case LoopHintAttr::PipelineInitiationInterval:
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000260 llvm_unreachable("Options cannot be disabled.");
261 break;
Tyler Nowicki9d268e12015-06-11 23:23:17 +0000262 }
263 break;
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000264 case LoopHintAttr::Enable:
265 switch (Option) {
266 case LoopHintAttr::Vectorize:
267 case LoopHintAttr::Interleave:
268 setVectorizeEnable(true);
269 break;
270 case LoopHintAttr::Unroll:
Mark Heffernan397a98d2015-08-10 17:29:39 +0000271 setUnrollState(LoopAttributes::Enable);
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000272 break;
David Greenc8e39242018-08-01 14:36:12 +0000273 case LoopHintAttr::UnrollAndJam:
274 setUnrollAndJamState(LoopAttributes::Enable);
275 break;
Adam Nemet2de463e2016-06-14 12:04:26 +0000276 case LoopHintAttr::Distribute:
277 setDistributeState(true);
278 break;
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000279 case LoopHintAttr::UnrollCount:
David Greenc8e39242018-08-01 14:36:12 +0000280 case LoopHintAttr::UnrollAndJamCount:
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000281 case LoopHintAttr::VectorizeWidth:
282 case LoopHintAttr::InterleaveCount:
Aaron Ballman9bdf5152019-01-04 17:20:00 +0000283 case LoopHintAttr::PipelineDisabled:
284 case LoopHintAttr::PipelineInitiationInterval:
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000285 llvm_unreachable("Options cannot enabled.");
286 break;
287 }
288 break;
289 case LoopHintAttr::AssumeSafety:
290 switch (Option) {
291 case LoopHintAttr::Vectorize:
292 case LoopHintAttr::Interleave:
293 // Apply "llvm.mem.parallel_loop_access" metadata to load/stores.
294 setParallel(true);
295 setVectorizeEnable(true);
296 break;
297 case LoopHintAttr::Unroll:
David Greenc8e39242018-08-01 14:36:12 +0000298 case LoopHintAttr::UnrollAndJam:
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000299 case LoopHintAttr::UnrollCount:
David Greenc8e39242018-08-01 14:36:12 +0000300 case LoopHintAttr::UnrollAndJamCount:
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000301 case LoopHintAttr::VectorizeWidth:
302 case LoopHintAttr::InterleaveCount:
Adam Nemet2de463e2016-06-14 12:04:26 +0000303 case LoopHintAttr::Distribute:
Aaron Ballman9bdf5152019-01-04 17:20:00 +0000304 case LoopHintAttr::PipelineDisabled:
305 case LoopHintAttr::PipelineInitiationInterval:
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000306 llvm_unreachable("Options cannot be used to assume mem safety.");
307 break;
308 }
309 break;
Mark Heffernan397a98d2015-08-10 17:29:39 +0000310 case LoopHintAttr::Full:
311 switch (Option) {
312 case LoopHintAttr::Unroll:
313 setUnrollState(LoopAttributes::Full);
314 break;
David Greenc8e39242018-08-01 14:36:12 +0000315 case LoopHintAttr::UnrollAndJam:
316 setUnrollAndJamState(LoopAttributes::Full);
317 break;
Mark Heffernan397a98d2015-08-10 17:29:39 +0000318 case LoopHintAttr::Vectorize:
319 case LoopHintAttr::Interleave:
320 case LoopHintAttr::UnrollCount:
David Greenc8e39242018-08-01 14:36:12 +0000321 case LoopHintAttr::UnrollAndJamCount:
Mark Heffernan397a98d2015-08-10 17:29:39 +0000322 case LoopHintAttr::VectorizeWidth:
323 case LoopHintAttr::InterleaveCount:
Adam Nemet2de463e2016-06-14 12:04:26 +0000324 case LoopHintAttr::Distribute:
Aaron Ballman9bdf5152019-01-04 17:20:00 +0000325 case LoopHintAttr::PipelineDisabled:
326 case LoopHintAttr::PipelineInitiationInterval:
Mark Heffernan397a98d2015-08-10 17:29:39 +0000327 llvm_unreachable("Options cannot be used with 'full' hint.");
328 break;
329 }
330 break;
331 case LoopHintAttr::Numeric:
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000332 switch (Option) {
333 case LoopHintAttr::VectorizeWidth:
334 setVectorizeWidth(ValueInt);
335 break;
336 case LoopHintAttr::InterleaveCount:
337 setInterleaveCount(ValueInt);
338 break;
339 case LoopHintAttr::UnrollCount:
340 setUnrollCount(ValueInt);
341 break;
David Greenc8e39242018-08-01 14:36:12 +0000342 case LoopHintAttr::UnrollAndJamCount:
343 setUnrollAndJamCount(ValueInt);
344 break;
Aaron Ballman9bdf5152019-01-04 17:20:00 +0000345 case LoopHintAttr::PipelineInitiationInterval:
346 setPipelineInitiationInterval(ValueInt);
347 break;
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000348 case LoopHintAttr::Unroll:
David Greenc8e39242018-08-01 14:36:12 +0000349 case LoopHintAttr::UnrollAndJam:
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000350 case LoopHintAttr::Vectorize:
351 case LoopHintAttr::Interleave:
Adam Nemet2de463e2016-06-14 12:04:26 +0000352 case LoopHintAttr::Distribute:
Aaron Ballman9bdf5152019-01-04 17:20:00 +0000353 case LoopHintAttr::PipelineDisabled:
Mark Heffernan397a98d2015-08-10 17:29:39 +0000354 llvm_unreachable("Options cannot be assigned a value.");
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000355 break;
356 }
Tyler Nowicki9d268e12015-06-11 23:23:17 +0000357 break;
358 }
359 }
360
Tyler Nowicki54c020d2015-07-27 20:10:20 +0000361 /// Stage the attributes.
Amara Emerson652795d2016-11-10 14:44:30 +0000362 push(Header, StartLoc, EndLoc);
Alexander Musman515ad8c2014-05-22 08:54:05 +0000363}
364
365void LoopInfoStack::pop() {
366 assert(!Active.empty() && "No active loops to pop");
367 Active.pop_back();
368}
369
370void LoopInfoStack::InsertHelper(Instruction *I) const {
Michael Kruse05351372018-12-20 21:24:54 +0000371 if (I->mayReadOrWriteMemory()) {
372 SmallVector<Metadata *, 4> AccessGroups;
373 for (const LoopInfo &AL : Active) {
374 // Here we assume that every loop that has an access group is parallel.
375 if (MDNode *Group = AL.getAccessGroup())
376 AccessGroups.push_back(Group);
377 }
378 MDNode *UnionMD = nullptr;
379 if (AccessGroups.size() == 1)
380 UnionMD = cast<MDNode>(AccessGroups[0]);
381 else if (AccessGroups.size() >= 2)
382 UnionMD = MDNode::get(I->getContext(), AccessGroups);
383 I->setMetadata("llvm.access.group", UnionMD);
384 }
385
Alexander Musman515ad8c2014-05-22 08:54:05 +0000386 if (!hasInfo())
387 return;
388
389 const LoopInfo &L = getInfo();
390 if (!L.getLoopID())
391 return;
392
Chandler Carruth4aaaaab2018-10-18 08:16:20 +0000393 if (I->isTerminator()) {
394 for (BasicBlock *Succ : successors(I))
395 if (Succ == L.getHeader()) {
396 I->setMetadata(llvm::LLVMContext::MD_loop, L.getLoopID());
Alexander Musman515ad8c2014-05-22 08:54:05 +0000397 break;
398 }
399 return;
400 }
Alexander Musman515ad8c2014-05-22 08:54:05 +0000401}