Skip to content

[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

Merged
merged 1 commit into from
May 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion mlir/include/mlir/Target/LLVMIR/Import.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion mlir/include/mlir/Target/LLVMIR/ModuleImport.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 2 additions & 3 deletions mlir/include/mlir/Target/LLVMIR/TypeFromLLVM.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
#include <memory>

namespace llvm {
class DataLayout;
class LLVMContext;
class Type;
} // namespace llvm

Expand All @@ -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.
Expand Down
8 changes: 7 additions & 1 deletion mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
11 changes: 7 additions & 4 deletions mlir/lib/Target/LLVMIR/ModuleImport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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
Expand All @@ -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()))
Expand Down
19 changes: 13 additions & 6 deletions mlir/lib/Target/LLVMIR/TypeFromLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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) {
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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.
Expand All @@ -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;

Expand Down
13 changes: 13 additions & 0 deletions mlir/test/Target/LLVMIR/Import/import-structs-as-literals.ll
Original file line number Diff line number Diff line change
@@ -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