[Mlir-commits] [mlir] [MLIR][LLVM] Add import-structs-as-literals flag to the IR import (PR #140098)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu May 15 23:33:08 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-llvm

@llvm/pr-subscribers-mlir

Author: Christian Ulmann (Dinistro)

<details>
<summary>Changes</summary>

This commit introduces the `import-structs-as-literals` option to the MLIR import. This ensures that all struct types are imported as literal structs, even when they are named in LLVM IR.

---
Full diff: https://github.com/llvm/llvm-project/pull/140098.diff


7 Files Affected:

- (modified) mlir/include/mlir/Target/LLVMIR/Import.h (+5-1) 
- (modified) mlir/include/mlir/Target/LLVMIR/ModuleImport.h (+1-1) 
- (modified) mlir/include/mlir/Target/LLVMIR/TypeFromLLVM.h (+2-3) 
- (modified) mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp (+7-1) 
- (modified) mlir/lib/Target/LLVMIR/ModuleImport.cpp (+7-4) 
- (modified) mlir/lib/Target/LLVMIR/TypeFromLLVM.cpp (+13-6) 
- (added) mlir/test/Target/LLVMIR/Import/import-structs-as-literals.ll (+13) 


``````````diff
diff --git a/mlir/include/mlir/Target/LLVMIR/Import.h b/mlir/include/mlir/Target/LLVMIR/Import.h
index c6181243a06b0..458361842ec81 100644
--- a/mlir/include/mlir/Target/LLVMIR/Import.h
+++ b/mlir/include/mlir/Target/LLVMIR/Import.h
@@ -46,10 +46,14 @@ class ModuleOp;
 /// registered an explicit intrinsic operation. Warning: passes that rely on
 /// matching explicit intrinsic operations may not work properly if this flag is
 /// enabled.
+/// The `importStructsAsLiterals` flag (default off) ensures that all structs
+/// are imported as literal structs, even when they are named in the LLVM
+/// module.
 OwningOpRef<ModuleOp> translateLLVMIRToModule(
     std::unique_ptr<llvm::Module> llvmModule, MLIRContext *context,
     bool emitExpensiveWarnings = true, bool dropDICompositeTypeElements = false,
-    bool loadAllDialects = true, bool preferUnregisteredIntrinsics = false);
+    bool loadAllDialects = true, bool preferUnregisteredIntrinsics = false,
+    bool importStructsAsLiterals = false);
 
 /// Translate the given LLVM data layout into an MLIR equivalent using the DLTI
 /// dialect.
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
index 568dc00b3bb97..a5b38299d07b2 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
@@ -48,7 +48,7 @@ class ModuleImport {
 public:
   ModuleImport(ModuleOp mlirModule, std::unique_ptr<llvm::Module> llvmModule,
                bool emitExpensiveWarnings, bool importEmptyDICompositeTypes,
-               bool preferUnregisteredIntrinsics);
+               bool preferUnregisteredIntrinsics, bool importStructsAsLiterals);
 
   /// Calls the LLVMImportInterface initialization that queries the registered
   /// dialect interfaces for the supported LLVM IR intrinsics and metadata kinds
diff --git a/mlir/include/mlir/Target/LLVMIR/TypeFromLLVM.h b/mlir/include/mlir/Target/LLVMIR/TypeFromLLVM.h
index 9bb56ee358b8c..0a519534128d6 100644
--- a/mlir/include/mlir/Target/LLVMIR/TypeFromLLVM.h
+++ b/mlir/include/mlir/Target/LLVMIR/TypeFromLLVM.h
@@ -17,8 +17,6 @@
 #include <memory>
 
 namespace llvm {
-class DataLayout;
-class LLVMContext;
 class Type;
 } // namespace llvm
 
@@ -38,7 +36,8 @@ class TypeFromLLVMIRTranslatorImpl;
 /// reused across translations.
 class TypeFromLLVMIRTranslator {
 public:
-  TypeFromLLVMIRTranslator(MLIRContext &context);
+  TypeFromLLVMIRTranslator(MLIRContext &context,
+                           bool importStructsAsLiterals = false);
   ~TypeFromLLVMIRTranslator();
 
   /// Translates the given LLVM IR type to the MLIR LLVM dialect.
diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
index b21db4aa18284..187e2a9b75a9b 100644
--- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
+++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
@@ -44,6 +44,12 @@ void registerFromLLVMIRTranslation() {
           "of using dialect supported intrinsics"),
       llvm::cl::init(false));
 
