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 translateLLVMIRToModule( std::unique_ptr 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 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 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 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 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( mlirModule, importEmptyDICompositeTypes)), loopAnnotationImporter( @@ -3080,7 +3081,8 @@ ModuleImport::translateDereferenceableAttr(const llvm::MDNode *node, OwningOpRef mlir::translateLLVMIRToModule( std::unique_ptr 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 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 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( + 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