MLIR 24.0.0git
LLVMIRToLLVMTranslation.cpp
Go to the documentation of this file.
1//===- LLVMIRToLLVMTranslation.cpp - Translate LLVM IR to LLVM dialect ----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements a translation between LLVM IR and the MLIR LLVM dialect.
10//
11//===----------------------------------------------------------------------===//
12
17#include "mlir/Support/LLVM.h"
19
20#include "llvm/ADT/TypeSwitch.h"
21#include "llvm/IR/ConstantRange.h"
22#include "llvm/IR/Constants.h"
23#include "llvm/IR/InlineAsm.h"
24#include "llvm/IR/Instructions.h"
25#include "llvm/IR/IntrinsicInst.h"
26#include "llvm/IR/MemoryModelRelaxationAnnotations.h"
27#include <optional>
28
29using namespace mlir;
30using namespace mlir::LLVM;
31using namespace mlir::LLVM::detail;
32
33#include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
34
35static constexpr StringLiteral vecTypeHintMDName = "vec_type_hint";
36static constexpr StringLiteral workGroupSizeHintMDName = "work_group_size_hint";
37static constexpr StringLiteral reqdWorkGroupSizeMDName = "reqd_work_group_size";
38static constexpr StringLiteral intelReqdSubGroupSizeMDName =
39 "intel_reqd_sub_group_size";
40
41/// Returns true if the LLVM IR intrinsic is convertible to an MLIR LLVM dialect
42/// intrinsic. Returns false otherwise.
43static bool isConvertibleIntrinsic(llvm::Intrinsic::ID id) {
44 static const DenseSet<unsigned> convertibleIntrinsics = {
45#include "mlir/Dialect/LLVMIR/LLVMConvertibleLLVMIRIntrinsics.inc"
46 };
47 return convertibleIntrinsics.contains(id);
48}
49
50/// Returns the list of LLVM IR intrinsic identifiers that are convertible to
51/// MLIR LLVM dialect intrinsics.
53 static const SmallVector<unsigned> convertibleIntrinsics = {
54#include "mlir/Dialect/LLVMIR/LLVMConvertibleLLVMIRIntrinsics.inc"
55 };
56 return convertibleIntrinsics;
57}
58
59/// Converts the LLVM intrinsic to an MLIR LLVM dialect operation if a
60/// conversion exits. Returns failure otherwise.
61static LogicalResult convertIntrinsicImpl(OpBuilder &odsBuilder,
62 llvm::CallInst *inst,
63 LLVM::ModuleImport &moduleImport) {
64 llvm::Intrinsic::ID intrinsicID = inst->getIntrinsicID();
65
66 // Check if the intrinsic is convertible to an MLIR dialect counterpart and
67 // copy the arguments to an an LLVM operands array reference for conversion.
68 if (isConvertibleIntrinsic(intrinsicID)) {
69 SmallVector<llvm::Value *> args(inst->args());
70 ArrayRef<llvm::Value *> llvmOperands(args);
71
73 llvmOpBundles.reserve(inst->getNumOperandBundles());
74 for (unsigned i = 0; i < inst->getNumOperandBundles(); ++i)
75 llvmOpBundles.push_back(inst->getOperandBundleAt(i));
76
77#include "mlir/Dialect/LLVMIR/LLVMIntrinsicFromLLVMIRConversions.inc"
78 }
79
80 return failure();
81}
82
83/// Returns the list of LLVM IR metadata kinds that are convertible to MLIR LLVM
84/// dialect attributes.
86getSupportedMetadataImpl(llvm::LLVMContext &llvmContext) {
87 SmallVector<unsigned> convertibleMetadata = {
88 llvm::LLVMContext::MD_prof,
89 llvm::LLVMContext::MD_tbaa,
90 llvm::LLVMContext::MD_access_group,
91 llvm::LLVMContext::MD_loop,
92 llvm::LLVMContext::MD_noalias,
93 llvm::LLVMContext::MD_alias_scope,
94 llvm::LLVMContext::MD_dereferenceable,
95 llvm::LLVMContext::MD_dereferenceable_or_null,
96 llvm::LLVMContext::MD_range,
97 llvm::LLVMContext::MD_mmra,
98 llvm::LLVMContext::MD_memprof,
99 llvm::LLVMContext::MD_callsite,
100 llvm::LLVMContext::MD_tbaa_struct,
101 llvmContext.getMDKindID(vecTypeHintMDName),
102 llvmContext.getMDKindID(workGroupSizeHintMDName),
103 llvmContext.getMDKindID(reqdWorkGroupSizeMDName),
104 llvmContext.getMDKindID(intelReqdSubGroupSizeMDName)};
105 return convertibleMetadata;
106}
107
108/// Extracts an LLVM metadata constant as an unsigned 64-bit integer.
109static std::optional<uint64_t> getUInt64Metadata(llvm::Metadata *metadata) {
110 auto *constant = llvm::mdconst::dyn_extract<llvm::ConstantInt>(metadata);
111 if (!constant)
112 return std::nullopt;
113 return constant->getValue().tryZExtValue();
114}
115
116/// Converts the given profiling metadata `node` to an MLIR profiling attribute
117/// and attaches it to the imported operation if the translation succeeds.
118/// Returns failure otherwise.
119static LogicalResult setProfilingAttr(OpBuilder &builder, llvm::MDNode *node,
120 Operation *op,
121 LLVM::ModuleImport &moduleImport) {
122 // Return failure for empty metadata nodes since there is nothing to import.
123 if (!node->getNumOperands())
124 return failure();
125
126 auto *name = dyn_cast<llvm::MDString>(node->getOperand(0));
127 if (!name)
128 return failure();
129 StringRef profName = name->getString();
130
131 // Handle function entry count metadata.
132 if (profName == llvm::MDProfLabels::FunctionEntryCount) {
133 if (node->getNumOperands() < 2)
134 return failure();
135
136 std::optional<uint64_t> entryCountValue =
137 getUInt64Metadata(node->getOperand(1));
138 if (!entryCountValue)
139 return failure();
140
141 SmallVector<uint64_t> importGUIDValues;
142 importGUIDValues.reserve(node->getNumOperands() - 2);
143 for (unsigned idx = 2, e = node->getNumOperands(); idx < e; ++idx) {
144 std::optional<uint64_t> guidValue =
145 getUInt64Metadata(node->getOperand(idx));
146 if (!guidValue)
147 return failure();
148 importGUIDValues.push_back(*guidValue);
149 }
150
151 if (auto funcOp = dyn_cast<LLVMFuncOp>(op)) {
152 funcOp.setFunctionEntryCountAttr(FunctionEntryCountAttr::get(
153 builder.getContext(), *entryCountValue, importGUIDValues));
154 return success();
155 }
156 return op->emitWarning()
157 << "expected function_entry_count to be attached to a function";
158 }
159
160 if (profName != llvm::MDProfLabels::BranchWeights)
161 return failure();
162 // The branch_weights metadata must have at least 2 operands.
163 if (node->getNumOperands() < 2)
164 return failure();
165
166 ArrayRef<llvm::MDOperand> branchWeightOperands =
167 node->operands().drop_front();
168 if (auto *mdString = dyn_cast<llvm::MDString>(node->getOperand(1))) {
169 if (mdString->getString() != llvm::MDProfLabels::ExpectedBranchWeights)
170 return failure();
171 // The MLIR WeightedBranchOpInterface does not support the
172 // ExpectedBranchWeights field, so it is dropped.
173 branchWeightOperands = branchWeightOperands.drop_front();
174 }
175
176 // Handle branch weights metadata.
177 SmallVector<int32_t> branchWeights;
178 branchWeights.reserve(branchWeightOperands.size());
179 for (const llvm::MDOperand &operand : branchWeightOperands) {
180 llvm::ConstantInt *branchWeight =
181 llvm::mdconst::dyn_extract<llvm::ConstantInt>(operand);
182 if (!branchWeight)
183 return failure();
184 branchWeights.push_back(branchWeight->getZExtValue());
185 }
186
187 if (auto iface = dyn_cast<WeightedBranchOpInterface>(op)) {
188 // LLVM allows attaching a single weight to call instructions.
189 // This is used for carrying the execution count information
190 // in PGO modes. MLIR WeightedBranchOpInterface does not allow this,
191 // so we drop the metadata in this case.
192 // LLVM should probably use the VP form of MD_prof metadata
193 // for such cases.
194 if (op->getNumSuccessors() != 0)
195 iface.setWeights(branchWeights);
196 return success();
197 }
198 return failure();
199}
200
201/// Searches for the attribute that maps to the given TBAA metadata `node` and
202/// attaches it to the imported operation if the lookup succeeds. Returns
203/// failure otherwise.
204static LogicalResult setTBAAAttr(const llvm::MDNode *node, Operation *op,
205 LLVM::ModuleImport &moduleImport) {
206 Attribute tbaaTagSym = moduleImport.lookupTBAAAttr(node);
207 if (!tbaaTagSym)
208 return failure();
209
210 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
211 if (!iface)
212 return failure();
213
214 iface.setTBAATags(ArrayAttr::get(iface.getContext(), tbaaTagSym));
215 return success();
216}
217
218/// Attaches the `tbaa_struct` attribute converted from `!tbaa.struct` by
219/// ModuleImport::convertTBAAStructMetadata to the imported aggregate copy,
220/// like setTBAAAttr does for access tags. Nodes that could not be modeled
221/// are unmapped and declined here.
222static LogicalResult setTBAAStructAttr(const llvm::MDNode *node, Operation *op,
223 LLVM::ModuleImport &moduleImport) {
224 auto fields =
225 dyn_cast_if_present<ArrayAttr>(moduleImport.lookupTBAAStructAttr(node));
226 if (!fields)
227 return failure();
228
229 auto iface = dyn_cast<TBAAStructOpInterface>(op);
230 if (!iface)
231 return failure();
232 iface.setTBAAStruct(fields);
233 return success();
234}
235
236/// Looks up all the access group attributes that map to the access group nodes
237/// starting from the access group metadata `node`, and attaches all of them to
238/// the imported operation if the lookups succeed. Returns failure otherwise.
239static LogicalResult setAccessGroupsAttr(const llvm::MDNode *node,
240 Operation *op,
241 LLVM::ModuleImport &moduleImport) {
242 FailureOr<SmallVector<AccessGroupAttr>> accessGroups =
243 moduleImport.lookupAccessGroupAttrs(node);
244 if (failed(accessGroups))
245 return failure();
246
247 auto iface = dyn_cast<AccessGroupOpInterface>(op);
248 if (!iface)
249 return failure();
250
251 iface.setAccessGroups(ArrayAttr::get(
252 iface.getContext(), llvm::to_vector_of<Attribute>(*accessGroups)));
253 return success();
254}
255
256/// Converts the given dereferenceable metadata node to a dereferenceable
257/// attribute, and attaches it to the imported operation if the translation
258/// succeeds. Returns failure if the LLVM IR metadata node is ill-formed.
259static LogicalResult setDereferenceableAttr(const llvm::MDNode *node,
260 unsigned kindID, Operation *op,
261 LLVM::ModuleImport &moduleImport) {
262 auto dereferenceable =
263 moduleImport.translateDereferenceableAttr(node, kindID);
264 if (failed(dereferenceable))
265 return failure();
266
267 auto iface = dyn_cast<DereferenceableOpInterface>(op);
268 if (!iface)
269 return failure();
270
271 iface.setDereferenceable(*dereferenceable);
272 return success();
273}
274
275/// Multi-range metadata is imported as the union of its ranges.
276static LogicalResult setRangeAttr(const llvm::MDNode *node, Operation *op) {
277 auto iface = dyn_cast<RangeOpInterface>(op);
278 if (!iface)
279 return failure();
280
281 llvm::ConstantRange range = llvm::getConstantRangeFromMetadata(*node);
282 iface.setRange(ConstantRangeAttr::get(op->getContext(), range.getLower(),
283 range.getUpper()));
284 return success();
285}
286
287/// Convert the given MMRA metadata (either an MMRA tag or an array of them)
288/// into corresponding MLIR attributes and set them on the given operation as a
289/// discardable `llvm.mmra` attribute.
290static LogicalResult setMmraAttr(llvm::MDNode *node, Operation *op,
291 LLVM::ModuleImport &moduleImport) {
292 if (!node)
293 return success();
294
295 // We don't use the LLVM wrappers here becasue we care about the order
296 // of the metadata for deterministic roundtripping.
297 MLIRContext *ctx = op->getContext();
298 auto toAttribute = [&](llvm::MDNode *tag) -> Attribute {
299 return LLVM::MMRATagAttr::get(
300 ctx, cast<llvm::MDString>(tag->getOperand(0))->getString(),
301 cast<llvm::MDString>(tag->getOperand(1))->getString());
302 };
303 Attribute mlirMmra;
304 if (llvm::MMRAMetadata::isTagMD(node)) {
305 mlirMmra = toAttribute(node);
306 } else {
308 for (const llvm::MDOperand &operand : node->operands()) {
309 auto *tagNode = dyn_cast<llvm::MDNode>(operand.get());
310 if (!tagNode || !llvm::MMRAMetadata::isTagMD(tagNode))
311 return failure();
312 tags.push_back(toAttribute(tagNode));
313 }
314 mlirMmra = ArrayAttr::get(ctx, tags);
315 }
316 op->setDiscardableAttr(LLVMDialect::getMmraAttrName(), mlirMmra);
317 return success();
318}
319
320/// Converts the given loop metadata node to an MLIR loop annotation attribute
321/// and attaches it to the imported operation if the translation succeeds.
322/// Returns failure otherwise.
323static LogicalResult setLoopAttr(const llvm::MDNode *node, Operation *op,
324 LLVM::ModuleImport &moduleImport) {
325 LoopAnnotationAttr attr =
326 moduleImport.translateLoopAnnotationAttr(node, op->getLoc());
327 if (!attr)
328 return failure();
329
331 .Case<LLVM::BrOp, LLVM::CondBrOp>([&](auto branchOp) {
332 branchOp.setLoopAnnotationAttr(attr);
333 return success();
334 })
335 .Default(failure());
336}
337
338/// Looks up all the alias scope attributes that map to the alias scope nodes
339/// starting from the alias scope metadata `node`, and attaches all of them to
340/// the imported operation if the lookups succeed. Returns failure otherwise.
341static LogicalResult setAliasScopesAttr(const llvm::MDNode *node, Operation *op,
342 LLVM::ModuleImport &moduleImport) {
343 FailureOr<SmallVector<AliasScopeAttr>> aliasScopes =
344 moduleImport.lookupAliasScopeAttrs(node);
345 if (failed(aliasScopes))
346 return failure();
347
348 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
349 if (!iface)
350 return failure();
351
352 iface.setAliasScopes(ArrayAttr::get(
353 iface.getContext(), llvm::to_vector_of<Attribute>(*aliasScopes)));
354 return success();
355}
356
357/// Looks up all the alias scope attributes that map to the alias scope nodes
358/// starting from the noalias metadata `node`, and attaches all of them to the
359/// imported operation if the lookups succeed. Returns failure otherwise.
360static LogicalResult setNoaliasScopesAttr(const llvm::MDNode *node,
361 Operation *op,
362 LLVM::ModuleImport &moduleImport) {
363 FailureOr<SmallVector<AliasScopeAttr>> noAliasScopes =
364 moduleImport.lookupAliasScopeAttrs(node);
365 if (failed(noAliasScopes))
366 return failure();
367
368 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
369 if (!iface)
370 return failure();
371
372 iface.setNoAliasScopes(ArrayAttr::get(
373 iface.getContext(), llvm::to_vector_of<Attribute>(*noAliasScopes)));
374 return success();
375}
376
377/// Extracts an integer from the provided metadata `md` if possible. Returns
378/// nullopt otherwise.
379static std::optional<int32_t> parseIntegerMD(llvm::Metadata *md) {
380 auto *constant = dyn_cast_if_present<llvm::ConstantAsMetadata>(md);
381 if (!constant)
382 return {};
383
384 auto *intConstant = dyn_cast<llvm::ConstantInt>(constant->getValue());
385 if (!intConstant)
386 return {};
387
388 return intConstant->getValue().getSExtValue();
389}
390
391/// Converts the provided metadata node `node` to an LLVM dialect
392/// VecTypeHintAttr if possible.
393static VecTypeHintAttr convertVecTypeHint(Builder builder, llvm::MDNode *node,
394 ModuleImport &moduleImport) {
395 if (!node || node->getNumOperands() != 2)
396 return {};
397
398 auto *hintMD = dyn_cast<llvm::ValueAsMetadata>(node->getOperand(0).get());
399 if (!hintMD)
400 return {};
401 TypeAttr hint = TypeAttr::get(moduleImport.convertType(hintMD->getType()));
402
403 std::optional<int32_t> optIsSigned =
404 parseIntegerMD(node->getOperand(1).get());
405 if (!optIsSigned)
406 return {};
407 bool isSigned = *optIsSigned != 0;
408
409 return builder.getAttr<VecTypeHintAttr>(hint, isSigned);
410}
411
412/// Converts the provided metadata node `node` to an MLIR DenseI32ArrayAttr if
413/// possible.
415 llvm::MDNode *node) {
416 if (!node)
417 return {};
419 for (const llvm::MDOperand &op : node->operands()) {
420 std::optional<int32_t> mdValue = parseIntegerMD(op.get());
421 if (!mdValue)
422 return {};
423 vals.push_back(*mdValue);
424 }
425 return builder.getDenseI32ArrayAttr(vals);
426}
427
428/// Convert an `MDNode` to an MLIR `IntegerAttr` if possible.
429static IntegerAttr convertIntegerMD(Builder builder, llvm::MDNode *node) {
430 if (!node || node->getNumOperands() != 1)
431 return {};
432 std::optional<int32_t> val = parseIntegerMD(node->getOperand(0));
433 if (!val)
434 return {};
435 return builder.getI32IntegerAttr(*val);
436}
437
438static LogicalResult setVecTypeHintAttr(Builder &builder, llvm::MDNode *node,
439 Operation *op,
440 LLVM::ModuleImport &moduleImport) {
441 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
442 if (!funcOp)
443 return failure();
444
445 VecTypeHintAttr attr = convertVecTypeHint(builder, node, moduleImport);
446 if (!attr)
447 return failure();
448
449 funcOp.setVecTypeHintAttr(attr);
450 return success();
451}
452
453static LogicalResult
454setWorkGroupSizeHintAttr(Builder &builder, llvm::MDNode *node, Operation *op) {
455 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
456 if (!funcOp)
457 return failure();
458
459 DenseI32ArrayAttr attr = convertDenseI32Array(builder, node);
460 if (!attr)
461 return failure();
462
463 funcOp.setWorkGroupSizeHintAttr(attr);
464 return success();
465}
466
467static LogicalResult
468setReqdWorkGroupSizeAttr(Builder &builder, llvm::MDNode *node, Operation *op) {
469 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
470 if (!funcOp)
471 return failure();
472
473 DenseI32ArrayAttr attr = convertDenseI32Array(builder, node);
474 if (!attr)
475 return failure();
476
477 funcOp.setReqdWorkGroupSizeAttr(attr);
478 return success();
479}
480
481/// Converts the given intel required subgroup size metadata node to an MLIR
482/// attribute and attaches it to the imported operation if the translation
483/// succeeds. Returns failure otherwise.
484static LogicalResult setIntelReqdSubGroupSizeAttr(Builder &builder,
485 llvm::MDNode *node,
486 Operation *op) {
487 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
488 if (!funcOp)
489 return failure();
490
491 IntegerAttr attr = convertIntegerMD(builder, node);
492 if (!attr)
493 return failure();
494
495 funcOp.setIntelReqdSubGroupSizeAttr(attr);
496 return success();
497}
498
499/// Builds the call-stack hash list of a MemProf `callsite` node, one int64
500/// per operand. Returns an empty attribute for an empty or malformed node.
502 const llvm::MDNode *node) {
503 if (node->getNumOperands() == 0)
504 return {};
506 ids.reserve(node->getNumOperands());
507 for (const llvm::MDOperand &operand : node->operands()) {
508 auto *id = llvm::mdconst::dyn_extract_or_null<llvm::ConstantInt>(operand);
509 // The ids are hashes, so the whole 64-bit pattern is meaningful and is
510 // kept as-is rather than being range-checked as a signed quantity.
511 if (!id || id->getBitWidth() > 64)
512 return {};
513 ids.push_back(static_cast<int64_t>(id->getZExtValue()));
514 }
515 return builder.getDenseI64ArrayAttr(ids);
516}
517
518/// Converts `!callsite` to the `llvm.callsite` attribute. The node is the
519/// partial allocation call stack this call sits on, which is what ties it to a
520/// `!memprof` record elsewhere in the profile.
521static LogicalResult setCallsiteAttr(OpBuilder &builder,
522 const llvm::MDNode *node, Operation *op) {
523 DenseI64ArrayAttr callStack = getCallStackAttr(builder, node);
524 if (!callStack)
525 return failure();
526 op->setDiscardableAttr(LLVMDialect::getCallsiteAttrName(), callStack);
527 return success();
528}
529
530/// Converts `!memprof` to the `llvm.memprof` attribute. The node is a list of
531/// MemInfoBlocks; each is an allocation call stack, the one allocation-type
532/// tag string, then optionally `(context id, total size)` pairs.
533static LogicalResult setMemProfAttr(OpBuilder &builder,
534 const llvm::MDNode *node, Operation *op) {
535 if (node->getNumOperands() == 0)
536 return failure();
538 mibs.reserve(node->getNumOperands());
539 for (const llvm::MDOperand &mibOperand : node->operands()) {
540 auto *mib = dyn_cast_if_present<llvm::MDNode>(mibOperand);
541 if (!mib || mib->getNumOperands() < 2)
542 return failure();
543 auto *stack = dyn_cast_if_present<llvm::MDNode>(mib->getOperand(0));
544 if (!stack)
545 return failure();
546 DenseI64ArrayAttr callStack = getCallStackAttr(builder, stack);
547 if (!callStack)
548 return failure();
549 auto *tag = dyn_cast_if_present<llvm::MDString>(mib->getOperand(1));
550 if (!tag)
551 return failure();
552
554 for (unsigned index = 2; index < mib->getNumOperands(); ++index) {
555 auto *pair = dyn_cast_if_present<llvm::MDNode>(mib->getOperand(index));
556 if (!pair || pair->getNumOperands() != 2)
557 return failure();
558 auto *id = llvm::mdconst::dyn_extract_or_null<llvm::ConstantInt>(
559 pair->getOperand(0));
560 auto *size = llvm::mdconst::dyn_extract_or_null<llvm::ConstantInt>(
561 pair->getOperand(1));
562 if (!id || !size || id->getBitWidth() > 64 || size->getBitWidth() > 64)
563 return failure();
564 contextSizes.push_back(MemProfContextSizeAttr::get(
565 op->getContext(), id->getZExtValue(), size->getZExtValue()));
566 }
567
568 mibs.push_back(MemProfMIBAttr::get(op->getContext(), callStack,
569 builder.getStringAttr(tag->getString()),
570 contextSizes));
571 }
572 op->setDiscardableAttr(LLVMDialect::getMemProfAttrName(),
573 builder.getArrayAttr(mibs));
574 return success();
575}
576
577namespace {
578
579/// Implementation of the dialect interface that converts operations belonging
580/// to the LLVM dialect to LLVM IR.
581class LLVMDialectLLVMIRImportInterface : public LLVMImportDialectInterface {
582public:
583 using LLVMImportDialectInterface::LLVMImportDialectInterface;
584
585 /// Converts the LLVM intrinsic to an MLIR LLVM dialect operation if a
586 /// conversion exits. Returns failure otherwise.
587 LogicalResult convertIntrinsic(OpBuilder &builder, llvm::CallInst *inst,
588 LLVM::ModuleImport &moduleImport) const final {
589 return convertIntrinsicImpl(builder, inst, moduleImport);
590 }
591
592 /// Attaches the given LLVM metadata to the imported operation if a conversion
593 /// to an LLVM dialect attribute exists and succeeds. Returns failure
594 /// otherwise.
595 LogicalResult setMetadataAttrs(OpBuilder &builder, unsigned kind,
596 llvm::MDNode *node, Operation *op,
597 LLVM::ModuleImport &moduleImport) const final {
598 // Call metadata specific handlers.
599 if (kind == llvm::LLVMContext::MD_prof)
600 return setProfilingAttr(builder, node, op, moduleImport);
601 if (kind == llvm::LLVMContext::MD_tbaa)
602 return setTBAAAttr(node, op, moduleImport);
603 if (kind == llvm::LLVMContext::MD_access_group)
604 return setAccessGroupsAttr(node, op, moduleImport);
605 if (kind == llvm::LLVMContext::MD_loop)
606 return setLoopAttr(node, op, moduleImport);
607 if (kind == llvm::LLVMContext::MD_alias_scope)
608 return setAliasScopesAttr(node, op, moduleImport);
609 if (kind == llvm::LLVMContext::MD_noalias)
610 return setNoaliasScopesAttr(node, op, moduleImport);
611 if (kind == llvm::LLVMContext::MD_dereferenceable)
612 return setDereferenceableAttr(node, llvm::LLVMContext::MD_dereferenceable,
613 op, moduleImport);
614 if (kind == llvm::LLVMContext::MD_dereferenceable_or_null)
616 node, llvm::LLVMContext::MD_dereferenceable_or_null, op,
617 moduleImport);
618 if (kind == llvm::LLVMContext::MD_range)
619 return setRangeAttr(node, op);
620 if (kind == llvm::LLVMContext::MD_mmra)
621 return setMmraAttr(node, op, moduleImport);
622 if (kind == llvm::LLVMContext::MD_memprof)
623 return setMemProfAttr(builder, node, op);
624 if (kind == llvm::LLVMContext::MD_callsite)
625 return setCallsiteAttr(builder, node, op);
626 if (kind == llvm::LLVMContext::MD_tbaa_struct)
627 return setTBAAStructAttr(node, op, moduleImport);
628 llvm::LLVMContext &context = node->getContext();
629 if (kind == context.getMDKindID(vecTypeHintMDName))
630 return setVecTypeHintAttr(builder, node, op, moduleImport);
631 if (kind == context.getMDKindID(workGroupSizeHintMDName))
632 return setWorkGroupSizeHintAttr(builder, node, op);
633 if (kind == context.getMDKindID(reqdWorkGroupSizeMDName))
634 return setReqdWorkGroupSizeAttr(builder, node, op);
635 if (kind == context.getMDKindID(intelReqdSubGroupSizeMDName))
636 return setIntelReqdSubGroupSizeAttr(builder, node, op);
637
638 // A handler for a supported metadata kind is missing.
639 llvm_unreachable("unknown metadata type");
640 }
641
642 /// Returns the list of LLVM IR intrinsic identifiers that are convertible to
643 /// MLIR LLVM dialect intrinsics.
644 ArrayRef<unsigned> getSupportedIntrinsics() const final {
646 }
647
648 /// Returns the list of LLVM IR metadata kinds that are convertible to MLIR
649 /// LLVM dialect attributes.
650 SmallVector<unsigned>
651 getSupportedMetadata(llvm::LLVMContext &llvmContext) const final {
652 return getSupportedMetadataImpl(llvmContext);
653 }
654};
655} // namespace
656
658 registry.insert<LLVM::LLVMDialect>();
659 registry.addExtension(+[](MLIRContext *ctx, LLVM::LLVMDialect *dialect) {
660 dialect->addInterfaces<LLVMDialectLLVMIRImportInterface>();
661 });
662}
663
665 DialectRegistry registry;
667 context.appendDialectRegistry(registry);
668}
return success()
static VecTypeHintAttr convertVecTypeHint(Builder builder, llvm::MDNode *node, ModuleImport &moduleImport)
Converts the provided metadata node node to an LLVM dialect VecTypeHintAttr if possible.
static ArrayRef< unsigned > getSupportedIntrinsicsImpl()
Returns the list of LLVM IR intrinsic identifiers that are convertible to MLIR LLVM dialect intrinsic...
static constexpr StringLiteral workGroupSizeHintMDName
static LogicalResult setReqdWorkGroupSizeAttr(Builder &builder, llvm::MDNode *node, Operation *op)
static DenseI32ArrayAttr convertDenseI32Array(Builder builder, llvm::MDNode *node)
Converts the provided metadata node node to an MLIR DenseI32ArrayAttr if possible.
static LogicalResult setWorkGroupSizeHintAttr(Builder &builder, llvm::MDNode *node, Operation *op)
static LogicalResult setVecTypeHintAttr(Builder &builder, llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport)
static SmallVector< unsigned > getSupportedMetadataImpl(llvm::LLVMContext &llvmContext)
Returns the list of LLVM IR metadata kinds that are convertible to MLIR LLVM dialect attributes.
static LogicalResult setLoopAttr(const llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport)
Converts the given loop metadata node to an MLIR loop annotation attribute and attaches it to the imp...
static LogicalResult setTBAAAttr(const llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport)
Searches for the attribute that maps to the given TBAA metadata node and attaches it to the imported ...
static constexpr StringLiteral intelReqdSubGroupSizeMDName
static std::optional< uint64_t > getUInt64Metadata(llvm::Metadata *metadata)
Extracts an LLVM metadata constant as an unsigned 64-bit integer.
static LogicalResult setMemProfAttr(OpBuilder &builder, const llvm::MDNode *node, Operation *op)
Converts !memprof to the llvm.memprof attribute.
static LogicalResult setProfilingAttr(OpBuilder &builder, llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport)
Converts the given profiling metadata node to an MLIR profiling attribute and attaches it to the impo...
static LogicalResult setCallsiteAttr(OpBuilder &builder, const llvm::MDNode *node, Operation *op)
Converts !callsite to the llvm.callsite attribute.
static LogicalResult setIntelReqdSubGroupSizeAttr(Builder &builder, llvm::MDNode *node, Operation *op)
Converts the given intel required subgroup size metadata node to an MLIR attribute and attaches it to...
static LogicalResult setAliasScopesAttr(const llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport)
Looks up all the alias scope attributes that map to the alias scope nodes starting from the alias sco...
static LogicalResult setNoaliasScopesAttr(const llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport)
Looks up all the alias scope attributes that map to the alias scope nodes starting from the noalias m...
static bool isConvertibleIntrinsic(llvm::Intrinsic::ID id)
Returns true if the LLVM IR intrinsic is convertible to an MLIR LLVM dialect intrinsic.
static constexpr StringLiteral reqdWorkGroupSizeMDName
static LogicalResult setMmraAttr(llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport)
Convert the given MMRA metadata (either an MMRA tag or an array of them) into corresponding MLIR attr...
static LogicalResult convertIntrinsicImpl(OpBuilder &odsBuilder, llvm::CallInst *inst, LLVM::ModuleImport &moduleImport)
Converts the LLVM intrinsic to an MLIR LLVM dialect operation if a conversion exits.
static std::optional< int32_t > parseIntegerMD(llvm::Metadata *md)
Extracts an integer from the provided metadata md if possible.
static constexpr StringLiteral vecTypeHintMDName
static LogicalResult setAccessGroupsAttr(const llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport)
Looks up all the access group attributes that map to the access group nodes starting from the access ...
static LogicalResult setTBAAStructAttr(const llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport)
Attaches the tbaa_struct attribute converted from !tbaa.struct by ModuleImport::convertTBAAStructMeta...
static IntegerAttr convertIntegerMD(Builder builder, llvm::MDNode *node)
Convert an MDNode to an MLIR IntegerAttr if possible.
static DenseI64ArrayAttr getCallStackAttr(OpBuilder &builder, const llvm::MDNode *node)
Builds the call-stack hash list of a MemProf callsite node, one int64 per operand.
static LogicalResult setDereferenceableAttr(const llvm::MDNode *node, unsigned kindID, Operation *op, LLVM::ModuleImport &moduleImport)
Converts the given dereferenceable metadata node to a dereferenceable attribute, and attaches it to t...
static LogicalResult setRangeAttr(const llvm::MDNode *node, Operation *op)
Multi-range metadata is imported as the union of its ranges.
Attributes are known-constant values of operations.
Definition Attributes.h:25
This class is a general helper class for creating context-global objects like types,...
Definition Builders.h:51
IntegerAttr getI32IntegerAttr(int32_t value)
Definition Builders.cpp:208
DenseI32ArrayAttr getDenseI32ArrayAttr(ArrayRef< int32_t > values)
Definition Builders.cpp:171
DenseI64ArrayAttr getDenseI64ArrayAttr(ArrayRef< int64_t > values)
Definition Builders.cpp:175
StringAttr getStringAttr(const Twine &bytes)
Definition Builders.cpp:271
ArrayAttr getArrayAttr(ArrayRef< Attribute > value)
Definition Builders.cpp:275
MLIRContext * getContext() const
Definition Builders.h:56
Attr getAttr(Args &&...args)
Get or construct an instance of the attribute Attr with provided arguments.
Definition Builders.h:101
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
Module import implementation class that provides methods to import globals and functions from an LLVM...
Attribute lookupTBAAAttr(const llvm::MDNode *node) const
Returns the MLIR attribute mapped to the given LLVM TBAA metadata node.
Attribute lookupTBAAStructAttr(const llvm::MDNode *node) const
Looks up a converted !tbaa.struct node.
FailureOr< SmallVector< AliasScopeAttr > > lookupAliasScopeAttrs(const llvm::MDNode *node) const
Returns the alias scope attributes that map to the alias scope nodes starting from the metadata node.
Type convertType(llvm::Type *type)
Converts the type from LLVM to MLIR LLVM dialect.
LoopAnnotationAttr translateLoopAnnotationAttr(const llvm::MDNode *node, Location loc) const
Returns the loop annotation attribute that corresponds to the given LLVM loop metadata node.
FailureOr< SmallVector< AccessGroupAttr > > lookupAccessGroupAttrs(const llvm::MDNode *node) const
Returns the access group attributes that map to the access group nodes starting from the access group...
FailureOr< DereferenceableAttr > translateDereferenceableAttr(const llvm::MDNode *node, unsigned kindID)
Returns the dereferenceable attribute that corresponds to the given LLVM dereferenceable or dereferen...
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:71
void appendDialectRegistry(const DialectRegistry &registry)
Append the contents of the given dialect registry to the registry associated with this context.
This class helps build Operations.
Definition Builders.h:210
Operation is the basic unit of execution within MLIR.
Definition Operation.h:87
unsigned getNumSuccessors()
Definition Operation.h:760
InFlightDiagnostic emitWarning(const Twine &message={})
Emit a warning about this operation, reporting up to any diagnostic handlers that may be listening.
void setDiscardableAttr(StringAttr name, Attribute value)
Set a discardable attribute by name.
Definition Operation.h:514
Location getLoc()
The source location the operation was defined or derived from.
Definition Operation.h:240
MLIRContext * getContext()
Return the context this operation is associated with.
Definition Operation.h:233
Include the generated interface declarations.
detail::DenseArrayAttrImpl< int64_t > DenseI64ArrayAttr
llvm::DenseSet< ValueT, ValueInfoT > DenseSet
Definition LLVM.h:125
detail::DenseArrayAttrImpl< int32_t > DenseI32ArrayAttr
llvm::TypeSwitch< T, ResultT > TypeSwitch
Definition LLVM.h:147
void registerLLVMDialectImport(DialectRegistry &registry)
Registers the LLVM dialect and its import from LLVM IR in the given registry.