+  static llvm::cl::opt<bool> importStructsAsLiterals(
+      "import-structs-as-literals",
+      llvm::cl::desc("Controls if structs should be imported as literal "
+                     "structs, i.e., nameless structs."),
+      llvm::cl::init(false));
+
   TranslateToMLIRRegistration registration(
       "import-llvm", "Translate LLVMIR to MLIR",
       [](llvm::SourceMgr &sourceMgr,
@@ -70,7 +76,7 @@ void registerFromLLVMIRTranslation() {
         return translateLLVMIRToModule(
             std::move(llvmModule), context, emitExpensiveWarnings,
             dropDICompositeTypeElements, /*loadAllDialects=*/true,
-            preferUnregisteredIntrinsics);
+            preferUnregisteredIntrinsics, importStructsAsLiterals);
       },
       [](DialectRegistry &registry) {
         // Register the DLTI dialect used to express the data layout
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 77094d4b75f38..8a3e47d29c258 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -164,11 +164,12 @@ ModuleImport::ModuleImport(ModuleOp mlirModule,
                            std::unique_ptr<llvm::Module> llvmModule,
                            bool emitExpensiveWarnings,
                            bool importEmptyDICompositeTypes,
-                           bool preferUnregisteredIntrinsics)
+                           bool preferUnregisteredIntrinsics,
+                           bool importStructsAsLiterals)
     : builder(mlirModule->getContext()), context(mlirModule->getContext()),
       mlirModule(mlirModule), llvmModule(std::move(llvmModule)),
       iface(mlirModule->getContext()),
-      typeTranslator(*mlirModule->getContext()),
+      typeTranslator(*mlirModule->getContext(), importStructsAsLiterals),
       debugImporter(std::make_unique<DebugImporter>(
           mlirModule, importEmptyDICompositeTypes)),
       loopAnnotationImporter(
@@ -3080,7 +3081,8 @@ ModuleImport::translateDereferenceableAttr(const llvm::MDNode *node,
 OwningOpRef<ModuleOp> mlir::translateLLVMIRToModule(
     std::unique_ptr<llvm::Module> llvmModule, MLIRContext *context,
     bool emitExpensiveWarnings, bool dropDICompositeTypeElements,
-    bool loadAllDialects, bool preferUnregisteredIntrinsics) {
+    bool loadAllDialects, bool preferUnregisteredIntrinsics,
+    bool importStructsAsLiterals) {
   // Preload all registered dialects to allow the import to iterate the
   // registered LLVMImportDialectInterface implementations and query the
   // supported LLVM IR constructs before starting the translation. Assumes the
@@ -3098,7 +3100,8 @@ OwningOpRef<ModuleOp> mlir::translateLLVMIRToModule(
 
   ModuleImport moduleImport(module.get(), std::move(llvmModule),
                             emitExpensiveWarnings, dropDICompositeTypeElements,
-                            preferUnregisteredIntrinsics);
+                            preferUnregisteredIntrinsics,
+                            importStructsAsLiterals);
   if (failed(moduleImport.initializeImportInterface()))
     return {};
   if (failed(moduleImport.convertDataLayout()))
diff --git a/mlir/lib/Target/LLVMIR/TypeFromLLVM.cpp b/mlir/lib/Target/LLVMIR/TypeFromLLVM.cpp
index c46aa3e80d51a..5d9345d707a44 100644
--- a/mlir/lib/Target/LLVMIR/TypeFromLLVM.cpp
+++ b/mlir/lib/Target/LLVMIR/TypeFromLLVM.cpp
@@ -12,7 +12,6 @@
 #include "mlir/IR/MLIRContext.h"
 
 #include "llvm/ADT/TypeSwitch.h"
-#include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Type.h"
 
@@ -25,7 +24,9 @@ namespace detail {
 class TypeFromLLVMIRTranslatorImpl {
 public:
   /// Constructs a class creating types in the given MLIR context.
-  TypeFromLLVMIRTranslatorImpl(MLIRContext &context) : context(context) {}
+  TypeFromLLVMIRTranslatorImpl(MLIRContext &context,
+                               bool importStructsAsLiterals)
+      : context(context), importStructsAsLiterals(importStructsAsLiterals) {}
 
   /// Translates the given type.
   Type translateType(llvm::Type *type) {
@@ -103,7 +104,7 @@ class TypeFromLLVMIRTranslatorImpl {
   /// Translates the given structure type.
   Type translate(llvm::StructType *type) {
     SmallVector<Type, 8> subtypes;
-    if (type->isLiteral()) {
+    if (type->isLiteral() || importStructsAsLiterals) {
       translateTypes(type->subtypes(), subtypes);
       return LLVM::LLVMStructType::getLiteral(&context, subtypes,
                                               type->isPacked());
@@ -132,7 +133,7 @@ class TypeFromLLVMIRTranslatorImpl {
   Type translate(llvm::ScalableVectorType *type) {
     return VectorType::get(type->getMinNumElements(),
                            translateType(type->getElementType()),
-                           /*scalable=*/true);
+                           /*scalableDims=*/true);
   }
 
   /// Translates the given target extension type.
@@ -158,14 +159,20 @@ class TypeFromLLVMIRTranslatorImpl {
 
   /// The context in which MLIR types are created.
   MLIRContext &context;
+
+  /// Controls if structs should be imported as literal structs, i.e., nameless
+  /// structs.
+  bool importStructsAsLiterals;
 };
 
 } // namespace detail
 } // namespace LLVM
 } // namespace mlir
 
-LLVM::TypeFromLLVMIRTranslator::TypeFromLLVMIRTranslator(MLIRContext &context)
-    : impl(new detail::TypeFromLLVMIRTranslatorImpl(context)) {}
+LLVM::TypeFromLLVMIRTranslator::TypeFromLLVMIRTranslator(
+    MLIRContext &context, bool importStructsAsLiterals)
+    : impl(std::make_unique<detail::TypeFromLLVMIRTranslatorImpl>(
+          context, importStructsAsLiterals)) {}
 
 LLVM::TypeFromLLVMIRTranslator::~TypeFromLLVMIRTranslator() = default;
 
diff --git a/mlir/test/Target/LLVMIR/Import/import-structs-as-literals.ll b/mlir/test/Target/LLVMIR/Import/import-structs-as-literals.ll
new file mode 100644
index 0000000000000..40fd834817d04
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/Import/import-structs-as-literals.ll
@@ -0,0 +1,13 @@
+; RUN: mlir-translate -import-llvm -import-structs-as-literals -split-input-file %s | FileCheck %s
+
+%named = type {i32, i8, i16, i32}
+
+; CHECK: @named
+; CHECK-SAME: !llvm.struct<(i32, i8, i16, i32)>
+ at named = external global %named
+
+%opaque = type opaque
+
+; CHECK: @opaque
+; CHECK-SAME: !llvm.struct<()>
+ at opaque = external global %opaque

``````````

</details>


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


More information about the Mlir-commits mailing list