Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MLIR] Add llvm (debug) attributes to CAPI #83992

Merged
merged 1 commit into from
Mar 7, 2024

Conversation

edg-l
Copy link
Contributor

@edg-l edg-l commented Mar 5, 2024

This PR adds the following to the mlir c api:

  • The disctinct mlir builtin attribute.
  • LLVM attributes (mostly debug related ones)

@llvmbot
Copy link
Collaborator

llvmbot commented Mar 5, 2024

@llvm/pr-subscribers-llvm-ir
@llvm/pr-subscribers-debuginfo
@llvm/pr-subscribers-mlir

@llvm/pr-subscribers-mlir-llvm

Author: Edgar (edg-l)

Changes

This PR adds the following to the mlir c api:

  • The disctinct mlir builtin attribute.
  • LLVM attributes (mostly debug related ones)

While i almost have this working, there is an issue i encountered and have no idea how to solve, when trying to create attributes which need a list of attributes, such as DINodeAttr or DITypeAttr, i get a compilation error when unwrapping the list:

<details><summary>The error example</summary>

❯ ninja
[1/4] Building CXX object tools/mlir/lib/CAPI/Dialect/CMakeFiles/obj.MLIRCAPILLVM.dir/LLVM.cpp.o
FAILED: tools/mlir/lib/CAPI/Dialect/CMakeFiles/obj.MLIRCAPILLVM.dir/LLVM.cpp.o 
CCACHE_CPP2=yes CCACHE_HASHDIR=yes /usr/bin/ccache ccache /usr/lib/ccache/bin/clang++ -DGTEST_HAS_RTTI=0 -DMLIR_CAPI_BUILDING_LIBRARY=1 -DMLIR_ROCM_CONVERSIONS_ENABLED=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/data2/edgar/llvm-project/build/tools/mlir/lib/CAPI/Dialect -I/data2/edgar/llvm-project/mlir/lib/CAPI/Dialect -I/data2/edgar/llvm-project/build/include -I/data2/edgar/llvm-project/llvm/include -I/data2/edgar/llvm-project/mlir/include -I/data2/edgar/llvm-project/build/tools/mlir/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fno-omit-frame-pointer -O1 -fsanitize=address -fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all -fsanitize-blacklist=/data2/edgar/llvm-project/llvm/utils/sanitizers/ubsan_ignorelist.txt -fdiagnostics-color -Werror=mismatched-tags -g -std=c++17 -fvisibility=hidden  -fno-exceptions -funwind-tables -fno-rtti -gsplit-dwarf -MD -MT tools/mlir/lib/CAPI/Dialect/CMakeFiles/obj.MLIRCAPILLVM.dir/LLVM.cpp.o -MF tools/mlir/lib/CAPI/Dialect/CMakeFiles/obj.MLIRCAPILLVM.dir/LLVM.cpp.o.d -o tools/mlir/lib/CAPI/Dialect/CMakeFiles/obj.MLIRCAPILLVM.dir/LLVM.cpp.o -c /data2/edgar/llvm-project/mlir/lib/CAPI/Dialect/LLVM.cpp
In file included from /data2/edgar/llvm-project/mlir/lib/CAPI/Dialect/LLVM.cpp:12:
In file included from /data2/edgar/llvm-project/mlir/include/mlir/CAPI/Registration.h:13:
In file included from /data2/edgar/llvm-project/mlir/include/mlir/CAPI/IR.h:19:
/data2/edgar/llvm-project/mlir/include/mlir/CAPI/Wrap.h:43:7: error: static assertion failed due to requirement 'std::is_same&lt;mlir::Attribute, mlir::LLVM::DITypeAttr&gt;::value': incompatible C and C++ types
   43 |       std::is_same&lt;decltype(unwrap(std::declval&lt;CTy&gt;())), CppTy&gt;::value,
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/data2/edgar/llvm-project/mlir/lib/CAPI/Dialect/LLVM.cpp:241:37: note: in instantiation of function template specialization 'unwrapList&lt;mlir::LLVM::DITypeAttr, const MlirAttribute&gt;' requested here
  241 |   mlir::ArrayRef&lt;DITypeAttr&gt; list = unwrapList(nTypes, types, elementsStorage);
      |                                     ^
