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"
32#include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
38 "intel_reqd_sub_group_size";
44#include "mlir/Dialect/LLVMIR/LLVMConvertibleLLVMIRIntrinsics.inc"
46 return convertibleIntrinsics.contains(
id);
53#include "mlir/Dialect/LLVMIR/LLVMConvertibleLLVMIRIntrinsics.inc"
55 return convertibleIntrinsics;
63 llvm::Intrinsic::ID intrinsicID = inst->getIntrinsicID();
72 llvmOpBundles.reserve(inst->getNumOperandBundles());
73 for (
unsigned i = 0; i < inst->getNumOperandBundles(); ++i)
74 llvmOpBundles.push_back(inst->getOperandBundleAt(i));
76#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,
95 llvm::LLVMContext::MD_mmra,
100 return convertibleMetadata;
105 auto *constant = llvm::mdconst::dyn_extract<llvm::ConstantInt>(metadata);
108 return constant->getValue().tryZExtValue();
118 if (!node->getNumOperands())
121 auto *name = dyn_cast<llvm::MDString>(node->getOperand(0));
124 StringRef profName = name->getString();
127 if (profName == llvm::MDProfLabels::FunctionEntryCount ||
128 profName == llvm::MDProfLabels::SyntheticFunctionEntryCount) {
129 if (node->getNumOperands() < 2)
133 profName == llvm::MDProfLabels::SyntheticFunctionEntryCount;
134 ProfileCountType profileCountType =
135 isSynthetic ? ProfileCountType::Synthetic : ProfileCountType::Real;
137 std::optional<uint64_t> entryCountValue =
139 if (!entryCountValue)
143 importGUIDValues.reserve(node->getNumOperands() - 2);
144 for (
unsigned idx = 2, e = node->getNumOperands(); idx < e; ++idx) {
145 std::optional<uint64_t> guidValue =
149 importGUIDValues.push_back(*guidValue);
152 if (
auto funcOp = dyn_cast<LLVMFuncOp>(op)) {
153 funcOp.setFunctionEntryCountAttr(
154 FunctionEntryCountAttr::get(builder.
getContext(), *entryCountValue,
155 profileCountType, importGUIDValues));
159 <<
"expected function_entry_count to be attached to a function";
162 if (profName != llvm::MDProfLabels::BranchWeights)
165 if (node->getNumOperands() < 2)
169 node->operands().drop_front();
170 if (
auto *mdString = dyn_cast<llvm::MDString>(node->getOperand(1))) {
171 if (mdString->getString() != llvm::MDProfLabels::ExpectedBranchWeights)
175 branchWeightOperands = branchWeightOperands.drop_front();
180 branchWeights.reserve(branchWeightOperands.size());
181 for (
const llvm::MDOperand &operand : branchWeightOperands) {
182 llvm::ConstantInt *branchWeight =
183 llvm::mdconst::dyn_extract<llvm::ConstantInt>(operand);
186 branchWeights.push_back(branchWeight->getZExtValue());
189 if (
auto iface = dyn_cast<WeightedBranchOpInterface>(op)) {
197 iface.setWeights(branchWeights);
212 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
216 iface.setTBAATags(ArrayAttr::get(iface.getContext(), tbaaTagSym));
226 FailureOr<SmallVector<AccessGroupAttr>> accessGroups =
228 if (failed(accessGroups))
231 auto iface = dyn_cast<AccessGroupOpInterface>(op);
235 iface.setAccessGroups(ArrayAttr::get(
236 iface.getContext(), llvm::to_vector_of<Attribute>(*accessGroups)));
246 auto dereferenceable =
248 if (failed(dereferenceable))
251 auto iface = dyn_cast<DereferenceableOpInterface>(op);
255 iface.setDereferenceable(*dereferenceable);
270 auto toAttribute = [&](llvm::MDNode *tag) ->
Attribute {
271 return LLVM::MMRATagAttr::get(
272 ctx, cast<llvm::MDString>(tag->getOperand(0))->getString(),
273 cast<llvm::MDString>(tag->getOperand(1))->getString());
276 if (llvm::MMRAMetadata::isTagMD(node)) {
277 mlirMmra = toAttribute(node);
280 for (
const llvm::MDOperand &operand : node->operands()) {
281 auto *tagNode = dyn_cast<llvm::MDNode>(operand.get());
282 if (!tagNode || !llvm::MMRAMetadata::isTagMD(tagNode))
284 tags.push_back(toAttribute(tagNode));
286 mlirMmra = ArrayAttr::get(ctx, tags);
288 op->
setAttr(LLVMDialect::getMmraAttrName(), mlirMmra);
297 LoopAnnotationAttr attr =
303 .Case<LLVM::BrOp, LLVM::CondBrOp>([&](
auto branchOp) {
304 branchOp.setLoopAnnotationAttr(attr);
315 FailureOr<SmallVector<AliasScopeAttr>> aliasScopes =
317 if (failed(aliasScopes))
320 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
324 iface.setAliasScopes(ArrayAttr::get(
325 iface.getContext(), llvm::to_vector_of<Attribute>(*aliasScopes)));
335 FailureOr<SmallVector<AliasScopeAttr>> noAliasScopes =
337 if (failed(noAliasScopes))
340 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
344 iface.setNoAliasScopes(ArrayAttr::get(
345 iface.getContext(), llvm::to_vector_of<Attribute>(*noAliasScopes)));
352 auto *constant = dyn_cast_if_present<llvm::ConstantAsMetadata>(md);
356 auto *intConstant = dyn_cast<llvm::ConstantInt>(constant->getValue());
360 return intConstant->getValue().getSExtValue();
367 if (!node || node->getNumOperands() != 2)
370 auto *hintMD = dyn_cast<llvm::ValueAsMetadata>(node->getOperand(0).get());
373 TypeAttr hint = TypeAttr::get(moduleImport.
convertType(hintMD->getType()));
375 std::optional<int32_t> optIsSigned =
379 bool isSigned = *optIsSigned != 0;
381 return builder.
getAttr<VecTypeHintAttr>(hint, isSigned);
387 llvm::MDNode *node) {
391 for (
const llvm::MDOperand &op : node->operands()) {
395 vals.push_back(*mdValue);
402 if (!node || node->getNumOperands() != 1)
413 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
421 funcOp.setVecTypeHintAttr(attr);
427 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
435 funcOp.setWorkGroupSizeHintAttr(attr);
441 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
449 funcOp.setReqdWorkGroupSizeAttr(attr);
459 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
467 funcOp.setIntelReqdSubGroupSizeAttr(attr);
475class LLVMDialectLLVMIRImportInterface :
public LLVMImportDialectInterface {
477 using LLVMImportDialectInterface::LLVMImportDialectInterface;
481 LogicalResult convertIntrinsic(OpBuilder &builder, llvm::CallInst *inst,
482 LLVM::ModuleImport &moduleImport)
const final {
489 LogicalResult setMetadataAttrs(OpBuilder &builder,
unsigned kind,
490 llvm::MDNode *node, Operation *op,
491 LLVM::ModuleImport &moduleImport)
const final {
493 if (kind == llvm::LLVMContext::MD_prof)
495 if (kind == llvm::LLVMContext::MD_tbaa)
497 if (kind == llvm::LLVMContext::MD_access_group)
499 if (kind == llvm::LLVMContext::MD_loop)
501 if (kind == llvm::LLVMContext::MD_alias_scope)
503 if (kind == llvm::LLVMContext::MD_noalias)
505 if (kind == llvm::LLVMContext::MD_dereferenceable)
508 if (kind == llvm::LLVMContext::MD_dereferenceable_or_null)
510 node, llvm::LLVMContext::MD_dereferenceable_or_null, op,
512 if (kind == llvm::LLVMContext::MD_mmra)
514 llvm::LLVMContext &context = node->getContext();
525 llvm_unreachable(
"unknown metadata type");
530 ArrayRef<unsigned> getSupportedIntrinsics() const final {
536 SmallVector<unsigned>
537 getSupportedMetadata(llvm::LLVMContext &llvmContext)
const final {
544 registry.
insert<LLVM::LLVMDialect>();
546 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 std::optional< uint64_t > getUInt64Metadata(llvm::Metadata *metadata)
Extracts an LLVM metadata constant as an unsigned 64-bit integer.
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)
MLIRContext * getContext() const
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.
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.