[Mlir-commits] [mlir] [MLIR][LLVM] add metadata attrs and `llvm.named_metadata` op (PR #186703)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Sun Mar 15 15:36:16 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir-llvm

Author: Maksim Levental (makslevental)

<details>
<summary>Changes</summary>

This PR adds some LLVM metadata attributes and an `llvm.named_metadata` container op (similar to `llvm.module_flags`) for those attributes.

Note, the added attributes are sufficient for my downstream use case but let me know if there are some others I should cover here (e.g., mapping more than just `ConstantInt` -> `Constant`).

Note, we could also consider refactoring all the existing ops/attributes which really just map to `Metadata` in terms of these but I'd prefer to keep that as a follow-up PR (if that's what in fact decide to do, not saying I'm currently proposing that...).

Note, in order to test the python bindings I had to add a python binding for `mlir::LLVM:FunctionType`.

Summary:

  - Add MLIR attributes modeling LLVM IR metadata: `#llvm.md_string`, `#llvm.md_const`, `#llvm.md_func`, and `#llvm.md_node`;
  - Add `llvm.named_metadata` container op for module-level named metadata nodes;
  - Add MLIR-to-LLVM-IR translation for the new attributes and op;
  - Add C API functions (`mlirLLVMMDStringAttrGet`, `mlirLLVMMDNodeAttrGet`, etc.);
  - Add Python bindings (`llvm.MDStringAttr`, `llvm.MDConstantAttr`, `llvm.MDFuncAttr`, `llvm.MDNodeAttr`, `llvm.FunctionType`).


Note, this PR was "clauded" (not "coded") so let me know if there's something awry that I need to fix the good 'ol fashioned way.

---

Patch is 31.70 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/186703.diff


9 Files Affected:

- (modified) mlir/include/mlir-c/Dialect/LLVM.h (+78) 
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td (+71) 
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td (+40) 
- (modified) mlir/lib/Bindings/Python/DialectLLVM.cpp (+166) 
- (modified) mlir/lib/CAPI/Dialect/LLVM.cpp (+92) 
- (modified) mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp (+49) 
- (modified) mlir/python/mlir/dialects/llvm.py (+14-1) 
- (added) mlir/test/Target/LLVMIR/llvmir-named-metadata.mlir (+49) 
- (modified) mlir/test/python/dialects/llvm.py (+139) 


``````````diff
diff --git a/mlir/include/mlir-c/Dialect/LLVM.h b/mlir/include/mlir-c/Dialect/LLVM.h
index 93602a286c9c4..2c167d23a7d9a 100644
--- a/mlir/include/mlir-c/Dialect/LLVM.h
+++ b/mlir/include/mlir-c/Dialect/LLVM.h
@@ -63,6 +63,12 @@ mlirLLVMFunctionTypeGet(MlirType resultType, intptr_t nArgumentTypes,
 
 MLIR_CAPI_EXPORTED MlirStringRef mlirLLVMFunctionTypeGetName(void);
 
+/// Returns `true` if the type is an LLVM dialect function type.
+MLIR_CAPI_EXPORTED bool mlirTypeIsALLVMFunctionType(MlirType type);
+
+/// Returns the TypeID of an LLVM function type.
+MLIR_CAPI_EXPORTED MlirTypeID mlirLLVMFunctionTypeGetTypeID(void);
+
 /// Returns the number of input types.
 MLIR_CAPI_EXPORTED intptr_t mlirLLVMFunctionTypeGetNumInputs(MlirType type);
 
@@ -70,6 +76,9 @@ MLIR_CAPI_EXPORTED intptr_t mlirLLVMFunctionTypeGetNumInputs(MlirType type);
 MLIR_CAPI_EXPORTED MlirType mlirLLVMFunctionTypeGetInput(MlirType type,
                                                          intptr_t pos);
 
+/// Returns `true` if the function type is variadic.
+MLIR_CAPI_EXPORTED bool mlirLLVMFunctionTypeIsVarArg(MlirType type);
+
 /// Returns the return type of the function type.
 MLIR_CAPI_EXPORTED MlirType mlirLLVMFunctionTypeGetReturnType(MlirType type);
 
@@ -190,6 +199,7 @@ enum MlirLLVMCConv {
   MlirLLVMCConvAMDGPU_Gfx = 100,
   MlirLLVMCConvM68k_INTR = 101,
 };
+
 typedef enum MlirLLVMCConv MlirLLVMCConv;
 
 /// Creates a LLVM CConv attribute.
@@ -205,6 +215,7 @@ enum MlirLLVMComdat {
   MlirLLVMComdatNoDeduplicate = 3,
   MlirLLVMComdatSameSize = 4,
 };
+
 typedef enum MlirLLVMComdat MlirLLVMComdat;
 
 /// Creates a LLVM Comdat attribute.
@@ -226,6 +237,7 @@ enum MlirLLVMLinkage {
   MlirLLVMLinkageExternWeak = 9,
   MlirLLVMLinkageCommon = 10,
 };
+
 typedef enum MlirLLVMLinkage MlirLLVMLinkage;
 
 /// Creates a LLVM Linkage attribute.
@@ -274,6 +286,7 @@ enum MlirLLVMTypeEncoding {
   MlirLLVMTypeEncodingLoUser = 0x80,
   MlirLLVMTypeEncodingHiUser = 0xff,
 };
+
 typedef enum MlirLLVMTypeEncoding MlirLLVMTypeEncoding;
 
 /// Creates a LLVM DIBasicType attribute.
@@ -337,6 +350,7 @@ enum MlirLLVMDIEmissionKind {
   MlirLLVMDIEmissionKindLineTablesOnly = 2,
   MlirLLVMDIEmissionKindDebugDirectivesOnly = 3,
 };
+
 typedef enum MlirLLVMDIEmissionKind MlirLLVMDIEmissionKind;
 
 enum MlirLLVMDINameTableKind {
@@ -345,6 +359,7 @@ enum MlirLLVMDINameTableKind {
   MlirLLVMDINameTableKindNone = 2,
   MlirLLVMDINameTableKindApple = 3,
 };
+
 typedef enum MlirLLVMDINameTableKind MlirLLVMDINameTableKind;
 
 /// Creates a LLVM DICompileUnit attribute.
@@ -456,6 +471,69 @@ MLIR_CAPI_EXPORTED MlirStringRef mlirLLVMDIImportedEntityAttrGetName(void);
 MLIR_CAPI_EXPORTED MlirAttribute
 mlirLLVMDIModuleAttrGetScope(MlirAttribute diModule);
 
+//===----------------------------------------------------------------------===//
+// Metadata Attributes
+//===----------------------------------------------------------------------===//
+
+/// Creates an LLVM MDStringAttr.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMMDStringAttrGet(MlirContext ctx,
+                                                         MlirStringRef value);
+
+/// Returns `true` if the attribute is an LLVM MDStringAttr.
+MLIR_CAPI_EXPORTED bool mlirLLVMAttrIsAMDStringAttr(MlirAttribute attr);
+
+/// Returns the TypeID of MDStringAttr.
+MLIR_CAPI_EXPORTED MlirTypeID mlirLLVMMDStringAttrGetTypeID(void);
+
+/// Returns the string value of an LLVM MDStringAttr.
+MLIR_CAPI_EXPORTED MlirStringRef
+mlirLLVMMDStringAttrGetValue(MlirAttribute attr);
+
+/// Creates an LLVM MDConstantAttr wrapping an attribute.
+MLIR_CAPI_EXPORTED MlirAttribute
+mlirLLVMMDConstantAttrGet(MlirContext ctx, MlirAttribute valueAttr);
+
+/// Returns `true` if the attribute is an LLVM MDConstantAttr.
+MLIR_CAPI_EXPORTED bool mlirLLVMAttrIsAMDConstantAttr(MlirAttribute attr);
+
+/// Returns the TypeID of MDConstantAttr.
+MLIR_CAPI_EXPORTED MlirTypeID mlirLLVMMDConstantAttrGetTypeID(void);
+
+/// Returns the attribute value of an LLVM MDConstantAttr.
+MLIR_CAPI_EXPORTED MlirAttribute
+mlirLLVMMDConstantAttrGetValue(MlirAttribute attr);
+
+/// Creates an LLVM MDFuncAttr referencing a function symbol.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMMDFuncAttrGet(MlirContext ctx,
+                                                       MlirAttribute name);
+
+/// Returns `true` if the attribute is an LLVM MDFuncAttr.
+MLIR_CAPI_EXPORTED bool mlirLLVMAttrIsAMDFuncAttr(MlirAttribute attr);
+
+/// Returns the TypeID of MDFuncAttr.
+MLIR_CAPI_EXPORTED MlirTypeID mlirLLVMMDFuncAttrGetTypeID(void);
+
+/// Returns the symbol name of an LLVM MDFuncAttr.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMMDFuncAttrGetName(MlirAttribute attr);
+
+/// Creates an LLVM MDNodeAttr.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMMDNodeAttrGet(
+    MlirContext ctx, intptr_t nOperands, MlirAttribute const *operands);
+
+/// Returns `true` if the attribute is an LLVM MDNodeAttr.
+MLIR_CAPI_EXPORTED bool mlirLLVMAttrIsAMDNodeAttr(MlirAttribute attr);
+
+/// Returns the TypeID of MDNodeAttr.
+MLIR_CAPI_EXPORTED MlirTypeID mlirLLVMMDNodeAttrGetTypeID(void);
+
+/// Returns the number of operands in an LLVM MDNodeAttr.
+MLIR_CAPI_EXPORTED intptr_t
+mlirLLVMMDNodeAttrGetNumOperands(MlirAttribute attr);
+
+/// Returns the operand at the given index of an LLVM MDNodeAttr.
+MLIR_CAPI_EXPORTED MlirAttribute
+mlirLLVMMDNodeAttrGetOperand(MlirAttribute attr, intptr_t index);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 36acf244865eb..077c5c880cc9b 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -1686,4 +1686,75 @@ def UWTableKindAttr : LLVM_Attr<"UWTableKind", "uwtableKind"> {
   let assemblyFormat = "`<` $uwtableKind `>`";
 }
 
