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);
437 const llvm::DebugLoc &StartLoc,
438 const llvm::DebugLoc &EndLoc,
440 : Header(Header), Attrs(Attrs), StartLoc(StartLoc), EndLoc(EndLoc),
443 if (Attrs.IsParallel) {
445 LLVMContext &Ctx = Header->getContext();
446 AccGroup = MDNode::getDistinct(Ctx, {});
462 TempLoopID = MDNode::getTemporary(Header->getContext(), {});
473 LLVMContext &Ctx = Header->getContext();
475 if (Parent && (Parent->Attrs.UnrollAndJamEnable ||
476 Parent->Attrs.UnrollAndJamCount != 0)) {
493 switch (Attrs.UnrollEnable) {
522 if (!Parent->UnrollAndJamInnerFollowup) {
532 BeforeLoopProperties.push_back(
533 MDNode::get(Ctx, MDString::get(Ctx,
"llvm.loop.isvectorized")));
535 bool InnerFollowupHasTransform =
false;
537 AfterJam, BeforeLoopProperties, InnerFollowupHasTransform);
538 if (InnerFollowupHasTransform)
539 Parent->UnrollAndJamInnerFollowup = InnerFollowup;
542 CurLoopAttr = BeforeJam;
545 bool HasUserTransforms =
false;
547 createMetadata(CurLoopAttr, {}, HasUserTransforms);
549 Args.push_back(
nullptr);
550 Args.append(Properties.begin(), Properties.end());
551 LoopID = MDNode::getDistinct(Ctx, Args);
552 LoopID->replaceOperandWith(0, LoopID);
554 TempLoopID->replaceAllUsesWith(LoopID);
558 const llvm::DebugLoc &EndLoc) {
560 new LoopInfo(Header, StagedAttrs, StartLoc, EndLoc,
561 Active.empty() ?
nullptr : Active.back().get()));
569 const llvm::DebugLoc &StartLoc,
570 const llvm::DebugLoc &EndLoc,
bool MustProgress) {
574 push(Header, StartLoc, EndLoc);
578 assert(!Active.empty() &&
"No active loops to pop");
579 Active.back()->finish();
584 if (I->mayReadOrWriteMemory()) {
586 for (
const auto &AL : Active) {
588 if (MDNode *Group = AL->getAccessGroup())
589 AccessGroups.push_back(Group);
591 MDNode *UnionMD =
nullptr;
592 if (AccessGroups.size() == 1)
594 else if (AccessGroups.size() >= 2)
595 UnionMD = MDNode::get(I->getContext(), AccessGroups);
596 I->setMetadata(
"llvm.access.group", UnionMD);
606 if (I->isTerminator()) {
607 for (BasicBlock *Succ : successors(I))
609 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 ...
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
bool hasInfo() const
Returns true if there is LoopInfo on the stack.
void InsertHelper(llvm::Instruction *I) const
Function called by the CodeGenFunction when an instruction is created.
void pop()
End the current loop.
void push(llvm::BasicBlock *Header, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
Begin a new structured loop.
const LoopInfo & getInfo() const
Return the LoopInfo for the current loop.
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.
void updateLoopAttributes(LoopAttributes &Attrs, ASTContext &Ctx, const CodeGenOptions &CGOpts, llvm::ArrayRef< const Attr * > StmtAttrs, bool MustProgress)
Update Attrs with the loop hints in StmtAttrs (#pragma clang loop, #pragma unroll,...
clang::CodeGenUtils::LoopAttributes LoopAttributes
Attributes that may be specified on loops.
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
bool LICMDisabled
Value for llvm.licm.disable metadata.
LVEnableState VectorizeEnable
Value for llvm.loop.vectorize.enable metadata.
LVEnableState VectorizeScalable
unsigned UnrollCount
llvm.unroll.
LVEnableState UnrollEnable
Value for llvm.loop.unroll.* metadata (enable, disable, or full).
unsigned PipelineInitiationInterval
Value for llvm.loop.pipeline.iicount metadata.
unsigned UnrollAndJamCount
llvm.unroll.
unsigned CodeAlign
Value for 'llvm.loop.align' metadata.
unsigned VectorizeWidth
Value for llvm.loop.vectorize.width metadata.
LVEnableState UnrollAndJamEnable
Value for llvm.loop.unroll_and_jam.* metadata (enable, disable, or full).
LVEnableState VectorizePredicateEnable
Value for llvm.loop.vectorize.predicate metadata.
bool PipelineDisabled
Value for llvm.loop.pipeline.disable metadata.
bool IsParallel
Generate llvm.loop.parallel metadata for loads and stores.
bool MustProgress
Value for whether the loop is required to make progress.
LVEnableState DistributeEnable
Value for llvm.loop.distribute.enable metadata.
unsigned InterleaveCount
Value for llvm.loop.interleave.count metadata.