20#include "llvm/ADT/TypeSwitch.h"
21#include "llvm/IR/ConstantRange.h"
22#include "llvm/IR/Constants.h"
23#include "llvm/IR/InlineAsm.h"
24#include "llvm/IR/Instructions.h"
25#include "llvm/IR/IntrinsicInst.h"
26#include "llvm/IR/MemoryModelRelaxationAnnotations.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;
64 llvm::Intrinsic::ID intrinsicID = inst->getIntrinsicID();
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"
88 llvm::LLVMContext::MD_prof,
89 llvm::LLVMContext::MD_tbaa,
90 llvm::LLVMContext::MD_access_group,
91 llvm::LLVMContext::MD_loop,
92 llvm::LLVMContext::MD_noalias,
93 llvm::LLVMContext::MD_alias_scope,
94 llvm::LLVMContext::MD_dereferenceable,
95 llvm::LLVMContext::MD_dereferenceable_or_null,
96 llvm::LLVMContext::MD_range,
97 llvm::LLVMContext::MD_mmra,
98 llvm::LLVMContext::MD_memprof,
99 llvm::LLVMContext::MD_callsite,
100 llvm::LLVMContext::MD_tbaa_struct,
105 return convertibleMetadata;
110 auto *constant = llvm::mdconst::dyn_extract<llvm::ConstantInt>(metadata);
113 return constant->getValue().tryZExtValue();
123 if (!node->getNumOperands())
126 auto *name = dyn_cast<llvm::MDString>(node->getOperand(0));
129 StringRef profName = name->getString();
132 if (profName == llvm::MDProfLabels::FunctionEntryCount) {
133 if (node->getNumOperands() < 2)
136 std::optional<uint64_t> entryCountValue =
138 if (!entryCountValue)
142 importGUIDValues.reserve(node->getNumOperands() - 2);
143 for (
unsigned idx = 2, e = node->getNumOperands(); idx < e; ++idx) {
144 std::optional<uint64_t> guidValue =
148 importGUIDValues.push_back(*guidValue);
151 if (
auto funcOp = dyn_cast<LLVMFuncOp>(op)) {
152 funcOp.setFunctionEntryCountAttr(FunctionEntryCountAttr::get(
153 builder.
getContext(), *entryCountValue, importGUIDValues));
157 <<
"expected function_entry_count to be attached to a function";
160 if (profName != llvm::MDProfLabels::BranchWeights)
163 if (node->getNumOperands() < 2)
167 node->operands().drop_front();
168 if (
auto *mdString = dyn_cast<llvm::MDString>(node->getOperand(1))) {
169 if (mdString->getString() != llvm::MDProfLabels::ExpectedBranchWeights)
173 branchWeightOperands = branchWeightOperands.drop_front();
178 branchWeights.reserve(branchWeightOperands.size());
179 for (
const llvm::MDOperand &operand : branchWeightOperands) {
180 llvm::ConstantInt *branchWeight =
181 llvm::mdconst::dyn_extract<llvm::ConstantInt>(operand);
184 branchWeights.push_back(branchWeight->getZExtValue());
187 if (
auto iface = dyn_cast<WeightedBranchOpInterface>(op)) {
195 iface.setWeights(branchWeights);
210 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
214 iface.setTBAATags(ArrayAttr::get(iface.getContext(), tbaaTagSym));
229 auto iface = dyn_cast<TBAAStructOpInterface>(op);
232 iface.setTBAAStruct(fields);
242 FailureOr<SmallVector<AccessGroupAttr>> accessGroups =
244 if (failed(accessGroups))
247 auto iface = dyn_cast<AccessGroupOpInterface>(op);
251 iface.setAccessGroups(ArrayAttr::get(
252 iface.getContext(), llvm::to_vector_of<Attribute>(*accessGroups)));
262 auto dereferenceable =
264 if (failed(dereferenceable))
267 auto iface = dyn_cast<DereferenceableOpInterface>(op);
271 iface.setDereferenceable(*dereferenceable);
277 auto iface = dyn_cast<RangeOpInterface>(op);
281 llvm::ConstantRange range = llvm::getConstantRangeFromMetadata(*node);
282 iface.setRange(ConstantRangeAttr::get(op->
getContext(), range.getLower(),
298 auto toAttribute = [&](llvm::MDNode *tag) ->
Attribute {
299 return LLVM::MMRATagAttr::get(
300 ctx, cast<llvm::MDString>(tag->getOperand(0))->getString(),
301 cast<llvm::MDString>(tag->getOperand(1))->getString());
304 if (llvm::MMRAMetadata::isTagMD(node)) {
305 mlirMmra = toAttribute(node);
308 for (
const llvm::MDOperand &operand : node->operands()) {
309 auto *tagNode = dyn_cast<llvm::MDNode>(operand.get());
310 if (!tagNode || !llvm::MMRAMetadata::isTagMD(tagNode))
312 tags.push_back(toAttribute(tagNode));
314 mlirMmra = ArrayAttr::get(ctx, tags);
325 LoopAnnotationAttr attr =
331 .Case<LLVM::BrOp, LLVM::CondBrOp>([&](
auto branchOp) {
332 branchOp.setLoopAnnotationAttr(attr);
343 FailureOr<SmallVector<AliasScopeAttr>> aliasScopes =
345 if (failed(aliasScopes))
348 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
352 iface.setAliasScopes(ArrayAttr::get(
353 iface.getContext(), llvm::to_vector_of<Attribute>(*aliasScopes)));
363 FailureOr<SmallVector<AliasScopeAttr>> noAliasScopes =
365 if (failed(noAliasScopes))
368 auto iface = dyn_cast<AliasAnalysisOpInterface>(op);
372 iface.setNoAliasScopes(ArrayAttr::get(
373 iface.getContext(), llvm::to_vector_of<Attribute>(*noAliasScopes)));
380 auto *constant = dyn_cast_if_present<llvm::ConstantAsMetadata>(md);
384 auto *intConstant = dyn_cast<llvm::ConstantInt>(constant->getValue());
388 return intConstant->getValue().getSExtValue();
395 if (!node || node->getNumOperands() != 2)
398 auto *hintMD = dyn_cast<llvm::ValueAsMetadata>(node->getOperand(0).get());
401 TypeAttr hint = TypeAttr::get(moduleImport.
convertType(hintMD->getType()));
403 std::optional<int32_t> optIsSigned =
407 bool isSigned = *optIsSigned != 0;
409 return builder.
getAttr<VecTypeHintAttr>(hint, isSigned);
415 llvm::MDNode *node) {
419 for (
const llvm::MDOperand &op : node->operands()) {
423 vals.push_back(*mdValue);
430 if (!node || node->getNumOperands() != 1)
441 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
449 funcOp.setVecTypeHintAttr(attr);
455 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
463 funcOp.setWorkGroupSizeHintAttr(attr);
469 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
477 funcOp.setReqdWorkGroupSizeAttr(attr);
487 auto funcOp = dyn_cast<LLVM::LLVMFuncOp>(op);
495 funcOp.setIntelReqdSubGroupSizeAttr(attr);
502 const llvm::MDNode *node) {
503 if (node->getNumOperands() == 0)
506 ids.reserve(node->getNumOperands());
507 for (
const llvm::MDOperand &operand : node->operands()) {
508 auto *
id = llvm::mdconst::dyn_extract_or_null<llvm::ConstantInt>(operand);
511 if (!
id || id->getBitWidth() > 64)
513 ids.push_back(
static_cast<int64_t>(id->getZExtValue()));
522 const llvm::MDNode *node,
Operation *op) {
534 const llvm::MDNode *node,
Operation *op) {
535 if (node->getNumOperands() == 0)
538 mibs.reserve(node->getNumOperands());
539 for (
const llvm::MDOperand &mibOperand : node->operands()) {
540 auto *mib = dyn_cast_if_present<llvm::MDNode>(mibOperand);
541 if (!mib || mib->getNumOperands() < 2)
543 auto *stack = dyn_cast_if_present<llvm::MDNode>(mib->getOperand(0));
549 auto *tag = dyn_cast_if_present<llvm::MDString>(mib->getOperand(1));
555 auto *pair = dyn_cast_if_present<llvm::MDNode>(mib->getOperand(
index));
556 if (!pair || pair->getNumOperands() != 2)
558 auto *
id = llvm::mdconst::dyn_extract_or_null<llvm::ConstantInt>(
559 pair->getOperand(0));
560 auto *size = llvm::mdconst::dyn_extract_or_null<llvm::ConstantInt>(
561 pair->getOperand(1));
562 if (!
id || !size || id->getBitWidth() > 64 || size->getBitWidth() > 64)
564 contextSizes.push_back(MemProfContextSizeAttr::get(
565 op->
getContext(), id->getZExtValue(), size->getZExtValue()));
568 mibs.push_back(MemProfMIBAttr::get(op->
getContext(), callStack,
581class LLVMDialectLLVMIRImportInterface :
public LLVMImportDialectInterface {
583 using LLVMImportDialectInterface::LLVMImportDialectInterface;
587 LogicalResult convertIntrinsic(OpBuilder &builder, llvm::CallInst *inst,
588 LLVM::ModuleImport &moduleImport)
const final {
595 LogicalResult setMetadataAttrs(OpBuilder &builder,
unsigned kind,
596 llvm::MDNode *node, Operation *op,
597 LLVM::ModuleImport &moduleImport)
const final {
599 if (kind == llvm::LLVMContext::MD_prof)
601 if (kind == llvm::LLVMContext::MD_tbaa)
603 if (kind == llvm::LLVMContext::MD_access_group)
605 if (kind == llvm::LLVMContext::MD_loop)
607 if (kind == llvm::LLVMContext::MD_alias_scope)
609 if (kind == llvm::LLVMContext::MD_noalias)
611 if (kind == llvm::LLVMContext::MD_dereferenceable)
614 if (kind == llvm::LLVMContext::MD_dereferenceable_or_null)
616 node, llvm::LLVMContext::MD_dereferenceable_or_null, op,
618 if (kind == llvm::LLVMContext::MD_range)
620 if (kind == llvm::LLVMContext::MD_mmra)
622 if (kind == llvm::LLVMContext::MD_memprof)
624 if (kind == llvm::LLVMContext::MD_callsite)
626 if (kind == llvm::LLVMContext::MD_tbaa_struct)
628 llvm::LLVMContext &context = node->getContext();
639 llvm_unreachable(
"unknown metadata type");
644 ArrayRef<unsigned> getSupportedIntrinsics() const final {
650 SmallVector<unsigned>
651 getSupportedMetadata(llvm::LLVMContext &llvmContext)
const final {
658 registry.
insert<LLVM::LLVMDialect>();
660 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 setMemProfAttr(OpBuilder &builder, const llvm::MDNode *node, Operation *op)
Converts !memprof to the llvm.memprof attribute.
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 setCallsiteAttr(OpBuilder &builder, const llvm::MDNode *node, Operation *op)
Converts !callsite to the llvm.callsite attribute.
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 LogicalResult setTBAAStructAttr(const llvm::MDNode *node, Operation *op, LLVM::ModuleImport &moduleImport)
Attaches the tbaa_struct attribute converted from !tbaa.struct by ModuleImport::convertTBAAStructMeta...
static IntegerAttr convertIntegerMD(Builder builder, llvm::MDNode *node)
Convert an MDNode to an MLIR IntegerAttr if possible.
static DenseI64ArrayAttr getCallStackAttr(OpBuilder &builder, const llvm::MDNode *node)
Builds the call-stack hash list of a MemProf callsite node, one int64 per operand.
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 LogicalResult setRangeAttr(const llvm::MDNode *node, Operation *op)
Multi-range metadata is imported as the union of its ranges.
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)
DenseI64ArrayAttr getDenseI64ArrayAttr(ArrayRef< int64_t > values)
StringAttr getStringAttr(const Twine &bytes)
ArrayAttr getArrayAttr(ArrayRef< Attribute > value)
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.
Attribute lookupTBAAStructAttr(const llvm::MDNode *node) const
Looks up a converted !tbaa.struct 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.
void setDiscardableAttr(StringAttr name, Attribute value)
Set a discardable attribute by name.
Location getLoc()
The source location the operation was defined or derived from.
MLIRContext * getContext()
Return the context this operation is associated with.
Include the generated interface declarations.
detail::DenseArrayAttrImpl< int64_t > DenseI64ArrayAttr
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.