In file included from /data2/edgar/llvm-project/mlir/lib/CAPI/Dialect/LLVM.cpp:12:
In file included from /data2/edgar/llvm-project/mlir/include/mlir/CAPI/Registration.h:13:
In file included from /data2/edgar/llvm-project/mlir/include/mlir/CAPI/IR.h:19:
/data2/edgar/llvm-project/mlir/include/mlir/CAPI/Wrap.h:52:23: error: no viable conversion from 'mlir::Attribute' to 'ValueParamT' (aka 'mlir::LLVM::DITypeAttr')
   52 |     storage.push_back(unwrap(*(first + i)));
      |                       ^~~~~~~~~~~~~~~~~~~~
/data2/edgar/llvm-project/mlir/include/mlir/IR/Attributes.h:38:18: note: candidate inherited constructor not viable: no known conversion from 'mlir::Attribute' to 'const ImplType *' (aka 'const mlir::AttributeStorage *') for 1st argument
   38 |   /* implicit */ Attribute(const ImplType *impl)
      |                  ^         ~~~~~~~~~~~~~~~~~~~~
/data2/edgar/llvm-project/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h:57:21: note: constructor from base class 'DINodeAttr' inherited here
   57 |   using DINodeAttr::DINodeAttr;
      |                     ^
/data2/edgar/llvm-project/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h:55:7: note: candidate constructor (the implicit copy constructor) not viable: cannot bind base class object of type 'mlir::Attribute' to derived class reference 'const DITypeAttr &amp;' for 1st argument
   55 | class DITypeAttr : public DINodeAttr {
      |       ^~~~~~~~~~
/data2/edgar/llvm-project/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h:55:7: note: candidate constructor (the implicit move constructor) not viable: cannot bind base class object of type 'mlir::Attribute' to derived class reference 'DITypeAttr &amp;&amp;' for 1st argument
   55 | class DITypeAttr : public DINodeAttr {
      |       ^~~~~~~~~~
/data2/edgar/llvm-project/llvm/include/llvm/ADT/SmallVector.h:574:30: note: passing argument to parameter 'Elt' here
  574 |   void push_back(ValueParamT Elt) {
      |                              ^
2 errors generated.
ninja: build stopped: subcommand failed.

</details>


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

6 Files Affected:

  • (modified) mlir/include/mlir-c/BuiltinAttributes.h (+3)
  • (modified) mlir/include/mlir-c/Dialect/LLVM.h (+95)
  • (modified) mlir/lib/CAPI/Dialect/LLVM.cpp (+162)
  • (modified) mlir/lib/CAPI/IR/BuiltinAttributes.cpp (+4)
  • (modified) mlir/test/CAPI/ir.c (+4)
  • (modified) mlir/test/CAPI/llvm.c (+102-1)
diff --git a/mlir/include/mlir-c/BuiltinAttributes.h b/mlir/include/mlir-c/BuiltinAttributes.h
index 01d1b6008f5e21..6c323f0b2c1033 100644
--- a/mlir/include/mlir-c/BuiltinAttributes.h
+++ b/mlir/include/mlir-c/BuiltinAttributes.h
@@ -266,6 +266,9 @@ mlirSymbolRefAttrGetNestedReference(MlirAttribute attr, intptr_t pos);
 /// Returns the typeID of an SymbolRef attribute.
 MLIR_CAPI_EXPORTED MlirTypeID mlirSymbolRefAttrGetTypeID(void);
 
+/// Creates a DisctinctAttr with the referenced attribute.
+MLIR_CAPI_EXPORTED MlirAttribute mlirDisctinctAttrCreate(MlirAttribute referencedAttr);
+
 //===----------------------------------------------------------------------===//
 // Flat SymbolRef attribute.
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir-c/Dialect/LLVM.h b/mlir/include/mlir-c/Dialect/LLVM.h
index ac216b01f364d4..be1eac07af774d 100644
--- a/mlir/include/mlir-c/Dialect/LLVM.h
+++ b/mlir/include/mlir-c/Dialect/LLVM.h
@@ -18,6 +18,8 @@ extern "C" {
 
 MLIR_DECLARE_CAPI_DIALECT_REGISTRATION(LLVM, llvm);
 
+#undef DEFINE_C_API_STRUCT
+
 /// Creates an llvm.ptr type.
 MLIR_CAPI_EXPORTED MlirType mlirLLVMPointerTypeGet(MlirContext ctx,
                                                    unsigned addressSpace);
@@ -98,6 +100,99 @@ MLIR_CAPI_EXPORTED MlirLogicalResult
 mlirLLVMStructTypeSetBody(MlirType structType, intptr_t nFieldTypes,
                           MlirType const *fieldTypes, bool isPacked);
 
+/// Creates a LLVM CConv attribute.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMCConvAttrGet(MlirContext ctx,
+                                                      uint64_t cconv);
+
+/// Creates a LLVM Comdat attribute.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMComdatAttrGet(MlirContext ctx,
+                                                       uint64_t comdat);
+
+/// Creates a LLVM Linkage attribute.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMLinkageAttrGet(MlirContext ctx,
+                                                        uint64_t linkage);
+
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDINullTypeAttrGet(MlirContext ctx);
+
+/// Creates a LLVM DIExpression attribute.
+/*
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDIExpressionAttrGet(
+    MlirContext ctx, intptr_t nOperations, MlirAttribute const *operations);
+*/
+
+/// Creates a LLVM DIBasicType attribute.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDIBasicTypeAttrGet(
+    MlirContext ctx, unsigned int tag, MlirAttribute name, uint64_t sizeInBits,
+    unsigned int encoding);
+
+/// Creates a LLVM DICompositeType attribute.
+/* fails to compile with: error: no viable conversion from 'mlir::Attribute' to 'ValueParamT' (aka 'mlir::LLVM::DINodeAttr')
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDICompositeTypeAttrGet(
+    MlirContext ctx, unsigned int tag, MlirAttribute name, MlirAttribute file,
+    uint32_t line, MlirAttribute scope, MlirAttribute baseType, int64_t flags,
+    uint64_t sizeInBits, uint64_t alignInBits, intptr_t nElements,
+    MlirAttribute const *elements);
+*/
+
+
+/// Creates a LLVM DIDerivedType attribute.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDIDerivedTypeAttrGet(
+    MlirContext ctx, unsigned int tag, MlirAttribute name,
+    MlirAttribute baseType, uint64_t sizeInBits, uint32_t alignInBits,
+    uint64_t offsetInBits);
+
+/// Creates a LLVM DIFileAttr attribute.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDIFileAttrGet(MlirContext ctx,
+                                                       MlirAttribute name,
+                                                       MlirAttribute directory);
+
+/// Creates a LLVM DICompileUnit attribute.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDICompileUnitAttrGet(
+    MlirContext ctx, MlirAttribute id, unsigned int sourceLanguage,
+    MlirAttribute file, MlirAttribute producer, bool isOptimized,
+    uint64_t emissionKind);
+
+/// Creates a LLVM DIFlags attribute.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDIFlagsAttrGet(MlirContext ctx,
+                                                        uint64_t value);
+
+/// Creates a LLVM DILexicalBlock attribute.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDILexicalBlockAttrGet(
+    MlirContext ctx, MlirAttribute scope, MlirAttribute file, unsigned int line,
+    unsigned int column);
+
+/// Creates a LLVM DILexicalBlockFile attribute.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDILexicalBlockFileAttrGet(
+    MlirContext ctx, MlirAttribute scope, MlirAttribute file,
+    unsigned int discriminator);
+
+/// Creates a LLVM DILocalVariableAttr attribute.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDILocalVariableAttrGet(
+    MlirContext ctx, MlirAttribute scope, MlirAttribute name,
+    MlirAttribute diFile, unsigned int line, unsigned int arg,
+    unsigned int alignInBits, MlirAttribute diType);
+
+/// Creates a LLVM DISubprogramAttr attribute.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDISubprogramAttrGet(
+    MlirContext ctx, MlirAttribute id, MlirAttribute compileUnit,
+    MlirAttribute scope, MlirAttribute name, MlirAttribute linkageName,
+    MlirAttribute file, unsigned int line, unsigned int scopeLine,
+    uint64_t subprogramFlags, MlirAttribute type);
+
+/// Creates a LLVM DISubroutineTypeAttr attribute.
+/* fails to compile with error: no viable conversion from 'mlir::Attribute' to 'ValueParamT' (aka 'mlir::LLVM::DITypeAttr')
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDISubroutineTypeAttrGet(MlirContext ctx,
+                                              unsigned int callingConvention,
+                                              intptr_t nTypes,
+                                              MlirAttribute const *types);
+*/
+
+/// Creates a LLVM DIModuleAttr attribute.
+MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDIModuleAttrGet(
+    MlirContext ctx, MlirAttribute file, MlirAttribute scope,
+    MlirAttribute name, MlirAttribute configMacros, MlirAttribute includePath,
+    MlirAttribute apinotes, unsigned int line, bool isDecl);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/mlir/lib/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp
index 642018a814ca12..7385f18c867c48 100644
--- a/mlir/lib/CAPI/Dialect/LLVM.cpp
+++ b/mlir/lib/CAPI/Dialect/LLVM.cpp
@@ -7,9 +7,17 @@
 //===----------------------------------------------------------------------===//
 
 #include "mlir-c/Dialect/LLVM.h"
