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;
71 #include "mlir/Dialect/LLVMIR/LLVMIntrinsicFromLLVMIRConversions.inc"
81 llvm::LLVMContext::MD_prof,
82 llvm::LLVMContext::MD_tbaa,
83 llvm::LLVMContext::MD_access_group,
84 llvm::LLVMContext::MD_loop,
85 llvm::LLVMContext::MD_noalias,
86 llvm::LLVMContext::MD_alias_scope,
91 return convertibleMetadata;
101 if (!node->getNumOperands())
104 auto *name = dyn_cast<llvm::MDString>(node->getOperand(0));
109 if (name->getString() ==
"function_entry_count") {
112 if (node->getNumOperands() != 2)
115 llvm::ConstantInt *entryCount =
116 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(1));
119 if (
auto funcOp = dyn_cast<LLVMFuncOp>(op)) {
120 funcOp.setFunctionEntryCount(entryCount->getZExtValue());
124 <<
"expected function_entry_count to be attached to a function";
127 if (name->getString() !=
"branch_weights")
132 branchWeights.reserve(node->getNumOperands() - 1);
133 for (
unsigned i = 1, e = node->getNumOperands(); i != e; ++i) {
134 llvm::ConstantInt *branchWeight =
135 llvm::mdconst::dyn_extract<llvm::ConstantInt>(node->getOperand(i));
138 branchWeights.push_back(branchWeight->getZExtValue());
141 if (
auto iface = dyn_cast<BranchWeightOpInterface>(op)) {
157 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
161 iface.setTBAATags(
ArrayAttr::get(iface.getContext(), tbaaTagSym));
171 FailureOr<SmallVector<AccessGroupAttr>> accessGroups =
173 if (failed(accessGroups))
176 auto iface = dyn_cast<AccessGroupOpInterface>(op);
181 iface.getContext(), llvm::to_vector_of<Attribute>(*accessGroups)));
190 LoopAnnotationAttr attr =
196 .Case<LLVM::BrOp, LLVM::CondBrOp>([&](
auto branchOp) {
197 branchOp.setLoopAnnotationAttr(attr);
200 .Default([](
auto) {
return failure(); });
208 FailureOr<SmallVector<AliasScopeAttr>> aliasScopes =
210 if (failed(aliasScopes))
213 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
218 iface.getContext(), llvm::to_vector_of<Attribute>(*aliasScopes)));
228 FailureOr<SmallVector<AliasScopeAttr>> noAliasScopes =
230 if (failed(noAliasScopes))
233 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
238 iface.getContext(), llvm::to_vector_of<Attribute>(*noAliasScopes)));
245 auto *constant = dyn_cast_if_present<llvm::ConstantAsMetadata>(md);
249 auto *intConstant = dyn_cast<llvm::ConstantInt>(constant->getValue());
253 return intConstant->getValue().getSExtValue();
260 if (!node || node->getNumOperands() != 2)
263 auto *hintMD = dyn_cast<llvm::ValueAsMetadata>(node->getOperand(0).get());
268 std::optional<int32_t> optIsSigned =
272 bool isSigned = *optIsSigned != 0;
274 return builder.
getAttr<VecTypeHintAttr>(hint, isSigned);
280 llvm::MDNode *node) {
284 for (
const llvm::MDOperand &op : node->operands()) {
288 vals.push_back(*mdValue);
295 if (!node || node->getNumOperands() != 1)
306 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
314 funcOp.setVecTypeHintAttr(attr);
320 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
328 funcOp.setWorkGroupSizeHintAttr(attr);
334 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
342 funcOp.setReqdWorkGroupSizeAttr(attr);
352 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
360 funcOp.setIntelReqdSubGroupSizeAttr(attr);
374 LogicalResult convertIntrinsic(
OpBuilder &builder, llvm::CallInst *inst,
382 LogicalResult setMetadataAttrs(
OpBuilder &builder,
unsigned kind,
386 if (kind == llvm::LLVMContext::MD_prof)
388 if (kind == llvm::LLVMContext::MD_tbaa)
390 if (kind == llvm::LLVMContext::MD_access_group)
392 if (kind == llvm::LLVMContext::MD_loop)
394 if (kind == llvm::LLVMContext::MD_alias_scope)
396 if (kind == llvm::LLVMContext::MD_noalias)
399 llvm::LLVMContext &context = node->getContext();
410 llvm_unreachable(
"unknown metadata type");
422 getSupportedMetadata(llvm::LLVMContext &context)
const final {
429 registry.
insert<LLVM::LLVMDialect>();
431 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...