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,
97 return convertibleMetadata;
107 if (!node->getNumOperands())
110 auto *name = dyn_cast<llvm::MDString>(node->getOperand(0));
115 if (name->getString() ==
"function_entry_count") {
118 if (node->getNumOperands() != 2)
121 llvm::ConstantInt *entryCount =
122 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(1));
125 if (
auto funcOp = dyn_cast<LLVMFuncOp>(op)) {
126 funcOp.setFunctionEntryCount(entryCount->getZExtValue());
130 <<
"expected function_entry_count to be attached to a function";
133 if (name->getString() !=
"branch_weights")
138 branchWeights.reserve(node->getNumOperands() - 1);
139 for (
unsigned i = 1, e = node->getNumOperands(); i != e; ++i) {
140 llvm::ConstantInt *branchWeight =
141 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(i));
144 branchWeights.push_back(branchWeight->getZExtValue());
147 if (
auto iface = dyn_cast<BranchWeightOpInterface>(op)) {
163 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
167 iface.setTBAATags(
ArrayAttr::get(iface.getContext(), tbaaTagSym));
177 FailureOr<SmallVector<AccessGroupAttr>> accessGroups =
179 if (failed(accessGroups))
182 auto iface = dyn_cast<AccessGroupOpInterface>(op);
187 iface.getContext(), llvm::to_vector_of<Attribute>(*accessGroups)));
196 LoopAnnotationAttr attr =
202 .Case<LLVM::BrOp, LLVM::CondBrOp>([&](
auto branchOp) {
203 branchOp.setLoopAnnotationAttr(attr);
206 .Default([](
auto) {
return failure(); });
214 FailureOr<SmallVector<AliasScopeAttr>> aliasScopes =
216 if (failed(aliasScopes))
219 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
224 iface.getContext(), llvm::to_vector_of<Attribute>(*aliasScopes)));
234 FailureOr<SmallVector<AliasScopeAttr>> noAliasScopes =
236 if (failed(noAliasScopes))
239 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
244 iface.getContext(), llvm::to_vector_of<Attribute>(*noAliasScopes)));
251 auto *constant = dyn_cast_if_present<llvm::ConstantAsMetadata>(md);
255 auto *intConstant = dyn_cast<llvm::ConstantInt>(constant->getValue());
259 return intConstant->getValue().getSExtValue();
266 if (!node || node->getNumOperands() != 2)
269 auto *hintMD = dyn_cast<llvm::ValueAsMetadata>(node->getOperand(0).get());
274 std::optional<int32_t> optIsSigned =
278 bool isSigned = *optIsSigned != 0;
280 return builder.
getAttr<VecTypeHintAttr>(hint, isSigned);
286 llvm::MDNode *node) {
290 for (
const llvm::MDOperand &op : node->operands()) {
294 vals.push_back(*mdValue);
301 if (!node || node->getNumOperands() != 1)
312 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
320 funcOp.setVecTypeHintAttr(attr);
326 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
334 funcOp.setWorkGroupSizeHintAttr(attr);
340 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
348 funcOp.setReqdWorkGroupSizeAttr(attr);
358 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
366 funcOp.setIntelReqdSubGroupSizeAttr(attr);
380 LogicalResult convertIntrinsic(
OpBuilder &builder, llvm::CallInst *inst,
388 LogicalResult setMetadataAttrs(
OpBuilder &builder,
unsigned kind,
392 if (kind == llvm::LLVMContext::MD_prof)
394 if (kind == llvm::LLVMContext::MD_tbaa)
396 if (kind == llvm::LLVMContext::MD_access_group)
398 if (kind == llvm::LLVMContext::MD_loop)
400 if (kind == llvm::LLVMContext::MD_alias_scope)
402 if (kind == llvm::LLVMContext::MD_noalias)
405 llvm::LLVMContext &context = node->getContext();
416 llvm_unreachable(
"unknown metadata type");
428 getSupportedMetadata(llvm::LLVMContext &context)
const final {
435 registry.
insert<LLVM::LLVMDialect>();
437 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 std::optional< int32_t > parseIntegerMD(llvm::Metadata *md)
Extracts an integer from the provided metadata md if possible.
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...
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...