CGLoopInfo.cpp revision 1.1.1.2 1 1.1 joerg //===---- CGLoopInfo.cpp - LLVM CodeGen for loop metadata -*- C++ -*-------===//
2 1.1 joerg //
3 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 1.1 joerg // See https://llvm.org/LICENSE.txt for license information.
5 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 1.1 joerg //
7 1.1 joerg //===----------------------------------------------------------------------===//
8 1.1 joerg
9 1.1 joerg #include "CGLoopInfo.h"
10 1.1 joerg #include "clang/AST/ASTContext.h"
11 1.1 joerg #include "clang/AST/Attr.h"
12 1.1.1.2 joerg #include "clang/AST/Expr.h"
13 1.1.1.2 joerg #include "clang/Basic/CodeGenOptions.h"
14 1.1 joerg #include "llvm/IR/BasicBlock.h"
15 1.1 joerg #include "llvm/IR/CFG.h"
16 1.1 joerg #include "llvm/IR/Constants.h"
17 1.1 joerg #include "llvm/IR/InstrTypes.h"
18 1.1 joerg #include "llvm/IR/Instructions.h"
19 1.1 joerg #include "llvm/IR/Metadata.h"
20 1.1 joerg using namespace clang::CodeGen;
21 1.1 joerg using namespace llvm;
22 1.1 joerg
23 1.1 joerg MDNode *
24 1.1 joerg LoopInfo::createLoopPropertiesMetadata(ArrayRef<Metadata *> LoopProperties) {
25 1.1 joerg LLVMContext &Ctx = Header->getContext();
26 1.1 joerg SmallVector<Metadata *, 4> NewLoopProperties;
27 1.1.1.2 joerg NewLoopProperties.push_back(nullptr);
28 1.1 joerg NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
29 1.1 joerg
30 1.1 joerg MDNode *LoopID = MDNode::getDistinct(Ctx, NewLoopProperties);
31 1.1 joerg LoopID->replaceOperandWith(0, LoopID);
32 1.1 joerg return LoopID;
33 1.1 joerg }
34 1.1 joerg
35 1.1 joerg MDNode *LoopInfo::createPipeliningMetadata(const LoopAttributes &Attrs,
36 1.1 joerg ArrayRef<Metadata *> LoopProperties,
37 1.1 joerg bool &HasUserTransforms) {
38 1.1 joerg LLVMContext &Ctx = Header->getContext();
39 1.1 joerg
40 1.1 joerg Optional<bool> Enabled;
41 1.1 joerg if (Attrs.PipelineDisabled)
42 1.1 joerg Enabled = false;
43 1.1 joerg else if (Attrs.PipelineInitiationInterval != 0)
44 1.1 joerg Enabled = true;
45 1.1 joerg
46 1.1 joerg if (Enabled != true) {
47 1.1 joerg SmallVector<Metadata *, 4> NewLoopProperties;
48 1.1 joerg if (Enabled == false) {
49 1.1 joerg NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
50 1.1 joerg NewLoopProperties.push_back(
51 1.1 joerg MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.pipeline.disable"),
52 1.1 joerg ConstantAsMetadata::get(ConstantInt::get(
53 1.1 joerg llvm::Type::getInt1Ty(Ctx), 1))}));
54 1.1 joerg LoopProperties = NewLoopProperties;
55 1.1 joerg }
56 1.1 joerg return createLoopPropertiesMetadata(LoopProperties);
57 1.1 joerg }
58 1.1 joerg
59 1.1 joerg SmallVector<Metadata *, 4> Args;
60 1.1.1.2 joerg Args.push_back(nullptr);
61 1.1 joerg Args.append(LoopProperties.begin(), LoopProperties.end());
62 1.1 joerg
63 1.1 joerg if (Attrs.PipelineInitiationInterval > 0) {
64 1.1 joerg Metadata *Vals[] = {
65 1.1 joerg MDString::get(Ctx, "llvm.loop.pipeline.initiationinterval"),
66 1.1 joerg ConstantAsMetadata::get(ConstantInt::get(
67 1.1 joerg llvm::Type::getInt32Ty(Ctx), Attrs.PipelineInitiationInterval))};
68 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals));
69 1.1 joerg }
70 1.1 joerg
71 1.1 joerg // No follow-up: This is the last transformation.
72 1.1 joerg
73 1.1 joerg MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
74 1.1 joerg LoopID->replaceOperandWith(0, LoopID);
75 1.1 joerg HasUserTransforms = true;
76 1.1 joerg return LoopID;
77 1.1 joerg }
78 1.1 joerg
79 1.1 joerg MDNode *
80 1.1 joerg LoopInfo::createPartialUnrollMetadata(const LoopAttributes &Attrs,
81 1.1 joerg ArrayRef<Metadata *> LoopProperties,
82 1.1 joerg bool &HasUserTransforms) {
83 1.1 joerg LLVMContext &Ctx = Header->getContext();
84 1.1 joerg
85 1.1 joerg Optional<bool> Enabled;
86 1.1 joerg if (Attrs.UnrollEnable == LoopAttributes::Disable)
87 1.1 joerg Enabled = false;
88 1.1 joerg else if (Attrs.UnrollEnable == LoopAttributes::Full)
89 1.1 joerg Enabled = None;
90 1.1 joerg else if (Attrs.UnrollEnable != LoopAttributes::Unspecified ||
91 1.1 joerg Attrs.UnrollCount != 0)
92 1.1 joerg Enabled = true;
93 1.1 joerg
94 1.1 joerg if (Enabled != true) {
95 1.1 joerg // createFullUnrollMetadata will already have added llvm.loop.unroll.disable
96 1.1 joerg // if unrolling is disabled.
97 1.1 joerg return createPipeliningMetadata(Attrs, LoopProperties, HasUserTransforms);
98 1.1 joerg }
99 1.1 joerg
100 1.1 joerg SmallVector<Metadata *, 4> FollowupLoopProperties;
101 1.1 joerg
102 1.1 joerg // Apply all loop properties to the unrolled loop.
103 1.1 joerg FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
104 1.1 joerg
105 1.1 joerg // Don't unroll an already unrolled loop.
106 1.1 joerg FollowupLoopProperties.push_back(
107 1.1 joerg MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.disable")));
108 1.1 joerg
109 1.1 joerg bool FollowupHasTransforms = false;
110 1.1 joerg MDNode *Followup = createPipeliningMetadata(Attrs, FollowupLoopProperties,
111 1.1 joerg FollowupHasTransforms);
112 1.1 joerg
113 1.1 joerg SmallVector<Metadata *, 4> Args;
114 1.1.1.2 joerg Args.push_back(nullptr);
115 1.1 joerg Args.append(LoopProperties.begin(), LoopProperties.end());
116 1.1 joerg
117 1.1 joerg // Setting unroll.count
118 1.1 joerg if (Attrs.UnrollCount > 0) {
119 1.1 joerg Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll.count"),
120 1.1 joerg ConstantAsMetadata::get(ConstantInt::get(
121 1.1 joerg llvm::Type::getInt32Ty(Ctx), Attrs.UnrollCount))};
122 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals));
123 1.1 joerg }
124 1.1 joerg
125 1.1 joerg // Setting unroll.full or unroll.disable
126 1.1 joerg if (Attrs.UnrollEnable == LoopAttributes::Enable) {
127 1.1 joerg Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll.enable")};
128 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals));
129 1.1 joerg }
130 1.1 joerg
131 1.1 joerg if (FollowupHasTransforms)
132 1.1 joerg Args.push_back(MDNode::get(
133 1.1 joerg Ctx, {MDString::get(Ctx, "llvm.loop.unroll.followup_all"), Followup}));
134 1.1 joerg
135 1.1 joerg MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
136 1.1 joerg LoopID->replaceOperandWith(0, LoopID);
137 1.1 joerg HasUserTransforms = true;
138 1.1 joerg return LoopID;
139 1.1 joerg }
140 1.1 joerg
141 1.1 joerg MDNode *
142 1.1 joerg LoopInfo::createUnrollAndJamMetadata(const LoopAttributes &Attrs,
143 1.1 joerg ArrayRef<Metadata *> LoopProperties,
144 1.1 joerg bool &HasUserTransforms) {
145 1.1 joerg LLVMContext &Ctx = Header->getContext();
146 1.1 joerg
147 1.1 joerg Optional<bool> Enabled;
148 1.1 joerg if (Attrs.UnrollAndJamEnable == LoopAttributes::Disable)
149 1.1 joerg Enabled = false;
150 1.1 joerg else if (Attrs.UnrollAndJamEnable == LoopAttributes::Enable ||
151 1.1 joerg Attrs.UnrollAndJamCount != 0)
152 1.1 joerg Enabled = true;
153 1.1 joerg
154 1.1 joerg if (Enabled != true) {
155 1.1 joerg SmallVector<Metadata *, 4> NewLoopProperties;
156 1.1 joerg if (Enabled == false) {
157 1.1 joerg NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
158 1.1 joerg NewLoopProperties.push_back(MDNode::get(
159 1.1 joerg Ctx, MDString::get(Ctx, "llvm.loop.unroll_and_jam.disable")));
160 1.1 joerg LoopProperties = NewLoopProperties;
161 1.1 joerg }
162 1.1 joerg return createPartialUnrollMetadata(Attrs, LoopProperties,
163 1.1 joerg HasUserTransforms);
164 1.1 joerg }
165 1.1 joerg
166 1.1 joerg SmallVector<Metadata *, 4> FollowupLoopProperties;
167 1.1 joerg FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
168 1.1 joerg FollowupLoopProperties.push_back(
169 1.1 joerg MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll_and_jam.disable")));
170 1.1 joerg
171 1.1 joerg bool FollowupHasTransforms = false;
172 1.1 joerg MDNode *Followup = createPartialUnrollMetadata(Attrs, FollowupLoopProperties,
173 1.1 joerg FollowupHasTransforms);
174 1.1 joerg
175 1.1 joerg SmallVector<Metadata *, 4> Args;
176 1.1.1.2 joerg Args.push_back(nullptr);
177 1.1 joerg Args.append(LoopProperties.begin(), LoopProperties.end());
178 1.1 joerg
179 1.1 joerg // Setting unroll_and_jam.count
180 1.1 joerg if (Attrs.UnrollAndJamCount > 0) {
181 1.1 joerg Metadata *Vals[] = {
182 1.1 joerg MDString::get(Ctx, "llvm.loop.unroll_and_jam.count"),
183 1.1 joerg ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
184 1.1 joerg Attrs.UnrollAndJamCount))};
185 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals));
186 1.1 joerg }
187 1.1 joerg
188 1.1 joerg if (Attrs.UnrollAndJamEnable == LoopAttributes::Enable) {
189 1.1 joerg Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll_and_jam.enable")};
190 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals));
191 1.1 joerg }
192 1.1 joerg
193 1.1 joerg if (FollowupHasTransforms)
194 1.1 joerg Args.push_back(MDNode::get(
195 1.1 joerg Ctx, {MDString::get(Ctx, "llvm.loop.unroll_and_jam.followup_outer"),
196 1.1 joerg Followup}));
197 1.1 joerg
198 1.1 joerg if (UnrollAndJamInnerFollowup)
199 1.1 joerg Args.push_back(MDNode::get(
200 1.1 joerg Ctx, {MDString::get(Ctx, "llvm.loop.unroll_and_jam.followup_inner"),
201 1.1 joerg UnrollAndJamInnerFollowup}));
202 1.1 joerg
203 1.1 joerg MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
204 1.1 joerg LoopID->replaceOperandWith(0, LoopID);
205 1.1 joerg HasUserTransforms = true;
206 1.1 joerg return LoopID;
207 1.1 joerg }
208 1.1 joerg
209 1.1 joerg MDNode *
210 1.1 joerg LoopInfo::createLoopVectorizeMetadata(const LoopAttributes &Attrs,
211 1.1 joerg ArrayRef<Metadata *> LoopProperties,
212 1.1 joerg bool &HasUserTransforms) {
213 1.1 joerg LLVMContext &Ctx = Header->getContext();
214 1.1 joerg
215 1.1 joerg Optional<bool> Enabled;
216 1.1 joerg if (Attrs.VectorizeEnable == LoopAttributes::Disable)
217 1.1 joerg Enabled = false;
218 1.1 joerg else if (Attrs.VectorizeEnable != LoopAttributes::Unspecified ||
219 1.1 joerg Attrs.VectorizePredicateEnable != LoopAttributes::Unspecified ||
220 1.1.1.2 joerg Attrs.InterleaveCount != 0 || Attrs.VectorizeWidth != 0 ||
221 1.1.1.2 joerg Attrs.VectorizeScalable != LoopAttributes::Unspecified)
222 1.1 joerg Enabled = true;
223 1.1 joerg
224 1.1 joerg if (Enabled != true) {
225 1.1 joerg SmallVector<Metadata *, 4> NewLoopProperties;
226 1.1 joerg if (Enabled == false) {
227 1.1 joerg NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
228 1.1 joerg NewLoopProperties.push_back(
229 1.1 joerg MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.vectorize.enable"),
230 1.1 joerg ConstantAsMetadata::get(ConstantInt::get(
231 1.1 joerg llvm::Type::getInt1Ty(Ctx), 0))}));
232 1.1 joerg LoopProperties = NewLoopProperties;
233 1.1 joerg }
234 1.1 joerg return createUnrollAndJamMetadata(Attrs, LoopProperties, HasUserTransforms);
235 1.1 joerg }
236 1.1 joerg
237 1.1 joerg // Apply all loop properties to the vectorized loop.
238 1.1 joerg SmallVector<Metadata *, 4> FollowupLoopProperties;
239 1.1 joerg FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
240 1.1 joerg
241 1.1 joerg // Don't vectorize an already vectorized loop.
242 1.1 joerg FollowupLoopProperties.push_back(
243 1.1 joerg MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.isvectorized")));
244 1.1 joerg
245 1.1 joerg bool FollowupHasTransforms = false;
246 1.1 joerg MDNode *Followup = createUnrollAndJamMetadata(Attrs, FollowupLoopProperties,
247 1.1 joerg FollowupHasTransforms);
248 1.1 joerg
249 1.1 joerg SmallVector<Metadata *, 4> Args;
250 1.1.1.2 joerg Args.push_back(nullptr);
251 1.1 joerg Args.append(LoopProperties.begin(), LoopProperties.end());
252 1.1 joerg
253 1.1.1.2 joerg // Setting vectorize.predicate when it has been specified and vectorization
254 1.1.1.2 joerg // has not been disabled.
255 1.1 joerg bool IsVectorPredicateEnabled = false;
256 1.1.1.2 joerg if (Attrs.VectorizePredicateEnable != LoopAttributes::Unspecified) {
257 1.1 joerg IsVectorPredicateEnabled =
258 1.1 joerg (Attrs.VectorizePredicateEnable == LoopAttributes::Enable);
259 1.1 joerg
260 1.1 joerg Metadata *Vals[] = {
261 1.1 joerg MDString::get(Ctx, "llvm.loop.vectorize.predicate.enable"),
262 1.1 joerg ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt1Ty(Ctx),
263 1.1 joerg IsVectorPredicateEnabled))};
264 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals));
265 1.1 joerg }
266 1.1 joerg
267 1.1 joerg // Setting vectorize.width
268 1.1 joerg if (Attrs.VectorizeWidth > 0) {
269 1.1 joerg Metadata *Vals[] = {
270 1.1 joerg MDString::get(Ctx, "llvm.loop.vectorize.width"),
271 1.1 joerg ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
272 1.1 joerg Attrs.VectorizeWidth))};
273 1.1.1.2 joerg
274 1.1.1.2 joerg Args.push_back(MDNode::get(Ctx, Vals));
275 1.1.1.2 joerg }
276 1.1.1.2 joerg
277 1.1.1.2 joerg if (Attrs.VectorizeScalable != LoopAttributes::Unspecified) {
278 1.1.1.2 joerg bool IsScalable = Attrs.VectorizeScalable == LoopAttributes::Enable;
279 1.1.1.2 joerg Metadata *Vals[] = {
280 1.1.1.2 joerg MDString::get(Ctx, "llvm.loop.vectorize.scalable.enable"),
281 1.1.1.2 joerg ConstantAsMetadata::get(
282 1.1.1.2 joerg ConstantInt::get(llvm::Type::getInt1Ty(Ctx), IsScalable))};
283 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals));
284 1.1 joerg }
285 1.1 joerg
286 1.1 joerg // Setting interleave.count
287 1.1 joerg if (Attrs.InterleaveCount > 0) {
288 1.1 joerg Metadata *Vals[] = {
289 1.1 joerg MDString::get(Ctx, "llvm.loop.interleave.count"),
290 1.1 joerg ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
291 1.1 joerg Attrs.InterleaveCount))};
292 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals));
293 1.1 joerg }
294 1.1 joerg
295 1.1.1.2 joerg // vectorize.enable is set if:
296 1.1.1.2 joerg // 1) loop hint vectorize.enable is set, or
297 1.1.1.2 joerg // 2) it is implied when vectorize.predicate is set, or
298 1.1.1.2 joerg // 3) it is implied when vectorize.width is set to a value > 1
299 1.1.1.2 joerg // 4) it is implied when vectorize.scalable.enable is true
300 1.1.1.2 joerg // 5) it is implied when vectorize.width is unset (0) and the user
301 1.1.1.2 joerg // explicitly requested fixed-width vectorization, i.e.
302 1.1.1.2 joerg // vectorize.scalable.enable is false.
303 1.1 joerg if (Attrs.VectorizeEnable != LoopAttributes::Unspecified ||
304 1.1.1.2 joerg (IsVectorPredicateEnabled && Attrs.VectorizeWidth != 1) ||
305 1.1.1.2 joerg Attrs.VectorizeWidth > 1 ||
306 1.1.1.2 joerg Attrs.VectorizeScalable == LoopAttributes::Enable ||
307 1.1.1.2 joerg (Attrs.VectorizeScalable == LoopAttributes::Disable &&
308 1.1.1.2 joerg Attrs.VectorizeWidth != 1)) {
309 1.1.1.2 joerg bool AttrVal = Attrs.VectorizeEnable != LoopAttributes::Disable;
310 1.1.1.2 joerg Args.push_back(
311 1.1.1.2 joerg MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.vectorize.enable"),
312 1.1.1.2 joerg ConstantAsMetadata::get(ConstantInt::get(
313 1.1.1.2 joerg llvm::Type::getInt1Ty(Ctx), AttrVal))}));
314 1.1 joerg }
315 1.1 joerg
316 1.1 joerg if (FollowupHasTransforms)
317 1.1 joerg Args.push_back(MDNode::get(
318 1.1 joerg Ctx,
319 1.1 joerg {MDString::get(Ctx, "llvm.loop.vectorize.followup_all"), Followup}));
320 1.1 joerg
321 1.1.1.2 joerg MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
322 1.1 joerg LoopID->replaceOperandWith(0, LoopID);
323 1.1 joerg HasUserTransforms = true;
324 1.1 joerg return LoopID;
325 1.1 joerg }
326 1.1 joerg
327 1.1 joerg MDNode *
328 1.1 joerg LoopInfo::createLoopDistributeMetadata(const LoopAttributes &Attrs,
329 1.1 joerg ArrayRef<Metadata *> LoopProperties,
330 1.1 joerg bool &HasUserTransforms) {
331 1.1 joerg LLVMContext &Ctx = Header->getContext();
332 1.1 joerg
333 1.1 joerg Optional<bool> Enabled;
334 1.1 joerg if (Attrs.DistributeEnable == LoopAttributes::Disable)
335 1.1 joerg Enabled = false;
336 1.1 joerg if (Attrs.DistributeEnable == LoopAttributes::Enable)
337 1.1 joerg Enabled = true;
338 1.1 joerg
339 1.1 joerg if (Enabled != true) {
340 1.1 joerg SmallVector<Metadata *, 4> NewLoopProperties;
341 1.1 joerg if (Enabled == false) {
342 1.1 joerg NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
343 1.1 joerg NewLoopProperties.push_back(
344 1.1 joerg MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.distribute.enable"),
345 1.1 joerg ConstantAsMetadata::get(ConstantInt::get(
346 1.1 joerg llvm::Type::getInt1Ty(Ctx), 0))}));
347 1.1 joerg LoopProperties = NewLoopProperties;
348 1.1 joerg }
349 1.1 joerg return createLoopVectorizeMetadata(Attrs, LoopProperties,
350 1.1 joerg HasUserTransforms);
351 1.1 joerg }
352 1.1 joerg
353 1.1 joerg bool FollowupHasTransforms = false;
354 1.1 joerg MDNode *Followup =
355 1.1 joerg createLoopVectorizeMetadata(Attrs, LoopProperties, FollowupHasTransforms);
356 1.1 joerg
357 1.1 joerg SmallVector<Metadata *, 4> Args;
358 1.1.1.2 joerg Args.push_back(nullptr);
359 1.1 joerg Args.append(LoopProperties.begin(), LoopProperties.end());
360 1.1 joerg
361 1.1 joerg Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.distribute.enable"),
362 1.1 joerg ConstantAsMetadata::get(ConstantInt::get(
363 1.1 joerg llvm::Type::getInt1Ty(Ctx),
364 1.1 joerg (Attrs.DistributeEnable == LoopAttributes::Enable)))};
365 1.1 joerg Args.push_back(MDNode::get(Ctx, Vals));
366 1.1 joerg
367 1.1 joerg if (FollowupHasTransforms)
368 1.1 joerg Args.push_back(MDNode::get(
369 1.1 joerg Ctx,
370 1.1 joerg {MDString::get(Ctx, "llvm.loop.distribute.followup_all"), Followup}));
371 1.1 joerg
372 1.1.1.2 joerg MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
373 1.1 joerg LoopID->replaceOperandWith(0, LoopID);
374 1.1 joerg HasUserTransforms = true;
375 1.1 joerg return LoopID;
376 1.1 joerg }
377 1.1 joerg
378 1.1 joerg MDNode *LoopInfo::createFullUnrollMetadata(const LoopAttributes &Attrs,
379 1.1 joerg ArrayRef<Metadata *> LoopProperties,
380 1.1 joerg bool &HasUserTransforms) {
381 1.1 joerg LLVMContext &Ctx = Header->getContext();
382 1.1 joerg
383 1.1 joerg Optional<bool> Enabled;
384 1.1 joerg if (Attrs.UnrollEnable == LoopAttributes::Disable)
385 1.1 joerg Enabled = false;
386 1.1 joerg else if (Attrs.UnrollEnable == LoopAttributes::Full)
387 1.1 joerg Enabled = true;
388 1.1 joerg
389 1.1 joerg if (Enabled != true) {
390 1.1 joerg SmallVector<Metadata *, 4> NewLoopProperties;
391 1.1 joerg if (Enabled == false) {
392 1.1 joerg NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
393 1.1 joerg NewLoopProperties.push_back(
394 1.1 joerg MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.disable")));
395 1.1 joerg LoopProperties = NewLoopProperties;
396 1.1 joerg }
397 1.1 joerg return createLoopDistributeMetadata(Attrs, LoopProperties,
398 1.1 joerg HasUserTransforms);
399 1.1 joerg }
400 1.1 joerg
401 1.1 joerg SmallVector<Metadata *, 4> Args;
402 1.1.1.2 joerg Args.push_back(nullptr);
403 1.1 joerg Args.append(LoopProperties.begin(), LoopProperties.end());
404 1.1 joerg Args.push_back(MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.full")));
405 1.1 joerg
406 1.1 joerg // No follow-up: there is no loop after full unrolling.
407 1.1 joerg // TODO: Warn if there are transformations after full unrolling.
408 1.1 joerg
409 1.1 joerg MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
410 1.1 joerg LoopID->replaceOperandWith(0, LoopID);
411 1.1 joerg HasUserTransforms = true;
412 1.1 joerg return LoopID;
413 1.1 joerg }
414 1.1 joerg
415 1.1 joerg MDNode *LoopInfo::createMetadata(
416 1.1 joerg const LoopAttributes &Attrs,
417 1.1 joerg llvm::ArrayRef<llvm::Metadata *> AdditionalLoopProperties,
418 1.1 joerg bool &HasUserTransforms) {
419 1.1 joerg SmallVector<Metadata *, 3> LoopProperties;
420 1.1 joerg
421 1.1 joerg // If we have a valid start debug location for the loop, add it.
422 1.1 joerg if (StartLoc) {
423 1.1 joerg LoopProperties.push_back(StartLoc.getAsMDNode());
424 1.1 joerg
425 1.1 joerg // If we also have a valid end debug location for the loop, add it.
426 1.1 joerg if (EndLoc)
427 1.1 joerg LoopProperties.push_back(EndLoc.getAsMDNode());
428 1.1 joerg }
429 1.1 joerg
430 1.1.1.2 joerg LLVMContext &Ctx = Header->getContext();
431 1.1.1.2 joerg if (Attrs.MustProgress)
432 1.1.1.2 joerg LoopProperties.push_back(
433 1.1.1.2 joerg MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.mustprogress")));
434 1.1.1.2 joerg
435 1.1 joerg assert(!!AccGroup == Attrs.IsParallel &&
436 1.1 joerg "There must be an access group iff the loop is parallel");
437 1.1 joerg if (Attrs.IsParallel) {
438 1.1 joerg LoopProperties.push_back(MDNode::get(
439 1.1 joerg Ctx, {MDString::get(Ctx, "llvm.loop.parallel_accesses"), AccGroup}));
440 1.1 joerg }
441 1.1 joerg
442 1.1 joerg LoopProperties.insert(LoopProperties.end(), AdditionalLoopProperties.begin(),
443 1.1 joerg AdditionalLoopProperties.end());
444 1.1 joerg return createFullUnrollMetadata(Attrs, LoopProperties, HasUserTransforms);
445 1.1 joerg }
446 1.1 joerg
447 1.1 joerg LoopAttributes::LoopAttributes(bool IsParallel)
448 1.1 joerg : IsParallel(IsParallel), VectorizeEnable(LoopAttributes::Unspecified),
449 1.1 joerg UnrollEnable(LoopAttributes::Unspecified),
450 1.1 joerg UnrollAndJamEnable(LoopAttributes::Unspecified),
451 1.1 joerg VectorizePredicateEnable(LoopAttributes::Unspecified), VectorizeWidth(0),
452 1.1.1.2 joerg VectorizeScalable(LoopAttributes::Unspecified), InterleaveCount(0),
453 1.1.1.2 joerg UnrollCount(0), UnrollAndJamCount(0),
454 1.1 joerg DistributeEnable(LoopAttributes::Unspecified), PipelineDisabled(false),
455 1.1.1.2 joerg PipelineInitiationInterval(0), MustProgress(false) {}
456 1.1 joerg
457 1.1 joerg void LoopAttributes::clear() {
458 1.1 joerg IsParallel = false;
459 1.1 joerg VectorizeWidth = 0;
460 1.1.1.2 joerg VectorizeScalable = LoopAttributes::Unspecified;
461 1.1 joerg InterleaveCount = 0;
462 1.1 joerg UnrollCount = 0;
463 1.1 joerg UnrollAndJamCount = 0;
464 1.1 joerg VectorizeEnable = LoopAttributes::Unspecified;
465 1.1 joerg UnrollEnable = LoopAttributes::Unspecified;
466 1.1 joerg UnrollAndJamEnable = LoopAttributes::Unspecified;
467 1.1 joerg VectorizePredicateEnable = LoopAttributes::Unspecified;
468 1.1 joerg DistributeEnable = LoopAttributes::Unspecified;
469 1.1 joerg PipelineDisabled = false;
470 1.1 joerg PipelineInitiationInterval = 0;
471 1.1.1.2 joerg MustProgress = false;
472 1.1 joerg }
473 1.1 joerg
474 1.1 joerg LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
475 1.1 joerg const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc,
476 1.1 joerg LoopInfo *Parent)
477 1.1 joerg : Header(Header), Attrs(Attrs), StartLoc(StartLoc), EndLoc(EndLoc),
478 1.1 joerg Parent(Parent) {
479 1.1 joerg
480 1.1 joerg if (Attrs.IsParallel) {
481 1.1 joerg // Create an access group for this loop.
482 1.1 joerg LLVMContext &Ctx = Header->getContext();
483 1.1 joerg AccGroup = MDNode::getDistinct(Ctx, {});
484 1.1 joerg }
485 1.1 joerg
486 1.1 joerg if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 &&
487 1.1.1.2 joerg Attrs.VectorizeScalable == LoopAttributes::Unspecified &&
488 1.1 joerg Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 &&
489 1.1 joerg Attrs.UnrollAndJamCount == 0 && !Attrs.PipelineDisabled &&
490 1.1 joerg Attrs.PipelineInitiationInterval == 0 &&
491 1.1 joerg Attrs.VectorizePredicateEnable == LoopAttributes::Unspecified &&
492 1.1 joerg Attrs.VectorizeEnable == LoopAttributes::Unspecified &&
493 1.1 joerg Attrs.UnrollEnable == LoopAttributes::Unspecified &&
494 1.1 joerg Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified &&
495 1.1 joerg Attrs.DistributeEnable == LoopAttributes::Unspecified && !StartLoc &&
496 1.1.1.2 joerg !EndLoc && !Attrs.MustProgress)
497 1.1 joerg return;
498 1.1 joerg
499 1.1 joerg TempLoopID = MDNode::getTemporary(Header->getContext(), None);
500 1.1 joerg }
501 1.1 joerg
502 1.1 joerg void LoopInfo::finish() {
503 1.1 joerg // We did not annotate the loop body instructions because there are no
504 1.1 joerg // attributes for this loop.
505 1.1 joerg if (!TempLoopID)
506 1.1 joerg return;
507 1.1 joerg
508 1.1 joerg MDNode *LoopID;
509 1.1 joerg LoopAttributes CurLoopAttr = Attrs;
510 1.1 joerg LLVMContext &Ctx = Header->getContext();
511 1.1 joerg
512 1.1 joerg if (Parent && (Parent->Attrs.UnrollAndJamEnable ||
513 1.1 joerg Parent->Attrs.UnrollAndJamCount != 0)) {
514 1.1 joerg // Parent unroll-and-jams this loop.
515 1.1 joerg // Split the transformations in those that happens before the unroll-and-jam
516 1.1 joerg // and those after.
517 1.1 joerg
518 1.1 joerg LoopAttributes BeforeJam, AfterJam;
519 1.1 joerg
520 1.1 joerg BeforeJam.IsParallel = AfterJam.IsParallel = Attrs.IsParallel;
521 1.1 joerg
522 1.1 joerg BeforeJam.VectorizeWidth = Attrs.VectorizeWidth;
523 1.1.1.2 joerg BeforeJam.VectorizeScalable = Attrs.VectorizeScalable;
524 1.1 joerg BeforeJam.InterleaveCount = Attrs.InterleaveCount;
525 1.1 joerg BeforeJam.VectorizeEnable = Attrs.VectorizeEnable;
526 1.1 joerg BeforeJam.DistributeEnable = Attrs.DistributeEnable;
527 1.1 joerg BeforeJam.VectorizePredicateEnable = Attrs.VectorizePredicateEnable;
528 1.1 joerg
529 1.1 joerg switch (Attrs.UnrollEnable) {
530 1.1 joerg case LoopAttributes::Unspecified:
531 1.1 joerg case LoopAttributes::Disable:
532 1.1 joerg BeforeJam.UnrollEnable = Attrs.UnrollEnable;
533 1.1 joerg AfterJam.UnrollEnable = Attrs.UnrollEnable;
534 1.1 joerg break;
535 1.1 joerg case LoopAttributes::Full:
536 1.1 joerg BeforeJam.UnrollEnable = LoopAttributes::Full;
537 1.1 joerg break;
538 1.1 joerg case LoopAttributes::Enable:
539 1.1 joerg AfterJam.UnrollEnable = LoopAttributes::Enable;
540 1.1 joerg break;
541 1.1 joerg }
542 1.1 joerg
543 1.1 joerg AfterJam.VectorizePredicateEnable = Attrs.VectorizePredicateEnable;
544 1.1 joerg AfterJam.UnrollCount = Attrs.UnrollCount;
545 1.1 joerg AfterJam.PipelineDisabled = Attrs.PipelineDisabled;
546 1.1 joerg AfterJam.PipelineInitiationInterval = Attrs.PipelineInitiationInterval;
547 1.1 joerg
548 1.1 joerg // If this loop is subject of an unroll-and-jam by the parent loop, and has
549 1.1 joerg // an unroll-and-jam annotation itself, we have to decide whether to first
550 1.1 joerg // apply the parent's unroll-and-jam or this loop's unroll-and-jam. The
551 1.1 joerg // UnrollAndJam pass processes loops from inner to outer, so we apply the
552 1.1 joerg // inner first.
553 1.1 joerg BeforeJam.UnrollAndJamCount = Attrs.UnrollAndJamCount;
554 1.1 joerg BeforeJam.UnrollAndJamEnable = Attrs.UnrollAndJamEnable;
555 1.1 joerg
556 1.1 joerg // Set the inner followup metadata to process by the outer loop. Only
557 1.1 joerg // consider the first inner loop.
558 1.1 joerg if (!Parent->UnrollAndJamInnerFollowup) {
559 1.1 joerg // Splitting the attributes into a BeforeJam and an AfterJam part will
560 1.1 joerg // stop 'llvm.loop.isvectorized' (generated by vectorization in BeforeJam)
561 1.1 joerg // to be forwarded to the AfterJam part. We detect the situation here and
562 1.1 joerg // add it manually.
563 1.1 joerg SmallVector<Metadata *, 1> BeforeLoopProperties;
564 1.1 joerg if (BeforeJam.VectorizeEnable != LoopAttributes::Unspecified ||
565 1.1 joerg BeforeJam.VectorizePredicateEnable != LoopAttributes::Unspecified ||
566 1.1.1.2 joerg BeforeJam.InterleaveCount != 0 || BeforeJam.VectorizeWidth != 0 ||
567 1.1.1.2 joerg BeforeJam.VectorizeScalable == LoopAttributes::Enable)
568 1.1 joerg BeforeLoopProperties.push_back(
569 1.1 joerg MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.isvectorized")));
570 1.1 joerg
571 1.1 joerg bool InnerFollowupHasTransform = false;
572 1.1 joerg MDNode *InnerFollowup = createMetadata(AfterJam, BeforeLoopProperties,
573 1.1 joerg InnerFollowupHasTransform);
574 1.1 joerg if (InnerFollowupHasTransform)
575 1.1 joerg Parent->UnrollAndJamInnerFollowup = InnerFollowup;
576 1.1 joerg }
577 1.1 joerg
578 1.1 joerg CurLoopAttr = BeforeJam;
579 1.1 joerg }
580 1.1 joerg
581 1.1 joerg bool HasUserTransforms = false;
582 1.1 joerg LoopID = createMetadata(CurLoopAttr, {}, HasUserTransforms);
583 1.1 joerg TempLoopID->replaceAllUsesWith(LoopID);
584 1.1 joerg }
585 1.1 joerg
586 1.1 joerg void LoopInfoStack::push(BasicBlock *Header, const llvm::DebugLoc &StartLoc,
587 1.1 joerg const llvm::DebugLoc &EndLoc) {
588 1.1 joerg Active.emplace_back(
589 1.1 joerg new LoopInfo(Header, StagedAttrs, StartLoc, EndLoc,
590 1.1 joerg Active.empty() ? nullptr : Active.back().get()));
591 1.1 joerg // Clear the attributes so nested loops do not inherit them.
592 1.1 joerg StagedAttrs.clear();
593 1.1 joerg }
594 1.1 joerg
595 1.1 joerg void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
596 1.1.1.2 joerg const clang::CodeGenOptions &CGOpts,
597 1.1 joerg ArrayRef<const clang::Attr *> Attrs,
598 1.1 joerg const llvm::DebugLoc &StartLoc,
599 1.1.1.2 joerg const llvm::DebugLoc &EndLoc, bool MustProgress) {
600 1.1 joerg // Identify loop hint attributes from Attrs.
601 1.1 joerg for (const auto *Attr : Attrs) {
602 1.1 joerg const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr);
603 1.1 joerg const OpenCLUnrollHintAttr *OpenCLHint =
604 1.1 joerg dyn_cast<OpenCLUnrollHintAttr>(Attr);
605 1.1 joerg
606 1.1 joerg // Skip non loop hint attributes
607 1.1 joerg if (!LH && !OpenCLHint) {
608 1.1 joerg continue;
609 1.1 joerg }
610 1.1 joerg
611 1.1 joerg LoopHintAttr::OptionType Option = LoopHintAttr::Unroll;
612 1.1 joerg LoopHintAttr::LoopHintState State = LoopHintAttr::Disable;
613 1.1 joerg unsigned ValueInt = 1;
614 1.1 joerg // Translate opencl_unroll_hint attribute argument to
615 1.1 joerg // equivalent LoopHintAttr enums.
616 1.1 joerg // OpenCL v2.0 s6.11.5:
617 1.1 joerg // 0 - enable unroll (no argument).
618 1.1 joerg // 1 - disable unroll.
619 1.1 joerg // other positive integer n - unroll by n.
620 1.1 joerg if (OpenCLHint) {
621 1.1 joerg ValueInt = OpenCLHint->getUnrollHint();
622 1.1 joerg if (ValueInt == 0) {
623 1.1 joerg State = LoopHintAttr::Enable;
624 1.1 joerg } else if (ValueInt != 1) {
625 1.1 joerg Option = LoopHintAttr::UnrollCount;
626 1.1 joerg State = LoopHintAttr::Numeric;
627 1.1 joerg }
628 1.1 joerg } else if (LH) {
629 1.1 joerg auto *ValueExpr = LH->getValue();
630 1.1 joerg if (ValueExpr) {
631 1.1 joerg llvm::APSInt ValueAPS = ValueExpr->EvaluateKnownConstInt(Ctx);
632 1.1 joerg ValueInt = ValueAPS.getSExtValue();
633 1.1 joerg }
634 1.1 joerg
635 1.1 joerg Option = LH->getOption();
636 1.1 joerg State = LH->getState();
637 1.1 joerg }
638 1.1 joerg switch (State) {
639 1.1 joerg case LoopHintAttr::Disable:
640 1.1 joerg switch (Option) {
641 1.1 joerg case LoopHintAttr::Vectorize:
642 1.1 joerg // Disable vectorization by specifying a width of 1.
643 1.1 joerg setVectorizeWidth(1);
644 1.1.1.2 joerg setVectorizeScalable(LoopAttributes::Unspecified);
645 1.1 joerg break;
646 1.1 joerg case LoopHintAttr::Interleave:
647 1.1 joerg // Disable interleaving by speciyfing a count of 1.
648 1.1 joerg setInterleaveCount(1);
649 1.1 joerg break;
650 1.1 joerg case LoopHintAttr::Unroll:
651 1.1 joerg setUnrollState(LoopAttributes::Disable);
652 1.1 joerg break;
653 1.1 joerg case LoopHintAttr::UnrollAndJam:
654 1.1 joerg setUnrollAndJamState(LoopAttributes::Disable);
655 1.1 joerg break;
656 1.1 joerg case LoopHintAttr::VectorizePredicate:
657 1.1 joerg setVectorizePredicateState(LoopAttributes::Disable);
658 1.1 joerg break;
659 1.1 joerg case LoopHintAttr::Distribute:
660 1.1 joerg setDistributeState(false);
661 1.1 joerg break;
662 1.1 joerg case LoopHintAttr::PipelineDisabled:
663 1.1 joerg setPipelineDisabled(true);
664 1.1 joerg break;
665 1.1 joerg case LoopHintAttr::UnrollCount:
666 1.1 joerg case LoopHintAttr::UnrollAndJamCount:
667 1.1 joerg case LoopHintAttr::VectorizeWidth:
668 1.1 joerg case LoopHintAttr::InterleaveCount:
669 1.1 joerg case LoopHintAttr::PipelineInitiationInterval:
670 1.1 joerg llvm_unreachable("Options cannot be disabled.");
671 1.1 joerg break;
672 1.1 joerg }
673 1.1 joerg break;
674 1.1 joerg case LoopHintAttr::Enable:
675 1.1 joerg switch (Option) {
676 1.1 joerg case LoopHintAttr::Vectorize:
677 1.1 joerg case LoopHintAttr::Interleave:
678 1.1 joerg setVectorizeEnable(true);
679 1.1 joerg break;
680 1.1 joerg case LoopHintAttr::Unroll:
681 1.1 joerg setUnrollState(LoopAttributes::Enable);
682 1.1 joerg break;
683 1.1 joerg case LoopHintAttr::UnrollAndJam:
684 1.1 joerg setUnrollAndJamState(LoopAttributes::Enable);
685 1.1 joerg break;
686 1.1 joerg case LoopHintAttr::VectorizePredicate:
687 1.1 joerg setVectorizePredicateState(LoopAttributes::Enable);
688 1.1 joerg break;
689 1.1 joerg case LoopHintAttr::Distribute:
690 1.1 joerg setDistributeState(true);
691 1.1 joerg break;
692 1.1 joerg case LoopHintAttr::UnrollCount:
693 1.1 joerg case LoopHintAttr::UnrollAndJamCount:
694 1.1 joerg case LoopHintAttr::VectorizeWidth:
695 1.1 joerg case LoopHintAttr::InterleaveCount:
696 1.1 joerg case LoopHintAttr::PipelineDisabled:
697 1.1 joerg case LoopHintAttr::PipelineInitiationInterval:
698 1.1 joerg llvm_unreachable("Options cannot enabled.");
699 1.1 joerg break;
700 1.1 joerg }
701 1.1 joerg break;
702 1.1 joerg case LoopHintAttr::AssumeSafety:
703 1.1 joerg switch (Option) {
704 1.1 joerg case LoopHintAttr::Vectorize:
705 1.1 joerg case LoopHintAttr::Interleave:
706 1.1 joerg // Apply "llvm.mem.parallel_loop_access" metadata to load/stores.
707 1.1 joerg setParallel(true);
708 1.1 joerg setVectorizeEnable(true);
709 1.1 joerg break;
710 1.1 joerg case LoopHintAttr::Unroll:
711 1.1 joerg case LoopHintAttr::UnrollAndJam:
712 1.1 joerg case LoopHintAttr::VectorizePredicate:
713 1.1 joerg case LoopHintAttr::UnrollCount:
714 1.1 joerg case LoopHintAttr::UnrollAndJamCount:
715 1.1 joerg case LoopHintAttr::VectorizeWidth:
716 1.1 joerg case LoopHintAttr::InterleaveCount:
717 1.1 joerg case LoopHintAttr::Distribute:
718 1.1 joerg case LoopHintAttr::PipelineDisabled:
719 1.1 joerg case LoopHintAttr::PipelineInitiationInterval:
720 1.1 joerg llvm_unreachable("Options cannot be used to assume mem safety.");
721 1.1 joerg break;
722 1.1 joerg }
723 1.1 joerg break;
724 1.1 joerg case LoopHintAttr::Full:
725 1.1 joerg switch (Option) {
726 1.1 joerg case LoopHintAttr::Unroll:
727 1.1 joerg setUnrollState(LoopAttributes::Full);
728 1.1 joerg break;
729 1.1 joerg case LoopHintAttr::UnrollAndJam:
730 1.1 joerg setUnrollAndJamState(LoopAttributes::Full);
731 1.1 joerg break;
732 1.1 joerg case LoopHintAttr::Vectorize:
733 1.1 joerg case LoopHintAttr::Interleave:
734 1.1 joerg case LoopHintAttr::UnrollCount:
735 1.1 joerg case LoopHintAttr::UnrollAndJamCount:
736 1.1 joerg case LoopHintAttr::VectorizeWidth:
737 1.1 joerg case LoopHintAttr::InterleaveCount:
738 1.1 joerg case LoopHintAttr::Distribute:
739 1.1 joerg case LoopHintAttr::PipelineDisabled:
740 1.1 joerg case LoopHintAttr::PipelineInitiationInterval:
741 1.1 joerg case LoopHintAttr::VectorizePredicate:
742 1.1 joerg llvm_unreachable("Options cannot be used with 'full' hint.");
743 1.1 joerg break;
744 1.1 joerg }
745 1.1 joerg break;
746 1.1.1.2 joerg case LoopHintAttr::FixedWidth:
747 1.1.1.2 joerg case LoopHintAttr::ScalableWidth:
748 1.1 joerg switch (Option) {
749 1.1 joerg case LoopHintAttr::VectorizeWidth:
750 1.1.1.2 joerg setVectorizeScalable(State == LoopHintAttr::ScalableWidth
751 1.1.1.2 joerg ? LoopAttributes::Enable
752 1.1.1.2 joerg : LoopAttributes::Disable);
753 1.1.1.2 joerg if (LH->getValue())
754 1.1.1.2 joerg setVectorizeWidth(ValueInt);
755 1.1.1.2 joerg break;
756 1.1.1.2 joerg default:
757 1.1.1.2 joerg llvm_unreachable("Options cannot be used with 'scalable' hint.");
758 1.1 joerg break;
759 1.1.1.2 joerg }
760 1.1.1.2 joerg break;
761 1.1.1.2 joerg case LoopHintAttr::Numeric:
762 1.1.1.2 joerg switch (Option) {
763 1.1 joerg case LoopHintAttr::InterleaveCount:
764 1.1 joerg setInterleaveCount(ValueInt);
765 1.1 joerg break;
766 1.1 joerg case LoopHintAttr::UnrollCount:
767 1.1 joerg setUnrollCount(ValueInt);
768 1.1 joerg break;
769 1.1 joerg case LoopHintAttr::UnrollAndJamCount:
770 1.1 joerg setUnrollAndJamCount(ValueInt);
771 1.1 joerg break;
772 1.1 joerg case LoopHintAttr::PipelineInitiationInterval:
773 1.1 joerg setPipelineInitiationInterval(ValueInt);
774 1.1 joerg break;
775 1.1 joerg case LoopHintAttr::Unroll:
776 1.1 joerg case LoopHintAttr::UnrollAndJam:
777 1.1 joerg case LoopHintAttr::VectorizePredicate:
778 1.1 joerg case LoopHintAttr::Vectorize:
779 1.1.1.2 joerg case LoopHintAttr::VectorizeWidth:
780 1.1 joerg case LoopHintAttr::Interleave:
781 1.1 joerg case LoopHintAttr::Distribute:
782 1.1 joerg case LoopHintAttr::PipelineDisabled:
783 1.1 joerg llvm_unreachable("Options cannot be assigned a value.");
784 1.1 joerg break;
785 1.1 joerg }
786 1.1 joerg break;
787 1.1 joerg }
788 1.1 joerg }
789 1.1 joerg
790 1.1.1.2 joerg setMustProgress(MustProgress);
791 1.1.1.2 joerg
792 1.1.1.2 joerg if (CGOpts.OptimizationLevel > 0)
793 1.1.1.2 joerg // Disable unrolling for the loop, if unrolling is disabled (via
794 1.1.1.2 joerg // -fno-unroll-loops) and no pragmas override the decision.
795 1.1.1.2 joerg if (!CGOpts.UnrollLoops &&
796 1.1.1.2 joerg (StagedAttrs.UnrollEnable == LoopAttributes::Unspecified &&
797 1.1.1.2 joerg StagedAttrs.UnrollCount == 0))
798 1.1.1.2 joerg setUnrollState(LoopAttributes::Disable);
799 1.1.1.2 joerg
800 1.1 joerg /// Stage the attributes.
801 1.1 joerg push(Header, StartLoc, EndLoc);
802 1.1 joerg }
803 1.1 joerg
804 1.1 joerg void LoopInfoStack::pop() {
805 1.1 joerg assert(!Active.empty() && "No active loops to pop");
806 1.1 joerg Active.back()->finish();
807 1.1 joerg Active.pop_back();
808 1.1 joerg }
809 1.1 joerg
810 1.1 joerg void LoopInfoStack::InsertHelper(Instruction *I) const {
811 1.1 joerg if (I->mayReadOrWriteMemory()) {
812 1.1 joerg SmallVector<Metadata *, 4> AccessGroups;
813 1.1 joerg for (const auto &AL : Active) {
814 1.1 joerg // Here we assume that every loop that has an access group is parallel.
815 1.1 joerg if (MDNode *Group = AL->getAccessGroup())
816 1.1 joerg AccessGroups.push_back(Group);
817 1.1 joerg }
818 1.1 joerg MDNode *UnionMD = nullptr;
819 1.1 joerg if (AccessGroups.size() == 1)
820 1.1 joerg UnionMD = cast<MDNode>(AccessGroups[0]);
821 1.1 joerg else if (AccessGroups.size() >= 2)
822 1.1 joerg UnionMD = MDNode::get(I->getContext(), AccessGroups);
823 1.1 joerg I->setMetadata("llvm.access.group", UnionMD);
824 1.1 joerg }
825 1.1 joerg
826 1.1 joerg if (!hasInfo())
827 1.1 joerg return;
828 1.1 joerg
829 1.1 joerg const LoopInfo &L = getInfo();
830 1.1 joerg if (!L.getLoopID())
831 1.1 joerg return;
832 1.1 joerg
833 1.1 joerg if (I->isTerminator()) {
834 1.1 joerg for (BasicBlock *Succ : successors(I))
835 1.1 joerg if (Succ == L.getHeader()) {
836 1.1 joerg I->setMetadata(llvm::LLVMContext::MD_loop, L.getLoopID());
837 1.1 joerg break;
838 1.1 joerg }
839 1.1 joerg return;
840 1.1 joerg }
841 1.1 joerg }
842