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"
25LoopInfo::createFollowupMetadata(
const char *FollowupName,
27 LLVMContext &Ctx = Header->getContext();
30 Args.push_back(MDString::get(Ctx, FollowupName));
31 Args.append(LoopProperties.begin(), LoopProperties.end());
32 return MDNode::get(Ctx, Args);
38 bool &HasUserTransforms) {
39 LLVMContext &Ctx = Header->getContext();
41 std::optional<bool> Enabled;
48 Args.append(LoopProperties.begin(), LoopProperties.end());
50 if (Enabled !=
true) {
51 if (Enabled ==
false) {
53 MDNode::get(Ctx, {MDString::get(Ctx,
"llvm.loop.pipeline.disable"),
54 ConstantAsMetadata::get(ConstantInt::get(
55 llvm::Type::getInt1Ty(Ctx), 1))}));
62 MDString::get(Ctx,
"llvm.loop.pipeline.initiationinterval"),
63 ConstantAsMetadata::get(ConstantInt::get(
65 Args.push_back(MDNode::get(Ctx, Vals));
70 HasUserTransforms =
true;
77 bool &HasUserTransforms) {
78 LLVMContext &Ctx = Header->getContext();
80 std::optional<bool> Enabled;
84 Enabled = std::nullopt;
89 if (Enabled !=
true) {
92 return createPipeliningMetadata(Attrs, LoopProperties, HasUserTransforms);
98 FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
101 FollowupLoopProperties.push_back(
102 MDNode::get(Ctx, MDString::get(Ctx,
"llvm.loop.unroll.disable")));
104 bool FollowupHasTransforms =
false;
106 Attrs, FollowupLoopProperties, FollowupHasTransforms);
109 Args.append(LoopProperties.begin(), LoopProperties.end());
113 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.unroll.count"),
114 ConstantAsMetadata::get(ConstantInt::get(
116 Args.push_back(MDNode::get(Ctx, Vals));
121 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.unroll.enable")};
122 Args.push_back(MDNode::get(Ctx, Vals));
125 if (FollowupHasTransforms)
127 createFollowupMetadata(
"llvm.loop.unroll.followup_all", Followup));
129 HasUserTransforms =
true;
136 bool &HasUserTransforms) {
137 LLVMContext &Ctx = Header->getContext();
139 std::optional<bool> Enabled;
146 if (Enabled !=
true) {
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;
154 return createPartialUnrollMetadata(Attrs, LoopProperties,
159 FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
160 FollowupLoopProperties.push_back(
161 MDNode::get(Ctx, MDString::get(Ctx,
"llvm.loop.unroll_and_jam.disable")));
163 bool FollowupHasTransforms =
false;
165 Attrs, FollowupLoopProperties, FollowupHasTransforms);
168 Args.append(LoopProperties.begin(), LoopProperties.end());
173 MDString::get(Ctx,
"llvm.loop.unroll_and_jam.count"),
174 ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
176 Args.push_back(MDNode::get(Ctx, Vals));
180 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.unroll_and_jam.enable")};
181 Args.push_back(MDNode::get(Ctx, Vals));
184 if (FollowupHasTransforms)
185 Args.push_back(createFollowupMetadata(
186 "llvm.loop.unroll_and_jam.followup_outer", Followup));
188 if (UnrollAndJamInnerFollowup.has_value())
189 Args.push_back(createFollowupMetadata(
190 "llvm.loop.unroll_and_jam.followup_inner", *UnrollAndJamInnerFollowup));
192 HasUserTransforms =
true;
199 bool &HasUserTransforms) {
200 LLVMContext &Ctx = Header->getContext();
202 std::optional<bool> Enabled;
211 if (Enabled !=
true) {
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;
221 return createUnrollAndJamMetadata(Attrs, LoopProperties, HasUserTransforms);
225 Args.append(LoopProperties.begin(), LoopProperties.end());
229 bool IsVectorPredicateEnabled =
false;
231 IsVectorPredicateEnabled =
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));
244 MDString::get(Ctx,
"llvm.loop.vectorize.width"),
245 ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
248 Args.push_back(MDNode::get(Ctx, 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));
263 MDString::get(Ctx,
"llvm.loop.interleave.count"),
264 ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
266 Args.push_back(MDNode::get(Ctx, Vals));
277 bool VectorizeEnabled =
false;
286 MDNode::get(Ctx, {MDString::get(Ctx,
"llvm.loop.vectorize.enable"),
287 ConstantAsMetadata::get(ConstantInt::get(
288 llvm::Type::getInt1Ty(Ctx), VectorizeEnabled))}));
297 if (VectorizeEnabled)
298 FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
301 FollowupLoopProperties.push_back(
302 MDNode::get(Ctx, MDString::get(Ctx,
"llvm.loop.isvectorized")));
304 bool FollowupHasTransforms =
false;
306 Attrs, FollowupLoopProperties, FollowupHasTransforms);
308 if (FollowupHasTransforms) {
311 if (VectorizeEnabled)
313 createFollowupMetadata(
"llvm.loop.vectorize.followup_all", Followup));
315 Args.append(Followup.begin(), Followup.end());
318 HasUserTransforms =
true;
323LoopInfo::createLoopDistributeMetadata(
const LoopAttributes &Attrs,
325 bool &HasUserTransforms) {
326 LLVMContext &Ctx = Header->getContext();
328 std::optional<bool> Enabled;
334 if (Enabled !=
true) {
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;
344 return createLoopVectorizeMetadata(Attrs, LoopProperties,
348 bool FollowupHasTransforms =
false;
350 createLoopVectorizeMetadata(Attrs, LoopProperties, FollowupHasTransforms);
353 Args.append(LoopProperties.begin(), LoopProperties.end());
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));
361 if (FollowupHasTransforms)
363 createFollowupMetadata(
"llvm.loop.distribute.followup_all", Followup));
365 HasUserTransforms =
true;
372 bool &HasUserTransforms) {
373 LLVMContext &Ctx = Header->getContext();
375 std::optional<bool> Enabled;
381 if (Enabled !=
true) {
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;
389 return createLoopDistributeMetadata(Attrs, LoopProperties,
394 Args.append(LoopProperties.begin(), LoopProperties.end());
395 Args.push_back(MDNode::get(Ctx, MDString::get(Ctx,
"llvm.loop.unroll.full")));
400 HasUserTransforms =
true;
407 bool &HasUserTransforms) {
412 LoopProperties.push_back(StartLoc.getAsMDNode());
416 LoopProperties.push_back(EndLoc.getAsMDNode());
419 LLVMContext &Ctx = Header->getContext();
421 LoopProperties.push_back(
422 MDNode::get(Ctx, MDString::get(Ctx,
"llvm.loop.mustprogress")));
425 "There must be an access group iff the loop is parallel");
427 LoopProperties.push_back(MDNode::get(
428 Ctx, {MDString::get(Ctx,
"llvm.loop.parallel_accesses"), AccGroup}));
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));
439 llvm::append_range(LoopProperties, AdditionalLoopProperties);
440 return createFullUnrollMetadata(Attrs, LoopProperties, HasUserTransforms);
449 UnrollCount(0), UnrollAndJamCount(0),
451 PipelineInitiationInterval(0), CodeAlign(0), MustProgress(
false) {}
472 const llvm::DebugLoc &StartLoc,
const llvm::DebugLoc &EndLoc,
474 : Header(Header), Attrs(Attrs), StartLoc(StartLoc), EndLoc(EndLoc),
479 LLVMContext &Ctx = Header->getContext();
480 AccGroup = MDNode::getDistinct(Ctx, {});
496 TempLoopID = MDNode::getTemporary(Header->getContext(), {});
507 LLVMContext &Ctx = Header->getContext();
555 if (!Parent->UnrollAndJamInnerFollowup) {
565 BeforeLoopProperties.push_back(
566 MDNode::get(Ctx, MDString::get(Ctx,
"llvm.loop.isvectorized")));
568 bool InnerFollowupHasTransform =
false;
570 AfterJam, BeforeLoopProperties, InnerFollowupHasTransform);
571 if (InnerFollowupHasTransform)
572 Parent->UnrollAndJamInnerFollowup = InnerFollowup;
575 CurLoopAttr = BeforeJam;
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);
587 TempLoopID->replaceAllUsesWith(LoopID);
591 const llvm::DebugLoc &EndLoc) {
593 new LoopInfo(Header, StagedAttrs, StartLoc, EndLoc,
594 Active.empty() ?
nullptr : Active.back().get()));
602 const llvm::DebugLoc &StartLoc,
603 const llvm::DebugLoc &EndLoc,
bool MustProgress) {
605 for (
const auto *
Attr : Attrs) {
606 const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(
Attr);
607 const OpenCLUnrollHintAttr *OpenCLHint =
608 dyn_cast<OpenCLUnrollHintAttr>(
Attr);
609 const HLSLLoopHintAttr *HLSLLoopHint = dyn_cast<HLSLLoopHintAttr>(
Attr);
611 if (!LH && !OpenCLHint && !HLSLLoopHint) {
615 LoopHintAttr::OptionType Option = LoopHintAttr::Unroll;
616 LoopHintAttr::LoopHintState State = LoopHintAttr::Disable;
617 unsigned ValueInt = 1;
625 ValueInt = OpenCLHint->getUnrollHint();
627 State = LoopHintAttr::Enable;
628 }
else if (ValueInt != 1) {
629 Option = LoopHintAttr::UnrollCount;
630 State = LoopHintAttr::Numeric;
632 }
else if (HLSLLoopHint) {
633 ValueInt = HLSLLoopHint->getDirective();
634 if (HLSLLoopHint->getSemanticSpelling() ==
635 HLSLLoopHintAttr::Spelling::Microsoft_unroll) {
637 State = LoopHintAttr::Enable;
639 Option = LoopHintAttr::UnrollCount;
640 State = LoopHintAttr::Numeric;
644 auto *ValueExpr = LH->getValue();
646 llvm::APSInt ValueAPS = ValueExpr->EvaluateKnownConstInt(Ctx);
647 ValueInt = ValueAPS.getSExtValue();
650 Option = LH->getOption();
651 State = LH->getState();
654 case LoopHintAttr::Disable:
656 case LoopHintAttr::Vectorize:
661 case LoopHintAttr::Interleave:
665 case LoopHintAttr::Unroll:
668 case LoopHintAttr::UnrollAndJam:
671 case LoopHintAttr::VectorizePredicate:
674 case LoopHintAttr::Distribute:
677 case LoopHintAttr::PipelineDisabled:
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 llvm_unreachable(
"Options cannot enabled.");
717 case LoopHintAttr::AssumeSafety:
719 case LoopHintAttr::Vectorize:
720 case LoopHintAttr::Interleave:
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.");
739 case LoopHintAttr::Full:
741 case LoopHintAttr::Unroll:
744 case LoopHintAttr::UnrollAndJam:
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.");
761 case LoopHintAttr::FixedWidth:
762 case LoopHintAttr::ScalableWidth:
764 case LoopHintAttr::VectorizeWidth:
772 llvm_unreachable(
"Options cannot be used with 'scalable' hint.");
776 case LoopHintAttr::Numeric:
778 case LoopHintAttr::InterleaveCount:
781 case LoopHintAttr::UnrollCount:
784 case LoopHintAttr::UnrollAndJamCount:
787 case LoopHintAttr::PipelineInitiationInterval:
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.");
808 if (
const auto *CodeAlign = getSpecificAttr<CodeAlignAttr>(Attrs)) {
809 const auto *CE = cast<ConstantExpr>(CodeAlign->getAlignment());
810 llvm::APSInt ArgVal = CE->getResultAsAPSInt();
816 if (CGOpts.OptimizationLevel > 0)
819 if (!CGOpts.UnrollLoops &&
825 push(Header, StartLoc, EndLoc);
829 assert(!Active.empty() &&
"No active loops to pop");
830 Active.back()->finish();
835 if (I->mayReadOrWriteMemory()) {
837 for (
const auto &AL : Active) {
839 if (MDNode *Group = AL->getAccessGroup())
840 AccessGroups.push_back(Group);
842 MDNode *UnionMD =
nullptr;
843 if (AccessGroups.size() == 1)
844 UnionMD = cast<MDNode>(AccessGroups[0]);
845 else if (AccessGroups.size() >= 2)
846 UnionMD = MDNode::get(I->getContext(), AccessGroups);
847 I->setMetadata(
"llvm.access.group", UnionMD);
857 if (I->isTerminator()) {
858 for (BasicBlock *Succ : successors(I))
860 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 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.
llvm::MDNode * getLoopID() const
Get the loop id metadata for this loop.
void finish()
Create the loop's metadata.
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.
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.