+#include "mlir-c/IR.h"
+#include "mlir-c/Support.h"
 #include "mlir/CAPI/Registration.h"
+#include "mlir/CAPI/Wrap.h"
+#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.h.inc"
 #include "mlir/Dialect/LLVMIR/LLVMTypes.h"
+#include "mlir/IR/Attributes.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include <stdint.h>
 
 using namespace mlir;
 using namespace mlir::LLVM;
@@ -110,3 +118,157 @@ MlirLogicalResult mlirLLVMStructTypeSetBody(MlirType structType,
       cast<LLVM::LLVMStructType>(unwrap(structType))
           .setBody(unwrapList(nFieldTypes, fieldTypes, fields), isPacked));
 }
+
+/* fails to compile with: error: no viable conversion from 'mlir::Attribute' to
+'ValueParamT' (aka 'mlir::LLVM::DIExpressionElemAttr') MlirAttribute
+mlirLLVMDIExpressionAttrGet(MlirContext ctx, intptr_t nOperations, MlirAttribute
+const *operations) { SmallVector<DIExpressionElemAttr, 2> valueStorage; return
+wrap(DIExpressionAttr::get( unwrap(ctx), unwrapList(nOperations, operations,
+valueStorage)));
+}
+*/
+
+MlirAttribute mlirLLVMDINullTypeAttrGet(MlirContext ctx) {
+  return wrap(DINullTypeAttr::get(unwrap(ctx)));
+}
+
+MlirAttribute mlirLLVMDIBasicTypeAttrGet(MlirContext ctx, unsigned int tag,
+                                         MlirAttribute name,
+                                         uint64_t sizeInBits,
+                                         unsigned int encoding) {
+  return wrap(DIBasicTypeAttr::get(
+      unwrap(ctx), tag, cast<StringAttr>(unwrap(name)), sizeInBits, encoding));
+}
+
+/* fails to compile with: error: no viable conversion from 'mlir::Attribute' to
+'ValueParamT' (aka 'mlir::LLVM::DINodeAttr') MlirAttribute
+mlirLLVMDICompositeTypeAttrGet( MlirContext ctx, unsigned int tag, MlirAttribute
+name, MlirAttribute file, uint32_t line, MlirAttribute scope, MlirAttribute
+baseType, int64_t flags, uint64_t sizeInBits, uint64_t alignInBits, intptr_t
+nElements, MlirAttribute const *elements) {
+  SmallVector<DINodeAttr, 2>
+elementsStorage; elementsStorage.reserve(nElements); mlir::ArrayRef<DINodeAttr>
+list = unwrapList(nElements, elements, elementsStorage); return
+wrap(DICompositeTypeAttr::get( unwrap(ctx), tag, cast<StringAttr>(unwrap(name)),
+      cast<DIFileAttr>(unwrap(file)), line, cast<DIScopeAttr>(unwrap(scope)),
+      cast<DITypeAttr>(unwrap(baseType)), DIFlags(flags), sizeInBits,
+      alignInBits, list));
+}
+*/
+
+MlirAttribute mlirLLVMDIDerivedTypeAttrGet(MlirContext ctx, unsigned int tag,
+                                           MlirAttribute name,
+                                           MlirAttribute baseType,
+                                           uint64_t sizeInBits,
+                                           uint32_t alignInBits,
+                                           uint64_t offsetInBits) {
+  return wrap(DIDerivedTypeAttr::get(unwrap(ctx), tag,
+                                     cast<StringAttr>(unwrap(name)),
+                                     cast<DITypeAttr>(unwrap(baseType)),
+                                     sizeInBits, alignInBits, offsetInBits));
+}
+
+MlirAttribute mlirLLVMCConvAttrGet(MlirContext ctx, uint64_t cconv) {
+  return wrap(CConvAttr::get(unwrap(ctx), CConv(cconv)));
+}
+
+MlirAttribute mlirLLVMComdatAttrGet(MlirContext ctx, uint64_t comdat) {
+  return wrap(ComdatAttr::get(unwrap(ctx), comdat::Comdat(comdat)));
+}
+
+MlirAttribute mlirLLVMLinkageAttrGet(MlirContext ctx, uint64_t linkage) {
+  return wrap(LinkageAttr::get(unwrap(ctx), linkage::Linkage(linkage)));
+}
+
+MlirAttribute mlirLLVMDIFileAttrGet(MlirContext ctx, MlirAttribute name,
+                                    MlirAttribute directory) {
+  return wrap(DIFileAttr::get(unwrap(ctx), cast<StringAttr>(unwrap(name)),
+                              cast<StringAttr>(unwrap(directory))));
+}
+
+MlirAttribute mlirLLVMDICompileUnitAttrGet(MlirContext ctx, MlirAttribute id,
+                                           unsigned int sourceLanguage,
+                                           MlirAttribute file,
+                                           MlirAttribute producer,
+                                           bool isOptimized,
+                                           uint64_t emissionKind) {
+  return wrap(DICompileUnitAttr::get(
+      unwrap(ctx), cast<DistinctAttr>(unwrap(id)), sourceLanguage,
+      cast<DIFileAttr>(unwrap(file)), cast<StringAttr>(unwrap(producer)),
+      isOptimized, DIEmissionKind(emissionKind)));
+}
+
+MlirAttribute mlirLLVMDIFlagsAttrGet(MlirContext ctx, uint64_t value) {
+  return wrap(DIFlagsAttr::get(unwrap(ctx), DIFlags(value)));
+}
+
+MlirAttribute mlirLLVMDILexicalBlockAttrGet(MlirContext ctx,
+                                            MlirAttribute scope,
+                                            MlirAttribute file,
+                                            unsigned int line,
+                                            unsigned int column) {
+  return wrap(
+      DILexicalBlockAttr::get(unwrap(ctx), cast<DIScopeAttr>(unwrap(scope)),
+                              cast<DIFileAttr>(unwrap(file)), line, column));
+}
+
+MlirAttribute mlirLLVMDILexicalBlockFileAttrGet(MlirContext ctx,
+                                                MlirAttribute scope,
+                                                MlirAttribute file,
+                                                unsigned int discriminator) {
+  return wrap(DILexicalBlockFileAttr::get(
+      unwrap(ctx), cast<DIScopeAttr>(unwrap(scope)),
+      cast<DIFileAttr>(unwrap(file)), discriminator));
+}
+
+MlirAttribute
+mlirLLVMDILocalVariableAttrGet(MlirContext ctx, MlirAttribute scope,
+                               MlirAttribute name, MlirAttribute diFile,
+                               unsigned int line, unsigned int arg,
+                               unsigned int alignInBits, MlirAttribute diType) {
+  return wrap(DILocalVariableAttr::get(
+      unwrap(ctx), cast<DIScopeAttr>(unwrap(scope)),
+      cast<StringAttr>(unwrap(name)), cast<DIFileAttr>(unwrap(diFile)), line,
+      arg, alignInBits, cast<DITypeAttr>(unwrap(diType))));
+}
+
+// fails to compile with error: no viable conversion from 'mlir::Attribute' to 'ValueParamT' (aka 'mlir::LLVM::DITypeAttr')
+/*
+MlirAttribute mlirLLVMDISubroutineTypeAttrGet(MlirContext ctx,
+                                              unsigned int callingConvention,
+                                              intptr_t nTypes,
+                                              MlirAttribute const *types) {
+  SmallVector<DITypeAttr, 2> elementsStorage;
+  elementsStorage.reserve(nTypes);
+  mlir::ArrayRef<DITypeAttr> list = unwrapList(nTypes, types, elementsStorage);
+  return wrap(DISubroutineTypeAttr::get(unwrap(ctx), callingConvention, list));
+}
+*/
+
+MlirAttribute mlirLLVMDISubprogramAttrGet(
+    MlirContext ctx, MlirAttribute id, MlirAttribute compileUnit,
+    MlirAttribute scope, MlirAttribute name, MlirAttribute linkageName,
+    MlirAttribute file, unsigned int line, unsigned int scopeLine,
+    uint64_t subprogramFlags, MlirAttribute type) {
+  return wrap(DISubprogramAttr::get(
+      unwrap(ctx), cast<DistinctAttr>(unwrap(id)),
+      cast<DICompileUnitAttr>(unwrap(compileUnit)),
+      cast<DIScopeAttr>(unwrap(scope)), cast<StringAttr>(unwrap(name)),
+      cast<StringAttr>(unwrap(linkageName)), cast<DIFileAttr>(unwrap(file)),
+      line, scopeLine, DISubprogramFlags(subprogramFlags),
+      cast<DISubroutineTypeAttr>(unwrap(type))));
+}
+
+MlirAttribute mlirLLVMDIModuleAttrGet(MlirContext ctx, MlirAttribute file,
+                                      MlirAttribute scope, MlirAttribute name,
+                                      MlirAttribute configMacros,
+                                      MlirAttribute includePath,
+                                      MlirAttribute apinotes, unsigned int line,
+                                      bool isDecl) {
+  return wrap(DIModuleAttr::get(
+      unwrap(ctx), cast<DIFileAttr>(unwrap(file)),
+      cast<DIScopeAttr>(unwrap(scope)), cast<StringAttr>(unwrap(name)),
+      cast<StringAttr>(unwrap(configMacros)),
+      cast<StringAttr>(unwrap(includePath)), cast<StringAttr>(unwrap(apinotes)),
+      line, isDecl));
+}
diff --git a/mlir/lib/CAPI/IR/BuiltinAttributes.cpp b/mlir/lib/CAPI/IR/BuiltinAttributes.cpp
index b3066ee0c28bdc..726af884668b2d 100644
--- a/mlir/lib/CAPI/IR/BuiltinAttributes.cpp
+++ b/mlir/lib/CAPI/IR/BuiltinAttributes.cpp
@@ -289,6 +289,10 @@ MlirTypeID mlirSymbolRefAttrGetTypeID(void) {
   return wrap(SymbolRefAttr::getTypeID());
 }
 
