Currently, there is no common mechanism for supported intrinsics to be generically annotated with arg and ret attributes. Since there are many supported intrinsics around different dialects, the amount of work to teach all them about these attributes is not trivial (though it would be nice in the long term). This PR adds a new flag `-prefer-unregistered-intrinsics` that can be used alongside `--import-llvm` to always use `llvm.intrinsic_call` during import time (ignoring dialect hooks for custom intrinsic support). Using this flag allow us to roundtrip the LLVM IR while eliminating a whole set of differences coming from lack of arg/ret attributes on supported intrinsics. Note `convertIntrinsic` has to be moved to an implementation file because it queries into `moduleImport` state, which is a fwd declaration in `LLVMImportInterface.h`
85 lines
3.3 KiB
C++
85 lines
3.3 KiB
C++
//===- ConvertFromLLVMIR.cpp - MLIR to LLVM IR conversion -----------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the function that registers the translation between
|
|
// LLVM IR and the MLIR LLVM dialect.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/Dialect/DLTI/DLTI.h"
|
|
#include "mlir/IR/BuiltinOps.h"
|
|
#include "mlir/Target/LLVMIR/Dialect/All.h"
|
|
#include "mlir/Target/LLVMIR/Import.h"
|
|
#include "mlir/Tools/mlir-translate/Translation.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/IR/Verifier.h"
|
|
#include "llvm/IRReader/IRReader.h"
|
|
#include "llvm/Support/SourceMgr.h"
|
|
|
|
using namespace mlir;
|
|
|
|
namespace mlir {
|
|
void registerFromLLVMIRTranslation() {
|
|
static llvm::cl::opt<bool> emitExpensiveWarnings(
|
|
"emit-expensive-warnings",
|
|
llvm::cl::desc("Emit expensive warnings during LLVM IR import "
|
|
"(discouraged: testing only!)"),
|
|
llvm::cl::init(false));
|
|
static llvm::cl::opt<bool> dropDICompositeTypeElements(
|
|
"drop-di-composite-type-elements",
|
|
llvm::cl::desc(
|
|
"Avoid translating the elements of DICompositeTypes during "
|
|
"the LLVM IR import (discouraged: testing only!)"),
|
|
llvm::cl::init(false));
|
|
|
|
static llvm::cl::opt<bool> preferUnregisteredIntrinsics(
|
|
"prefer-unregistered-intrinsics",
|
|
llvm::cl::desc(
|
|
"Prefer translating all intrinsics into llvm.call_intrinsic instead "
|
|
"of using dialect supported intrinsics"),
|
|
llvm::cl::init(false));
|
|
|
|
TranslateToMLIRRegistration registration(
|
|
"import-llvm", "Translate LLVMIR to MLIR",
|
|
[](llvm::SourceMgr &sourceMgr,
|
|
MLIRContext *context) -> OwningOpRef<Operation *> {
|
|
llvm::SMDiagnostic err;
|
|
llvm::LLVMContext llvmContext;
|
|
std::unique_ptr<llvm::Module> llvmModule =
|
|
llvm::parseIR(*sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID()),
|
|
err, llvmContext);
|
|
if (!llvmModule) {
|
|
std::string errStr;
|
|
llvm::raw_string_ostream errStream(errStr);
|
|
err.print(/*ProgName=*/"", errStream);
|
|
emitError(UnknownLoc::get(context)) << errStr;
|
|
return {};
|
|
}
|
|
if (llvm::verifyModule(*llvmModule, &llvm::errs()))
|
|
return nullptr;
|
|
|
|
// Debug records are not currently supported in the LLVM IR translator.
|
|
if (llvmModule->IsNewDbgInfoFormat)
|
|
llvmModule->convertFromNewDbgValues();
|
|
|
|
return translateLLVMIRToModule(
|
|
std::move(llvmModule), context, emitExpensiveWarnings,
|
|
dropDICompositeTypeElements, /*loadAllDialects=*/true,
|
|
preferUnregisteredIntrinsics);
|
|
},
|
|
[](DialectRegistry ®istry) {
|
|
// Register the DLTI dialect used to express the data layout
|
|
// specification of the imported module.
|
|
registry.insert<DLTIDialect>();
|
|
// Register all dialects that implement the LLVMImportDialectInterface
|
|
// including the LLVM dialect.
|
|
registerAllFromLLVMIRTranslations(registry);
|
|
});
|
|
}
|
|
} // namespace mlir
|