blob: 3b6ae8d9a054584e7dbde55ac4f4a0b681fc4fa9 [file] [log] [blame]
// Copyright 2021 The IREE Authors
//
// Licensed 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
#include "iree-compiler-c/Compiler.h"
#include "iree/compiler/Dialect/VM/IR/VMOps.h"
#include "iree/compiler/Dialect/VM/Target/Bytecode/BytecodeModuleTarget.h"
#include "iree/compiler/Translation/IREEVM.h"
#include "iree/tools/init_targets.h"
#include "mlir/CAPI/IR.h"
#include "mlir/CAPI/Pass.h"
#include "mlir/CAPI/Support.h"
#include "mlir/CAPI/Utils.h"
#include "mlir/CAPI/Wrap.h"
#include "mlir/IR/BuiltinOps.h"
using namespace mlir;
using namespace mlir::iree_compiler;
// TODO: There is a loose ::IREE namespace somewhere which means that we
// have to fully qualify from the unnamed namespace.
using HALTargetOptions = mlir::iree_compiler::IREE::HAL::TargetOptions;
using VMTargetOptions = mlir::iree_compiler::IREE::VM::TargetOptions;
using VMBytecodeTargetOptions =
mlir::iree_compiler::IREE::VM::BytecodeTargetOptions;
namespace {
// We have one composite options struct for everything. Not all components
// are applicable to every translation.
struct CompilerOptions {
BindingOptions bindingOptions;
InputDialectOptions inputDialectOptions;
HALTargetOptions executableOptions;
VMTargetOptions vmTargetOptions;
VMBytecodeTargetOptions vmBytecodeTargetOptions;
};
} // namespace
DEFINE_C_API_PTR_METHODS(IreeCompilerOptions, CompilerOptions)
void ireeCompilerRegisterTargetBackends() { registerHALTargetBackends(); }
IreeCompilerOptions ireeCompilerOptionsCreate() {
return wrap(new CompilerOptions);
}
void ireeCompilerOptionsDestroy(IreeCompilerOptions options) {
delete unwrap(options);
}
void ireeCompilerOptionsAddTargetBackend(IreeCompilerOptions options,
const char *targetBackend) {
unwrap(options)->executableOptions.targets.push_back(
std::string(targetBackend));
}
void ireeCompilerOptionsSetInputDialectMHLO(IreeCompilerOptions options) {
unwrap(options)->inputDialectOptions.type = InputDialectOptions::Type::mhlo;
}
void ireeCompilerOptionsSetInputDialectTOSA(IreeCompilerOptions options) {
unwrap(options)->inputDialectOptions.type = InputDialectOptions::Type::tosa;
}
void ireeCompilerBuildIREEVMPassPipeline(IreeCompilerOptions options,
MlirOpPassManager passManager) {
auto *optionsCpp = unwrap(options);
auto *passManagerCpp = unwrap(passManager);
buildIREEVMTransformPassPipeline(
optionsCpp->bindingOptions, optionsCpp->inputDialectOptions,
optionsCpp->executableOptions, optionsCpp->vmTargetOptions,
*passManagerCpp);
}
// Translates a module op derived from the ireeCompilerBuildIREEVMPassPipeline
// to serialized bytecode. The module op may either be an outer builtin ModuleOp
// wrapping a VM::ModuleOp or a VM::ModuleOp.
MlirLogicalResult ireeCompilerTranslateModuletoVMBytecode(
IreeCompilerOptions options, MlirOperation moduleOp,
MlirStringCallback dataCallback, void *dataUserObject) {
auto *optionsCpp = unwrap(options);
Operation *moduleOpCpp = unwrap(moduleOp);
LogicalResult result = failure();
mlir::detail::CallbackOstream output(dataCallback, dataUserObject);
if (auto op = llvm::dyn_cast<mlir::ModuleOp>(moduleOpCpp)) {
result = iree_compiler::IREE::VM::translateModuleToBytecode(
op, optionsCpp->vmBytecodeTargetOptions, output);
} else if (auto op = llvm::dyn_cast<iree_compiler::IREE::VM::ModuleOp>(
moduleOpCpp)) {
result = iree_compiler::IREE::VM::translateModuleToBytecode(
op, optionsCpp->vmBytecodeTargetOptions, output);
} else {
emitError(moduleOpCpp->getLoc()) << "expected a supported module operation";
result = failure();
}
return wrap(result);
}