-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[MLIR][LLVM] Add import-structs-as-literals flag to the IR import #140098
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
Conversation
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@llvm/pr-subscribers-mlir-llvm @llvm/pr-subscribers-mlir Author: Christian Ulmann (Dinistro) ChangesThis commit introduces the Full diff: https://github.com/llvm/llvm-project/pull/140098.diff 7 Files Affected:
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)>
+@named = external global %named
+
+%opaque = type opaque
+
+; CHECK: @opaque
+; CHECK-SAME: !llvm.struct<()>
+@opaque = external global %opaque
|
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.