//===- TestFromLLVMIRTranslation.cpp - Import Test dialect from LLVM IR ---===// // // 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 a translation between LLVM IR and the MLIR Test dialect. // //===----------------------------------------------------------------------===// #include "TestDialect.h" #include "TestOps.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/IR/Builders.h" #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/Support/LLVM.h" #include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMIRToLLVMTranslation.h" #include "mlir/Target/LLVMIR/Import.h" #include "mlir/Target/LLVMIR/ModuleImport.h" #include "mlir/Tools/mlir-translate/Translation.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" #include "llvm/Support/SourceMgr.h" using namespace mlir; using namespace test; static ArrayRef getSupportedInstructionsImpl() { static unsigned instructions[] = {llvm::Instruction::Load}; return instructions; } static LogicalResult convertLoad(OpBuilder &builder, llvm::Instruction *inst, ArrayRef llvmOperands, LLVM::ModuleImport &moduleImport) { FailureOr addr = moduleImport.convertValue(llvmOperands[0]); if (failed(addr)) return failure(); // Create the LoadOp Value loadOp = LLVM::LoadOp::create( builder, moduleImport.translateLoc(inst->getDebugLoc()), moduleImport.convertType(inst->getType()), *addr); moduleImport.mapValue(inst) = SameOperandElementTypeOp::create( builder, loadOp.getLoc(), loadOp.getType(), loadOp, loadOp); return success(); } namespace { class TestDialectLLVMImportDialectInterface : public LLVMImportDialectInterface { public: using LLVMImportDialectInterface::LLVMImportDialectInterface; LogicalResult convertInstruction(OpBuilder &builder, llvm::Instruction *inst, ArrayRef llvmOperands, LLVM::ModuleImport &moduleImport) const override { switch (inst->getOpcode()) { case llvm::Instruction::Load: return convertLoad(builder, inst, llvmOperands, moduleImport); default: break; } return failure(); } ArrayRef getSupportedInstructions() const override { return getSupportedInstructionsImpl(); } }; } // namespace namespace mlir { void registerTestFromLLVMIR() { TranslateToMLIRRegistration registration( "test-import-llvmir", "test dialect from LLVM IR", [](llvm::SourceMgr &sourceMgr, MLIRContext *context) -> OwningOpRef { llvm::SMDiagnostic err; llvm::LLVMContext llvmContext; std::unique_ptr 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)) << errStream.str(); return {}; } if (llvm::verifyModule(*llvmModule, &llvm::errs())) return nullptr; return translateLLVMIRToModule(std::move(llvmModule), context, false); }, [](DialectRegistry ®istry) { registry.insert(); registry.insert(); registerLLVMDialectImport(registry); registry.addExtension( +[](MLIRContext *ctx, test::TestDialect *dialect) { dialect->addInterfaces(); }); }); } } // namespace mlir