[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 ®istry) {
// 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