Hoist buildIREEVMTransformPassPipeline() to its own library and build standalone ireec tool. (#8559)
* Hoist buildIREEVMTransformPassPipeline() to its own library and build standalone ireec tool.
* NFC for iree-translate: we can slim it down in a subsequent patch, but right now, it does exactly what it did before.
* Supplies the ConstEval hook at the very top levels in order to make dependencies a DAG.
* Refactors constant jitting to use buildIREEVMTransformPassPipeline() now that the circular dep is broken.
* Makes IREEVM/CMakeLists.txt generated by bazel_to_cmake:
* If EMITC is disabled, just generated dummy libraries that do not define IREE_HAVE_EMITC_DIALECT
* Adds an iree/compiler/Dialect/VM/Target/C:Enabled library which defines IREE_HAVE_EMITC_DIALECT
* Backs out build graph changes based on emitc enable/disable: now the targets remain no matter what and code can just check the macro
* Removes the global CMake IREE_HAVE_EMITC_DIALECT copt.
* Adds new ireec tool:
* Gloms it onto the existing iree_translate_lib which will get renamed to ireec_lib when I'm done (and the existing iree-translate bits that are still needed just inlined into iree-translate-main.cc).
* Requires an input file (or '-') vs blocking forever.
* Translation is specified with a new `--output-format=vm-bytecode|c-module|vm-asm` with fallbacks to the old `--iree-mlir-to-vm-c-module` and `--iree-mlir-to-vm-bytecode-module`
* Defaults to "vm-bytecode".
* Adds a bit of grouping to CL options for aesthetics.
* Removes the redundant emitError on the module for any failure (for both old and new tool). This is redundant and we now just print a simple compile failed message to errs() in case if there are any lingering bugs where we return failure() but fail to emit a diagnostic. Should be a pretty big QOL improvement.
* A subsequent patch will convert everything to use ireec and downgrade iree-translate to just a serialization testing tool.
diff --git a/build_tools/cmake/iree_copts.cmake b/build_tools/cmake/iree_copts.cmake
index 8a8ae4b..89955ab 100644
--- a/build_tools/cmake/iree_copts.cmake
+++ b/build_tools/cmake/iree_copts.cmake
@@ -416,10 +416,3 @@
# tools in LLVM.
iree_get_executable_path(IREE_TABLEGEN_EXE iree-tblgen)
endif()
-#-------------------------------------------------------------------------------
-# Third party: mlir-emitc
-#-------------------------------------------------------------------------------
-
-if(IREE_ENABLE_EMITC)
- add_definitions(-DIREE_HAVE_EMITC_DIALECT)
-endif()
diff --git a/iree/compiler/ConstEval/BUILD b/iree/compiler/ConstEval/BUILD
index 9c0c8db..8d46a3a 100644
--- a/iree/compiler/ConstEval/BUILD
+++ b/iree/compiler/ConstEval/BUILD
@@ -54,22 +54,12 @@
":PassHeaders",
":PassesIncGen",
":Runtime",
- # TODO: Prune.
- "//iree/compiler/Bindings/Native/Transforms",
- "//iree/compiler/Dialect/Flow/Transforms",
- "//iree/compiler/Dialect/HAL/Transforms",
- "//iree/compiler/Dialect/Stream/Transforms",
- "//iree/compiler/Dialect/Util/Transforms",
- "//iree/compiler/Dialect/Util/IR",
- "//iree/compiler/Dialect/VM/Conversion",
- "//iree/compiler/Dialect/VM/Conversion/StandardToVM",
- "//iree/compiler/Dialect/VM/Target/Bytecode",
- "//iree/compiler/Dialect/VM/Transforms",
+ "//iree/compiler/Pipelines",
"//iree/compiler/Utils",
"@llvm-project//llvm:Support",
+ "@llvm-project//mlir:FuncDialect",
"@llvm-project//mlir:IR",
"@llvm-project//mlir:Pass",
- "@llvm-project//mlir:FuncDialect",
],
)
diff --git a/iree/compiler/ConstEval/CMakeLists.txt b/iree/compiler/ConstEval/CMakeLists.txt
index 9c0a3e4..4fe7503 100644
--- a/iree/compiler/ConstEval/CMakeLists.txt
+++ b/iree/compiler/ConstEval/CMakeLists.txt
@@ -49,16 +49,7 @@
MLIRFunc
MLIRIR
MLIRPass
- iree::compiler::Bindings::Native::Transforms
- iree::compiler::Dialect::Flow::Transforms
- iree::compiler::Dialect::HAL::Transforms
- iree::compiler::Dialect::Stream::Transforms
- iree::compiler::Dialect::Util::IR
- iree::compiler::Dialect::Util::Transforms
- iree::compiler::Dialect::VM::Conversion
- iree::compiler::Dialect::VM::Conversion::StandardToVM
- iree::compiler::Dialect::VM::Target::Bytecode
- iree::compiler::Dialect::VM::Transforms
+ iree::compiler::Pipelines
iree::compiler::Utils
PUBLIC
)
diff --git a/iree/compiler/ConstEval/JitGlobals.cpp b/iree/compiler/ConstEval/JitGlobals.cpp
index eda8cac..e455d9d 100644
--- a/iree/compiler/ConstEval/JitGlobals.cpp
+++ b/iree/compiler/ConstEval/JitGlobals.cpp
@@ -4,17 +4,10 @@
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-#include "iree/compiler/Bindings/Native/Transforms/Passes.h"
#include "iree/compiler/ConstEval/PassDetail.h"
#include "iree/compiler/ConstEval/Passes.h"
#include "iree/compiler/ConstEval/Runtime.h"
-#include "iree/compiler/Dialect/Flow/Transforms/Passes.h"
-#include "iree/compiler/Dialect/HAL/Transforms/Passes.h"
-#include "iree/compiler/Dialect/Stream/Transforms/Passes.h"
-#include "iree/compiler/Dialect/Util/IR/UtilOps.h"
-#include "iree/compiler/Dialect/Util/Transforms/Passes.h"
-#include "iree/compiler/Dialect/VM/Target/Bytecode/BytecodeModuleTarget.h"
-#include "iree/compiler/Dialect/VM/Transforms/Passes.h"
+#include "iree/compiler/Pipelines/Pipelines.h"
#include "iree/compiler/Utils/PassUtils.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/Debug.h"
@@ -119,10 +112,13 @@
// shared.
// TODO: See if we can make them copyable?
struct CompileOptions {
- IREE::Flow::TransformOptions flowOptions;
+ BindingOptions bindingOptions;
+ InputDialectOptions inputOptions;
+ HighLevelOptimizationOptions highLevelOptimizationOptions;
+ SchedulingOptions schedulingOptions;
IREE::HAL::TargetOptions executableOptions;
- IREE::Stream::TransformOptions streamOptions;
IREE::VM::TargetOptions targetOptions;
+ IREEVMPipelineHooks hooks;
};
struct JitGlobalsPass : public JitGlobalsBase<JitGlobalsPass> {
@@ -130,22 +126,16 @@
: options(std::make_shared<CompileOptions>()),
compilePipeline("builtin.module") {
// Invoke IREE compilation flow.
- // TODO: Find a better place for this canonical list of passes?
- // TODO: Something better?
options->executableOptions.targets.push_back("vmvx");
options->targetOptions.i64Extension = true;
options->targetOptions.f32Extension = true;
options->targetOptions.f64Extension = true;
- IREE::ABI::buildTransformPassPipeline(compilePipeline);
- IREE::Flow::buildFlowTransformPassPipeline(compilePipeline,
- options->flowOptions);
- IREE::Stream::buildStreamTransformPassPipeline(compilePipeline,
- options->streamOptions);
- IREE::HAL::buildHALTransformPassPipeline(compilePipeline,
- options->executableOptions);
- IREE::VM::buildVMTransformPassPipeline(compilePipeline,
- options->targetOptions);
+ buildIREEVMTransformPassPipeline(
+ options->bindingOptions, options->inputOptions,
+ options->highLevelOptimizationOptions, options->schedulingOptions,
+ options->executableOptions, options->targetOptions, options->hooks,
+ compilePipeline);
}
void getDependentDialects(DialectRegistry ®istry) const override {
diff --git a/iree/compiler/Dialect/VM/Target/C/BUILD b/iree/compiler/Dialect/VM/Target/C/BUILD
index c3963b0..18e6b73 100644
--- a/iree/compiler/Dialect/VM/Target/C/BUILD
+++ b/iree/compiler/Dialect/VM/Target/C/BUILD
@@ -15,12 +15,33 @@
iree_cmake_extra_content(
content = """
if(NOT "${IREE_ENABLE_EMITC}")
+ # If the real "C" library is enabled, it will define IREE_ENABLE_EMITC,
+ # which can be used for conditionally switching.
+ iree_cc_library(
+ NAME Enabled
+ )
+ iree_cc_library(
+ NAME C
+ )
+ iree_cc_library(
+ NAME TranslateToCpp
+ )
return()
endif()
""",
)
cc_library(
+ name = "Enabled",
+ defines = [
+ "IREE_HAVE_EMITC_DIALECT",
+ ],
+ deps = [
+ "@llvm-project//mlir:EmitC",
+ ],
+)
+
+cc_library(
name = "TranslateToCpp",
srcs = [
"TranslateToCpp.cpp",
@@ -29,6 +50,7 @@
"CppEmitter.h",
],
deps = [
+ ":Enabled",
"@llvm-project//llvm:Support",
"@llvm-project//mlir:ControlFlowOps",
"@llvm-project//mlir:EmitC",
@@ -51,6 +73,7 @@
"TranslationFlags.h",
],
deps = [
+ ":Enabled",
":TranslateToCpp",
"//iree/compiler/Dialect/Util/IR",
"//iree/compiler/Dialect/Util/Transforms",
diff --git a/iree/compiler/Dialect/VM/Target/C/CMakeLists.txt b/iree/compiler/Dialect/VM/Target/C/CMakeLists.txt
index b5ff5e6..7da6351 100644
--- a/iree/compiler/Dialect/VM/Target/C/CMakeLists.txt
+++ b/iree/compiler/Dialect/VM/Target/C/CMakeLists.txt
@@ -9,6 +9,17 @@
################################################################################
if(NOT "${IREE_ENABLE_EMITC}")
+ # If the real "C" library is enabled, it will define IREE_ENABLE_EMITC,
+ # which can be used for conditionally switching.
+ iree_cc_library(
+ NAME Enabled
+ )
+ iree_cc_library(
+ NAME C
+ )
+ iree_cc_library(
+ NAME TranslateToCpp
+ )
return()
endif()
@@ -16,12 +27,23 @@
iree_cc_library(
NAME
+ Enabled
+ DEPS
+ MLIREmitC
+ DEFINES
+ "IREE_HAVE_EMITC_DIALECT"
+ PUBLIC
+)
+
+iree_cc_library(
+ NAME
TranslateToCpp
HDRS
"CppEmitter.h"
SRCS
"TranslateToCpp.cpp"
DEPS
+ ::Enabled
LLVMSupport
MLIRControlFlow
MLIREmitC
@@ -43,6 +65,7 @@
"TranslationFlags.cpp"
"TranslationRegistration.cpp"
DEPS
+ ::Enabled
::TranslateToCpp
LLVMSupport
MLIRIR
diff --git a/iree/compiler/Pipelines/BUILD b/iree/compiler/Pipelines/BUILD
new file mode 100644
index 0000000..0007b07
--- /dev/null
+++ b/iree/compiler/Pipelines/BUILD
@@ -0,0 +1,51 @@
+# Copyright 2022 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
+
+package(
+ default_visibility = ["//visibility:public"],
+ features = ["layering_check"],
+ licenses = ["notice"], # Apache 2.0
+)
+
+cc_library(
+ name = "Options",
+ srcs = ["Options.cpp"],
+ hdrs = ["Options.h"],
+ deps = [
+ "//iree/compiler/Utils",
+ ],
+)
+
+cc_library(
+ name = "Pipelines",
+ srcs = [
+ "Pipelines.cpp",
+ ],
+ hdrs = [
+ "Pipelines.h",
+ ],
+ deps = [
+ ":Options",
+ "//iree/compiler/Bindings/Native/Transforms",
+ "//iree/compiler/Bindings/TFLite/Transforms",
+ "//iree/compiler/Dialect/Flow/Transforms",
+ "//iree/compiler/Dialect/HAL/Conversion/HALToVM",
+ "//iree/compiler/Dialect/HAL/Transforms",
+ "//iree/compiler/Dialect/Stream/Transforms",
+ "//iree/compiler/Dialect/Util/Transforms",
+ "//iree/compiler/Dialect/VM/Conversion",
+ "//iree/compiler/Dialect/VM/Conversion/StandardToVM",
+ "//iree/compiler/Dialect/VM/Target/Bytecode",
+ "//iree/compiler/Dialect/VM/Transforms",
+ "//iree/compiler/InputConversion/Common",
+ "//iree/compiler/InputConversion/MHLO",
+ "//iree/compiler/InputConversion/TOSA",
+ "@llvm-project//llvm:Support",
+ "@llvm-project//mlir:IR",
+ "@llvm-project//mlir:Pass",
+ "@llvm-project//mlir:Support",
+ ],
+)
diff --git a/iree/compiler/Pipelines/CMakeLists.txt b/iree/compiler/Pipelines/CMakeLists.txt
new file mode 100644
index 0000000..1885ff0
--- /dev/null
+++ b/iree/compiler/Pipelines/CMakeLists.txt
@@ -0,0 +1,55 @@
+################################################################################
+# Autogenerated by build_tools/bazel_to_cmake/bazel_to_cmake.py from #
+# iree/compiler/Pipelines/BUILD #
+# #
+# Use iree_cmake_extra_content from iree/build_defs.oss.bzl to add arbitrary #
+# CMake-only content. #
+# #
+# To disable autogeneration for this file entirely, delete this header. #
+################################################################################
+
+iree_add_all_subdirs()
+
+iree_cc_library(
+ NAME
+ Options
+ HDRS
+ "Options.h"
+ SRCS
+ "Options.cpp"
+ DEPS
+ iree::compiler::Utils
+ PUBLIC
+)
+
+iree_cc_library(
+ NAME
+ Pipelines
+ HDRS
+ "Pipelines.h"
+ SRCS
+ "Pipelines.cpp"
+ DEPS
+ ::Options
+ LLVMSupport
+ MLIRIR
+ MLIRPass
+ MLIRSupport
+ iree::compiler::Bindings::Native::Transforms
+ iree::compiler::Bindings::TFLite::Transforms
+ iree::compiler::Dialect::Flow::Transforms
+ iree::compiler::Dialect::HAL::Conversion::HALToVM
+ iree::compiler::Dialect::HAL::Transforms
+ iree::compiler::Dialect::Stream::Transforms
+ iree::compiler::Dialect::Util::Transforms
+ iree::compiler::Dialect::VM::Conversion
+ iree::compiler::Dialect::VM::Conversion::StandardToVM
+ iree::compiler::Dialect::VM::Target::Bytecode
+ iree::compiler::Dialect::VM::Transforms
+ iree::compiler::InputConversion::Common
+ iree::compiler::InputConversion::MHLO
+ iree::compiler::InputConversion::TOSA
+ PUBLIC
+)
+
+### BAZEL_TO_CMAKE_PRESERVES_ALL_CONTENT_BELOW_THIS_LINE ###
diff --git a/iree/compiler/Pipelines/Options.cpp b/iree/compiler/Pipelines/Options.cpp
new file mode 100644
index 0000000..56c09c8
--- /dev/null
+++ b/iree/compiler/Pipelines/Options.cpp
@@ -0,0 +1,97 @@
+// Copyright 2022 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/Pipelines/Options.h"
+
+namespace mlir {
+namespace iree_compiler {
+
+void BindingOptions::bindOptions(OptionsBinder &binder) {
+ static llvm::cl::OptionCategory bindingOptionsCategory(
+ "IREE translation binding support options.");
+
+ binder.opt<bool>(
+ "iree-native-bindings-support", native,
+ llvm::cl::desc(
+ "Include runtime support for native IREE ABI-compatible bindings."),
+ llvm::cl::cat(bindingOptionsCategory));
+ binder.opt<bool>("iree-tflite-bindings-support", tflite,
+ llvm::cl::desc("Include runtime support for the IREE TFLite "
+ "compatibility bindings."),
+ llvm::cl::cat(bindingOptionsCategory));
+}
+
+void InputDialectOptions::bindOptions(OptionsBinder &binder) {
+ static llvm::cl::OptionCategory inputDialectOptions(
+ "IREE options for controlling the input transformations to apply.");
+
+ binder.opt<InputDialectOptions::Type>(
+ "iree-input-type", type,
+ llvm::cl::desc("Specifies the input program representation."),
+ llvm::cl::values(
+ clEnumValN(InputDialectOptions::Type::none, "none",
+ "No input dialect transformation."),
+ clEnumValN(InputDialectOptions::Type::tosa, "tosa",
+ "Legalize from TOSA ops."),
+ clEnumValN(InputDialectOptions::Type::mhlo, "mhlo",
+ "Legalize from MHLO ops."),
+ clEnumValN(
+ InputDialectOptions::Type::xla, "xla",
+ "Legalize from MHLO ops (with XLA cleanup preprocessing).")),
+ llvm::cl::cat(inputDialectOptions));
+}
+
+void HighLevelOptimizationOptions::bindOptions(OptionsBinder &binder) {
+ static llvm::cl::OptionCategory category(
+ "IREE options for controlling high level optimizations.");
+
+ binder.opt<bool>(
+ "iree-opt-const-eval", constEval,
+ llvm::cl::desc("Enables eager evaluation of constants using the full "
+ "compiler and runtime."),
+ llvm::cl::cat(category));
+ binder.opt<bool>(
+ "iree-opt-const-expr-hoisting", constExprHoisting,
+ llvm::cl::desc(
+ "Hoists the results of latent constant expressions into immutable "
+ "global initializers for evaluation at program load."),
+ llvm::cl::cat(category));
+ binder.opt<bool>(
+ "iree-opt-numeric-precision-reduction", numericPrecisionReduction,
+ llvm::cl::desc(
+ "Reduces numeric precision to lower bit depths where possible."),
+ llvm::cl::cat(category));
+ binder.opt<bool>("iree-opt-strip-assertions", stripAssertions,
+ llvm::cl::desc("Strips debug assertions after any useful "
+ "information has been extracted."),
+ llvm::cl::cat(category));
+}
+
+void SchedulingOptions::bindOptions(OptionsBinder &binder) {
+ static llvm::cl::OptionCategory category(
+ "IREE options for controlling host/device scheduling.");
+
+ binder.opt<DumpOutputFormat>(
+ "iree-scheduling-dump-statistics-format", dumpStatisticsFormat,
+ llvm::cl::desc("Dumps statistics in the specified output format."),
+ llvm::cl::cat(category),
+ llvm::cl::values(
+ clEnumValN(DumpOutputFormat::Pretty, "pretty",
+ "Human-readable pretty printed output."),
+ clEnumValN(DumpOutputFormat::Verbose, "verbose",
+ "Pretty printed output with additional IR."),
+ clEnumValN(DumpOutputFormat::CSV, "csv", "Comma separated values."),
+ clEnumValN(DumpOutputFormat::JSON, "json",
+ "JSON output with structures for data exchange")));
+ binder.opt<std::string>("iree-scheduling-dump-statistics-file",
+ dumpStatisticsFile,
+ llvm::cl::desc("File path to write statistics to; or "
+ "`` for stderr or `-` for stdout."),
+ llvm::cl::cat(category));
+}
+
+} // namespace iree_compiler
+} // namespace mlir
diff --git a/iree/compiler/Pipelines/Options.h b/iree/compiler/Pipelines/Options.h
new file mode 100644
index 0000000..4648d49
--- /dev/null
+++ b/iree/compiler/Pipelines/Options.h
@@ -0,0 +1,104 @@
+// Copyright 2022 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
+
+#ifndef IREE_COMPILER_PIPELINES_OPTIONS_H_
+#define IREE_COMPILER_PIPELINES_OPTIONS_H_
+
+#include "iree/compiler/Utils/OptionUtils.h"
+
+namespace mlir {
+namespace iree_compiler {
+
+struct BindingOptions {
+ // Whether to include runtime support functions for the IREE native ABI.
+ bool native = true;
+ // Whether to include runtime support functions required for the IREE TFLite
+ // API compatibility bindings.
+ bool tflite = false;
+
+ void bindOptions(OptionsBinder &binder);
+ using FromFlags = OptionsFromFlags<BindingOptions>;
+};
+
+// The transformation to apply to the input prior to main compiler execution.
+// These input pipelines are purposefully primitive and mainly focused on
+// test case/reproducers as opposed to anything that should be coming from
+// a user. For user/framework level interfacing, a dedicated importer likely
+// needs to be created in order to represent whole-module level framework
+// quirks. These are just about the ops in the functions.
+struct InputDialectOptions {
+ enum class Type {
+ // Applies no input transformation. Only supported core and extension ops
+ // are supported.
+ none,
+ // Legalizes input defined over TOSA ops.
+ tosa,
+ // Legalizes input defined over MHLO ops.
+ mhlo,
+ // Special case of 'mhlo' legalization which also performs some XLA
+ // cleanup activities.
+ xla,
+ };
+ Type type = Type::none;
+
+ void bindOptions(OptionsBinder &binder);
+ using FromFlags = OptionsFromFlags<InputDialectOptions>;
+};
+
+// Options controlling high level optimizations.
+struct HighLevelOptimizationOptions {
+ // Enables const-expr hoisting into globals.
+ bool constExprHoisting = false;
+
+ // Enables recursive evaluation of immutable globals using the compiler
+ // and runtime.
+ bool constEval = false;
+
+ // Optimizations to reduce numeric precision where it is safe to do so.
+ bool numericPrecisionReduction = false;
+
+ // Strips debug assertions after any useful information has been extracted.
+ bool stripAssertions = false;
+
+ void bindOptions(OptionsBinder &binder);
+ using FromFlags = OptionsFromFlags<HighLevelOptimizationOptions>;
+};
+
+// Options controlling scheduling across host/device.
+struct SchedulingOptions {
+ // TODO(benvanik): find a way to share this with
+ // Stream/Transforms/PassDetail.h w/o circular deps.
+ // Defines the output format of a dump pass.
+ enum class DumpOutputFormat {
+ // Dumping disabled.
+ None = 0,
+ // Human-readable pretty printing.
+ Pretty = 1,
+ // Pretty printing with additional information that can result in large
+ // dumps.
+ Verbose = 2,
+ // Comma separated values for throwing into Sheets.
+ CSV = 3,
+ // JSON format for better structure and data exchange.
+ JSON = 4,
+ };
+ // Enables and specifies the the format for a stream statistics dump.
+ DumpOutputFormat dumpStatisticsFormat = DumpOutputFormat::None;
+ // File path to write statistics to; or `` for stderr or `-` for stdout.
+ std::string dumpStatisticsFile = "";
+
+ // TODO(benvanik): favor size/speed/etc for partitioning.
+ // TODO(benvanik): execution model to optimize for (unified/discrete memory,
+ // single/multiple processors, etc).
+
+ void bindOptions(OptionsBinder &binder);
+ using FromFlags = OptionsFromFlags<SchedulingOptions>;
+};
+
+} // namespace iree_compiler
+} // namespace mlir
+
+#endif // IREE_COMPILER_PIPELINES_OPTIONS_H_
diff --git a/iree/compiler/Pipelines/Pipelines.cpp b/iree/compiler/Pipelines/Pipelines.cpp
new file mode 100644
index 0000000..14fd07a
--- /dev/null
+++ b/iree/compiler/Pipelines/Pipelines.cpp
@@ -0,0 +1,97 @@
+// Copyright 2022 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/Pipelines/Pipelines.h"
+
+#include "iree/compiler/Bindings/Native/Transforms/Passes.h"
+#include "iree/compiler/Bindings/TFLite/Transforms/Passes.h"
+#include "iree/compiler/Dialect/Flow/Transforms/Passes.h"
+#include "iree/compiler/Dialect/HAL/Transforms/Passes.h"
+#include "iree/compiler/Dialect/Stream/Transforms/Passes.h"
+#include "iree/compiler/Dialect/Util/Transforms/Passes.h"
+#include "iree/compiler/Dialect/VM/Transforms/Passes.h"
+#include "iree/compiler/InputConversion/Common/Passes.h"
+#include "iree/compiler/InputConversion/MHLO/Passes.h"
+#include "iree/compiler/InputConversion/TOSA/Passes.h"
+
+namespace mlir {
+namespace iree_compiler {
+
+void buildIREEVMTransformPassPipeline(
+ BindingOptions bindingOptions, InputDialectOptions inputOptions,
+ HighLevelOptimizationOptions highLevelOptimizationOptions,
+ SchedulingOptions schedulingOptions,
+ IREE::HAL::TargetOptions executableOptions,
+ IREE::VM::TargetOptions targetOptions, IREEVMPipelineHooks &hooks,
+ OpPassManager &passManager) {
+ // Input pipelines can result in changes to the exported functions and types
+ // and must run before generating bindings.
+ // After input processing, there should only be IREE legal types in
+ // signatures.
+ switch (inputOptions.type) {
+ case InputDialectOptions::Type::none:
+ break;
+ case InputDialectOptions::Type::tosa:
+ buildTOSAInputConversionPassPipeline(passManager);
+ break;
+ case InputDialectOptions::Type::mhlo:
+ MHLO::buildMHLOInputConversionPassPipeline(passManager);
+ break;
+ case InputDialectOptions::Type::xla:
+ MHLO::buildXLACleanupPassPipeline(passManager);
+ MHLO::buildMHLOInputConversionPassPipeline(passManager);
+ break;
+ }
+ buildCommonInputConversionPassPipeline(passManager);
+
+ // Now that inputs are legalized, generate wrapper for entry functions.
+ if (bindingOptions.native) {
+ IREE::ABI::buildTransformPassPipeline(passManager);
+ }
+ if (bindingOptions.tflite) {
+ IREE::TFLite::buildTransformPassPipeline(passManager);
+ }
+
+ IREE::Flow::TransformOptions flowOptions;
+ flowOptions.constExprHoisting =
+ highLevelOptimizationOptions.constExprHoisting;
+ flowOptions.numericPrecisionReduction =
+ highLevelOptimizationOptions.numericPrecisionReduction;
+
+ // Enable const-eval via hook. For debug builds, we assert if enabled without
+ // a hook. For release, we just silently skip enabling const-eval.
+ if (highLevelOptimizationOptions.constEval) {
+ assert(hooks.buildConstEvalPassPipelineCallback &&
+ "if const-eval is enabled the buildConstEvalPassPipelineCallback "
+ "hook must be enabled");
+ }
+ if (highLevelOptimizationOptions.constEval &&
+ hooks.buildConstEvalPassPipelineCallback) {
+ flowOptions.buildConstEvalPassPipeline =
+ hooks.buildConstEvalPassPipelineCallback;
+ }
+
+ if (highLevelOptimizationOptions.stripAssertions) {
+ // Strip std.assert & co after we perform optimizations; prior to this we
+ // may use the assertions to derive information during analysis.
+ passManager.addPass(IREE::Util::createStripDebugOpsPass());
+ }
+
+ IREE::Stream::TransformOptions streamOptions;
+ // TODO(benvanik): find a way to share the enums w/o circular deps.
+ streamOptions.dumpStatisticsFormat =
+ (IREE::Stream::DumpOutputFormat)schedulingOptions.dumpStatisticsFormat;
+ streamOptions.dumpStatisticsFile = schedulingOptions.dumpStatisticsFile;
+
+ IREE::Flow::buildFlowTransformPassPipeline(passManager, flowOptions);
+ IREE::Stream::buildStreamTransformPassPipeline(passManager, streamOptions);
+ IREE::HAL::buildHALTransformPassPipeline(passManager, executableOptions);
+ IREE::VM::buildVMTransformPassPipeline(passManager, targetOptions);
+ passManager.addPass(IREE::Util::createDropCompilerHintsPass());
+}
+
+} // namespace iree_compiler
+} // namespace mlir
diff --git a/iree/compiler/Pipelines/Pipelines.h b/iree/compiler/Pipelines/Pipelines.h
new file mode 100644
index 0000000..b958286
--- /dev/null
+++ b/iree/compiler/Pipelines/Pipelines.h
@@ -0,0 +1,44 @@
+// Copyright 2022 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
+
+#ifndef IREE_COMPILER_PIPELINES_PIPELINES_H_
+#define IREE_COMPILER_PIPELINES_PIPELINES_H_
+
+#include "iree/compiler/Dialect/HAL/Target/TargetRegistry.h"
+#include "iree/compiler/Dialect/VM/Conversion/TargetOptions.h"
+#include "iree/compiler/Dialect/VM/Target/Bytecode/BytecodeModuleTarget.h"
+#include "iree/compiler/Pipelines/Options.h"
+#include "mlir/Pass/PassManager.h"
+
+namespace mlir {
+namespace iree_compiler {
+
+// Hooks for injecting behavior into the IREEVM pipeline. Since these are not
+// derived from CLI options, we maintain them as a separate struct.
+struct IREEVMPipelineHooks {
+ // If the HighLevelOptimizationOptions::constEval option is true, then
+ // this callback must be set to populate a pass manager to perform
+ // constant eval. It typically just adds a ConstEval::createJitGlobalsPass()
+ // pass. It must be injected like this to avoid circular dependencies from
+ // the constant evaluator, which needs to recursively invoke these
+ // pipelines.
+ std::function<void(OpPassManager &)> buildConstEvalPassPipelineCallback;
+};
+
+// Builds a pass pipeline to perform end-to-end compilation from a
+// supported MLIR-based input to the IREE vm dialect.
+void buildIREEVMTransformPassPipeline(
+ BindingOptions bindingOptions, InputDialectOptions inputOptions,
+ HighLevelOptimizationOptions highLevelOptimizationOptions,
+ SchedulingOptions schedulingOptions,
+ IREE::HAL::TargetOptions executableOptions,
+ IREE::VM::TargetOptions targetOptions, IREEVMPipelineHooks &hooks,
+ OpPassManager &passManager);
+
+} // namespace iree_compiler
+} // namespace mlir
+
+#endif // IREE_COMPILER_PIPELINES_PIPELINES_H_
diff --git a/iree/compiler/Pipelines/README.md b/iree/compiler/Pipelines/README.md
new file mode 100644
index 0000000..5096c4a
--- /dev/null
+++ b/iree/compiler/Pipelines/README.md
@@ -0,0 +1,5 @@
+# IREE Compiler Top-Level Pipelines
+
+This directory defines top-level compiler pipelines and tools integrations.
+It roughly depends on "everything" and is used to construct both CLI compiler
+tools and APIs.
diff --git a/iree/compiler/Translation/BUILD b/iree/compiler/Translation/BUILD
index 39fa7ee..246e24b 100644
--- a/iree/compiler/Translation/BUILD
+++ b/iree/compiler/Translation/BUILD
@@ -30,33 +30,15 @@
name = "IREEVM",
srcs = ["IREEVM.cpp"],
hdrs = ["IREEVM.h"],
- defines = [
- "IREE_HAVE_EMITC_DIALECT",
- ],
deps = [
- "//iree/compiler/Bindings/Native/Transforms",
- "//iree/compiler/Bindings/TFLite/Transforms",
"//iree/compiler/ConstEval",
"//iree/compiler/Dialect/Flow/IR",
- "//iree/compiler/Dialect/Flow/Transforms",
- "//iree/compiler/Dialect/HAL/Conversion/HALToVM",
"//iree/compiler/Dialect/HAL/Target",
- "//iree/compiler/Dialect/HAL/Transforms",
- "//iree/compiler/Dialect/Stream/Transforms",
- "//iree/compiler/Dialect/Util/Transforms",
- "//iree/compiler/Dialect/VM/Conversion",
- "//iree/compiler/Dialect/VM/Conversion/StandardToVM",
- "//iree/compiler/Dialect/VM/Target/Bytecode",
"//iree/compiler/Dialect/VM/Target/C",
- "//iree/compiler/Dialect/VM/Transforms",
- "//iree/compiler/InputConversion/Common",
- "//iree/compiler/InputConversion/MHLO",
- "//iree/compiler/InputConversion/TOSA",
+ "//iree/compiler/Pipelines",
+ "//iree/compiler/Pipelines:Options",
"//iree/compiler/Utils",
- "@llvm-project//llvm:Support",
- "@llvm-project//mlir:IR",
"@llvm-project//mlir:Pass",
- "@llvm-project//mlir:Support",
"@llvm-project//mlir:Translation",
],
)
diff --git a/iree/compiler/Translation/CMakeLists.txt b/iree/compiler/Translation/CMakeLists.txt
index 5ce302b..8c8aab5 100644
--- a/iree/compiler/Translation/CMakeLists.txt
+++ b/iree/compiler/Translation/CMakeLists.txt
@@ -1,18 +1,15 @@
-# Copyright 2019 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
+################################################################################
+# Autogenerated by build_tools/bazel_to_cmake/bazel_to_cmake.py from #
+# iree/compiler/Translation/BUILD #
+# #
+# Use iree_cmake_extra_content from iree/build_defs.oss.bzl to add arbitrary #
+# CMake-only content. #
+# #
+# To disable autogeneration for this file entirely, delete this header. #
+################################################################################
iree_add_all_subdirs()
-if(IREE_ENABLE_EMITC)
- set(IREE_VM_CONDITIONAL_TARGETS
- iree::compiler::Dialect::VM::Target::C
- )
-endif()
-
-
iree_cc_library(
NAME
HALExecutable
@@ -40,28 +37,16 @@
SRCS
"IREEVM.cpp"
DEPS
- LLVMSupport
- MLIRIR
MLIRPass
- MLIRSupport
MLIRTranslateLib
- iree::compiler::Bindings::Native::Transforms
- iree::compiler::Bindings::TFLite::Transforms
iree::compiler::ConstEval
iree::compiler::Dialect::Flow::IR
- iree::compiler::Dialect::Flow::Transforms
- iree::compiler::Dialect::HAL::Conversion::HALToVM
iree::compiler::Dialect::HAL::Target
- iree::compiler::Dialect::HAL::Transforms
- iree::compiler::Dialect::Stream::Transforms
- iree::compiler::Dialect::Util::Transforms
- iree::compiler::Dialect::VM::Conversion
- iree::compiler::Dialect::VM::Conversion::StandardToVM
- iree::compiler::Dialect::VM::Target::Bytecode
- iree::compiler::Dialect::VM::Transforms
- iree::compiler::InputConversion::MHLO
- iree::compiler::InputConversion::TOSA
+ iree::compiler::Dialect::VM::Target::C
+ iree::compiler::Pipelines
+ iree::compiler::Pipelines::Options
iree::compiler::Utils
- ${IREE_VM_CONDITIONAL_TARGETS}
PUBLIC
)
+
+### BAZEL_TO_CMAKE_PRESERVES_ALL_CONTENT_BELOW_THIS_LINE ###
diff --git a/iree/compiler/Translation/IREEVM.cpp b/iree/compiler/Translation/IREEVM.cpp
index 8e0bf84..b31abd8 100644
--- a/iree/compiler/Translation/IREEVM.cpp
+++ b/iree/compiler/Translation/IREEVM.cpp
@@ -6,20 +6,10 @@
#include "iree/compiler/Translation/IREEVM.h"
-#include "iree/compiler/Bindings/Native/Transforms/Passes.h"
-#include "iree/compiler/Bindings/TFLite/Transforms/Passes.h"
#include "iree/compiler/ConstEval/Passes.h"
-#include "iree/compiler/Dialect/Flow/Transforms/Passes.h"
-#include "iree/compiler/Dialect/HAL/Transforms/Passes.h"
-#include "iree/compiler/Dialect/Stream/Transforms/Passes.h"
-#include "iree/compiler/Dialect/Util/Transforms/Passes.h"
-#include "iree/compiler/Dialect/VM/Transforms/Passes.h"
-#include "iree/compiler/InputConversion/Common/Passes.h"
-#include "iree/compiler/InputConversion/MHLO/Passes.h"
-#include "iree/compiler/InputConversion/TOSA/Passes.h"
+#include "iree/compiler/Pipelines/Pipelines.h"
#include "iree/compiler/Utils/PassUtils.h"
#include "iree/compiler/Utils/TracingUtils.h"
-#include "mlir/IR/BuiltinOps.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Tools/mlir-translate/Translation.h"
@@ -31,153 +21,16 @@
namespace mlir {
namespace iree_compiler {
-void BindingOptions::bindOptions(OptionsBinder &binder) {
- static llvm::cl::OptionCategory bindingOptionsCategory(
- "IREE translation binding support options.");
+namespace {
- binder.opt<bool>(
- "iree-native-bindings-support", native,
- llvm::cl::desc(
- "Include runtime support for native IREE ABI-compatible bindings."),
- llvm::cl::cat(bindingOptionsCategory));
- binder.opt<bool>("iree-tflite-bindings-support", tflite,
- llvm::cl::desc("Include runtime support for the IREE TFLite "
- "compatibility bindings."),
- llvm::cl::cat(bindingOptionsCategory));
+IREEVMPipelineHooks &getHooks() {
+ static IREEVMPipelineHooks hooks = {
+ // buildConstEvalPassPipelineCallback =
+ [](OpPassManager &pm) { pm.addPass(ConstEval::createJitGlobalsPass()); }};
+ return hooks;
}
-void InputDialectOptions::bindOptions(OptionsBinder &binder) {
- static llvm::cl::OptionCategory inputDialectOptions(
- "IREE options for controlling the input transformations to apply.");
-
- binder.opt<InputDialectOptions::Type>(
- "iree-input-type", type,
- llvm::cl::desc("Specifies the input program representation."),
- llvm::cl::values(
- clEnumValN(InputDialectOptions::Type::none, "none",
- "No input dialect transformation."),
- clEnumValN(InputDialectOptions::Type::tosa, "tosa",
- "Legalize from TOSA ops."),
- clEnumValN(InputDialectOptions::Type::mhlo, "mhlo",
- "Legalize from MHLO ops."),
- clEnumValN(
- InputDialectOptions::Type::xla, "xla",
- "Legalize from MHLO ops (with XLA cleanup preprocessing).")),
- llvm::cl::cat(inputDialectOptions));
-}
-
-void HighLevelOptimizationOptions::bindOptions(OptionsBinder &binder) {
- static llvm::cl::OptionCategory category(
- "IREE options for controlling high level optimizations.");
-
- binder.opt<bool>(
- "iree-opt-const-eval", constEval,
- llvm::cl::desc("Enables eager evaluation of constants using the full "
- "compiler and runtime."),
- llvm::cl::cat(category));
- binder.opt<bool>(
- "iree-opt-const-expr-hoisting", constExprHoisting,
- llvm::cl::desc(
- "Hoists the results of latent constant expressions into immutable "
- "global initializers for evaluation at program load."),
- llvm::cl::cat(category));
- binder.opt<bool>(
- "iree-opt-numeric-precision-reduction", numericPrecisionReduction,
- llvm::cl::desc(
- "Reduces numeric precision to lower bit depths where possible."),
- llvm::cl::cat(category));
- binder.opt<bool>("iree-opt-strip-assertions", stripAssertions,
- llvm::cl::desc("Strips debug assertions after any useful "
- "information has been extracted."),
- llvm::cl::cat(category));
-}
-
-void SchedulingOptions::bindOptions(OptionsBinder &binder) {
- static llvm::cl::OptionCategory category(
- "IREE options for controlling host/device scheduling.");
-
- binder.opt<DumpOutputFormat>(
- "iree-scheduling-dump-statistics-format", dumpStatisticsFormat,
- llvm::cl::desc("Dumps statistics in the specified output format."),
- llvm::cl::cat(category),
- llvm::cl::values(
- clEnumValN(DumpOutputFormat::Pretty, "pretty",
- "Human-readable pretty printed output."),
- clEnumValN(DumpOutputFormat::Verbose, "verbose",
- "Pretty printed output with additional IR."),
- clEnumValN(DumpOutputFormat::CSV, "csv", "Comma separated values."),
- clEnumValN(DumpOutputFormat::JSON, "json",
- "JSON output with structures for data exchange")));
- binder.opt<std::string>("iree-scheduling-dump-statistics-file",
- dumpStatisticsFile,
- llvm::cl::desc("File path to write statistics to; or "
- "`` for stderr or `-` for stdout."),
- llvm::cl::cat(category));
-}
-
-void buildIREEVMTransformPassPipeline(
- BindingOptions bindingOptions, InputDialectOptions inputOptions,
- HighLevelOptimizationOptions highLevelOptimizationOptions,
- SchedulingOptions schedulingOptions,
- IREE::HAL::TargetOptions executableOptions,
- IREE::VM::TargetOptions targetOptions, OpPassManager &passManager) {
- // Input pipelines can result in changes to the exported functions and types
- // and must run before generating bindings.
- // After input processing, there should only be IREE legal types in
- // signatures.
- switch (inputOptions.type) {
- case InputDialectOptions::Type::none:
- break;
- case InputDialectOptions::Type::tosa:
- buildTOSAInputConversionPassPipeline(passManager);
- break;
- case InputDialectOptions::Type::mhlo:
- MHLO::buildMHLOInputConversionPassPipeline(passManager);
- break;
- case InputDialectOptions::Type::xla:
- MHLO::buildXLACleanupPassPipeline(passManager);
- MHLO::buildMHLOInputConversionPassPipeline(passManager);
- break;
- }
- buildCommonInputConversionPassPipeline(passManager);
-
- // Now that inputs are legalized, generate wrapper for entry functions.
- if (bindingOptions.native) {
- IREE::ABI::buildTransformPassPipeline(passManager);
- }
- if (bindingOptions.tflite) {
- IREE::TFLite::buildTransformPassPipeline(passManager);
- }
-
- IREE::Flow::TransformOptions flowOptions;
- flowOptions.constExprHoisting =
- highLevelOptimizationOptions.constExprHoisting;
- if (highLevelOptimizationOptions.constEval) {
- flowOptions.buildConstEvalPassPipeline = [](OpPassManager &passManager) {
- passManager.addPass(ConstEval::createJitGlobalsPass());
- };
- }
- flowOptions.numericPrecisionReduction =
- highLevelOptimizationOptions.numericPrecisionReduction;
-
- if (highLevelOptimizationOptions.stripAssertions) {
- // Strip std.assert & co after we perform optimizations; prior to this we
- // may use the assertions to derive information during analysis.
- passManager.addPass(IREE::Util::createStripDebugOpsPass());
- }
-
- IREE::Stream::TransformOptions streamOptions;
- // TODO(benvanik): find a way to share the enums w/o circular deps.
- streamOptions.dumpStatisticsFormat =
- (IREE::Stream::DumpOutputFormat)schedulingOptions.dumpStatisticsFormat;
- streamOptions.dumpStatisticsFile = schedulingOptions.dumpStatisticsFile;
-
- IREE::Flow::buildFlowTransformPassPipeline(passManager, flowOptions);
- IREE::Stream::buildStreamTransformPassPipeline(passManager, streamOptions);
- IREE::HAL::buildHALTransformPassPipeline(passManager, executableOptions);
- IREE::VM::buildVMTransformPassPipeline(passManager, targetOptions);
- passManager.addPass(IREE::Util::createDropCompilerHintsPass());
-}
+} // namespace
void buildDefaultIREEVMTransformPassPipeline(OpPassManager &passManager) {
buildIREEVMTransformPassPipeline(
@@ -185,7 +38,7 @@
HighLevelOptimizationOptions::FromFlags::get(),
SchedulingOptions::FromFlags::get(),
IREE::HAL::TargetOptions::FromFlags::get(),
- IREE::VM::TargetOptions::FromFlags::get(), passManager);
+ IREE::VM::TargetOptions::FromFlags::get(), getHooks(), passManager);
}
void registerIREEVMTransformPassPipeline() {
@@ -211,11 +64,13 @@
mlir::applyPassManagerCLOptions(passManager);
mlir::applyDefaultTimingPassManagerCLOptions(passManager);
passManager.addInstrumentation(std::make_unique<PassTracing>());
- buildIREEVMTransformPassPipeline(
- bindingOptions, inputOptions, highLevelOptimizationOptions,
- schedulingOptions, executableOptions, targetOptions, passManager);
+ buildIREEVMTransformPassPipeline(bindingOptions, inputOptions,
+ highLevelOptimizationOptions,
+ schedulingOptions, executableOptions,
+ targetOptions, getHooks(), passManager);
if (failed(passManager.run(moduleOp))) {
- return moduleOp.emitError() << "conversion from source -> vm failed";
+ llvm::errs() << "compilation from source to vm failed\n";
+ return failure();
}
return success();
}
diff --git a/iree/compiler/Translation/IREEVM.h b/iree/compiler/Translation/IREEVM.h
index 4f9608f..ab19f05 100644
--- a/iree/compiler/Translation/IREEVM.h
+++ b/iree/compiler/Translation/IREEVM.h
@@ -10,6 +10,7 @@
#include "iree/compiler/Dialect/HAL/Target/TargetRegistry.h"
#include "iree/compiler/Dialect/VM/Conversion/TargetOptions.h"
#include "iree/compiler/Dialect/VM/Target/Bytecode/BytecodeModuleTarget.h"
+#include "iree/compiler/Pipelines/Options.h"
#include "iree/compiler/Utils/OptionUtils.h"
#include "llvm/Support/raw_ostream.h"
#include "mlir/IR/BuiltinOps.h"
@@ -19,108 +20,9 @@
namespace mlir {
namespace iree_compiler {
-// TODO(#3817): move all of this code to the iree-compile driver/API.
-// Breaking this up such that for development iree-opt runs all passes/pipelines
-// and iree-translate strictly does the VM dialect to bytecode/emitc files will
-// match upstream better, and then our own iree-compile C API/binary will do the
-// whole end-to-end with options for bindings/targets/etc.
-struct BindingOptions {
- // Whether to include runtime support functions for the IREE native ABI.
- bool native = true;
- // Whether to include runtime support functions required for the IREE TFLite
- // API compatibility bindings.
- bool tflite = false;
-
- void bindOptions(OptionsBinder &binder);
- using FromFlags = OptionsFromFlags<BindingOptions>;
-};
-
-// The transformation to apply to the input prior to main compiler execution.
-// These input pipelines are purposefully primitive and mainly focused on
-// test case/reproducers as opposed to anything that should be coming from
-// a user. For user/framework level interfacing, a dedicated importer likely
-// needs to be created in order to represent whole-module level framework
-// quirks. These are just about the ops in the functions.
-struct InputDialectOptions {
- enum class Type {
- // Applies no input transformation. Only supported core and extension ops
- // are supported.
- none,
- // Legalizes input defined over TOSA ops.
- tosa,
- // Legalizes input defined over MHLO ops.
- mhlo,
- // Special case of 'mhlo' legalization which also performs some XLA
- // cleanup activities.
- xla,
- };
- Type type = Type::none;
-
- void bindOptions(OptionsBinder &binder);
- using FromFlags = OptionsFromFlags<InputDialectOptions>;
-};
-
-// Options controlling high level optimizations.
-struct HighLevelOptimizationOptions {
- // Enables const-expr hoisting into globals.
- bool constExprHoisting = false;
-
- // Enables recursive evaluation of immutable globals using the compiler
- // and runtime.
- bool constEval = false;
-
- // Optimizations to reduce numeric precision where it is safe to do so.
- bool numericPrecisionReduction = false;
-
- // Strips debug assertions after any useful information has been extracted.
- bool stripAssertions = false;
-
- void bindOptions(OptionsBinder &binder);
- using FromFlags = OptionsFromFlags<HighLevelOptimizationOptions>;
-};
-
-// Options controlling scheduling across host/device.
-struct SchedulingOptions {
- // TODO(benvanik): find a way to share this with
- // Stream/Transforms/PassDetail.h w/o circular deps.
- // Defines the output format of a dump pass.
- enum class DumpOutputFormat {
- // Dumping disabled.
- None = 0,
- // Human-readable pretty printing.
- Pretty = 1,
- // Pretty printing with additional information that can result in large
- // dumps.
- Verbose = 2,
- // Comma separated values for throwing into Sheets.
- CSV = 3,
- // JSON format for better structure and data exchange.
- JSON = 4,
- };
- // Enables and specifies the the format for a stream statistics dump.
- DumpOutputFormat dumpStatisticsFormat = DumpOutputFormat::None;
- // File path to write statistics to; or `` for stderr or `-` for stdout.
- std::string dumpStatisticsFile = "";
-
- // TODO(benvanik): favor size/speed/etc for partitioning.
- // TODO(benvanik): execution model to optimize for (unified/discrete memory,
- // single/multiple processors, etc).
-
- void bindOptions(OptionsBinder &binder);
- using FromFlags = OptionsFromFlags<SchedulingOptions>;
-};
-
// Builds the translation pipeline with defaults.
void buildDefaultIREEVMTransformPassPipeline(OpPassManager &passManager);
-// Builds the translation pipeline with explicit options.
-void buildIREEVMTransformPassPipeline(
- BindingOptions bindingOptions, InputDialectOptions inputOptions,
- HighLevelOptimizationOptions highLevelOptimizationOptions,
- SchedulingOptions schedulingOptions,
- IREE::HAL::TargetOptions executableOptions,
- IREE::VM::TargetOptions targetOptions, OpPassManager &passManager);
-
// Registration hooks.
void registerIREEVMTransformPassPipeline();
void registerIREEVMTranslation();
diff --git a/iree/tools/BUILD b/iree/tools/BUILD
index ed0414c..6c4b3b2 100644
--- a/iree/tools/BUILD
+++ b/iree/tools/BUILD
@@ -131,10 +131,8 @@
"init_mlir_dialects.h",
"init_mlir_passes.h",
],
- defines = [
- "IREE_HAVE_EMITC_DIALECT",
- ],
deps = [
+ "//iree/compiler/Dialect/VM/Target/C:Enabled",
"@llvm-project//mlir:Affine",
"@llvm-project//mlir:AffineTransforms",
"@llvm-project//mlir:ArmNeon",
@@ -381,7 +379,10 @@
cc_library(
name = "iree_translate_lib",
- srcs = ["iree_translate_lib.cc"],
+ srcs = [
+ "iree_translate_lib.cc",
+ "ireec_lib.cc",
+ ],
hdrs = ["iree_translate_lib.h"],
deps = [
":init_compiler_modules",
@@ -392,14 +393,19 @@
":init_translations",
":init_xla_dialects",
"//iree/compiler/Codegen",
+ "//iree/compiler/ConstEval",
"//iree/compiler/Dialect/VM/Target:init_targets",
"//iree/compiler/Dialect/VM/Target/Bytecode",
+ "//iree/compiler/Dialect/VM/Target/C",
+ "//iree/compiler/Pipelines",
"//iree/compiler/Translation:HALExecutable",
"//iree/compiler/Translation:IREEVM",
+ "//iree/compiler/Utils",
"@llvm-project//llvm:Support",
"@llvm-project//mlir:ArmNeonToLLVMIRTranslation",
"@llvm-project//mlir:IR",
"@llvm-project//mlir:LLVMToLLVMIRTranslation",
+ "@llvm-project//mlir:Parser",
"@llvm-project//mlir:Pass",
"@llvm-project//mlir:SCFTransforms",
"@llvm-project//mlir:Support",
@@ -416,3 +422,12 @@
":iree_translate_lib",
],
)
+
+cc_binary(
+ name = "ireec",
+ srcs = ["ireec-main.cc"],
+ tags = ["hostonly"],
+ deps = [
+ ":iree_translate_lib",
+ ],
+)
diff --git a/iree/tools/CMakeLists.txt b/iree/tools/CMakeLists.txt
index 45a47c7..fa8e3bb 100644
--- a/iree/tools/CMakeLists.txt
+++ b/iree/tools/CMakeLists.txt
@@ -59,12 +59,6 @@
list(APPEND IREE_COMPILER_TARGET_COPTS "-DIREE_HAVE_ROCM_TARGET")
endif()
-if(IREE_ENABLE_EMITC)
- set(IREE_EMITC_CONDITIONAL_DEP
- MLIREmitC
- )
-endif()
-
iree_cc_binary(
NAME
iree-benchmark-module
@@ -264,6 +258,9 @@
"init_mlir_dialects.h"
"init_mlir_passes.h"
DEPS
+ # Sets IREE_HAVE_EMITC_DIALECT and transitively depends on MLIREmitC
+ # if enabled.
+ iree::compiler::Dialect::VM::Target::C::Enabled
MLIRAffine
MLIRAffineTransforms
MLIRArmNeon
@@ -293,7 +290,6 @@
MLIRTosaTransforms
MLIRTransforms
MLIRVector
- ${IREE_EMITC_CONDITIONAL_DEP}
PUBLIC
)
@@ -380,6 +376,7 @@
HDRS
"iree_translate_lib.h"
SRCS
+ "ireec_lib.cc"
"iree_translate_lib.cc"
DEPS
::init_compiler_modules
@@ -393,15 +390,20 @@
MLIRArmNeonToLLVMIRTranslation
MLIRLLVMToLLVMIRTranslation
MLIRSCFTransforms
+ MLIRParser
MLIRPass
MLIRSupport
MLIRTargetLLVMIRExport
MLIRTranslateLib
iree::compiler::Codegen::Codegen
+ iree::compiler::ConstEval
iree::compiler::Dialect::VM::Target::Bytecode
iree::compiler::Dialect::VM::Target::init_targets
+ iree::compiler::Dialect::VM::Target::C
+ iree::compiler::Pipelines
iree::compiler::Translation::HALExecutable
iree::compiler::Translation::IREEVM
+ iree::compiler::Utils
PUBLIC
)
@@ -419,6 +421,20 @@
iree_cc_binary(
NAME
+ ireec
+ SRCS
+ "ireec-main.cc"
+ DEPS
+ ::iree_translate_lib
+ DATA
+ ${IREE_LLD_TARGET}
+ HOSTONLY
+ # TODO: Enable when ready. Excluded for now to save build time for folks.
+ EXCLUDE_FROM_ALL
+ )
+
+ iree_cc_binary(
+ NAME
iree-opt
DEPS
::iree_opt_main
diff --git a/iree/tools/iree_translate_lib.cc b/iree/tools/iree_translate_lib.cc
index 0c8c768..9c9a3b2 100644
--- a/iree/tools/iree_translate_lib.cc
+++ b/iree/tools/iree_translate_lib.cc
@@ -40,6 +40,8 @@
#include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
#include "mlir/Tools/mlir-translate/Translation.h"
+// TODO: Once we are switched to runIreecMain, this can be slimmed down
+// substantially, since it will just be about testing actual translations.
int mlir::iree_compiler::runIreeTranslateMain(int argc, char **argv) {
llvm::InitLLVM y(argc, argv);
mlir::DialectRegistry registry;
diff --git a/iree/tools/iree_translate_lib.h b/iree/tools/iree_translate_lib.h
index 572e03a..d964d2e 100644
--- a/iree/tools/iree_translate_lib.h
+++ b/iree/tools/iree_translate_lib.h
@@ -12,6 +12,12 @@
int runIreeTranslateMain(int argc, char **argv);
+// NOTE: We are transitioning from the main compiler being based on
+// the MLIR translation library (i.e. iree-translate) to a dedicated tool
+// called ireec. When this is done, the above should go away and this file
+// should be renamed to ireec_lib.h.
+int runIreecMain(int argc, char **argv);
+
} // namespace iree_compiler
} // namespace mlir
diff --git a/iree/tools/ireec-main.cc b/iree/tools/ireec-main.cc
new file mode 100644
index 0000000..ec65906
--- /dev/null
+++ b/iree/tools/ireec-main.cc
@@ -0,0 +1,11 @@
+// Copyright 2022 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/tools/iree_translate_lib.h"
+
+int main(int argc, char **argv) {
+ return mlir::iree_compiler::runIreecMain(argc, argv);
+}
diff --git a/iree/tools/ireec_lib.cc b/iree/tools/ireec_lib.cc
new file mode 100644
index 0000000..0ef5b78
--- /dev/null
+++ b/iree/tools/ireec_lib.cc
@@ -0,0 +1,251 @@
+// Copyright 2022 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 <functional>
+#include <memory>
+#include <string>
+#include <type_traits>
+
+#include "iree/compiler/ConstEval/Passes.h"
+#include "iree/compiler/Dialect/VM/Target/init_targets.h"
+#include "iree/compiler/Pipelines/Pipelines.h"
+#include "iree/compiler/Utils/PassUtils.h"
+#include "iree/compiler/Utils/TracingUtils.h"
+#include "iree/tools/init_compiler_modules.h"
+#include "iree/tools/init_iree_dialects.h"
+#include "iree/tools/init_mlir_dialects.h"
+#include "iree/tools/init_passes.h"
+#include "iree/tools/init_targets.h"
+#include "iree/tools/init_xla_dialects.h"
+#include "iree/tools/iree_translate_lib.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SMLoc.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/raw_ostream.h"
+#include "mlir/IR/AsmState.h"
+#include "mlir/IR/Diagnostics.h"
+#include "mlir/IR/Dialect.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/Verifier.h"
+#include "mlir/Parser/Parser.h"
+#include "mlir/Pass/PassManager.h"
+#include "mlir/Support/FileUtilities.h"
+#include "mlir/Support/LogicalResult.h"
+#include "mlir/Support/Timing.h"
+#include "mlir/Support/ToolUtilities.h"
+#include "mlir/Tools/mlir-translate/Translation.h"
+
+#ifdef IREE_HAVE_EMITC_DIALECT
+#include "iree/compiler/Dialect/VM/Target/C/CModuleTarget.h"
+#include "iree/compiler/Dialect/VM/Target/C/TranslationFlags.h"
+#endif // IREE_HAVE_EMITC_DIALECT
+
+namespace mlir {
+namespace iree_compiler {
+
+namespace {
+
+enum class OutputFormat {
+ none,
+ vm_asm,
+ vm_bytecode,
+ vm_c,
+};
+
+IREEVMPipelineHooks &getHooks() {
+ static IREEVMPipelineHooks hooks = {
+ // buildConstEvalPassPipelineCallback =
+ [](OpPassManager &pm) { pm.addPass(ConstEval::createJitGlobalsPass()); }};
+ return hooks;
+}
+
+} // namespace
+
+} // namespace iree_compiler
+} // namespace mlir
+
+int mlir::iree_compiler::runIreecMain(int argc, char **argv) {
+ llvm::InitLLVM y(argc, argv);
+ mlir::DialectRegistry registry;
+ static llvm::cl::OptionCategory mainOptions("IREE Main Options");
+
+ mlir::registerMlirDialects(registry);
+ // TODO: Make this conditional?
+ mlir::registerXLADialects(registry);
+ mlir::iree_compiler::registerAllPasses();
+ mlir::iree_compiler::registerIreeDialects(registry);
+ mlir::iree_compiler::registerIreeCompilerModuleDialects(registry);
+ mlir::iree_compiler::registerHALTargetBackends();
+ mlir::iree_compiler::registerVMTargets();
+
+ // Register MLIRContext command-line options like
+ // -mlir-print-op-on-diagnostic.
+ mlir::registerMLIRContextCLOptions();
+ // Register assembly printer command-line options like
+ // -mlir-print-op-generic.
+ mlir::registerAsmPrinterCLOptions();
+ // Register pass manager command-line options like -print-ir-*.
+ mlir::registerPassManagerCLOptions();
+ mlir::registerDefaultTimingManagerCLOptions();
+
+ // Flag options structs (must resolve prior to CLI parsing).
+ auto &bindingOptions = BindingOptions::FromFlags::get();
+ auto &inputOptions = InputDialectOptions::FromFlags::get();
+ auto &highLevelOptimizationOptions =
+ HighLevelOptimizationOptions::FromFlags::get();
+ auto &schedulingOptions = SchedulingOptions::FromFlags::get();
+ auto &halTargetOptions = IREE::HAL::TargetOptions::FromFlags::get();
+ auto &vmTargetOptions = IREE::VM::TargetOptions::FromFlags::get();
+ auto &bytecodeTargetOptions =
+ IREE::VM::BytecodeTargetOptions::FromFlags::get();
+
+ // General command line flags.
+ llvm::cl::opt<std::string> inputFilename(
+ llvm::cl::Positional, llvm::cl::desc("<input file or '-' for stdin>"),
+ llvm::cl::Required, llvm::cl::cat(mainOptions));
+
+ llvm::cl::opt<std::string> outputFilename(
+ "o", llvm::cl::desc("Output filename"), llvm::cl::value_desc("filename"),
+ llvm::cl::init("-"), llvm::cl::cat(mainOptions));
+
+ // The output format flag is the master control for what we do with the
+ // in-memory compiled form.
+ llvm::cl::opt<OutputFormat> outputFormat(
+ "output-format", llvm::cl::desc("Format of compiled output"),
+ llvm::cl::values(
+ clEnumValN(OutputFormat::vm_bytecode, "vm-bytecode",
+ "IREE VM Bytecode (default)"),
+#ifdef IREE_HAVE_EMITC_DIALECT
+ clEnumValN(OutputFormat::vm_c, "vm-c", "C source module"),
+#endif
+ clEnumValN(OutputFormat::vm_asm, "vm-asm", "IREE VM MLIR Assembly")),
+ llvm::cl::init(OutputFormat::none), llvm::cl::cat(mainOptions));
+
+ llvm::cl::opt<bool> legacyTranslateToCModule(
+ "iree-mlir-to-vm-c-module",
+ llvm::cl::desc("Alias for --output-format=c-module (deprecated)"),
+ llvm::cl::init(false));
+ llvm::cl::opt<bool> legacyTranslateToVMBytecodeModule(
+ "iree-mlir-to-vm-bytecode-module",
+ llvm::cl::desc("Alias for --output-format=vm-bytecode (deprecated)"),
+ llvm::cl::init(false));
+
+ // Misc options.
+ llvm::cl::opt<bool> splitInputFile(
+ "split-input-file",
+ llvm::cl::desc("Split the input file into pieces and "
+ "process each chunk independently"),
+ llvm::cl::init(false));
+
+// Optional output formats.
+#ifdef IREE_HAVE_EMITC_DIALECT
+ auto cTargetOptions = IREE::VM::getCTargetOptionsFromFlags();
+#endif
+
+ llvm::cl::ParseCommandLineOptions(argc, argv, "IREE compilation driver\n");
+
+ // Post-process and select the correct outputFormat.
+ if (legacyTranslateToCModule) {
+ if (outputFormat != OutputFormat::none) {
+ llvm::errs()
+ << "Cannot specify --output-format= and --iree-mlir-to-vm-c-module\n";
+ return 1;
+ }
+ outputFormat = OutputFormat::vm_c;
+ }
+ if (legacyTranslateToVMBytecodeModule) {
+ if (outputFormat != OutputFormat::none) {
+ llvm::errs() << "Cannot specify --output-format= and "
+ "--iree-mlir-to-vm-bytecode-module\n";
+ return 1;
+ }
+ outputFormat = OutputFormat::vm_bytecode;
+ }
+
+ // Defualt output format.
+ if (outputFormat == OutputFormat::none) {
+ outputFormat = OutputFormat::vm_bytecode;
+ }
+
+ std::string errorMessage;
+ auto input = mlir::openInputFile(inputFilename, &errorMessage);
+ if (!input) {
+ llvm::errs() << errorMessage << "\n";
+ return 1;
+ }
+
+ auto output = mlir::openOutputFile(outputFilename, &errorMessage);
+ if (!output) {
+ llvm::errs() << errorMessage << "\n";
+ return 1;
+ }
+
+ /// Processes the memory buffer with a new MLIRContext.
+ auto processBuffer = [&](std::unique_ptr<llvm::MemoryBuffer> ownedBuffer,
+ llvm::raw_ostream &os) -> LogicalResult {
+ mlir::MLIRContext context;
+ context.allowUnregisteredDialects();
+ context.appendDialectRegistry(registry);
+ llvm::SourceMgr sourceMgr;
+ sourceMgr.AddNewSourceBuffer(std::move(ownedBuffer), llvm::SMLoc());
+ mlir::SourceMgrDiagnosticHandler diagHandler(sourceMgr, &context);
+
+ // Parse source.
+ auto module = parseSourceFile<ModuleOp>(sourceMgr, &context);
+ if (!module || failed(verify(*module))) {
+ return failure();
+ }
+
+ // Main compilation pipeline.
+ PassManager passManager(&context);
+ mlir::applyPassManagerCLOptions(passManager);
+ mlir::applyDefaultTimingPassManagerCLOptions(passManager);
+ passManager.addInstrumentation(std::make_unique<PassTracing>());
+ buildIREEVMTransformPassPipeline(bindingOptions, inputOptions,
+ highLevelOptimizationOptions,
+ schedulingOptions, halTargetOptions,
+ vmTargetOptions, getHooks(), passManager);
+ if (failed(passManager.run(module.get()))) {
+ llvm::errs() << "compilation from source to vm failed\n";
+ return failure();
+ }
+
+ // Switch based on output format.
+ switch (outputFormat) {
+ case OutputFormat::vm_asm:
+ os << module.get();
+ return success();
+ case OutputFormat::vm_bytecode:
+ return translateModuleToBytecode(module.get(), bytecodeTargetOptions,
+ os);
+#ifdef IREE_HAVE_EMITC_DIALECT
+ case OutputFormat::vm_c:
+ return mlir::iree_compiler::IREE::VM::translateModuleToC(
+ module.get(), cTargetOptions, os);
+#endif
+ default:
+ llvm::errs() << "INTERNAL ERROR: Unknown output format\n";
+ return failure();
+ }
+
+ return failure();
+ };
+
+ if (splitInputFile) {
+ if (failed(mlir::splitAndProcessBuffer(std::move(input), processBuffer,
+ output->os())))
+ return 1;
+ } else {
+ if (failed(processBuffer(std::move(input), output->os()))) return 1;
+ }
+
+ output->keep();
+ return 0;
+}
diff --git a/llvm-external-projects/iree-compiler-api/BUILD.bazel b/llvm-external-projects/iree-compiler-api/BUILD.bazel
index f103ced..98ff213 100644
--- a/llvm-external-projects/iree-compiler-api/BUILD.bazel
+++ b/llvm-external-projects/iree-compiler-api/BUILD.bazel
@@ -64,11 +64,12 @@
],
includes = ["include"],
deps = [
+ "//iree/compiler/ConstEval",
"//iree/compiler/Dialect/VM/IR",
"//iree/compiler/Dialect/VM/Target/Bytecode",
"//iree/compiler/InputConversion/MHLO",
"//iree/compiler/InputConversion/TOSA",
- "//iree/compiler/Translation:IREEVM",
+ "//iree/compiler/Pipelines",
"//iree/compiler/Utils",
"//iree/tools:init_targets",
"//iree/tools:iree_translate_lib",
diff --git a/llvm-external-projects/iree-compiler-api/lib/CAPI/CMakeLists.txt b/llvm-external-projects/iree-compiler-api/lib/CAPI/CMakeLists.txt
index 4226ead..1b4d785 100644
--- a/llvm-external-projects/iree-compiler-api/lib/CAPI/CMakeLists.txt
+++ b/llvm-external-projects/iree-compiler-api/lib/CAPI/CMakeLists.txt
@@ -25,11 +25,12 @@
Support
LINK_LIBS PUBLIC
MLIRIR
+ iree::compiler::ConstEval
iree::compiler::InputConversion::MHLO::MHLO
iree::compiler::InputConversion::TOSA::TOSA
iree::compiler::Dialect::VM::IR::IR
iree::compiler::Dialect::VM::Target::Bytecode::Bytecode
- iree::compiler::Translation::IREEVM
+ iree::compiler::Pipelines
# All HAL Targets.
iree::tools::init_targets
diff --git a/llvm-external-projects/iree-compiler-api/lib/CAPI/Compiler.cpp b/llvm-external-projects/iree-compiler-api/lib/CAPI/Compiler.cpp
index 756c04a..b783580 100644
--- a/llvm-external-projects/iree-compiler-api/lib/CAPI/Compiler.cpp
+++ b/llvm-external-projects/iree-compiler-api/lib/CAPI/Compiler.cpp
@@ -6,11 +6,12 @@
#include "iree-compiler-c/Compiler.h"
+#include "iree/compiler/ConstEval/Passes.h"
#include "iree/compiler/Dialect/VM/IR/VMOps.h"
#include "iree/compiler/Dialect/VM/Target/Bytecode/BytecodeModuleTarget.h"
#include "iree/compiler/InputConversion/MHLO/Passes.h"
#include "iree/compiler/InputConversion/TOSA/Passes.h"
-#include "iree/compiler/Translation/IREEVM.h"
+#include "iree/compiler/Pipelines/Pipelines.h"
#include "iree/compiler/Utils/OptionUtils.h"
#include "iree/tools/init_targets.h"
#include "mlir/CAPI/IR.h"
@@ -133,10 +134,13 @@
MlirOpPassManager passManager) {
auto *optionsCpp = unwrap(options);
auto *passManagerCpp = unwrap(passManager);
+ IREEVMPipelineHooks hooks = {
+ // buildConstEvalPassPipelineCallback =
+ [](OpPassManager &pm) { pm.addPass(ConstEval::createJitGlobalsPass()); }};
buildIREEVMTransformPassPipeline(
optionsCpp->bindingOptions, optionsCpp->inputDialectOptions,
optionsCpp->highLevelOptimizationOptions, optionsCpp->schedulingOptions,
- optionsCpp->halTargetOptions, optionsCpp->vmTargetOptions,
+ optionsCpp->halTargetOptions, optionsCpp->vmTargetOptions, hooks,
*passManagerCpp);
}