+MlirAttribute mlirDisctinctAttrCreate(MlirAttribute referencedAttr) {
+  return wrap(mlir::DistinctAttr::create(unwrap(referencedAttr)));
+}
+
 //===----------------------------------------------------------------------===//
 // Flat SymbolRef attribute.
 //===----------------------------------------------------------------------===//
diff --git a/mlir/test/CAPI/ir.c b/mlir/test/CAPI/ir.c
index a9850c0a132e75..8e79338c57a22a 100644
--- a/mlir/test/CAPI/ir.c
+++ b/mlir/test/CAPI/ir.c
@@ -1482,6 +1482,10 @@ int printAffineMap(MlirContext ctx) {
   // CHECK: (d0, d1, d2) -> (d0)
   // CHECK: (d0, d1, d2) -> (d2)
 
+  // CHECK: distinct[0]<"foo">
+  mlirAttributeDump(mlirDisctinctAttrCreate(
+      mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("foo"))));
+
   return 0;
 }
 
diff --git a/mlir/test/CAPI/llvm.c b/mlir/test/CAPI/llvm.c
index 1817988dd67dd6..dfae8fd3686898 100644
--- a/mlir/test/CAPI/llvm.c
+++ b/mlir/test/CAPI/llvm.c
@@ -10,6 +10,7 @@
 // RUN: mlir-capi-llvm-test 2>&1 | FileCheck %s
 
 #include "mlir-c/Dialect/LLVM.h"
