20#include "llvm/ADT/TypeSwitch.h"
21#include "llvm/IR/Constants.h"
22#include "llvm/IR/InlineAsm.h"
23#include "llvm/IR/Instructions.h"
24#include "llvm/IR/IntrinsicInst.h"
25#include "llvm/IR/MemoryModelRelaxationAnnotations.h"
31#include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
37 "intel_reqd_sub_group_size";
43#include "mlir/Dialect/LLVMIR/LLVMConvertibleLLVMIRIntrinsics.inc"
45 return convertibleIntrinsics.contains(
id);
52#include "mlir/Dialect/LLVMIR/LLVMConvertibleLLVMIRIntrinsics.inc"
54 return convertibleIntrinsics;
62 llvm::Intrinsic::ID intrinsicID = inst->getIntrinsicID();
71 llvmOpBundles.reserve(inst->getNumOperandBundles());
72 for (
unsigned i = 0; i < inst->getNumOperandBundles(); ++i)
73 llvmOpBundles.push_back(inst->getOperandBundleAt(i));
75#include "mlir/Dialect/LLVMIR/LLVMIntrinsicFromLLVMIRConversions.inc"
86 llvm::LLVMContext::MD_prof,
87 llvm::LLVMContext::MD_tbaa,
88 llvm::LLVMContext::MD_access_group,
89 llvm::LLVMContext::MD_loop,
90 llvm::LLVMContext::MD_noalias,
91 llvm::LLVMContext::MD_alias_scope,
92 llvm::LLVMContext::MD_dereferenceable,
93 llvm::LLVMContext::MD_dereferenceable_or_null,
94 llvm::LLVMContext::MD_mmra,
99 return convertibleMetadata;
109 if (!node->getNumOperands())
112 auto *name = dyn_cast<llvm::MDString>(node->getOperand(0));
117 if (name->getString() == llvm::MDProfLabels::FunctionEntryCount) {
120 if (node->getNumOperands() != 2)
123 llvm::ConstantInt *entryCount =
124 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(1));
127 if (
auto funcOp = dyn_cast<LLVMFuncOp>(op)) {
128 funcOp.setFunctionEntryCount(entryCount->getZExtValue());
132 <<
"expected function_entry_count to be attached to a function";
135 if (name->getString() != llvm::MDProfLabels::BranchWeights)
138 if (node->getNumOperands() < 2)
142 node->operands().drop_front();
143 if (
auto *mdString = dyn_cast<llvm::MDString>(node->getOperand(1))) {
144 if (mdString->getString() != llvm::MDProfLabels::ExpectedBranchWeights)
148 branchWeightOperands = branchWeightOperands.drop_front();
153 branchWeights.reserve(branchWeightOperands.size());
154 for (
const llvm::MDOperand &operand : branchWeightOperands) {
155 llvm::ConstantInt *branchWeight =
156 llvm::mdconst::dyn_extract<llvm::ConstantInt>(operand);
159 branchWeights.push_back(branchWeight->getZExtValue());
162 if (
auto iface = dyn_cast<WeightedBranchOpInterface>(op)) {
170 iface.setWeights(branchWeights);
185 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
189 iface.setTBAATags(ArrayAttr::get(iface.getContext(), tbaaTagSym));
199 FailureOr<SmallVector<AccessGroupAttr>> accessGroups =
201 if (failed(accessGroups))
204 auto iface = dyn_cast<AccessGroupOpInterface>(op);
208 iface.setAccessGroups(ArrayAttr::get(
209 iface.getContext(), llvm::to_vector_of<Attribute>(*accessGroups)));
219 auto dereferenceable =
221 if (failed(dereferenceable))
224 auto iface = dyn_cast<DereferenceableOpInterface>(op);
228 iface.setDereferenceable(*dereferenceable);
243 auto toAttribute = [&](llvm::MDNode *tag) ->
Attribute {
244 return LLVM::MMRATagAttr::get(
245 ctx, cast<llvm::MDString>(tag->getOperand(0))->getString(),
246 cast<llvm::MDString>(tag->getOperand(1))->getString());
249 if (llvm::MMRAMetadata::isTagMD(node)) {
250 mlirMmra = toAttribute(node);
253 for (
const llvm::MDOperand &operand : node->operands()) {
254 auto *tagNode = dyn_cast<llvm::MDNode>(operand.get());
255 if (!tagNode || !llvm::MMRAMetadata::isTagMD(tagNode))
257 tags.push_back(toAttribute(tagNode));
259 mlirMmra = ArrayAttr::get(ctx, tags);
261 op->
setAttr(LLVMDialect::getMmraAttrName(), mlirMmra);
270 LoopAnnotationAttr attr =
276 .Case<LLVM::BrOp, LLVM::CondBrOp>([&](
auto branchOp) {
277 branchOp.setLoopAnnotationAttr(attr);
280 .Default([](
auto) {
return failure(); });
288 FailureOr<SmallVector<AliasScopeAttr>> aliasScopes =
290 if (failed(aliasScopes))
293 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
297 iface.setAliasScopes(ArrayAttr::get(
298 iface.getContext(), llvm::to_vector_of<Attribute>(*aliasScopes)));
308 FailureOr<SmallVector<AliasScopeAttr>> noAliasScopes =
310 if (failed(noAliasScopes))
313 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
317 iface.setNoAliasScopes(ArrayAttr::get(
318 iface.getContext(), llvm::to_vector_of<Attribute>(*noAliasScopes)));
325 auto *constant = dyn_cast_if_present<llvm::ConstantAsMetadata>(md);
329 auto *intConstant = dyn_cast<llvm::ConstantInt>(constant->getValue());
333 return intConstant->getValue().getSExtValue();
340 if (!node || node->getNumOperands() != 2)
343 auto *hintMD = dyn_cast<llvm::ValueAsMetadata>(node->getOperand(0).get());
346 TypeAttr hint = TypeAttr::get(moduleImport.
convertType(hintMD->getType()));
348 std::optional<int32_t> optIsSigned =
352 bool isSigned = *optIsSigned != 0;
354 return builder.
getAttr<VecTypeHintAttr>(hint, isSigned);
360 llvm::MDNode *node) {
364 for (
const llvm::MDOperand &op : node->operands()) {
368 vals.push_back(*mdValue);
375 if (!node || node->getNumOperands() != 1)
386 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
394 funcOp.setVecTypeHintAttr(attr);
400 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
408 funcOp.setWorkGroupSizeHintAttr(attr);
414 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
422 funcOp.setReqdWorkGroupSizeAttr(attr);
432 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
440 funcOp.setIntelReqdSubGroupSizeAttr(attr);
454 LogicalResult convertIntrinsic(OpBuilder &builder, llvm::CallInst *inst,
455 LLVM::ModuleImport &moduleImport)
const final {
462 LogicalResult setMetadataAttrs(OpBuilder &builder,
unsigned kind,
463 llvm::MDNode *node, Operation *op,
464 LLVM::ModuleImport &moduleImport)
const final {
466 if (kind == llvm::LLVMContext::MD_prof)
468 if (kind == llvm::LLVMContext::MD_tbaa)
470 if (kind == llvm::LLVMContext::MD_access_group)
472 if (kind == llvm::LLVMContext::MD_loop)
474 if (kind == llvm::LLVMContext::MD_alias_scope)
476 if (kind == llvm::LLVMContext::MD_noalias)
478 if (kind == llvm::LLVMContext::MD_dereferenceable)
481 if (kind == llvm::LLVMContext::MD_dereferenceable_or_null)
483 node, llvm::LLVMContext::MD_dereferenceable_or_null, op,
485 if (kind == llvm::LLVMContext::MD_mmra)
487 llvm::LLVMContext &context = node->getContext();
498 llvm_unreachable(
"unknown metadata type");
503 ArrayRef<unsigned> getSupportedIntrinsics() const final {
509 SmallVector<unsigned>
510 getSupportedMetadata(llvm::LLVMContext &llvmContext)
const final {
517 registry.
insert<LLVM::LLVMDialect>();
519 dialect->addInterfaces<LLVMDialectLLVMIRImportInterface>();
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 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 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 IntegerAttr convertIntegerMD(Builder builder, llvm::MDNode *node)
Convert an MDNode to an MLIR IntegerAttr if possible.
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...
Attributes are known-constant values of operations.
This class is a general helper class for creating context-global objects like types,...
IntegerAttr getI32IntegerAttr(int32_t value)
DenseI32ArrayAttr getDenseI32ArrayAttr(ArrayRef< int32_t > values)
Attr getAttr(Args &&...args)
Get or construct an instance of the attribute Attr with provided arguments.
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.
Base class for dialect interfaces used to import LLVM IR.
LLVMImportDialectInterface(Dialect *dialect)
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.
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.
void appendDialectRegistry(const DialectRegistry ®istry)
Append the contents of the given dialect registry to the registry associated with this context.
This class helps build Operations.
Operation is the basic unit of execution within MLIR.
unsigned getNumSuccessors()
InFlightDiagnostic emitWarning(const Twine &message={})
Emit a warning about this operation, reporting up to any diagnostic handlers that may be listening.
Location getLoc()
The source location the operation was defined or derived from.
void setAttr(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
MLIRContext * getContext()
Return the context this operation is associated with.
Include the generated interface declarations.
llvm::DenseSet< ValueT, ValueInfoT > DenseSet
detail::DenseArrayAttrImpl< int32_t > DenseI32ArrayAttr
llvm::TypeSwitch< T, ResultT > TypeSwitch
void registerLLVMDialectImport(DialectRegistry ®istry)
Registers the LLVM dialect and its import from LLVM IR in the given registry.