19 #include "llvm/ADT/TypeSwitch.h"
20 #include "llvm/IR/Constants.h"
21 #include "llvm/IR/InlineAsm.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/IntrinsicInst.h"
29 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
35 "intel_reqd_sub_group_size";
41 #include "mlir/Dialect/LLVMIR/LLVMConvertibleLLVMIRIntrinsics.inc"
43 return convertibleIntrinsics.contains(
id);
50 #include "mlir/Dialect/LLVMIR/LLVMConvertibleLLVMIRIntrinsics.inc"
52 return convertibleIntrinsics;
59 LLVM::ModuleImport &moduleImport) {
69 llvmOpBundles.reserve(inst->getNumOperandBundles());
70 for (
unsigned i = 0; i < inst->getNumOperandBundles(); ++i)
71 llvmOpBundles.push_back(inst->getOperandBundleAt(i));
73 #include "mlir/Dialect/LLVMIR/LLVMIntrinsicFromLLVMIRConversions.inc"
83 llvm::LLVMContext::MD_prof,
84 llvm::LLVMContext::MD_tbaa,
85 llvm::LLVMContext::MD_access_group,
86 llvm::LLVMContext::MD_loop,
87 llvm::LLVMContext::MD_noalias,
88 llvm::LLVMContext::MD_alias_scope,
89 llvm::LLVMContext::MD_dereferenceable,
90 llvm::LLVMContext::MD_dereferenceable_or_null,
95 return convertibleMetadata;
103 LLVM::ModuleImport &moduleImport) {
105 if (!node->getNumOperands())
108 auto *name = dyn_cast<llvm::MDString>(node->getOperand(0));
113 if (name->getString() ==
"function_entry_count") {
116 if (node->getNumOperands() != 2)
119 llvm::ConstantInt *entryCount =
120 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(1));
123 if (
auto funcOp = dyn_cast<LLVMFuncOp>(op)) {
124 funcOp.setFunctionEntryCount(entryCount->getZExtValue());
128 <<
"expected function_entry_count to be attached to a function";
131 if (name->getString() !=
"branch_weights")
136 branchWeights.reserve(node->getNumOperands() - 1);
137 for (
unsigned i = 1, e = node->getNumOperands(); i != e; ++i) {
138 llvm::ConstantInt *branchWeight =
139 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(i));
142 branchWeights.push_back(branchWeight->getZExtValue());
145 if (
auto iface = dyn_cast<WeightedBranchOpInterface>(op)) {
153 iface.setWeights(branchWeights);
163 LLVM::ModuleImport &moduleImport) {
164 Attribute tbaaTagSym = moduleImport.lookupTBAAAttr(node);
168 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
172 iface.setTBAATags(
ArrayAttr::get(iface.getContext(), tbaaTagSym));
181 LLVM::ModuleImport &moduleImport) {
182 FailureOr<SmallVector<AccessGroupAttr>> accessGroups =
183 moduleImport.lookupAccessGroupAttrs(node);
187 auto iface = dyn_cast<AccessGroupOpInterface>(op);
192 iface.getContext(), llvm::to_vector_of<Attribute>(*accessGroups)));
201 LLVM::ModuleImport &moduleImport) {
202 auto dereferenceable =
203 moduleImport.translateDereferenceableAttr(node, kindID);
204 if (
failed(dereferenceable))
207 auto iface = dyn_cast<DereferenceableOpInterface>(op);
211 iface.setDereferenceable(*dereferenceable);
219 LLVM::ModuleImport &moduleImport) {
220 LoopAnnotationAttr attr =
221 moduleImport.translateLoopAnnotationAttr(node, op->
getLoc());
226 .Case<LLVM::BrOp, LLVM::CondBrOp>([&](
auto branchOp) {
227 branchOp.setLoopAnnotationAttr(attr);
230 .Default([](
auto) {
return failure(); });
237 LLVM::ModuleImport &moduleImport) {
238 FailureOr<SmallVector<AliasScopeAttr>> aliasScopes =
239 moduleImport.lookupAliasScopeAttrs(node);
243 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
248 iface.getContext(), llvm::to_vector_of<Attribute>(*aliasScopes)));
257 LLVM::ModuleImport &moduleImport) {
258 FailureOr<SmallVector<AliasScopeAttr>> noAliasScopes =
259 moduleImport.lookupAliasScopeAttrs(node);
260 if (
failed(noAliasScopes))
263 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
268 iface.getContext(), llvm::to_vector_of<Attribute>(*noAliasScopes)));
275 auto *constant = dyn_cast_if_present<llvm::ConstantAsMetadata>(md);
279 auto *intConstant = dyn_cast<llvm::ConstantInt>(constant->getValue());
283 return intConstant->getValue().getSExtValue();
290 if (!node || node->getNumOperands() != 2)
293 auto *hintMD = dyn_cast<llvm::ValueAsMetadata>(node->getOperand(0).get());
298 std::optional<int32_t> optIsSigned =
302 bool isSigned = *optIsSigned != 0;
304 return builder.
getAttr<VecTypeHintAttr>(hint, isSigned);
310 llvm::MDNode *node) {
314 for (
const llvm::MDOperand &op : node->operands()) {
318 vals.push_back(*mdValue);
325 if (!node || node->getNumOperands() != 1)
335 LLVM::ModuleImport &moduleImport) {
336 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
344 funcOp.setVecTypeHintAttr(attr);
350 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
358 funcOp.setWorkGroupSizeHintAttr(attr);
364 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
372 funcOp.setReqdWorkGroupSizeAttr(attr);
382 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
390 funcOp.setIntelReqdSubGroupSizeAttr(attr);
404 LogicalResult convertIntrinsic(
OpBuilder &builder, llvm::CallInst *inst,
405 LLVM::ModuleImport &moduleImport)
const final {
412 LogicalResult setMetadataAttrs(
OpBuilder &builder,
unsigned kind,
414 LLVM::ModuleImport &moduleImport)
const final {
416 if (
kind == llvm::LLVMContext::MD_prof)
418 if (
kind == llvm::LLVMContext::MD_tbaa)
420 if (
kind == llvm::LLVMContext::MD_access_group)
422 if (
kind == llvm::LLVMContext::MD_loop)
424 if (
kind == llvm::LLVMContext::MD_alias_scope)
426 if (
kind == llvm::LLVMContext::MD_noalias)
428 if (
kind == llvm::LLVMContext::MD_dereferenceable)
431 if (
kind == llvm::LLVMContext::MD_dereferenceable_or_null)
433 node, llvm::LLVMContext::MD_dereferenceable_or_null, op,
436 llvm::LLVMContext &context = node->getContext();
447 llvm_unreachable(
"unknown metadata type");
459 getSupportedMetadata(llvm::LLVMContext &context)
const final {
466 registry.
insert<LLVM::LLVMDialect>();
468 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::@1244::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...
Type convertType(llvm::Type *type)
Converts the type from LLVM to MLIR LLVM dialect.
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.
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...