+#include "mlir-c/BuiltinAttributes.h"
 #include "mlir-c/BuiltinTypes.h"
 #include "mlir-c/IR.h"
 #include "mlir-c/Support.h"
@@ -73,11 +74,35 @@ static void testTypeCreation(MlirContext ctx) {
   // CHECK: !llvm.struct<(i32, i64)>: 1
   fprintf(stderr, "%s: %d\n", i32_i64_s_text,
           mlirTypeEqual(i32_i64_s, i32_i64_s_ref));
+
+  MlirAttribute name_attr =
+      mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("name"));
+
+  MlirAttribute di_null_attr = mlirLLVMDINullTypeAttrGet(ctx);
+  mlirAttributeDump(di_null_attr);
+  // CHECK: #llvm.di_null_type
+  MlirAttribute di_basic_type_arr =
+      mlirLLVMDIBasicTypeAttrGet(ctx, 1, name_attr, 32, 0);
+  mlirAttributeDump(di_basic_type_arr);
+
+  MlirAttribute di_basic_type_class =
+      mlirLLVMDIBasicTypeAttrGet(ctx, 2, name_attr, 32, 0);
+  mlirAttributeDump(di_basic_type_class);
+  // CHECK: #llvm.di_basic_type<tag = DW_TAG_class_type, name = "name",
+  // sizeInBits = 32>
+  MlirAttribute file_name_attr =
+      mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("name.c"));
+  MlirAttribute dir_name_attr =
+      mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("dir"));
+  MlirAttribute di_file_attr =
+      mlirLLVMDIFileAttrGet(ctx, file_name_attr, dir_name_attr);
+  mlirAttributeDump(di_file_attr);
+  // CHECK: #llvm.di_file<"name.c" in "dir">
 }
 
 // CHECK-LABEL: testStructTypeCreation
 static int testStructTypeCreation(MlirContext ctx) {
-  fprintf(stderr, "testStructTypeCreation");
+  fprintf(stderr, "testStructTypeCreation\n");
 
   // CHECK: !llvm.struct<()>
   mlirTypeDump(mlirLLVMStructTypeLiteralGet(ctx, /*nFieldTypes=*/0,
@@ -225,12 +250,88 @@ static int testStructTypeCreation(MlirContext ctx) {
   return 0;
 }
 
+// CHECK-LABEL: testLLVMAttributes
+static void testLLVMAttributes(MlirContext ctx) {
+  fprintf(stderr, "testLLVMAttributes\n");
+
+  // CHECK: #llvm.linkage<internal>
+  mlirAttributeDump(mlirLLVMLinkageAttrGet(ctx, 0x1));
+  // CHECK: #llvm.cconv<ccc>
+  mlirAttributeDump(mlirLLVMCConvAttrGet(ctx, 0x0));
+  // CHECK: #llvm<comdat any>
+  mlirAttributeDump(mlirLLVMComdatAttrGet(ctx, 0x0));
+}
+
+// CHECK-LABEL: testDebugInfoAttributes
+static void testDebugInfoAttributes(MlirContext ctx) {
+  fprintf(stderr, "testDebugInfoAttributes\n");
+
+  MlirAttribute foo =
+      mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("foo"));
+  MlirAttribute bar =
+      mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("bar"));
+  MlirAttribute id = mlirDisctinctAttrCreate(foo);
+
+  // CHECK: #llvm.di_null_type
+  mlirAttributeDump(mlirLLVMDINullTypeAttrGet(ctx));
+  // CHECK: #llvm.di_basic_type<tag = DW_TAG_null, name = "foo", sizeInBits =
+  // 64, encoding = DW_ATE_signed>
+  MlirAttribute di_type = mlirLLVMDIBasicTypeAttrGet(ctx, 0, foo, 64, 0x5);
+  mlirAttributeDump(di_type);
+
+  MlirAttribute file = mlirLLVMDIFileAttrGet(ctx, foo, bar);
+
+  // CHECK: #llvm.di_file<"foo" in "bar">
+  mlirAttributeDump(file);
+
+  MlirAttribute compile_unit =
+      mlirLLVMDICompileUnitAttrGet(ctx, id, 0x1C, file, foo, false, 0x1);
+
+  // CHECK: #llvm.di_compile_unit<id = distinct[0]<"foo">, sourceLanguage =
+  // DW_LANG_Rust, file = <"foo" in "bar">, producer = "foo", isOptimized =
+  // false, emissionKind = Full>
+  mlirAttributeDump(compile_unit);
+
+  // CHECK: 1 : i32
+  mlirAttributeDump(mlirLLVMDIFlagsAttrGet(ctx, 0x1));
+
+  // CHECK: #llvm.di_lexical_block<scope = #llvm.di_compile_unit<id =
+  // distinct[0]<"foo">, sourceLanguage = DW_LANG_Rust, file = <"foo" in "bar">,
+  // producer = "foo", isOptimized = false, emissionKind = Full>, file = <"foo"
+  // in "bar">, line = 1, column = 2>
+  mlirAttributeDump(
+      mlirLLVMDILexicalBlockAttrGet(ctx, compile_unit, file, 1, 2));
+
+  // CHECK: #llvm.di_lexical_block_file<scope = #llvm.di_compile_unit<id =
+  // distinct[0]<"foo">, sourceLanguage = DW_LANG_Rust, file = <"foo" in "bar">,
+  // producer = "foo", isOptimized = false, emissionKind = Full>, file = <"foo"
+  // in "bar">, discriminator = 3>
+  mlirAttributeDump(
+      mlirLLVMDILexicalBlockFileAttrGet(ctx, compile_unit, file, 3));
+
+  // CHECK: #llvm.di_local_variable<scope = #llvm.di_compile_unit<id =
+  // distinct[0]<"foo">, sourceLanguage = DW_LANG_Rust, file = <"foo" in "bar">,
+  // producer = "foo", isOptimized = false, emissionKind = Full>, name = "foo",
+  // file = <"foo" in "bar">, line = 1, alignInBits = 8, type =
+  // #llvm.di_basic_type<tag...
[truncated]

@edg-l edg-l force-pushed the mlir_c_llvm_attributes branch 2 times, most recently from c713072 to b2095aa Compare March 5, 2024 11:22
Copy link

github-actions bot commented Mar 5, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@edg-l edg-l force-pushed the mlir_c_llvm_attributes branch 2 times, most recently from ae3c52b to d2814ba Compare March 5, 2024 11:32
@ftynse
Copy link
Member

ftynse commented Mar 5, 2024

unwrapList can only unwrap C API data structures to their C++ counterpart, e.g. MlirAttribute to mlir::Attribute. It will not magically downcast attributes to a specific type. You will have to do that yourself.

@ftynse ftynse self-requested a review March 5, 2024 15:19
@edg-l
Copy link
Contributor Author

edg-l commented Mar 5, 2024

unwrapList can only unwrap C API data structures to their C++ counterpart, e.g. MlirAttribute to mlir::Attribute. It will not magically downcast attributes to a specific type. You will have to do that yourself.

thanks! my cpp was a bit rusty (haha pun intended), i know how to make it work now

@edg-l edg-l force-pushed the mlir_c_llvm_attributes branch 4 times, most recently from 0d9f2da to 4f004e6 Compare March 5, 2024 16:50
@edg-l
Copy link
Contributor Author

edg-l commented Mar 5, 2024

should be ready now

Copy link
Member

@ftynse ftynse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution! Please address the inline comments.

mlir/lib/CAPI/Dialect/LLVM.cpp Outdated Show resolved Hide resolved
mlir/lib/CAPI/Dialect/LLVM.cpp Outdated Show resolved Hide resolved
mlir/lib/CAPI/Dialect/LLVM.cpp Outdated Show resolved Hide resolved
mlir/lib/CAPI/Dialect/LLVM.cpp Outdated Show resolved Hide resolved
mlir/lib/CAPI/Dialect/LLVM.cpp Outdated Show resolved Hide resolved
mlir/lib/CAPI/Dialect/LLVM.cpp Outdated Show resolved Hide resolved
mlir/lib/CAPI/Dialect/LLVM.cpp Show resolved Hide resolved
mlir/test/CAPI/llvm.c Outdated Show resolved Hide resolved
mlir/test/CAPI/llvm.c Outdated Show resolved Hide resolved
mlir/test/CAPI/llvm.c Outdated Show resolved Hide resolved
@edg-l
Copy link
Contributor Author

edg-l commented Mar 6, 2024

Okay, i think i did most of your comments, in the process i found some outdated llvm-c enums and updated them, hope thats okay.

Copy link
Member

@ftynse ftynse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't have random reformatting in unrelated parts of the project. Please undo any change made to include/llvm-c.

Also, I did not mean that MLIR C API should include LLVM C API, but provide C enums for the corresponding C++ enums in MLIR C++ API. Similarly to how we do for MlirDiagnosticSeverity or MlirSparseTensorLevelFormat.

@edg-l
Copy link
Contributor Author

edg-l commented Mar 7, 2024

We shouldn't have random reformatting in unrelated parts of the project. Please undo any change made to include/llvm-c.

Also, I did not mean that MLIR C API should include LLVM C API, but provide C enums for the corresponding C++ enums in MLIR C++ API. Similarly to how we do for MlirDiagnosticSeverity or MlirSparseTensorLevelFormat.

is now better?

@ftynse ftynse merged commit 3714f93 into llvm:main Mar 7, 2024
4 checks passed
@edg-l edg-l deleted the mlir_c_llvm_attributes branch March 7, 2024 17:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants