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"
24MDNode *clang::CodeGen::LoopInfo::createFollowupMetadata(
26 LLVMContext &Ctx = Header->getContext();
28 SmallVector<Metadata *, 4> Args;
29 Args.push_back(MDString::get(Ctx, FollowupName));
30 Args.append(LoopProperties.begin(), LoopProperties.end());
31 return MDNode::get(Ctx, Args);
34SmallVector<Metadata *, 4> clang::CodeGen::LoopInfo::createPipeliningMetadata(
36 bool &HasUserTransforms) {
37 LLVMContext &Ctx = Header->getContext();
39 std::optional<bool> Enabled;
45 SmallVector<Metadata *, 4> Args;
46 Args.append(LoopProperties.begin(), LoopProperties.end());
48 if (Enabled !=
true) {
49 if (Enabled ==
false) {
51 MDNode::get(Ctx, {MDString::get(Ctx,
"llvm.loop.pipeline.disable"),
52 ConstantAsMetadata::get(ConstantInt::get(
53 llvm::Type::getInt1Ty(Ctx), 1))}));
60 MDString::get(Ctx,
"llvm.loop.pipeline.initiationinterval"),
61 ConstantAsMetadata::get(ConstantInt::get(
63 Args.push_back(MDNode::get(Ctx, Vals));
68 HasUserTransforms =
true;
72SmallVector<Metadata *, 4>
73clang::CodeGen::LoopInfo::createPartialUnrollMetadata(
75 bool &HasUserTransforms) {
76 LLVMContext &Ctx = Header->getContext();
78 std::optional<bool> Enabled;
82 Enabled = std::nullopt;
87 if (Enabled !=
true) {
90 return createPipeliningMetadata(Attrs, LoopProperties, HasUserTransforms);
93 SmallVector<Metadata *, 4> FollowupLoopProperties;
96 FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
99 FollowupLoopProperties.push_back(
100 MDNode::get(Ctx, MDString::get(Ctx,
"llvm.loop.unroll.disable")));
102 bool FollowupHasTransforms =
false;
103 SmallVector<Metadata *, 4> Followup = createPipeliningMetadata(
104 Attrs, FollowupLoopProperties, FollowupHasTransforms);
106 SmallVector<Metadata *, 4> Args;
107 Args.append(LoopProperties.begin(), LoopProperties.end());
111 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.unroll.count"),
112 ConstantAsMetadata::get(ConstantInt::get(
114 Args.push_back(MDNode::get(Ctx, Vals));
119 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.unroll.enable")};
120 Args.push_back(MDNode::get(Ctx, Vals));
123 if (FollowupHasTransforms)
125 createFollowupMetadata(
"llvm.loop.unroll.followup_all", Followup));
127 HasUserTransforms =
true;
131SmallVector<Metadata *, 4> clang::CodeGen::LoopInfo::createUnrollAndJamMetadata(
133 bool &HasUserTransforms) {
134 LLVMContext &Ctx = Header->getContext();
136 std::optional<bool> Enabled;
143 if (Enabled !=
true) {
144 SmallVector<Metadata *, 4> NewLoopProperties;
145 if (Enabled ==
false) {
146 NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
147 NewLoopProperties.push_back(MDNode::get(
148 Ctx, MDString::get(Ctx,
"llvm.loop.unroll_and_jam.disable")));
149 LoopProperties = NewLoopProperties;
151 return createPartialUnrollMetadata(Attrs, LoopProperties,
155 SmallVector<Metadata *, 4> FollowupLoopProperties;
156 FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
157 FollowupLoopProperties.push_back(
158 MDNode::get(Ctx, MDString::get(Ctx,
"llvm.loop.unroll_and_jam.disable")));
160 bool FollowupHasTransforms =
false;
161 SmallVector<Metadata *, 4> Followup = createPartialUnrollMetadata(
162 Attrs, FollowupLoopProperties, FollowupHasTransforms);
164 SmallVector<Metadata *, 4> Args;
165 Args.append(LoopProperties.begin(), LoopProperties.end());
170 MDString::get(Ctx,
"llvm.loop.unroll_and_jam.count"),
171 ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
173 Args.push_back(MDNode::get(Ctx, Vals));
177 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.unroll_and_jam.enable")};
178 Args.push_back(MDNode::get(Ctx, Vals));
181 if (FollowupHasTransforms)
182 Args.push_back(createFollowupMetadata(
183 "llvm.loop.unroll_and_jam.followup_outer", Followup));
185 if (UnrollAndJamInnerFollowup.has_value())
186 Args.push_back(createFollowupMetadata(
187 "llvm.loop.unroll_and_jam.followup_inner", *UnrollAndJamInnerFollowup));
189 HasUserTransforms =
true;
193SmallVector<Metadata *, 4>
194clang::CodeGen::LoopInfo::createLoopVectorizeMetadata(
196 bool &HasUserTransforms) {
197 LLVMContext &Ctx = Header->getContext();
199 std::optional<bool> Enabled;
208 if (Enabled !=
true) {
209 SmallVector<Metadata *, 4> NewLoopProperties;
210 if (Enabled ==
false) {
211 NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
212 NewLoopProperties.push_back(MDNode::get(
213 Ctx, {MDString::get(Ctx,
"llvm.loop.vectorize.disable")}));
214 LoopProperties = NewLoopProperties;
216 return createUnrollAndJamMetadata(Attrs, LoopProperties, HasUserTransforms);
219 SmallVector<Metadata *, 4> Args;
220 Args.append(LoopProperties.begin(), LoopProperties.end());
224 bool IsVectorPredicateEnabled =
false;
226 IsVectorPredicateEnabled =
229 Args.push_back(MDNode::get(
231 {MDString::get(Ctx, IsVectorPredicateEnabled
232 ?
"llvm.loop.vectorize.predicate.enable"
233 :
"llvm.loop.vectorize.predicate.disable")}));
239 MDString::get(Ctx,
"llvm.loop.vectorize.width"),
240 ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
243 Args.push_back(MDNode::get(Ctx, Vals));
248 Args.push_back(MDNode::get(
250 Ctx, IsScalable ?
"llvm.loop.vectorize.scalable.enable"
251 :
"llvm.loop.vectorize.scalable.disable")}));
257 MDString::get(Ctx,
"llvm.loop.interleave.count"),
258 ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
260 Args.push_back(MDNode::get(Ctx, Vals));
271 bool VectorizeEnabled =
false;
279 Args.push_back(MDNode::get(
280 Ctx, {MDString::get(Ctx, VectorizeEnabled
281 ?
"llvm.loop.vectorize.enable"
282 :
"llvm.loop.vectorize.disable")}));
286 SmallVector<Metadata *, 4> FollowupLoopProperties;
291 if (VectorizeEnabled)
292 FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
295 FollowupLoopProperties.push_back(
296 MDNode::get(Ctx, MDString::get(Ctx,
"llvm.loop.isvectorized")));
298 bool FollowupHasTransforms =
false;
299 SmallVector<Metadata *, 4> Followup = createUnrollAndJamMetadata(
300 Attrs, FollowupLoopProperties, FollowupHasTransforms);
302 if (FollowupHasTransforms) {
305 if (VectorizeEnabled)
307 createFollowupMetadata(
"llvm.loop.vectorize.followup_all", Followup));
309 Args.append(Followup.begin(), Followup.end());
312 HasUserTransforms =
true;
316SmallVector<Metadata *, 4>
317clang::CodeGen::LoopInfo::createLoopDistributeMetadata(
319 bool &HasUserTransforms) {
320 LLVMContext &Ctx = Header->getContext();
322 std::optional<bool> Enabled;
328 if (Enabled !=
true) {
329 SmallVector<Metadata *, 4> NewLoopProperties;
330 if (Enabled ==
false) {
331 NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
332 NewLoopProperties.push_back(MDNode::get(
333 Ctx, {MDString::get(Ctx,
"llvm.loop.distribute.disable")}));
334 LoopProperties = NewLoopProperties;
336 return createLoopVectorizeMetadata(Attrs, LoopProperties,
340 bool FollowupHasTransforms =
false;
341 SmallVector<Metadata *, 4> Followup =
342 createLoopVectorizeMetadata(Attrs, LoopProperties, FollowupHasTransforms);
344 SmallVector<Metadata *, 4> Args;
345 Args.append(LoopProperties.begin(), LoopProperties.end());
348 MDNode::get(Ctx, {MDString::get(Ctx,
"llvm.loop.distribute.enable")}));
350 if (FollowupHasTransforms)
352 createFollowupMetadata(
"llvm.loop.distribute.followup_all", Followup));
354 HasUserTransforms =
true;
358SmallVector<Metadata *, 4> clang::CodeGen::LoopInfo::createFullUnrollMetadata(
360 bool &HasUserTransforms) {
361 LLVMContext &Ctx = Header->getContext();
363 std::optional<bool> Enabled;
369 if (Enabled !=
true) {
370 SmallVector<Metadata *, 4> NewLoopProperties;
371 if (Enabled ==
false) {
372 NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
373 NewLoopProperties.push_back(
374 MDNode::get(Ctx, MDString::get(Ctx,
"llvm.loop.unroll.disable")));
375 LoopProperties = NewLoopProperties;
377 return createLoopDistributeMetadata(Attrs, LoopProperties,
381 SmallVector<Metadata *, 4> Args;
382 Args.append(LoopProperties.begin(), LoopProperties.end());
383 Args.push_back(MDNode::get(Ctx, MDString::get(Ctx,
"llvm.loop.unroll.full")));
388 HasUserTransforms =
true;
392SmallVector<Metadata *, 4> clang::CodeGen::LoopInfo::createMetadata(
394 llvm::ArrayRef<llvm::Metadata *> AdditionalLoopProperties,
395 bool &HasUserTransforms) {
396 SmallVector<Metadata *, 3> LoopProperties;
400 LoopProperties.push_back(StartLoc.getAsMDNode());
404 LoopProperties.push_back(EndLoc.getAsMDNode());
407 LLVMContext &Ctx = Header->getContext();
409 LoopProperties.push_back(
410 MDNode::get(Ctx, MDString::get(Ctx,
"llvm.loop.mustprogress")));
413 LoopProperties.push_back(
414 MDNode::get(Ctx, MDString::get(Ctx,
"llvm.licm.disable")));
417 "There must be an access group iff the loop is parallel");
419 LoopProperties.push_back(MDNode::get(
420 Ctx, {MDString::get(Ctx,
"llvm.loop.parallel_accesses"), AccGroup}));
425 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.align"),
426 ConstantAsMetadata::get(ConstantInt::get(
427 llvm::Type::getInt32Ty(Ctx), Attrs.
CodeAlign))};
428 LoopProperties.push_back(MDNode::get(Ctx, Vals));
431 llvm::append_range(LoopProperties, AdditionalLoopProperties);
432 return createFullUnrollMetadata(Attrs, LoopProperties, HasUserTransforms);
467 const llvm::DebugLoc &StartLoc,
468 const llvm::DebugLoc &EndLoc,
470 : Header(Header), Attrs(Attrs), StartLoc(StartLoc), EndLoc(EndLoc),
473 if (Attrs.IsParallel) {
475 LLVMContext &Ctx = Header->getContext();
476 AccGroup = MDNode::getDistinct(Ctx, {});
492 TempLoopID = MDNode::getTemporary(Header->getContext(), {});
503 LLVMContext &Ctx = Header->getContext();
505 if (Parent && (Parent->Attrs.UnrollAndJamEnable ||
506 Parent->Attrs.UnrollAndJamCount != 0)) {
523 switch (Attrs.UnrollEnable) {
552 if (!Parent->UnrollAndJamInnerFollowup) {
562 BeforeLoopProperties.push_back(
563 MDNode::get(Ctx, MDString::get(Ctx,
"llvm.loop.isvectorized")));
565 bool InnerFollowupHasTransform =
false;
567 AfterJam, BeforeLoopProperties, InnerFollowupHasTransform);
568 if (InnerFollowupHasTransform)
569 Parent->UnrollAndJamInnerFollowup = InnerFollowup;
572 CurLoopAttr = BeforeJam;
575 bool HasUserTransforms =
false;
577 createMetadata(CurLoopAttr, {}, HasUserTransforms);
579 Args.push_back(
nullptr);
580 Args.append(Properties.begin(), Properties.end());
581 LoopID = MDNode::getDistinct(Ctx, Args);
582 LoopID->replaceOperandWith(0, LoopID);
584 TempLoopID->replaceAllUsesWith(LoopID);
588 const llvm::DebugLoc &EndLoc) {
590 new LoopInfo(Header, StagedAttrs, StartLoc, EndLoc,
591 Active.empty() ?
nullptr : Active.back().get()));
599 const llvm::DebugLoc &StartLoc,
600 const llvm::DebugLoc &EndLoc,
bool MustProgress) {
602 for (
const auto *
Attr : Attrs) {
603 const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(
Attr);
604 const OpenCLUnrollHintAttr *OpenCLHint =
605 dyn_cast<OpenCLUnrollHintAttr>(
Attr);
606 const HLSLLoopHintAttr *HLSLLoopHint = dyn_cast<HLSLLoopHintAttr>(
Attr);
608 if (!LH && !OpenCLHint && !HLSLLoopHint) {
612 LoopHintAttr::OptionType Option = LoopHintAttr::Unroll;
613 LoopHintAttr::LoopHintState State = LoopHintAttr::Disable;
614 unsigned ValueInt = 1;
622 ValueInt = OpenCLHint->getUnrollHint();
624 State = LoopHintAttr::Enable;
625 }
else if (ValueInt != 1) {
626 Option = LoopHintAttr::UnrollCount;
627 State = LoopHintAttr::Numeric;
629 }
else if (HLSLLoopHint) {
630 ValueInt = HLSLLoopHint->getDirective();
631 if (HLSLLoopHint->getSemanticSpelling() ==
632 HLSLLoopHintAttr::Spelling::Microsoft_unroll) {
634 State = LoopHintAttr::Enable;
636 Option = LoopHintAttr::UnrollCount;
637 State = LoopHintAttr::Numeric;
641 auto *ValueExpr = LH->getValue();
643 llvm::APSInt ValueAPS = ValueExpr->EvaluateKnownConstInt(Ctx);
644 ValueInt = ValueAPS.getSExtValue();
647 Option = LH->getOption();
648 State = LH->getState();
651 case LoopHintAttr::Disable:
653 case LoopHintAttr::Vectorize:
658 case LoopHintAttr::Interleave:
662 case LoopHintAttr::Unroll:
665 case LoopHintAttr::UnrollAndJam:
668 case LoopHintAttr::VectorizePredicate:
671 case LoopHintAttr::Distribute:
674 case LoopHintAttr::PipelineDisabled:
677 case LoopHintAttr::LICMDisabled:
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.");
689 case LoopHintAttr::Enable:
691 case LoopHintAttr::Vectorize:
692 case LoopHintAttr::Interleave:
695 case LoopHintAttr::Unroll:
698 case LoopHintAttr::UnrollAndJam:
701 case LoopHintAttr::VectorizePredicate:
704 case LoopHintAttr::Distribute:
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 case LoopHintAttr::LICMDisabled:
714 llvm_unreachable(
"Options cannot enabled.");
718 case LoopHintAttr::AssumeSafety:
720 case LoopHintAttr::Vectorize:
721 case LoopHintAttr::Interleave:
726 case LoopHintAttr::Unroll:
727 case LoopHintAttr::UnrollAndJam:
728 case LoopHintAttr::VectorizePredicate:
729 case LoopHintAttr::UnrollCount:
730 case LoopHintAttr::UnrollAndJamCount:
731 case LoopHintAttr::VectorizeWidth:
732 case LoopHintAttr::InterleaveCount:
733 case LoopHintAttr::Distribute:
734 case LoopHintAttr::PipelineDisabled:
735 case LoopHintAttr::PipelineInitiationInterval:
736 case LoopHintAttr::LICMDisabled:
737 llvm_unreachable(
"Options cannot be used to assume mem safety.");
741 case LoopHintAttr::Full:
743 case LoopHintAttr::Unroll:
746 case LoopHintAttr::UnrollAndJam:
749 case LoopHintAttr::Vectorize:
750 case LoopHintAttr::Interleave:
751 case LoopHintAttr::UnrollCount:
752 case LoopHintAttr::UnrollAndJamCount:
753 case LoopHintAttr::VectorizeWidth:
754 case LoopHintAttr::InterleaveCount:
755 case LoopHintAttr::Distribute:
756 case LoopHintAttr::PipelineDisabled:
757 case LoopHintAttr::PipelineInitiationInterval:
758 case LoopHintAttr::VectorizePredicate:
759 case LoopHintAttr::LICMDisabled:
760 llvm_unreachable(
"Options cannot be used with 'full' hint.");
764 case LoopHintAttr::FixedWidth:
765 case LoopHintAttr::ScalableWidth:
767 case LoopHintAttr::VectorizeWidth:
775 llvm_unreachable(
"Options cannot be used with 'scalable' hint.");
779 case LoopHintAttr::Numeric:
781 case LoopHintAttr::InterleaveCount:
784 case LoopHintAttr::UnrollCount:
787 case LoopHintAttr::UnrollAndJamCount:
790 case LoopHintAttr::PipelineInitiationInterval:
793 case LoopHintAttr::Unroll:
794 case LoopHintAttr::UnrollAndJam:
795 case LoopHintAttr::VectorizePredicate:
796 case LoopHintAttr::Vectorize:
797 case LoopHintAttr::VectorizeWidth:
798 case LoopHintAttr::Interleave:
799 case LoopHintAttr::Distribute:
800 case LoopHintAttr::PipelineDisabled:
801 case LoopHintAttr::LICMDisabled:
802 llvm_unreachable(
"Options cannot be assigned a value.");
814 llvm::APSInt ArgVal = CE->getResultAsAPSInt();
820 if (CGOpts.OptimizationLevel > 0)
823 if (!CGOpts.UnrollLoops &&
825 StagedAttrs.UnrollCount == 0))
829 push(Header, StartLoc, EndLoc);
833 assert(!Active.empty() &&
"No active loops to pop");
834 Active.back()->finish();
839 if (I->mayReadOrWriteMemory()) {
841 for (
const auto &AL : Active) {
843 if (MDNode *Group = AL->getAccessGroup())
844 AccessGroups.push_back(Group);
846 MDNode *UnionMD =
nullptr;
847 if (AccessGroups.size() == 1)
849 else if (AccessGroups.size() >= 2)
850 UnionMD = MDNode::get(I->getContext(), AccessGroups);
851 I->setMetadata(
"llvm.access.group", UnionMD);
861 if (I->isTerminator()) {
862 for (BasicBlock *Succ : successors(I))
864 I->setMetadata(llvm::LLVMContext::MD_loop, L.
getLoopID());
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.
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.
void setCodeAlign(unsigned C)
Set value of code align for the next loop pushed.
void setLICMDisabled(bool Disabled=true)
Set the next pushed loop LICM disable state.
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.
void finish()
Create the loop's metadata.
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.
llvm::MDNode * getLoopID() const
Get the loop id metadata for this loop.
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)
bool IsParallel
Generate llvm.loop.parallel metadata for loads and stores.
bool LICMDisabled
Value for llvm.licm.disable metadata.
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.
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.