19 #include "llvm/ADT/PostOrderIterator.h"
20 #include "llvm/ADT/ScopeExit.h"
21 #include "llvm/ADT/StringSet.h"
22 #include "llvm/ADT/TypeSwitch.h"
23 #include "llvm/IR/Constants.h"
24 #include "llvm/IR/InlineAsm.h"
25 #include "llvm/IR/Instructions.h"
26 #include "llvm/IR/IntrinsicInst.h"
27 #include "llvm/Support/ModRef.h"
33 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
39 "intel_reqd_sub_group_size";
45 #include "mlir/Dialect/LLVMIR/LLVMConvertibleLLVMIRIntrinsics.inc"
47 return convertibleIntrinsics.contains(
id);
54 #include "mlir/Dialect/LLVMIR/LLVMConvertibleLLVMIRIntrinsics.inc"
56 return convertibleIntrinsics;
73 llvmOpBundles.reserve(inst->getNumOperandBundles());
74 for (
unsigned i = 0; i < inst->getNumOperandBundles(); ++i)
75 llvmOpBundles.push_back(inst->getOperandBundleAt(i));
77 #include "mlir/Dialect/LLVMIR/LLVMIntrinsicFromLLVMIRConversions.inc"
87 llvm::LLVMContext::MD_prof,
88 llvm::LLVMContext::MD_tbaa,
89 llvm::LLVMContext::MD_access_group,
90 llvm::LLVMContext::MD_loop,
91 llvm::LLVMContext::MD_noalias,
92 llvm::LLVMContext::MD_alias_scope,
93 llvm::LLVMContext::MD_dereferenceable,
94 llvm::LLVMContext::MD_dereferenceable_or_null,
99 return convertibleMetadata;
109 if (!node->getNumOperands())
112 auto *name = dyn_cast<llvm::MDString>(node->getOperand(0));
117 if (name->getString() ==
"function_entry_count") {
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() !=
"branch_weights")
140 branchWeights.reserve(node->getNumOperands() - 1);
141 for (
unsigned i = 1, e = node->getNumOperands(); i != e; ++i) {
142 llvm::ConstantInt *branchWeight =
143 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(i));
146 branchWeights.push_back(branchWeight->getZExtValue());
149 if (
auto iface = dyn_cast<BranchWeightOpInterface>(op)) {
165 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
169 iface.setTBAATags(
ArrayAttr::get(iface.getContext(), tbaaTagSym));
179 FailureOr<SmallVector<AccessGroupAttr>> accessGroups =
181 if (failed(accessGroups))
184 auto iface = dyn_cast<AccessGroupOpInterface>(op);
189 iface.getContext(), llvm::to_vector_of<Attribute>(*accessGroups)));
199 auto dereferenceable =
201 if (failed(dereferenceable))
204 auto iface = dyn_cast<DereferenceableOpInterface>(op);
208 iface.setDereferenceable(*dereferenceable);
217 LoopAnnotationAttr attr =
223 .Case<LLVM::BrOp, LLVM::CondBrOp>([&](
auto branchOp) {
224 branchOp.setLoopAnnotationAttr(attr);
227 .Default([](
auto) {
return failure(); });
235 FailureOr<SmallVector<AliasScopeAttr>> aliasScopes =
237 if (failed(aliasScopes))
240 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
245 iface.getContext(), llvm::to_vector_of<Attribute>(*aliasScopes)));
255 FailureOr<SmallVector<AliasScopeAttr>> noAliasScopes =
257 if (failed(noAliasScopes))
260 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
265 iface.getContext(), llvm::to_vector_of<Attribute>(*noAliasScopes)));
272 auto *constant = dyn_cast_if_present<llvm::ConstantAsMetadata>(md);
276 auto *intConstant = dyn_cast<llvm::ConstantInt>(constant->getValue());
280 return intConstant->getValue().getSExtValue();
287 if (!node || node->getNumOperands() != 2)
290 auto *hintMD = dyn_cast<llvm::ValueAsMetadata>(node->getOperand(0).get());
295 std::optional<int32_t> optIsSigned =
299 bool isSigned = *optIsSigned != 0;
301 return builder.
getAttr<VecTypeHintAttr>(hint, isSigned);
307 llvm::MDNode *node) {
311 for (
const llvm::MDOperand &op : node->operands()) {
315 vals.push_back(*mdValue);
322 if (!node || node->getNumOperands() != 1)
333 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
341 funcOp.setVecTypeHintAttr(attr);
347 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
355 funcOp.setWorkGroupSizeHintAttr(attr);
361 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
369 funcOp.setReqdWorkGroupSizeAttr(attr);
379 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
387 funcOp.setIntelReqdSubGroupSizeAttr(attr);
401 LogicalResult convertIntrinsic(
OpBuilder &builder, llvm::CallInst *inst,
409 LogicalResult setMetadataAttrs(
OpBuilder &builder,
unsigned kind,
413 if (
kind == llvm::LLVMContext::MD_prof)
415 if (
kind == llvm::LLVMContext::MD_tbaa)
417 if (
kind == llvm::LLVMContext::MD_access_group)
419 if (
kind == llvm::LLVMContext::MD_loop)
421 if (
kind == llvm::LLVMContext::MD_alias_scope)
423 if (
kind == llvm::LLVMContext::MD_noalias)
425 if (
kind == llvm::LLVMContext::MD_dereferenceable)
428 if (
kind == llvm::LLVMContext::MD_dereferenceable_or_null)
430 node, llvm::LLVMContext::MD_dereferenceable_or_null, op,
433 llvm::LLVMContext &context = node->getContext();
444 llvm_unreachable(
"unknown metadata type");
456 getSupportedMetadata(llvm::LLVMContext &context)
const final {
463 registry.
insert<LLVM::LLVMDialect>();
465 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 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 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 ArrayRef< unsigned > getSupportedIntrinsicsImpl()
Returns the list of LLVM IR intrinsic identifiers that are convertible to MLIR LLVM dialect intrinsic...
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 ArrayRef< unsigned > getSupportedMetadataImpl(llvm::LLVMContext &context)
Returns the list of LLVM IR metadata kinds that are convertible to MLIR LLVM dialect attributes.
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 convertIntrinsicImpl(OpBuilder &odsBuilder, llvm::CallInst *inst, LLVM::ModuleImport &moduleImport)
Converts the LLVM intrinsic to an MLIR LLVM dialect operation if a conversion exits.
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...
static std::optional< int32_t > parseIntegerMD(llvm::Metadata *md)
Extracts an integer from the provided metadata md if possible.
union mlir::linalg::@1194::ArityGroupAndKind::Kind kind
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.
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.
Include the generated interface declarations.
void registerLLVMDialectImport(DialectRegistry ®istry)
Registers the LLVM dialect and its import from LLVM IR in the given registry.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...