+//===----------------------------------------------------------------------===//
+// Metadata Attributes
+//===----------------------------------------------------------------------===//
+//
+// These attributes model LLVM IR metadata nodes (llvm::Metadata and its
+// subclasses). They can be nested to form arbitrary metadata trees and are
+// translated to their LLVM IR counterparts during MLIR-to-LLVM-IR conversion.
+
+def LLVM_MDStringAttr : LLVM_Attr<"MDString", "md_string"> {
+  let summary = "LLVM metadata string";
+  let description = [{
+    Wraps a string as an LLVM metadata node, corresponding to
+    `llvm::MDString` in LLVM IR.
+
+    Example:
+    ```mlir
+    #llvm.md_string<"foo.buffer">
+    ```
+  }];
+  let parameters = (ins "StringAttr":$value);
+  let assemblyFormat = "`<` $value `>`";
+}
+
+def LLVM_MDConstantAttr : LLVM_Attr<"MDConstant", "md_const"> {
+  let summary = "LLVM constant-as-metadata";
+  let description = [{
+    Wraps an attribute as an LLVM metadata node, corresponding to
+    `llvm::ConstantAsMetadata` wrapping a `llvm::Constant*` in LLVM IR.
+    Currently, only integers/IntegerAttrs supported.
+
+    Example:
+    ```mlir
+    #llvm.md_const<42 : i32>
+    ```
+  }];
+  let parameters = (ins "Attribute":$value);
+  let assemblyFormat = "`<` $value `>`";
+}
+
+def LLVM_MDFuncAttr : LLVM_Attr<"MDFunc", "md_func"> {
+  let summary = "LLVM function-as-metadata";
+  let description = [{
+    References a function (or global) symbol as LLVM metadata, corresponding
+    to `llvm::ValueAsMetadata::get(function)` in LLVM IR.
+
+    Example:
+    ```mlir
+    #llvm.md_func<@my_kernel>
+    ```
+  }];
+  let parameters = (ins "FlatSymbolRefAttr":$name);
+  let assemblyFormat = "`<` $name `>`";
+}
+
+def LLVM_MDNodeAttr : LLVM_Attr<"MDNode", "md_node"> {
+  let summary = "LLVM metadata node";
+  let description = [{
+    Represents an LLVM metadata node. The operands
+    can be any combination of metadata attributes: `#llvm.md_string`,
+    `#llvm.md_const`, `#llvm.md_func`, or nested `#llvm.md_node`.
+
+    Example:
+    ```mlir
+    #llvm.md_node<[#llvm.md_const<0 : i32>, #llvm.md_string<"foo.buffer">]>
+    #llvm.md_node<[]>
+    ```
+  }];
+  let parameters = (ins "ArrayAttr":$operands);
+  let assemblyFormat = "`<` $operands `>`";
+}
+
 #endif // LLVMIR_ATTRDEFS
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index e781d4c876315..097c41ee4668f 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -2576,4 +2576,44 @@ def LLVM_ModuleFlagsOp
   let hasVerifier = 1;
 }
 
