10#include "llvm/IR/DebugInfoMetadata.h"
18struct LoopAnnotationConversion {
19 LoopAnnotationConversion(LoopAnnotationAttr attr, Operation *op,
20 LoopAnnotationTranslation &loopAnnotationTranslation,
21 llvm::LLVMContext &ctx)
23 loopAnnotationTranslation(loopAnnotationTranslation), ctx(ctx) {}
27 llvm::MDNode *convert();
30 void addUnitNode(StringRef name);
31 void addUnitNode(StringRef name, BoolAttr attr);
32 void addI32NodeWithVal(StringRef name, uint32_t val);
33 void convertBoolNode(StringRef name, BoolAttr attr,
bool negated =
false);
34 void convertBooleanUnitNode(StringRef enableName, StringRef disableName,
35 BoolAttr attr,
bool negated =
false);
36 void convertI32Node(StringRef name, IntegerAttr attr);
37 void convertFollowupNode(StringRef name, LoopAnnotationAttr attr);
38 void convertLocation(FusedLoc attr);
41 void convertLoopOptions(LoopVectorizeAttr
options);
42 void convertLoopOptions(LoopInterleaveAttr
options);
43 void convertLoopOptions(LoopUnrollAttr
options);
44 void convertLoopOptions(LoopUnrollAndJamAttr
options);
45 void convertLoopOptions(LoopLICMAttr
options);
46 void convertLoopOptions(LoopDistributeAttr
options);
47 void convertLoopOptions(LoopPipelineAttr
options);
48 void convertLoopOptions(LoopPeeledAttr
options);
49 void convertLoopOptions(LoopUnswitchAttr
options);
51 LoopAnnotationAttr attr;
53 LoopAnnotationTranslation &loopAnnotationTranslation;
54 llvm::LLVMContext &ctx;
55 llvm::SmallVector<llvm::Metadata *> metadataNodes;
59void LoopAnnotationConversion::addUnitNode(StringRef name) {
60 metadataNodes.push_back(
61 llvm::MDNode::get(ctx, {llvm::MDString::get(ctx, name)}));
64void LoopAnnotationConversion::addUnitNode(StringRef name, BoolAttr attr) {
69void LoopAnnotationConversion::addI32NodeWithVal(StringRef name, uint32_t val) {
70 llvm::Constant *cstValue = llvm::ConstantInt::get(
71 llvm::IntegerType::get(ctx, 32), val,
false);
72 metadataNodes.push_back(
73 llvm::MDNode::get(ctx, {llvm::MDString::get(ctx, name),
74 llvm::ConstantAsMetadata::get(cstValue)}));
77void LoopAnnotationConversion::convertBoolNode(StringRef name, BoolAttr attr,
81 bool val = negated ^ attr.
getValue();
82 llvm::Constant *cstValue = llvm::ConstantInt::getBool(ctx, val);
83 metadataNodes.push_back(
84 llvm::MDNode::get(ctx, {llvm::MDString::get(ctx, name),
85 llvm::ConstantAsMetadata::get(cstValue)}));
92void LoopAnnotationConversion::convertBooleanUnitNode(StringRef enableName,
93 StringRef disableName,
98 addUnitNode((negated ^ attr.
getValue()) ? enableName : disableName);
101void LoopAnnotationConversion::convertI32Node(StringRef name,
105 addI32NodeWithVal(name, attr.getInt());
108void LoopAnnotationConversion::convertFollowupNode(StringRef name,
109 LoopAnnotationAttr attr) {
113 llvm::MDNode *loopID =
117 SmallVector<llvm::Metadata *> operands;
118 operands.push_back(llvm::MDString::get(ctx, name));
119 for (
const llvm::MDOperand &operand : llvm::drop_begin(loopID->operands()))
120 operands.push_back(operand.get());
121 metadataNodes.push_back(llvm::MDNode::get(ctx, operands));
124void LoopAnnotationConversion::convertLoopOptions(LoopVectorizeAttr
options) {
125 convertBooleanUnitNode(
"llvm.loop.vectorize.enable",
126 "llvm.loop.vectorize.disable",
options.getDisable(),
128 convertBooleanUnitNode(
"llvm.loop.vectorize.predicate.enable",
129 "llvm.loop.vectorize.predicate.disable",
131 convertBooleanUnitNode(
"llvm.loop.vectorize.scalable.enable",
132 "llvm.loop.vectorize.scalable.disable",
134 convertI32Node(
"llvm.loop.vectorize.width",
options.getWidth());
135 convertFollowupNode(
"llvm.loop.vectorize.followup_vectorized",
136 options.getFollowupVectorized());
137 convertFollowupNode(
"llvm.loop.vectorize.followup_epilogue",
138 options.getFollowupEpilogue());
139 convertFollowupNode(
"llvm.loop.vectorize.followup_all",
143void LoopAnnotationConversion::convertLoopOptions(LoopInterleaveAttr
options) {
144 convertI32Node(
"llvm.loop.interleave.count",
options.getCount());
147void LoopAnnotationConversion::convertLoopOptions(LoopUnrollAttr
options) {
148 if (
auto disable =
options.getDisable())
149 addUnitNode(disable.getValue() ?
"llvm.loop.unroll.disable"
150 :
"llvm.loop.unroll.enable");
151 convertI32Node(
"llvm.loop.unroll.count",
options.getCount());
152 convertBoolNode(
"llvm.loop.unroll.runtime.disable",
154 addUnitNode(
"llvm.loop.unroll.full",
options.getFull());
155 convertFollowupNode(
"llvm.loop.unroll.followup_unrolled",
156 options.getFollowupUnrolled());
157 convertFollowupNode(
"llvm.loop.unroll.followup_remainder",
158 options.getFollowupRemainder());
159 convertFollowupNode(
"llvm.loop.unroll.followup_all",
163void LoopAnnotationConversion::convertLoopOptions(
164 LoopUnrollAndJamAttr
options) {
165 if (
auto disable =
options.getDisable())
166 addUnitNode(disable.getValue() ?
"llvm.loop.unroll_and_jam.disable"
167 :
"llvm.loop.unroll_and_jam.enable");
168 convertI32Node(
"llvm.loop.unroll_and_jam.count",
options.getCount());
169 convertFollowupNode(
"llvm.loop.unroll_and_jam.followup_outer",
171 convertFollowupNode(
"llvm.loop.unroll_and_jam.followup_inner",
173 convertFollowupNode(
"llvm.loop.unroll_and_jam.followup_remainder_outer",
174 options.getFollowupRemainderOuter());
175 convertFollowupNode(
"llvm.loop.unroll_and_jam.followup_remainder_inner",
176 options.getFollowupRemainderInner());
177 convertFollowupNode(
"llvm.loop.unroll_and_jam.followup_all",
181void LoopAnnotationConversion::convertLoopOptions(LoopLICMAttr
options) {
182 addUnitNode(
"llvm.licm.disable",
options.getDisable());
183 addUnitNode(
"llvm.loop.licm_versioning.disable",
184 options.getVersioningDisable());
187void LoopAnnotationConversion::convertLoopOptions(LoopDistributeAttr
options) {
188 convertBooleanUnitNode(
"llvm.loop.distribute.enable",
189 "llvm.loop.distribute.disable",
options.getDisable(),
191 convertFollowupNode(
"llvm.loop.distribute.followup_coincident",
192 options.getFollowupCoincident());
193 convertFollowupNode(
"llvm.loop.distribute.followup_sequential",
194 options.getFollowupSequential());
195 convertFollowupNode(
"llvm.loop.distribute.followup_fallback",
196 options.getFollowupFallback());
197 convertFollowupNode(
"llvm.loop.distribute.followup_all",
201void LoopAnnotationConversion::convertLoopOptions(LoopPipelineAttr
options) {
202 convertBoolNode(
"llvm.loop.pipeline.disable",
options.getDisable());
203 convertI32Node(
"llvm.loop.pipeline.initiationinterval",
204 options.getInitiationinterval());
207void LoopAnnotationConversion::convertLoopOptions(LoopPeeledAttr
options) {
208 convertI32Node(
"llvm.loop.peeled.count",
options.getCount());
211void LoopAnnotationConversion::convertLoopOptions(LoopUnswitchAttr
options) {
212 addUnitNode(
"llvm.loop.unswitch.partial.disable",
216void LoopAnnotationConversion::convertLocation(FusedLoc location) {
217 auto localScopeAttr =
218 dyn_cast_or_null<DILocalScopeAttr>(location.getMetadata());
221 auto *localScope = dyn_cast<llvm::DILocalScope>(
226 llvm::Metadata *loc =
229 metadataNodes.push_back(loc);
232llvm::MDNode *LoopAnnotationConversion::convert() {
234 auto dummy = llvm::MDNode::getTemporary(ctx, {});
235 metadataNodes.push_back(dummy.get());
237 if (FusedLoc startLoc = attr.getStartLoc())
238 convertLocation(startLoc);
240 if (FusedLoc endLoc = attr.getEndLoc())
241 convertLocation(endLoc);
243 addUnitNode(
"llvm.loop.disable_nonforced", attr.getDisableNonforced());
244 addUnitNode(
"llvm.loop.mustprogress", attr.getMustProgress());
246 if (BoolAttr isVectorized = attr.getIsVectorized())
247 addI32NodeWithVal(
"llvm.loop.isvectorized", isVectorized.getValue());
249 if (
auto options = attr.getVectorize())
251 if (
auto options = attr.getInterleave())
253 if (
auto options = attr.getUnroll())
255 if (
auto options = attr.getUnrollAndJam())
257 if (
auto options = attr.getLicm())
259 if (
auto options = attr.getDistribute())
261 if (
auto options = attr.getPipeline())
263 if (
auto options = attr.getPeeled())
265 if (
auto options = attr.getUnswitch())
268 ArrayRef<AccessGroupAttr> parallelAccessGroups = attr.getParallelAccesses();
269 if (!parallelAccessGroups.empty()) {
270 SmallVector<llvm::Metadata *> parallelAccess;
271 parallelAccess.push_back(
272 llvm::MDString::get(ctx,
"llvm.loop.parallel_accesses"));
273 for (AccessGroupAttr accessGroupAttr : parallelAccessGroups)
274 parallelAccess.push_back(
276 metadataNodes.push_back(llvm::MDNode::get(ctx, parallelAccess));
280 llvm::MDNode *loopMD = llvm::MDNode::get(ctx, metadataNodes);
281 loopMD->replaceOperandWith(0, loopMD);
292 llvm::MDNode *loopMD = lookupLoopMetadata(attr);
297 LoopAnnotationConversion(attr, op, *
this, this->llvmModule.
getContext())
301 mapLoopMetadata(attr, loopMD);
308 accessGroupMetadataMapping.try_emplace(accessGroupAttr);
310 result->second = llvm::MDNode::getDistinct(llvmModule.getContext(), {});
316 ArrayAttr accessGroups = op.getAccessGroupsOrNull();
317 if (!accessGroups || accessGroups.empty())
321 for (AccessGroupAttr group : accessGroups.getAsRange<AccessGroupAttr>())
323 if (groupMDs.size() == 1)
324 return llvm::cast<llvm::MDNode>(groupMDs.front());
325 return llvm::MDNode::get(llvmModule.getContext(), groupMDs);
*if copies could not be generated due to yet unimplemented cases *copyInPlacementStart and copyOutPlacementStart in copyPlacementBlock *specify the insertion points where the incoming copies and outgoing should be inserted(the insertion happens right before the *insertion point). Since `begin` can itself be invalidated due to the memref *rewriting done from this method
static llvm::ManagedStatic< PassManagerOptions > options
bool getValue() const
Return the boolean value of this attribute.
llvm::DILocation * translateLoc(Location loc, llvm::DILocalScope *scope)
Translates the given location.
llvm::Metadata * translateDebugInfo(LLVM::DINodeAttr attr)
Translates the given LLVM debug info metadata.
llvm::MDNode * translateLoopAnnotation(LoopAnnotationAttr attr, Operation *op)
llvm::MDNode * getAccessGroups(AccessGroupOpInterface op)
Returns the LLVM metadata corresponding to the access group attribute referenced by the AccessGroupOp...
ModuleTranslation & moduleTranslation
The ModuleTranslation owning this instance.
llvm::MDNode * getAccessGroup(AccessGroupAttr accessGroupAttr)
Returns the LLVM metadata corresponding to an mlir LLVM dialect access group attribute.
Operation is the basic unit of execution within MLIR.
MLIRContext * getContext()
Return the context this operation is associated with.
Include the generated interface declarations.