clang: lib/CodeGen/CGLoopInfo.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
14#include "llvm/IR/BasicBlock.h"
15#include "llvm/IR/CFG.h"
16#include "llvm/IR/Constants.h"
17#include "llvm/IR/InstrTypes.h"
18#include "llvm/IR/Instructions.h"
19#include "llvm/IR/Metadata.h"
20#include
22using namespace llvm;
23
24MDNode *
25LoopInfo::createFollowupMetadata(const char *FollowupName,
27 LLVMContext &Ctx = Header->getContext();
28
29 SmallVector<Metadata *, 4> Args;
30 Args.push_back(MDString::get(Ctx, FollowupName));
31 Args.append(LoopProperties.begin(), LoopProperties.end());
32 return MDNode::get(Ctx, Args);
33}
34
35SmallVector<Metadata *, 4>
36LoopInfo::createPipeliningMetadata(const LoopAttributes &Attrs,
37 ArrayRef<Metadata *> LoopProperties,
38 bool &HasUserTransforms) {
39 LLVMContext &Ctx = Header->getContext();
40
41 std::optional Enabled;
42 if (Attrs.PipelineDisabled)
43 Enabled = false;
44 else if (Attrs.PipelineInitiationInterval != 0)
45 Enabled = true;
46
47 SmallVector<Metadata *, 4> Args;
48 Args.append(LoopProperties.begin(), LoopProperties.end());
49
50 if (Enabled != true) {
51 if (Enabled == false) {
52 Args.push_back(
53 MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.pipeline.disable"),
54 ConstantAsMetadata::get(ConstantInt::get(
55 llvm::Type::getInt1Ty(Ctx), 1))}));
56 }
57 return Args;
58 }
59
60 if (Attrs.PipelineInitiationInterval > 0) {
61 Metadata *Vals[] = {
62 MDString::get(Ctx, "llvm.loop.pipeline.initiationinterval"),
63 ConstantAsMetadata::get(ConstantInt::get(
64 llvm::Type::getInt32Ty(Ctx), Attrs.PipelineInitiationInterval))};
65 Args.push_back(MDNode::get(Ctx, Vals));
66 }
67
68
69
70 HasUserTransforms = true;
71 return Args;
72}
73
74SmallVector<Metadata *, 4>
75LoopInfo::createPartialUnrollMetadata(const LoopAttributes &Attrs,
76 ArrayRef<Metadata *> LoopProperties,
77 bool &HasUserTransforms) {
78 LLVMContext &Ctx = Header->getContext();
79
80 std::optional Enabled;
82 Enabled = false;
84 Enabled = std::nullopt;
86 Attrs.UnrollCount != 0)
87 Enabled = true;
88
89 if (Enabled != true) {
90
91
92 return createPipeliningMetadata(Attrs, LoopProperties, HasUserTransforms);
93 }
94
95 SmallVector<Metadata *, 4> FollowupLoopProperties;
96
97
98 FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
99
100
101 FollowupLoopProperties.push_back(
102 MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.disable")));
103
104 bool FollowupHasTransforms = false;
105 SmallVector<Metadata *, 4> Followup = createPipeliningMetadata(
106 Attrs, FollowupLoopProperties, FollowupHasTransforms);
107
108 SmallVector<Metadata *, 4> Args;
109 Args.append(LoopProperties.begin(), LoopProperties.end());
110
111
112 if (Attrs.UnrollCount > 0) {
113 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll.count"),
114 ConstantAsMetadata::get(ConstantInt::get(
115 llvm::Type::getInt32Ty(Ctx), Attrs.UnrollCount))};
116 Args.push_back(MDNode::get(Ctx, Vals));
117 }
118
119
121 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll.enable")};
122 Args.push_back(MDNode::get(Ctx, Vals));
123 }
124
125 if (FollowupHasTransforms)
126 Args.push_back(
127 createFollowupMetadata("llvm.loop.unroll.followup_all", Followup));
128
129 HasUserTransforms = true;
130 return Args;
131}
132
133SmallVector<Metadata *, 4>
134LoopInfo::createUnrollAndJamMetadata(const LoopAttributes &Attrs,
135 ArrayRef<Metadata *> LoopProperties,
136 bool &HasUserTransforms) {
137 LLVMContext &Ctx = Header->getContext();
138
139 std::optional Enabled;
141 Enabled = false;
143 Attrs.UnrollAndJamCount != 0)
144 Enabled = true;
145
146 if (Enabled != true) {
147 SmallVector<Metadata *, 4> NewLoopProperties;
148 if (Enabled == false) {
149 NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
150 NewLoopProperties.push_back(MDNode::get(
151 Ctx, MDString::get(Ctx, "llvm.loop.unroll_and_jam.disable")));
152 LoopProperties = NewLoopProperties;
153 }
154 return createPartialUnrollMetadata(Attrs, LoopProperties,
155 HasUserTransforms);
156 }
157
158 SmallVector<Metadata *, 4> FollowupLoopProperties;
159 FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
160 FollowupLoopProperties.push_back(
161 MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll_and_jam.disable")));
162
163 bool FollowupHasTransforms = false;
164 SmallVector<Metadata *, 4> Followup = createPartialUnrollMetadata(
165 Attrs, FollowupLoopProperties, FollowupHasTransforms);
166
167 SmallVector<Metadata *, 4> Args;
168 Args.append(LoopProperties.begin(), LoopProperties.end());
169
170
171 if (Attrs.UnrollAndJamCount > 0) {
172 Metadata *Vals[] = {
173 MDString::get(Ctx, "llvm.loop.unroll_and_jam.count"),
174 ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
175 Attrs.UnrollAndJamCount))};
176 Args.push_back(MDNode::get(Ctx, Vals));
177 }
178
180 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll_and_jam.enable")};
181 Args.push_back(MDNode::get(Ctx, Vals));
182 }
183
184 if (FollowupHasTransforms)
185 Args.push_back(createFollowupMetadata(
186 "llvm.loop.unroll_and_jam.followup_outer", Followup));
187
188 if (UnrollAndJamInnerFollowup.has_value())
189 Args.push_back(createFollowupMetadata(
190 "llvm.loop.unroll_and_jam.followup_inner", *UnrollAndJamInnerFollowup));
191
192 HasUserTransforms = true;
193 return Args;
194}
195
196SmallVector<Metadata *, 4>
197LoopInfo::createLoopVectorizeMetadata(const LoopAttributes &Attrs,
198 ArrayRef<Metadata *> LoopProperties,
199 bool &HasUserTransforms) {
200 LLVMContext &Ctx = Header->getContext();
201
202 std::optional Enabled;
204 Enabled = false;
207 Attrs.InterleaveCount != 0 || Attrs.VectorizeWidth != 0 ||
209 Enabled = true;
210
211 if (Enabled != true) {
212 SmallVector<Metadata *, 4> NewLoopProperties;
213 if (Enabled == false) {
214 NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
215 NewLoopProperties.push_back(
216 MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.vectorize.enable"),
217 ConstantAsMetadata::get(ConstantInt::get(
218 llvm::Type::getInt1Ty(Ctx), 0))}));
219 LoopProperties = NewLoopProperties;
220 }
221 return createUnrollAndJamMetadata(Attrs, LoopProperties, HasUserTransforms);
222 }
223
224 SmallVector<Metadata *, 4> Args;
225 Args.append(LoopProperties.begin(), LoopProperties.end());
226
227
228
229 bool IsVectorPredicateEnabled = false;
231 IsVectorPredicateEnabled =
233
234 Metadata *Vals[] = {
235 MDString::get(Ctx, "llvm.loop.vectorize.predicate.enable"),
236 ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt1Ty(Ctx),
237 IsVectorPredicateEnabled))};
238 Args.push_back(MDNode::get(Ctx, Vals));
239 }
240
241
242 if (Attrs.VectorizeWidth > 0) {
243 Metadata *Vals[] = {
244 MDString::get(Ctx, "llvm.loop.vectorize.width"),
245 ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
246 Attrs.VectorizeWidth))};
247
248 Args.push_back(MDNode::get(Ctx, Vals));
249 }
250
253 Metadata *Vals[] = {
254 MDString::get(Ctx, "llvm.loop.vectorize.scalable.enable"),
255 ConstantAsMetadata::get(
256 ConstantInt::get(llvm::Type::getInt1Ty(Ctx), IsScalable))};
257 Args.push_back(MDNode::get(Ctx, Vals));
258 }
259
260
261 if (Attrs.InterleaveCount > 0) {
262 Metadata *Vals[] = {
263 MDString::get(Ctx, "llvm.loop.interleave.count"),
264 ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
265 Attrs.InterleaveCount))};
266 Args.push_back(MDNode::get(Ctx, Vals));
267 }
268
269
270
271
272
273
274
275
276
277 bool VectorizeEnabled = false;
279 (IsVectorPredicateEnabled && Attrs.VectorizeWidth != 1) ||
280 Attrs.VectorizeWidth > 1 ||
283 Attrs.VectorizeWidth != 1)) {
285 Args.push_back(
286 MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.vectorize.enable"),
287 ConstantAsMetadata::get(ConstantInt::get(
288 llvm::Type::getInt1Ty(Ctx), VectorizeEnabled))}));
289 }
290
291
292 SmallVector<Metadata *, 4> FollowupLoopProperties;
293
294
295
296
297 if (VectorizeEnabled)
298 FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
299
300
301 FollowupLoopProperties.push_back(
302 MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.isvectorized")));
303
304 bool FollowupHasTransforms = false;
305 SmallVector<Metadata *, 4> Followup = createUnrollAndJamMetadata(
306 Attrs, FollowupLoopProperties, FollowupHasTransforms);
307
308 if (FollowupHasTransforms) {
309
310
311 if (VectorizeEnabled)
312 Args.push_back(
313 createFollowupMetadata("llvm.loop.vectorize.followup_all", Followup));
314 else
315 Args.append(Followup.begin(), Followup.end());
316 }
317
318 HasUserTransforms = true;
319 return Args;
320}
321
322SmallVector<Metadata *, 4>
323LoopInfo::createLoopDistributeMetadata(const LoopAttributes &Attrs,
324 ArrayRef<Metadata *> LoopProperties,
325 bool &HasUserTransforms) {
326 LLVMContext &Ctx = Header->getContext();
327
328 std::optional Enabled;
330 Enabled = false;
332 Enabled = true;
333
334 if (Enabled != true) {
335 SmallVector<Metadata *, 4> NewLoopProperties;
336 if (Enabled == false) {
337 NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
338 NewLoopProperties.push_back(
339 MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.distribute.enable"),
340 ConstantAsMetadata::get(ConstantInt::get(
341 llvm::Type::getInt1Ty(Ctx), 0))}));
342 LoopProperties = NewLoopProperties;
343 }
344 return createLoopVectorizeMetadata(Attrs, LoopProperties,
345 HasUserTransforms);
346 }
347
348 bool FollowupHasTransforms = false;
349 SmallVector<Metadata *, 4> Followup =
350 createLoopVectorizeMetadata(Attrs, LoopProperties, FollowupHasTransforms);
351
352 SmallVector<Metadata *, 4> Args;
353 Args.append(LoopProperties.begin(), LoopProperties.end());
354
355 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.distribute.enable"),
356 ConstantAsMetadata::get(ConstantInt::get(
357 llvm::Type::getInt1Ty(Ctx),
359 Args.push_back(MDNode::get(Ctx, Vals));
360
361 if (FollowupHasTransforms)
362 Args.push_back(
363 createFollowupMetadata("llvm.loop.distribute.followup_all", Followup));
364
365 HasUserTransforms = true;
366 return Args;
367}
368
369SmallVector<Metadata *, 4>
370LoopInfo::createFullUnrollMetadata(const LoopAttributes &Attrs,
371 ArrayRef<Metadata *> LoopProperties,
372 bool &HasUserTransforms) {
373 LLVMContext &Ctx = Header->getContext();
374
375 std::optional Enabled;
377 Enabled = false;
379 Enabled = true;
380
381 if (Enabled != true) {
382 SmallVector<Metadata *, 4> NewLoopProperties;
383 if (Enabled == false) {
384 NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
385 NewLoopProperties.push_back(
386 MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.disable")));
387 LoopProperties = NewLoopProperties;
388 }
389 return createLoopDistributeMetadata(Attrs, LoopProperties,
390 HasUserTransforms);
391 }
392
393 SmallVector<Metadata *, 4> Args;
394 Args.append(LoopProperties.begin(), LoopProperties.end());
395 Args.push_back(MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.full")));
396
397
398
399
400 HasUserTransforms = true;
401 return Args;
402}
403
404SmallVector<Metadata *, 4> LoopInfo::createMetadata(
406 llvm::ArrayRef<llvm::Metadata *> AdditionalLoopProperties,
407 bool &HasUserTransforms) {
408 SmallVector<Metadata *, 3> LoopProperties;
409
410
411 if (StartLoc) {
412 LoopProperties.push_back(StartLoc.getAsMDNode());
413
414
415 if (EndLoc)
416 LoopProperties.push_back(EndLoc.getAsMDNode());
417 }
418
419 LLVMContext &Ctx = Header->getContext();
420 if (Attrs.MustProgress)
421 LoopProperties.push_back(
422 MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.mustprogress")));
423
424 assert(!!AccGroup == Attrs.IsParallel &&
425 "There must be an access group iff the loop is parallel");
426 if (Attrs.IsParallel) {
427 LoopProperties.push_back(MDNode::get(
428 Ctx, {MDString::get(Ctx, "llvm.loop.parallel_accesses"), AccGroup}));
429 }
430
431
432 if (Attrs.CodeAlign > 0) {
433 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.align"),
434 ConstantAsMetadata::get(ConstantInt::get(
435 llvm::Type::getInt32Ty(Ctx), Attrs.CodeAlign))};
436 LoopProperties.push_back(MDNode::get(Ctx, Vals));
437 }
438
439 llvm::append_range(LoopProperties, AdditionalLoopProperties);
440 return createFullUnrollMetadata(Attrs, LoopProperties, HasUserTransforms);
441}
442
452
470
472 const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc,
474 : Header(Header), Attrs(Attrs), StartLoc(StartLoc), EndLoc(EndLoc),
475 Parent(Parent) {
476
477 if (Attrs.IsParallel) {
478
479 LLVMContext &Ctx = Header->getContext();
480 AccGroup = MDNode::getDistinct(Ctx, {});
481 }
482
494 return;
495
496 TempLoopID = MDNode::getTemporary(Header->getContext(), {});
497}
498
500
501
502 if (!TempLoopID)
503 return;
504
505 MDNode *LoopID;
507 LLVMContext &Ctx = Header->getContext();
508
509 if (Parent && (Parent->Attrs.UnrollAndJamEnable ||
510 Parent->Attrs.UnrollAndJamCount != 0)) {
511
512
513
514
516
518
525
526 switch (Attrs.UnrollEnable) {
531 break;
534 break;
537 break;
538 }
539
541 AfterJam.UnrollCount = Attrs.UnrollCount;
544
545
546
547
548
549
552
553
554
555 if (!Parent->UnrollAndJamInnerFollowup) {
556
557
558
559
565 BeforeLoopProperties.push_back(
566 MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.isvectorized")));
567
568 bool InnerFollowupHasTransform = false;
570 AfterJam, BeforeLoopProperties, InnerFollowupHasTransform);
571 if (InnerFollowupHasTransform)
572 Parent->UnrollAndJamInnerFollowup = InnerFollowup;
573 }
574
575 CurLoopAttr = BeforeJam;
576 }
577
578 bool HasUserTransforms = false;
580 createMetadata(CurLoopAttr, {}, HasUserTransforms);
582 Args.push_back(nullptr);
583 Args.append(Properties.begin(), Properties.end());
584 LoopID = MDNode::getDistinct(Ctx, Args);
585 LoopID->replaceOperandWith(0, LoopID);
586
587 TempLoopID->replaceAllUsesWith(LoopID);
588}
589
590void LoopInfoStack::push(BasicBlock *Header, const llvm::DebugLoc &StartLoc,
591 const llvm::DebugLoc &EndLoc) {
592 Active.emplace_back(
593 new LoopInfo(Header, StagedAttrs, StartLoc, EndLoc,
594 Active.empty() ? nullptr : Active.back().get()));
595
596 StagedAttrs.clear();
597}
598
602 const llvm::DebugLoc &StartLoc,
603 const llvm::DebugLoc &EndLoc, bool MustProgress) {
604
605 for (const auto *Attr : Attrs) {
606 const LoopHintAttr *LH = dyn_cast(Attr);
607 const OpenCLUnrollHintAttr *OpenCLHint =
608 dyn_cast(Attr);
609 const HLSLLoopHintAttr *HLSLLoopHint = dyn_cast(Attr);
610
611 if (!LH && !OpenCLHint && !HLSLLoopHint) {
612 continue;
613 }
614
615 LoopHintAttr::OptionType Option = LoopHintAttr::Unroll;
616 LoopHintAttr::LoopHintState State = LoopHintAttr::Disable;
617 unsigned ValueInt = 1;
618
619
620
621
622
623
624 if (OpenCLHint) {
625 ValueInt = OpenCLHint->getUnrollHint();
626 if (ValueInt == 0) {
627 State = LoopHintAttr::Enable;
628 } else if (ValueInt != 1) {
629 Option = LoopHintAttr::UnrollCount;
630 State = LoopHintAttr::Numeric;
631 }
632 } else if (HLSLLoopHint) {
633 ValueInt = HLSLLoopHint->getDirective();
634 if (HLSLLoopHint->getSemanticSpelling() ==
635 HLSLLoopHintAttr::Spelling::Microsoft_unroll) {
636 if (ValueInt == 0)
637 State = LoopHintAttr::Enable;
638 if (ValueInt > 0) {
639 Option = LoopHintAttr::UnrollCount;
640 State = LoopHintAttr::Numeric;
641 }
642 }
643 } else if (LH) {
644 auto *ValueExpr = LH->getValue();
645 if (ValueExpr) {
646 llvm::APSInt ValueAPS = ValueExpr->EvaluateKnownConstInt(Ctx);
647 ValueInt = ValueAPS.getSExtValue();
648 }
649
650 Option = LH->getOption();
651 State = LH->getState();
652 }
653 switch (State) {
654 case LoopHintAttr::Disable:
655 switch (Option) {
656 case LoopHintAttr::Vectorize:
657
660 break;
661 case LoopHintAttr::Interleave:
662
664 break;
665 case LoopHintAttr::Unroll:
667 break;
668 case LoopHintAttr::UnrollAndJam:
670 break;
671 case LoopHintAttr::VectorizePredicate:
673 break;
674 case LoopHintAttr::Distribute:
676 break;
677 case LoopHintAttr::PipelineDisabled:
679 break;
680 case LoopHintAttr::UnrollCount:
681 case LoopHintAttr::UnrollAndJamCount:
682 case LoopHintAttr::VectorizeWidth:
683 case LoopHintAttr::InterleaveCount:
684 case LoopHintAttr::PipelineInitiationInterval:
685 llvm_unreachable("Options cannot be disabled.");
686 break;
687 }
688 break;
689 case LoopHintAttr::Enable:
690 switch (Option) {
691 case LoopHintAttr::Vectorize:
692 case LoopHintAttr::Interleave:
694 break;
695 case LoopHintAttr::Unroll:
697 break;
698 case LoopHintAttr::UnrollAndJam:
700 break;
701 case LoopHintAttr::VectorizePredicate:
703 break;
704 case LoopHintAttr::Distribute:
706 break;
707 case LoopHintAttr::UnrollCount:
708 case LoopHintAttr::UnrollAndJamCount:
709 case LoopHintAttr::VectorizeWidth:
710 case LoopHintAttr::InterleaveCount:
711 case LoopHintAttr::PipelineDisabled:
712 case LoopHintAttr::PipelineInitiationInterval:
713 llvm_unreachable("Options cannot enabled.");
714 break;
715 }
716 break;
717 case LoopHintAttr::AssumeSafety:
718 switch (Option) {
719 case LoopHintAttr::Vectorize:
720 case LoopHintAttr::Interleave:
721
724 break;
725 case LoopHintAttr::Unroll:
726 case LoopHintAttr::UnrollAndJam:
727 case LoopHintAttr::VectorizePredicate:
728 case LoopHintAttr::UnrollCount:
729 case LoopHintAttr::UnrollAndJamCount:
730 case LoopHintAttr::VectorizeWidth:
731 case LoopHintAttr::InterleaveCount:
732 case LoopHintAttr::Distribute:
733 case LoopHintAttr::PipelineDisabled:
734 case LoopHintAttr::PipelineInitiationInterval:
735 llvm_unreachable("Options cannot be used to assume mem safety.");
736 break;
737 }
738 break;
739 case LoopHintAttr::Full:
740 switch (Option) {
741 case LoopHintAttr::Unroll:
743 break;
744 case LoopHintAttr::UnrollAndJam:
746 break;
747 case LoopHintAttr::Vectorize:
748 case LoopHintAttr::Interleave:
749 case LoopHintAttr::UnrollCount:
750 case LoopHintAttr::UnrollAndJamCount:
751 case LoopHintAttr::VectorizeWidth:
752 case LoopHintAttr::InterleaveCount:
753 case LoopHintAttr::Distribute:
754 case LoopHintAttr::PipelineDisabled:
755 case LoopHintAttr::PipelineInitiationInterval:
756 case LoopHintAttr::VectorizePredicate:
757 llvm_unreachable("Options cannot be used with 'full' hint.");
758 break;
759 }
760 break;
761 case LoopHintAttr::FixedWidth:
762 case LoopHintAttr::ScalableWidth:
763 switch (Option) {
764 case LoopHintAttr::VectorizeWidth:
768 if (LH->getValue())
770 break;
771 default:
772 llvm_unreachable("Options cannot be used with 'scalable' hint.");
773 break;
774 }
775 break;
776 case LoopHintAttr::Numeric:
777 switch (Option) {
778 case LoopHintAttr::InterleaveCount:
780 break;
781 case LoopHintAttr::UnrollCount:
783 break;
784 case LoopHintAttr::UnrollAndJamCount:
786 break;
787 case LoopHintAttr::PipelineInitiationInterval:
789 break;
790 case LoopHintAttr::Unroll:
791 case LoopHintAttr::UnrollAndJam:
792 case LoopHintAttr::VectorizePredicate:
793 case LoopHintAttr::Vectorize:
794 case LoopHintAttr::VectorizeWidth:
795 case LoopHintAttr::Interleave:
796 case LoopHintAttr::Distribute:
797 case LoopHintAttr::PipelineDisabled:
798 llvm_unreachable("Options cannot be assigned a value.");
799 break;
800 }
801 break;
802 }
803 }
804
805
806
807
810 llvm::APSInt ArgVal = CE->getResultAsAPSInt();
812 }
813
815
816 if (CGOpts.OptimizationLevel > 0)
817
818
819 if (!CGOpts.UnrollLoops &&
821 StagedAttrs.UnrollCount == 0))
823
824
825 push(Header, StartLoc, EndLoc);
826}
827
829 assert(!Active.empty() && "No active loops to pop");
830 Active.back()->finish();
831 Active.pop_back();
832}
833
835 if (I->mayReadOrWriteMemory()) {
837 for (const auto &AL : Active) {
838
839 if (MDNode *Group = AL->getAccessGroup())
840 AccessGroups.push_back(Group);
841 }
842 MDNode *UnionMD = nullptr;
843 if (AccessGroups.size() == 1)
845 else if (AccessGroups.size() >= 2)
846 UnionMD = MDNode::get(I->getContext(), AccessGroups);
847 I->setMetadata("llvm.access.group", UnionMD);
848 }
849
851 return;
852
855 return;
856
857 if (I->isTerminator()) {
858 for (BasicBlock *Succ : successors(I))
860 I->setMetadata(llvm::LLVMContext::MD_loop, L.getLoopID());
861 break;
862 }
863 return;
864 }
865}
Defines the clang::ASTContext interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Attr - This represents one attribute.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
void setPipelineDisabled(bool S)
Set the pipeline disabled state.
void setUnrollCount(unsigned C)
Set the unroll count for the next loop pushed.
bool hasInfo() const
Returns true if there is LoopInfo on the stack.
void setVectorizeWidth(unsigned W)
Set the vectorize width for the next loop pushed.
void InsertHelper(llvm::Instruction *I) const
Function called by the CodeGenFunction when an instruction is created.
Definition CGLoopInfo.cpp:834
void setDistributeState(bool Enable=true)
Set the next pushed loop as a distribution candidate.
void setParallel(bool Enable=true)
Set the next pushed loop as parallel.
void setInterleaveCount(unsigned C)
Set the interleave count for the next loop pushed.
void setUnrollState(const LoopAttributes::LVEnableState &State)
Set the next pushed loop unroll state.
void setVectorizeScalable(const LoopAttributes::LVEnableState &State)
void setVectorizePredicateState(const LoopAttributes::LVEnableState &State)
Set the next pushed vectorize predicate state.
void pop()
End the current loop.
Definition CGLoopInfo.cpp:828
void setCodeAlign(unsigned C)
Set value of code align for the next loop pushed.
void push(llvm::BasicBlock *Header, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
Begin a new structured loop.
void setMustProgress(bool P)
Set no progress for the next loop pushed.
void setUnrollAndJamState(const LoopAttributes::LVEnableState &State)
Set the next pushed loop unroll_and_jam state.
void setUnrollAndJamCount(unsigned C)
Set the unroll count for the next loop pushed.
const LoopInfo & getInfo() const
Return the LoopInfo for the current loop.
void setPipelineInitiationInterval(unsigned C)
Set the pipeline initiation interval.
void setVectorizeEnable(bool Enable=true)
Set the next pushed loop 'vectorize.enable'.
Information used when generating a structured loop.
llvm::BasicBlock * getHeader() const
Get the header block of this loop.
LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc, LoopInfo *Parent)
Construct a new LoopInfo for the loop with entry Header.
Definition CGLoopInfo.cpp:471
llvm::MDNode * getLoopID() const
Get the loop id metadata for this loop.
void finish()
Create the loop's metadata.
Definition CGLoopInfo.cpp:499
auto * getSpecificAttr(const Container &container)
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
Attributes that may be specified on loops.
unsigned UnrollCount
llvm.unroll.
bool MustProgress
Value for whether the loop is required to make progress.
unsigned InterleaveCount
Value for llvm.loop.interleave.count metadata.
LoopAttributes(bool IsParallel=false)
Definition CGLoopInfo.cpp:443
bool IsParallel
Generate llvm.loop.parallel metadata for loads and stores.
LVEnableState VectorizeScalable
LVEnableState UnrollAndJamEnable
Value for llvm.loop.unroll_and_jam.* metadata (enable, disable, or full).
unsigned UnrollAndJamCount
llvm.unroll.
LVEnableState VectorizePredicateEnable
Value for llvm.loop.vectorize.predicate metadata.
LVEnableState DistributeEnable
Value for llvm.loop.distribute.enable metadata.
bool PipelineDisabled
Value for llvm.loop.pipeline.disable metadata.
unsigned CodeAlign
Value for 'llvm.loop.align' metadata.
void clear()
Definition CGLoopInfo.cpp:453
LVEnableState UnrollEnable
Value for llvm.loop.unroll.* metadata (enable, disable, or full).
unsigned VectorizeWidth
Value for llvm.loop.vectorize.width metadata.
unsigned PipelineInitiationInterval
Value for llvm.loop.pipeline.iicount metadata.
LVEnableState VectorizeEnable
Value for llvm.loop.vectorize.enable metadata.