+//===--------------------------------------------------------------------===//
+// NamedMetadataOp
+//===--------------------------------------------------------------------===//
+
+def LLVM_NamedMetadataOp
+    : LLVM_Op<"named_metadata"> {
+  let summary = "Module-level named metadata";
+  let description = [{
+    Represents an LLVM named metadata node (`llvm::NamedMDNode`). Named
+    metadata nodes are module-level metadata that associate a name string
+    with a list of metadata nodes. Each operand must be an `#llvm.md_node`.
+
+    Example:
+    ```mlir
+    llvm.named_metadata "foo.version" [
+      #llvm.md_node<[#llvm.md_const<2 : i32>, #llvm.md_const<9 : i32>,
+                      #llvm.md_const<0 : i32>]>
+    ]
+    llvm.named_metadata "foo.kernel" [
+      #llvm.md_node<[
+        #llvm.md_func<@my_kernel>,
+        #llvm.md_node<[]>,
+        #llvm.md_node<[
+          #llvm.md_node<[#llvm.md_const<0 : i32>,
+                          #llvm.md_string<"foo.buffer">]>
+        ]>
+      ]>
+    ]
+    ```
+  }];
+  let arguments = (ins StrAttr:$metadata_name, ArrayAttr:$nodes);
+  let assemblyFormat = [{
+    $metadata_name $nodes attr-dict
+  }];
+
+  let llvmBuilder = [{
+    convertNamedMetadataOp($metadata_name, $nodes, builder, moduleTranslation);
+  }];
+}
+
 #endif // LLVMIR_OPS
diff --git a/mlir/lib/Bindings/Python/DialectLLVM.cpp b/mlir/lib/Bindings/Python/DialectLLVM.cpp
index 5c79f515c49eb..7e4f24b556613 100644
--- a/mlir/lib/Bindings/Python/DialectLLVM.cpp
+++ b/mlir/lib/Bindings/Python/DialectLLVM.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include <string>
+#include <vector>
 
 #include "mlir-c/Dialect/LLVM.h"
 #include "mlir-c/IR.h"
@@ -222,10 +223,175 @@ struct PointerType : PyConcreteType<PointerType> {
   }
 };
 
+//===--------------------------------------------------------------------===//
+// FunctionType
+//===--------------------------------------------------------------------===//
+
+struct FunctionType : PyConcreteType<FunctionType> {
+  static constexpr IsAFunctionTy isaFunction = mlirTypeIsALLVMFunctionType;
+  static constexpr GetTypeIDFunctionTy getTypeIdFunction =
+      mlirLLVMFunctionTypeGetTypeID;
+  static constexpr const char *pyClassName = "FunctionType";
+  static inline const MlirStringRef name = mlirLLVMFunctionTypeGetName();
+  using Base::Base;
+
+  static void bindDerived(ClassTy &c) {
+    c.def_static(
+        "get",
+        [](PyType &resultType, const std::vector<PyType> &argumentTypes,
+           bool isVarArg) {
+          std::vector<MlirType> argTypes(argumentTypes.size());
+          std::copy(argumentTypes.begin(), argumentTypes.end(),
+                    argTypes.begin());
+          return FunctionType(
+              resultType.getContext(),
+              mlirLLVMFunctionTypeGet(resultType, argTypes.size(),
+                                      argTypes.data(), isVarArg));
+        },
+        "result_type"_a, "argument_types"_a, nb::kw_only(),
+        "is_var_arg"_a = false);
+    c.def_prop_ro("return_type", [](const FunctionType &type) {
+      return mlirLLVMFunctionTypeGetReturnType(type);
+    });
+    c.def_prop_ro("num_inputs", [](const FunctionType &type) {
+      return mlirLLVMFunctionTypeGetNumInputs(type);
+    });
+    c.def_prop_ro("inputs", [](const FunctionType &type) {
+      nb::list inputs;
+      for (intptr_t i = 0, e = mlirLLVMFunctionTypeGetNumInputs(type); i < e;
+           ++i) {
+        inputs.append(mlirLLVMFunctionTypeGetInput(type, i));
+      }
+      return inputs;
+    });
+    c.def_prop_ro("is_var_arg", [](const FunctionType &type) {
+      return mlirLLVMFunctionTypeIsVarArg(type);
+    });
+  }
+};
+
+//===--------------------------------------------------------------------===//
+// Metadata Attributes
+//===--------------------------------------------------------------------===//
+
+struct MDStringAttr : PyConcreteAttribute<MDStringAttr> {
+  static constexpr IsAFunctionTy isaFunction = mlirLLVMAttrIsAMDStringAttr;
+  static constexpr GetTypeIDFunctionTy getTypeIdFunction =
+      mlirLLVMMDStringAttrGetTypeID;
+  static constexpr const char *pyClassName = "MDStringAttr";
+  using Base::Base;
+
+  static void bindDerived(ClassTy &c) {
+    c.def_static(
+        "get",
+        [](const std::string &value, DefaultingPyMlirContext context) {
+          return MDStringAttr(
+              context->getRef(),
+              mlirLLVMMDStringAttrGet(
+                  context.get()->get(),
+                  mlirStringRefCreate(value.data(), value.size())));
+        },
+        "value"_a, nb::kw_only(), "context"_a = nb::none());
+    c.def_prop_ro("value", [](const MDStringAttr &self) {
+      MlirStringRef ref = mlirLLVMMDStringAttrGetValue(self);
+      return nb::str(ref.data, ref.length);
+    });
+  }
+};
+
+struct MDConstantAttr : PyConcreteAttribute<MDConstantAttr> {
+  static constexpr IsAFunctionTy isaFunction = mlirLLVMAttrIsAMDConstantAttr;
+  static constexpr GetTypeIDFunctionTy getTypeIdFunction =
+      mlirLLVMMDConstantAttrGetTypeID;
+  static constexpr const char *pyClassName = "MDConstantAttr";
+  using Base::Base;
+
+  static void bindDerived(ClassTy &c) {
+    c.def_static(
+        "get",
+        [](PyAttribute &valueAttr, DefaultingPyMlirContext context) {
+          return MDConstantAttr(
+              context->getRef(),
+              mlirLLVMMDConstantAttrGet(context.get()->get(), valueAttr));
+        },
+        "value"_a, nb::kw_only(), "context"_a = nb::none());
+    c.def_prop_ro("value", [](const MDConstantAttr &self) {
+      return mlirLLVMMDConstantAttrGetValue(self);
+    });
+  }
+};
+
+struct MDFuncAttr : PyConcreteAttribute<MDFuncAttr> {
+  static constexpr IsAFunctionTy isaFunction = mlirLLVMAttrIsAMDFuncAttr;
+  static constexpr GetTypeIDFunctionTy getTypeIdFunction =
+      mlirLLVMMDFuncAttrGetTypeID;
+  static constexpr const char *pyClassName = "MDFuncAttr";
+  using Base::Base;
+
+  static void bindDerived(ClassTy &c) {
+    c.def_static(
+        "get",
+        [](const std::string &name, DefaultingPyMlirContext context) {
+          MlirAttribute symRef = mlirFlatSymbolRefAttrGet(
+              context.get()->get(),
+              mlirStringRefCreate(name.data(), name.size()));
+          return MDFuncAttr(
+              context->getRef(),
+              mlirLLVMMDFuncAttrGet(context.get()->get(), symRef));
+        },
+        "name"_a, nb::kw_only(), "context"_a = nb::none());
+    c.def_prop_ro("name", [](const MDFuncAttr &self) {
+      MlirAttribute symRef = mlirLLVMMDFuncAttrGetName(self);
+      MlirStringRef ref = mlirFlatSymbolRefAttrGetValue(symRef);
+      return nb::str(ref.data, ref.length);
+    });
+  }
+};
+
+struct MDNodeAttr : PyConcreteAttribute<MDNodeAttr> {
+  static constexpr IsAFunctionTy isaFunction = mlirLLVMAttrIsAMDNodeAttr;
+  static constexpr GetTypeIDFunctionTy getTypeIdFunction =
+      mlirLLVMMDNodeAttrGetTypeID;
+  static constexpr const char *pyClassName = "MDNodeAttr";
+  using Base::Base;
+
+  static void bindDerived(ClassTy &c) {
+    c.def_static(
+        "get",
+        [](const std::vector<PyAttribute> &operands,
+           DefaultingPyMlirContext context) {
+          std::vector<MlirAttribute> operands_(operands.size());
+          std::copy(operands.begin(), operands.end(), operands_.begin());
+          return MDNodeAttr(context->getRef(),
+                            mlirLLVMMDNodeAttrGet(context.get()->get(),
+                                                  operands_.size(),
+                                                  operands_.data()));
+        },
+        "operands"_a, nb::kw_only(), "context"_a = nb::none());
+    c.def_prop_ro("num_operands", [](const MDNodeAttr &self) {
+      return mlirLLVMMDNodeAttrGetNumOperands(self);
+    });
+    c.def("__getitem__", [](const MDNodeAttr &self, intptr_t index) {
+      intptr_t n = mlirLLVMMDNodeAttrGetNumOperands(self);
+      if (index < 0 || index >= n)
+        throw nb::index_error("MDNodeAttr operand index out of range");
+      return mlirLLVMMDNodeAttrGetOperand(self, index);
+    });
+    c.def("__len__", [](const MDNodeAttr &self) {
+      return mlirLLVMMDNodeAttrGetNumOperands(self);
+    });
+  }
+};
+
 static void populateDialectLLVMSubmodule(nanobind::module_ &m) {
   StructType::bind(m);
   ArrayType::bind(m);
   PointerType::bind(m);
+  FunctionType::bind(m);
+  MDStringAttr::bind(m);
+  MDConstantAttr::bind(m);
+  MDFuncAttr::bind(m);
+  MDNodeAttr::bind(m);
 
   m.def(
       "translate_module_to_llvmir",
diff --git a/mlir/lib/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp
index eb30f169e4289..0b85acaed4727 100644
--- a/mlir/lib/CAPI/Dialect/LLVM.cpp
+++ b/mlir/lib/CAPI/Dialect/LLVM.cpp
@@ -85,6 +85,14 @@ MlirStringRef mlirLLVMFunctionTypeGetName(void) {
   return wrap(LLVMFunctionType::name);
 }
 
+bool mlirTypeIsALLVMFunctionType(MlirType type) {
+  return isa<LLVM::LLVMFunctionType>(unwrap(type));
+}
+
+MlirTypeID mlirLLVMFunctionTypeGetTypeID(void) {
+  return wrap(LLVM::LLVMFunctionType::getTypeID());
+}
+
 intptr_t mlirLLVMFunctionTypeGetNumInputs(MlirType type) {
   return llvm::cast<LLVM::LLVMFunctionType>(unwrap(type)).getNumParams();
 }
@@ -99,6 +107,10 @@ MlirType mlirLLVMFunctionTypeGetReturnType(MlirType type) {
   return wrap(llvm::cast<LLVM::LLVMFunctionType>(unwrap(type)).getReturnType());
 }
 
+bool mlirLLVMFunctionTypeIsVarArg(MlirType type) {
+  return llvm::cast<LLVM::LLVMFunctionType>(unwrap(type)).isVarArg();
+}
+
 bool mlirTypeIsALLVMStructType(MlirType type) {
   return isa<LLVM::LLVMStructType>(unwrap(type));
 }
@@ -523,3 +535,83 @@ MlirAttribute mlirLLVMDIAnnotationAttrGet(MlirContext ctx, MlirAttribute name,
 MlirStringRef mlirLLVMDIAnnotationAttrGetName(void) {
   return wrap(DIAnnotationAttr::name);
 }
+
+//===----------------------------------------------------------------------===//
+// Metadata Attributes
+//===----------------------------------------------------------------------===//
+
+MlirAttribute mlirLLVMMDStringAttrGet(MlirContext ctx, MlirStringRef value) {
+  return wrap(MDStringAttr::get(unwrap(ctx),
+                                StringAttr::get(unwrap(ctx), unwrap(value))));
+}
+
+bool mlirLLVMAttrIsAMDStringAttr(MlirAttribute attr) {
+  return isa<MDStringAttr>(unwrap(attr));
+}
+
+MlirTypeID mlirLLVMMDStringAttrGetTypeID(void) {
+  return wrap(MDStringAttr::getTypeID());
+}
+
+MlirStringRef mlirLLVMMDStringAttrGetValue(MlirAttribute attr) {
+  return wrap(cast<MDStringAttr>(unwrap(attr)).getValue().getValue());
+}
+
+MlirAttribute mlirLLVMMDConstantAttrGet(MlirContext ctx,
+                                        MlirAttribute valueAttr) {
+  return wrap(MDConstantAttr::get(unwrap(ctx), unwrap(valueAttr)));
+}
+
+bool mlirLLVMAttrIsAMDConstantAttr(MlirAttribute attr) {
+  return isa<MDConstantAttr>(unwrap(attr));
+}
+
+MlirTypeID mlirLLVMMDConstantAttrGetTypeID(void) {
+  return wrap(MDConstantAttr::getTypeID());
+}
+
+MlirAttribute mlirLLVMMDConstantAttrGetValue(MlirAttribute attr) {
+  return wrap((Attribute)cast<MDConstantAttr>(unwrap(attr)).getValue());
+}
+
+MlirAttribute mlirLLVMMDFuncAttrGet(MlirContext ctx, MlirAttribute name) {
+  return wrap(
+      MDFuncAttr::get(unwrap(ctx), cast<FlatSymbolRefAttr>(unwrap(name))));
+}
+
+bool mlirLLVMAttrIsAMDFuncAttr(MlirAttribute attr) {
+  return isa<MDFuncAttr>(unwrap(attr));
+}
+
+MlirTypeID mlirLLVMMDFuncAttrGetTypeID(void) {
+  return wrap(MDFuncAttr::getTypeID());
+}
+
+MlirAttribute mlirLLVMMDFuncAttrGetName(MlirAttribute attr) {
+  return wrap((Attribute)cast<MDFuncAttr>(unwrap(attr)).getName());
+}
+
+MlirAttribute mlirLLVMMDNodeAttrGet(MlirContext ctx, intptr_t nOperands,
+                                    MlirAttribute const *operands) {
+  SmallVector<Attribute> attrStorage;
+  attrStorage.reserve(nOperands);
+  return wrap(MDNodeAttr::get(
+      unwrap(ctx), ArrayAttr::get(unwrap(...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/186703


More information about the Mlir-commits mailing list