Refactoring the iree::vm on top of iree::rt.
The dedupes the interfaces that were factored out previously and moves a bit more common code for printing/disassembling to keep feature parity with the old interface.
PiperOrigin-RevId: 274841300
diff --git a/iree/hal/interpreter/BUILD b/iree/hal/interpreter/BUILD
index 97235f6..204eb0a 100644
--- a/iree/hal/interpreter/BUILD
+++ b/iree/hal/interpreter/BUILD
@@ -18,6 +18,7 @@
"//iree/hal:executable",
"//iree/hal:executable_cache",
"//iree/hal:executable_format",
+ "//iree/rt",
],
)
@@ -38,13 +39,13 @@
"//iree/hal:allocator",
"//iree/hal:buffer_view",
"//iree/hal:heap_buffer",
+ "//iree/rt",
"//iree/schemas/bytecode:interpreter_bytecode_v0",
+ "//iree/vm:bytecode_module",
"//iree/vm:bytecode_reader",
"//iree/vm:bytecode_tables_interpreter",
"//iree/vm:bytecode_util",
- "//iree/vm:function",
"//iree/vm:opcode_info",
- "//iree/vm:stack",
"//iree/vm:type",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:inlined_vector",
@@ -57,16 +58,13 @@
srcs = ["bytecode_executable.cc"],
hdrs = ["bytecode_executable.h"],
deps = [
- ":interpreter_context",
+ ":interpreter_module",
"//iree/base:status",
"//iree/hal:allocator",
"//iree/hal:executable",
"//iree/hal:executable_spec",
+ "//iree/rt",
"//iree/vm:bytecode_tables_interpreter",
- "//iree/vm:bytecode_validator",
- "//iree/vm:context",
- "//iree/vm:module",
- "//iree/vm:module_printer",
"@com_google_absl//absl/types:span",
],
)
@@ -116,30 +114,13 @@
"//iree/base:tracing",
"//iree/hal:buffer_view",
"//iree/hal/host:host_local_command_processor",
+ "//iree/rt",
"@com_google_absl//absl/container:inlined_vector",
"@com_google_absl//absl/types:span",
],
)
cc_library(
- name = "interpreter_context",
- srcs = ["interpreter_context.cc"],
- hdrs = ["interpreter_context.h"],
- deps = [
- ":bytecode_dispatch",
- ":bytecode_kernels",
- "//iree/base:flatbuffer_util",
- "//iree/base:status",
- "//iree/hal:allocator",
- "//iree/hal:buffer_view",
- "//iree/vm:context",
- "//iree/vm:function",
- "//iree/vm:stack",
- "@com_google_absl//absl/types:span",
- ],
-)
-
-cc_library(
name = "interpreter_device",
srcs = ["interpreter_device.cc"],
hdrs = ["interpreter_device.h"],
@@ -159,6 +140,7 @@
"//iree/hal/host:host_local_allocator",
"//iree/hal/host:host_submission_queue",
"//iree/hal/host:inproc_command_buffer",
+ "//iree/rt",
"@com_google_absl//absl/container:inlined_vector",
"@com_google_absl//absl/memory",
"@com_google_absl//absl/types:span",
@@ -187,3 +169,22 @@
],
alwayslink = 1,
)
+
+cc_library(
+ name = "interpreter_module",
+ srcs = ["interpreter_module.cc"],
+ hdrs = ["interpreter_module.h"],
+ deps = [
+ ":bytecode_dispatch",
+ ":bytecode_kernels",
+ "//iree/base:flatbuffer_util",
+ "//iree/base:status",
+ "//iree/base:tracing",
+ "//iree/hal:allocator",
+ "//iree/hal:buffer_view",
+ "//iree/rt",
+ "//iree/vm:bytecode_module",
+ "//iree/vm:bytecode_tables_interpreter",
+ "@com_google_absl//absl/types:span",
+ ],
+)
diff --git a/iree/hal/interpreter/CMakeLists.txt b/iree/hal/interpreter/CMakeLists.txt
index 5031688..5295105 100644
--- a/iree/hal/interpreter/CMakeLists.txt
+++ b/iree/hal/interpreter/CMakeLists.txt
@@ -75,7 +75,7 @@
iree::hal::allocator
iree::hal::executable
iree::hal::executable_spec
- iree::hal::interpreter::interpreter_context
+ iree::hal::interpreter::interpreter_module
iree::vm::bytecode_tables_interpreter
iree::vm::bytecode_validator
iree::vm::context
@@ -138,27 +138,6 @@
iree_cc_library(
NAME
- interpreter_context
- HDRS
- "interpreter_context.h"
- SRCS
- "interpreter_context.cc"
- DEPS
- absl::span
- iree::base::flatbuffer_util
- iree::base::status
- iree::hal::allocator
- iree::hal::buffer_view
- iree::hal::interpreter::bytecode_dispatch
- iree::hal::interpreter::bytecode_kernels
- iree::vm::context
- iree::vm::function
- iree::vm::stack
- PUBLIC
-)
-
-iree_cc_library(
- NAME
interpreter_device
HDRS
"interpreter_device.h"
@@ -212,3 +191,24 @@
iree::hal::interpreter::interpreter_driver
PUBLIC
)
+
+iree_cc_library(
+ NAME
+ interpreter_module
+ HDRS
+ "interpreter_module.h"
+ SRCS
+ "interpreter_module.cc"
+ DEPS
+ absl::span
+ iree::base::flatbuffer_util
+ iree::base::status
+ iree::hal::allocator
+ iree::hal::buffer_view
+ iree::hal::interpreter::bytecode_dispatch
+ iree::hal::interpreter::bytecode_kernels
+ iree::vm::context
+ iree::vm::function
+ iree::vm::stack
+ PUBLIC
+)
diff --git a/iree/hal/interpreter/bytecode_cache.cc b/iree/hal/interpreter/bytecode_cache.cc
index de7d8f2..b42db5a 100644
--- a/iree/hal/interpreter/bytecode_cache.cc
+++ b/iree/hal/interpreter/bytecode_cache.cc
@@ -23,8 +23,9 @@
namespace iree {
namespace hal {
-BytecodeCache::BytecodeCache(hal::Allocator* allocator)
- : allocator_(allocator) {}
+BytecodeCache::BytecodeCache(ref_ptr<rt::Instance> instance,
+ hal::Allocator* allocator)
+ : instance_(std::move(instance)), allocator_(allocator) {}
BytecodeCache::~BytecodeCache() = default;
@@ -43,9 +44,9 @@
// Wrap the data (or copy it).
bool allow_aliasing_data =
AllBitsSet(mode, ExecutableCachingMode::kAliasProvidedData);
- ASSIGN_OR_RETURN(
- auto executable,
- BytecodeExecutable::Load(allocator_, spec, !allow_aliasing_data));
+ ASSIGN_OR_RETURN(auto executable,
+ BytecodeExecutable::Load(add_ref(instance_), allocator_,
+ spec, !allow_aliasing_data));
return executable;
}
diff --git a/iree/hal/interpreter/bytecode_cache.h b/iree/hal/interpreter/bytecode_cache.h
index fd955c5..4da59ec 100644
--- a/iree/hal/interpreter/bytecode_cache.h
+++ b/iree/hal/interpreter/bytecode_cache.h
@@ -18,13 +18,14 @@
#include "iree/hal/allocator.h"
#include "iree/hal/executable.h"
#include "iree/hal/executable_cache.h"
+#include "iree/rt/instance.h"
namespace iree {
namespace hal {
class BytecodeCache final : public ExecutableCache {
public:
- explicit BytecodeCache(hal::Allocator* allocator);
+ BytecodeCache(ref_ptr<rt::Instance> instance, hal::Allocator* allocator);
~BytecodeCache() override;
bool CanPrepareFormat(ExecutableFormat format) const override;
@@ -33,6 +34,7 @@
ExecutableCachingModeBitfield mode, const ExecutableSpec& spec) override;
private:
+ ref_ptr<rt::Instance> instance_;
hal::Allocator* allocator_;
};
diff --git a/iree/hal/interpreter/bytecode_dispatch.cc b/iree/hal/interpreter/bytecode_dispatch.cc
index b89fb44..f0e7040 100644
--- a/iree/hal/interpreter/bytecode_dispatch.cc
+++ b/iree/hal/interpreter/bytecode_dispatch.cc
@@ -33,11 +33,12 @@
#include "iree/hal/interpreter/bytecode_dispatch_conversion.h"
#include "iree/hal/interpreter/bytecode_dispatch_util.h"
#include "iree/hal/interpreter/bytecode_kernels.h"
+#include "iree/rt/function.h"
#include "iree/schemas/bytecode/interpreter_bytecode_v0.h"
+#include "iree/vm/bytecode_module.h"
#include "iree/vm/bytecode_reader.h"
#include "iree/vm/bytecode_tables_interpreter.h"
#include "iree/vm/bytecode_util.h"
-#include "iree/vm/function.h"
#include "iree/vm/opcode_info.h"
namespace iree {
@@ -45,11 +46,9 @@
namespace {
+using ::iree::rt::Stack;
+using ::iree::rt::StackFrame;
using ::iree::vm::BytecodeReader;
-using ::iree::vm::ImportFunction;
-using ::iree::vm::NativeFunction;
-using ::iree::vm::Stack;
-using ::iree::vm::StackFrame;
} // namespace
@@ -111,38 +110,23 @@
DISPATCH_CORE_OPCODE(kCall, {
auto* old_stack_frame = stack->current_frame();
ASSIGN_OR_RETURN(const auto& target_function, reader.ReadFunction());
+ // TODO(benvanik): rework register storage interface.
+ ASSIGN_OR_RETURN(
+ const auto* function_def,
+ static_cast<const vm::BytecodeModule*>(target_function.module())
+ ->GetFunctionDef(target_function.linkage(),
+ target_function.ordinal()));
ASSIGN_OR_RETURN(auto* new_stack_frame, stack->PushFrame(target_function));
+ new_stack_frame->mutable_registers()->buffer_views.resize(
+ function_def->bytecode()->local_count());
RETURN_IF_ERROR(
reader.CopyInputsAndSwitchStackFrame(old_stack_frame, new_stack_frame));
DVLOG(1) << "Call; stack now: " << stack->DebugString();
});
DISPATCH_CORE_OPCODE(kCallImport, {
- auto* old_stack_frame = stack->current_frame();
- ASSIGN_OR_RETURN(const auto* target_function, reader.ReadImportFunction());
- switch (target_function->link_type()) {
- case ImportFunction::LinkType::kModule: {
- ASSIGN_OR_RETURN(auto* new_stack_frame,
- stack->PushFrame(target_function->linked_function()));
- RETURN_IF_ERROR(reader.CopyInputsAndSwitchStackFrame(old_stack_frame,
- new_stack_frame));
- DVLOG(1) << "Call module import; stack now: " << stack->DebugString();
- break;
- }
- case ImportFunction::LinkType::kNativeFunction: {
- ASSIGN_OR_RETURN(auto* new_stack_frame,
- stack->PushFrame(*target_function));
- RETURN_IF_ERROR(reader.CopyInputsAndSwitchStackFrame(old_stack_frame,
- new_stack_frame));
- DVLOG(1) << "Call native import; stack now: " << stack->DebugString();
- RETURN_IF_ERROR(CallNativeFunction(stack, *target_function));
- RETURN_IF_ERROR(reader.CopyResultsAndSwitchStackFrame(old_stack_frame,
- new_stack_frame));
- RETURN_IF_ERROR(stack->PopFrame());
- DVLOG(1) << "Return from native; stack now: " << stack->DebugString();
- break;
- }
- }
+ return UnimplementedErrorBuilder(IREE_LOC)
+ << "Non-module imports not supported";
});
DISPATCH_CORE_OPCODE(kCallIndirect, {
@@ -156,8 +140,9 @@
// Returning from entry function. Marshal results from the return stmt.
ASSIGN_OR_RETURN(int32_t src_count, reader.ReadCount());
for (int i = 0; i < src_count; ++i) {
- ASSIGN_OR_RETURN(auto* src_local,
- reader.ReadLocal(old_stack_frame->mutable_locals()));
+ ASSIGN_OR_RETURN(
+ auto* src_local,
+ reader.ReadLocal(old_stack_frame->mutable_registers()));
entry_results[i] = std::move(*src_local);
}
DVLOG(1) << "Returning to entry";
diff --git a/iree/hal/interpreter/bytecode_dispatch.h b/iree/hal/interpreter/bytecode_dispatch.h
index 1d4b7d1..edd92d2 100644
--- a/iree/hal/interpreter/bytecode_dispatch.h
+++ b/iree/hal/interpreter/bytecode_dispatch.h
@@ -18,15 +18,15 @@
#include "iree/base/status.h"
#include "iree/hal/allocator.h"
#include "iree/hal/interpreter/bytecode_kernels.h"
-#include "iree/vm/stack.h"
-#include "iree/vm/stack_frame.h"
+#include "iree/rt/stack.h"
+#include "iree/rt/stack_frame.h"
namespace iree {
namespace hal {
Status Dispatch(hal::Allocator* allocator,
- kernels::RuntimeState* kernel_runtime_state, vm::Stack* stack,
- vm::StackFrame* entry_stack_frame,
+ kernels::RuntimeState* kernel_runtime_state, rt::Stack* stack,
+ rt::StackFrame* entry_stack_frame,
absl::Span<BufferView> entry_results);
} // namespace hal
diff --git a/iree/hal/interpreter/bytecode_dispatch_util.cc b/iree/hal/interpreter/bytecode_dispatch_util.cc
index 0e59bd8..40937e1 100644
--- a/iree/hal/interpreter/bytecode_dispatch_util.cc
+++ b/iree/hal/interpreter/bytecode_dispatch_util.cc
@@ -34,18 +34,6 @@
return false;
}
-Status CallNativeFunction(vm::Stack* stack,
- const vm::ImportFunction& function) {
- auto* stack_frame = stack->current_frame();
-
- // Marshal inputs and outputs.
- auto args = stack_frame->mutable_locals().subspan(0, function.input_count());
- auto results = stack_frame->mutable_locals().subspan(args.size());
-
- const auto& fn = function.native_function();
- return fn(stack, args, results);
-}
-
Status ValidateElementwiseUnaryOp(BufferView* src_local,
BufferView* dst_local) {
// TODO(benvanik): validate shapes.
diff --git a/iree/hal/interpreter/bytecode_dispatch_util.h b/iree/hal/interpreter/bytecode_dispatch_util.h
index b8f40e1..cb8d7d9 100644
--- a/iree/hal/interpreter/bytecode_dispatch_util.h
+++ b/iree/hal/interpreter/bytecode_dispatch_util.h
@@ -24,10 +24,10 @@
#include "iree/hal/buffer_view.h"
#include "iree/hal/heap_buffer.h"
#include "iree/hal/interpreter/bytecode_kernels.h"
+#include "iree/rt/function.h"
+#include "iree/rt/stack.h"
#include "iree/schemas/bytecode/interpreter_bytecode_v0.h"
#include "iree/vm/bytecode_reader.h"
-#include "iree/vm/function.h"
-#include "iree/vm/stack.h"
#include "iree/vm/type.h"
// TODO(benvanik): move to dedicated config file/build flags.
@@ -42,8 +42,6 @@
// bitwise zero.
bool BufferViewIsTrue(const BufferView& buffer_view);
-Status CallNativeFunction(vm::Stack* stack, const vm::ImportFunction& function);
-
Status ValidateElementwiseUnaryOp(BufferView* src_local, BufferView* dst_local);
Status ValidateElementwiseBinaryOp(BufferView* lhs_local, BufferView* rhs_local,
BufferView* dst_local);
diff --git a/iree/hal/interpreter/bytecode_executable.cc b/iree/hal/interpreter/bytecode_executable.cc
index 130eb77..c528263 100644
--- a/iree/hal/interpreter/bytecode_executable.cc
+++ b/iree/hal/interpreter/bytecode_executable.cc
@@ -16,63 +16,40 @@
#include <iostream>
-#include "iree/vm/bytecode_tables_interpreter.h"
-#include "iree/vm/bytecode_validator.h"
-#include "iree/vm/module.h"
-#include "iree/vm/module_printer.h"
+#include "iree/hal/interpreter/interpreter_module.h"
+#include "iree/rt/policy.h"
namespace iree {
namespace hal {
-namespace {
-// TODO(benvanik): remove when debugger is wired up to the HAL.
-const bool kEnableExecutablePrinting = false;
-} // namespace
-
// static
StatusOr<ref_ptr<BytecodeExecutable>> BytecodeExecutable::Load(
- hal::Allocator* allocator, ExecutableSpec spec, bool allow_aliasing_data) {
+ ref_ptr<rt::Instance> instance, hal::Allocator* allocator,
+ ExecutableSpec spec, bool allow_aliasing_data) {
// Allocate the executable now.
// We do this here so that if we need to clone the data we are passing that
// to the VM loader instead of the data we may not have access to later.
- auto executable =
- make_ref<BytecodeExecutable>(allocator, spec, allow_aliasing_data);
- auto* context = executable->mutable_context();
+ auto executable = make_ref<BytecodeExecutable>(std::move(instance), allocator,
+ spec, allow_aliasing_data);
// Create the executable module.
auto module_def =
::flatbuffers::GetRoot<ModuleDef>(executable->executable_data().data());
- ASSIGN_OR_RETURN(auto module, vm::Module::FromDef(*module_def));
- executable->module_ = module.get();
- RETURN_IF_ERROR(context->RegisterModule(std::move(module)));
-
- // Validate bytecode to ensure it will be usable for execution.
- // We do this here so that we get a good stack immediately when the bytecode
- // is provided instead of when we go to run it. This more closely mirrors how
- // a backend that performed compilation (such as SPIR-V) would fail.
- for (auto* function_def :
- *executable->module().function_table().def().functions()) {
- RETURN_IF_ERROR(vm::BytecodeValidator::Validate(
- *context, executable->module(), *function_def->bytecode()));
- }
-
- // Print the bytecode.
- // TODO(benvanik): remove when debugger is wired up to the HAL.
- if (kEnableExecutablePrinting) {
- vm::PrintModuleFlagBitfield print_flags = vm::PrintModuleFlag::kNone;
- for (const auto& module : context->modules()) {
- RETURN_IF_ERROR(vm::PrintModuleToStream(
- vm::interpreter_opcode_table(), *module, print_flags, &std::cout));
- }
- }
+ ASSIGN_OR_RETURN(auto module,
+ InterpreterModule::FromDef(allocator, *module_def));
+ executable->module_ = add_ref(module);
+ RETURN_IF_ERROR(executable->context()->RegisterModule(std::move(module)));
return executable;
}
-BytecodeExecutable::BytecodeExecutable(hal::Allocator* allocator,
+BytecodeExecutable::BytecodeExecutable(ref_ptr<rt::Instance> instance,
+ hal::Allocator* allocator,
ExecutableSpec spec,
bool allow_aliasing_data)
- : spec_(spec), context_(allocator) {
+ : spec_(spec),
+ context_(
+ make_ref<rt::Context>(std::move(instance), make_ref<rt::Policy>())) {
if (!allow_aliasing_data) {
// Clone data.
cloned_executable_data_ = {spec.executable_data.begin(),
diff --git a/iree/hal/interpreter/bytecode_executable.h b/iree/hal/interpreter/bytecode_executable.h
index 1fae48f..6cd47de 100644
--- a/iree/hal/interpreter/bytecode_executable.h
+++ b/iree/hal/interpreter/bytecode_executable.h
@@ -22,20 +22,21 @@
#include "iree/hal/allocator.h"
#include "iree/hal/executable.h"
#include "iree/hal/executable_spec.h"
-#include "iree/hal/interpreter/interpreter_context.h"
-#include "iree/vm/context.h"
+#include "iree/rt/context.h"
+#include "iree/rt/instance.h"
+#include "iree/rt/module.h"
namespace iree {
namespace hal {
class BytecodeExecutable final : public Executable {
public:
- static StatusOr<ref_ptr<BytecodeExecutable>> Load(hal::Allocator* allocator,
- ExecutableSpec spec,
- bool allow_aliasing_data);
+ static StatusOr<ref_ptr<BytecodeExecutable>> Load(
+ ref_ptr<rt::Instance> instance, hal::Allocator* allocator,
+ ExecutableSpec spec, bool allow_aliasing_data);
- BytecodeExecutable(hal::Allocator* allocator, ExecutableSpec spec,
- bool allow_aliasing_data);
+ BytecodeExecutable(ref_ptr<rt::Instance> instance, hal::Allocator* allocator,
+ ExecutableSpec spec, bool allow_aliasing_data);
~BytecodeExecutable() override;
bool supports_debugging() const override { return false; }
@@ -46,20 +47,19 @@
}
// VM context with the executable registered.
- const InterpreterContext& context() const { return context_; }
- InterpreterContext* mutable_context() { return &context_; }
+ const ref_ptr<rt::Context>& context() const { return context_; }
// VM module representing the executable.
// Note that there may be more than one module in the Context and only this
// module can be used to lookup executable exports.
- const vm::Module& module() const { return *module_; }
+ const ref_ptr<rt::Module>& module() const { return module_; }
private:
ExecutableSpec spec_;
std::vector<uint8_t> cloned_executable_data_;
- InterpreterContext context_;
- vm::Module* module_ = nullptr;
+ ref_ptr<rt::Context> context_;
+ ref_ptr<rt::Module> module_;
};
} // namespace hal
diff --git a/iree/hal/interpreter/interpreter_command_processor.cc b/iree/hal/interpreter/interpreter_command_processor.cc
index a79b10e..783809d 100644
--- a/iree/hal/interpreter/interpreter_command_processor.cc
+++ b/iree/hal/interpreter/interpreter_command_processor.cc
@@ -21,6 +21,7 @@
#include "iree/base/tracing.h"
#include "iree/hal/buffer_view.h"
#include "iree/hal/interpreter/bytecode_executable.h"
+#include "iree/rt/stack.h"
namespace iree {
namespace hal {
@@ -40,26 +41,23 @@
auto* executable =
static_cast<BytecodeExecutable*>(dispatch_request.executable);
const auto& module = executable->module();
- ASSIGN_OR_RETURN(auto entry_function, module.function_table().LookupExport(
+ ASSIGN_OR_RETURN(auto entry_function, module->LookupFunctionByOrdinal(
+ rt::Function::Linkage::kExport,
dispatch_request.entry_point));
- vm::Stack stack;
+ rt::Stack stack(executable->context().get());
// TODO(benvanik): avoid this by directly referencing the bindings.
- absl::InlinedVector<BufferView, 8> args;
- args.reserve(dispatch_request.bindings.size());
+ absl::InlinedVector<BufferView, 8> arguments;
+ arguments.reserve(dispatch_request.bindings.size());
for (auto& binding : dispatch_request.bindings) {
- args.push_back(BufferView{add_ref(binding.buffer), binding.shape,
- binding.element_size});
+ arguments.push_back(BufferView{add_ref(binding.buffer), binding.shape,
+ binding.element_size});
}
absl::InlinedVector<BufferView, 8> results;
- if (entry_function.result_count() > 0) {
- return UnimplementedErrorBuilder(IREE_LOC)
- << "Executable export results are not yet implemented";
- }
- RETURN_IF_ERROR(executable->context().Invoke(
- &stack, entry_function, absl::MakeSpan(args), absl::MakeSpan(results)));
+ RETURN_IF_ERROR(executable->module()->Execute(
+ &stack, entry_function, std::move(arguments), &results));
return OkStatus();
}
diff --git a/iree/hal/interpreter/interpreter_context.cc b/iree/hal/interpreter/interpreter_context.cc
deleted file mode 100644
index e30aa96..0000000
--- a/iree/hal/interpreter/interpreter_context.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "iree/hal/interpreter/interpreter_context.h"
-
-#include "iree/base/flatbuffer_util.h"
-#include "iree/base/status.h"
-#include "iree/hal/interpreter/bytecode_dispatch.h"
-
-namespace iree {
-namespace hal {
-
-namespace {
-
-using ::iree::vm::Function;
-
-} // namespace
-
-Status InterpreterContext::Invoke(vm::Stack* stack, Function function,
- absl::Span<BufferView> args,
- absl::Span<BufferView> results) const {
- // Verify arg/result counts.
- if (args.size() != function.input_count()) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Function " << function.name() << " requires "
- << function.input_count() << " inputs but only " << args.size()
- << " provided";
- }
- if (results.size() != function.result_count()) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Function " << function.name() << " requires "
- << function.result_count() << " outputs but only " << results.size()
- << " provided";
- }
-
- // Push stack frame for the function we are calling.
- ASSIGN_OR_RETURN(auto* callee_stack_frame, stack->PushFrame(function));
-
- // Marshal input arguments.
- for (int i = 0; i < args.size(); ++i) {
- *callee_stack_frame->mutable_local(i) = std::move(args[i]);
- }
-
- // Run main dispatch loop until it exits (or errors).
- RETURN_IF_ERROR(Dispatch(allocator_, &kernel_runtime_state_, stack,
- callee_stack_frame, results));
-
- // Pop the callee frame to balance out the stack.
- RETURN_IF_ERROR(stack->PopFrame());
-
- return OkStatus();
-}
-
-} // namespace hal
-} // namespace iree
diff --git a/iree/hal/interpreter/interpreter_context.h b/iree/hal/interpreter/interpreter_context.h
deleted file mode 100644
index 2808c14..0000000
--- a/iree/hal/interpreter/interpreter_context.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef IREE_HAL_INTERPRETER_INTERPRETER_CONTEXT_H_
-#define IREE_HAL_INTERPRETER_INTERPRETER_CONTEXT_H_
-
-#include <memory>
-
-#include "absl/types/span.h"
-#include "iree/base/status.h"
-#include "iree/hal/allocator.h"
-#include "iree/hal/buffer_view.h"
-#include "iree/hal/interpreter/bytecode_kernels.h"
-#include "iree/vm/context.h"
-#include "iree/vm/function.h"
-#include "iree/vm/stack.h"
-
-namespace iree {
-namespace hal {
-
-class InterpreterContext final : public vm::Context {
- public:
- explicit InterpreterContext(hal::Allocator* allocator)
- : allocator_(allocator) {}
-
- // TODO(benvanik): helpers to make passing args easier
- Status Invoke(vm::Stack* stack, vm::Function function,
- absl::Span<BufferView> args,
- absl::Span<BufferView> results) const;
-
- private:
- hal::Allocator* allocator_;
- mutable kernels::RuntimeState kernel_runtime_state_;
-};
-
-} // namespace hal
-} // namespace iree
-
-#endif // IREE_HAL_INTERPRETER_INTERPRETER_CONTEXT_H_
diff --git a/iree/hal/interpreter/interpreter_device.cc b/iree/hal/interpreter/interpreter_device.cc
index 239084e..7a61cc3 100644
--- a/iree/hal/interpreter/interpreter_device.cc
+++ b/iree/hal/interpreter/interpreter_device.cc
@@ -97,11 +97,12 @@
} // namespace
InterpreterDevice::InterpreterDevice(DeviceInfo device_info)
- : Device(std::move(device_info)) {
+ : Device(std::move(device_info)), instance_(make_ref<rt::Instance>()) {
// We currently only expose a single command queue.
auto command_queue = absl::make_unique<UnsynchronizedCommandQueue>(
&allocator_, "cpu0",
CommandCategory::kTransfer | CommandCategory::kDispatch);
+
// TODO(benvanik): allow injection of the wrapper type to support
// SyncCommandQueue without always linking in both.
auto async_command_queue =
@@ -112,7 +113,7 @@
InterpreterDevice::~InterpreterDevice() = default;
std::shared_ptr<ExecutableCache> InterpreterDevice::CreateExecutableCache() {
- return std::make_shared<BytecodeCache>(&allocator_);
+ return std::make_shared<BytecodeCache>(add_ref(instance_), &allocator_);
}
StatusOr<ref_ptr<CommandBuffer>> InterpreterDevice::CreateCommandBuffer(
diff --git a/iree/hal/interpreter/interpreter_device.h b/iree/hal/interpreter/interpreter_device.h
index 9afdaac..5987ab9 100644
--- a/iree/hal/interpreter/interpreter_device.h
+++ b/iree/hal/interpreter/interpreter_device.h
@@ -21,6 +21,7 @@
#include "iree/hal/device.h"
#include "iree/hal/host/host_local_allocator.h"
#include "iree/hal/interpreter/bytecode_kernels.h"
+#include "iree/rt/instance.h"
namespace iree {
namespace hal {
@@ -66,6 +67,7 @@
Status WaitIdle(absl::Time deadline) override;
private:
+ ref_ptr<rt::Instance> instance_;
kernels::RuntimeState kernel_runtime_state_;
mutable HostLocalAllocator allocator_;
mutable absl::InlinedVector<std::unique_ptr<CommandQueue>, 1> command_queues_;
diff --git a/iree/hal/interpreter/interpreter_module.cc b/iree/hal/interpreter/interpreter_module.cc
new file mode 100644
index 0000000..c569fea
--- /dev/null
+++ b/iree/hal/interpreter/interpreter_module.cc
@@ -0,0 +1,80 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "iree/hal/interpreter/interpreter_module.h"
+
+#include "iree/base/flatbuffer_util.h"
+#include "iree/base/status.h"
+#include "iree/base/tracing.h"
+#include "iree/hal/interpreter/bytecode_dispatch.h"
+#include "iree/vm/bytecode_tables_interpreter.h"
+
+namespace iree {
+namespace hal {
+
+// static
+StatusOr<ref_ptr<rt::Module>> InterpreterModule::FromDef(
+ hal::Allocator* allocator, const ModuleDef& module_def) {
+ ASSIGN_OR_RETURN(auto module_file,
+ vm::ModuleFile::Create(&module_def, []() {}));
+ if (module_file->root() == nullptr) {
+ return InvalidArgumentErrorBuilder(IREE_LOC) << "No root ModuleDef present";
+ }
+
+ auto module =
+ assign_ref(new InterpreterModule(allocator, std::move(module_file)));
+
+ // TODO(benvanik): validate internals here? or make explicit?
+
+ return {std::move(module)};
+}
+
+InterpreterModule::InterpreterModule(
+ hal::Allocator* allocator, std::unique_ptr<vm::ModuleFile> module_file)
+ : vm::BytecodeModule(std::move(module_file),
+ vm::interpreter_opcode_table()),
+ allocator_(allocator) {}
+
+Status InterpreterModule::Execute(
+ rt::Stack* stack, const rt::Function function,
+ absl::InlinedVector<hal::BufferView, 8> arguments,
+ absl::InlinedVector<hal::BufferView, 8>* results) const {
+ IREE_TRACE_SCOPE0("InterperterModule::Execute");
+
+ // Push stack frame for the function we are calling.
+ ASSIGN_OR_RETURN(auto* callee_stack_frame, stack->PushFrame(function));
+
+ // TODO(benvanik): rework register storage interface.
+ ASSIGN_OR_RETURN(const auto* function_def,
+ GetFunctionDef(function.linkage(), function.ordinal()));
+ auto* registers = callee_stack_frame->mutable_registers();
+ registers->buffer_views.resize(function_def->bytecode()->local_count());
+
+ // Marshal input arguments.
+ for (int i = 0; i < arguments.size(); ++i) {
+ registers->buffer_views[i] = std::move(arguments[i]);
+ }
+
+ // Run main dispatch loop until it exits (or errors).
+ RETURN_IF_ERROR(Dispatch(allocator_, &kernel_runtime_state_, stack,
+ callee_stack_frame, results));
+
+ // Pop the callee frame to balance out the stack.
+ RETURN_IF_ERROR(stack->PopFrame());
+
+ return OkStatus();
+}
+
+} // namespace hal
+} // namespace iree
diff --git a/iree/hal/interpreter/interpreter_module.h b/iree/hal/interpreter/interpreter_module.h
new file mode 100644
index 0000000..d7d98e3
--- /dev/null
+++ b/iree/hal/interpreter/interpreter_module.h
@@ -0,0 +1,55 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef IREE_HAL_INTERPRETER_INTERPRETER_MODULE_H_
+#define IREE_HAL_INTERPRETER_INTERPRETER_MODULE_H_
+
+#include <memory>
+
+#include "absl/types/span.h"
+#include "iree/base/status.h"
+#include "iree/hal/allocator.h"
+#include "iree/hal/buffer_view.h"
+#include "iree/hal/interpreter/bytecode_kernels.h"
+#include "iree/rt/function.h"
+#include "iree/rt/module.h"
+#include "iree/rt/stack.h"
+#include "iree/vm/bytecode_module.h"
+#include "iree/vm/bytecode_tables_interpreter.h"
+
+namespace iree {
+namespace hal {
+
+class InterpreterModule final : public vm::BytecodeModule {
+ public:
+ static StatusOr<ref_ptr<rt::Module>> FromDef(hal::Allocator* allocator,
+ const ModuleDef& module_def);
+
+ Status Execute(
+ rt::Stack* stack, const rt::Function function,
+ absl::InlinedVector<hal::BufferView, 8> arguments,
+ absl::InlinedVector<hal::BufferView, 8>* results) const override;
+
+ private:
+ InterpreterModule(hal::Allocator* allocator,
+ std::unique_ptr<vm::ModuleFile> module_file);
+
+ hal::Allocator* allocator_;
+ mutable kernels::RuntimeState kernel_runtime_state_;
+};
+
+} // namespace hal
+} // namespace iree
+
+#endif // IREE_HAL_INTERPRETER_INTERPRETER_MODULE_H_
diff --git a/iree/rt/BUILD b/iree/rt/BUILD
index 8fc7242..65e956b 100644
--- a/iree/rt/BUILD
+++ b/iree/rt/BUILD
@@ -39,25 +39,31 @@
"function.cc",
"instance.cc",
"invocation.cc",
+ "module_printer.cc",
"source_location.cc",
+ "stack.cc",
"stack_frame.cc",
"stack_trace.cc",
],
hdrs = [
"context.h",
+ "disassembler.h",
"function.h",
"function_signature.h",
"instance.h",
"invocation.h",
"module.h",
+ "module_printer.h",
"module_signature.h",
"policy.h",
"source_location.h",
"source_resolver.h",
+ "stack.h",
"stack_frame.h",
"stack_trace.h",
],
deps = [
+ "//iree/base:bitfield",
"//iree/base:intrusive_list",
"//iree/base:ref_ptr",
"//iree/base:status",
diff --git a/iree/rt/CMakeLists.txt b/iree/rt/CMakeLists.txt
index 8cf7786..61b14a3 100644
--- a/iree/rt/CMakeLists.txt
+++ b/iree/rt/CMakeLists.txt
@@ -40,20 +40,25 @@
"function.cc"
"instance.cc"
"invocation.cc"
+ "module_printer.cc"
"source_location.cc"
+ "stack.cc"
"stack_frame.cc"
"stack_trace.cc"
HDRS
"context.h"
+ "disassembler.h"
"function.h"
"function_signature.h"
"instance.h"
"invocation.h"
"module.h"
+ "module_printer.h"
"module_signature.h"
"policy.h"
"source_location.h"
"source_resolver.h"
+ "stack.h"
"stack_frame.h"
"stack_trace.h"
DEPS
@@ -64,6 +69,7 @@
absl::time
absl::optional
absl::span
+ iree::base::bitfield
iree::base::intrusive_list
iree::base::ref_ptr
iree::base::status
diff --git a/iree/rt/api.cc b/iree/rt/api.cc
index 6e1e5c5..db43358 100644
--- a/iree/rt/api.cc
+++ b/iree/rt/api.cc
@@ -108,6 +108,8 @@
SourceResolver* source_resolver() const override { return nullptr; }
+ Disassembler* disassembler() const override { return nullptr; }
+
std::string DebugStringShort() const override { return std::string(name()); }
StatusOr<const Function> LookupFunctionByOrdinal(
@@ -165,7 +167,7 @@
}
Status Execute(
- const Function function,
+ Stack* stack, const Function function,
absl::InlinedVector<hal::BufferView, 8> arguments,
absl::InlinedVector<hal::BufferView, 8>* results) const override {
// TODO(benvanik): fn ptr callback to external code. Waiting on fibers.
diff --git a/iree/rt/context.cc b/iree/rt/context.cc
index ba49cc4..6320325 100644
--- a/iree/rt/context.cc
+++ b/iree/rt/context.cc
@@ -123,6 +123,24 @@
function_name);
}
+StatusOr<const Function> Context::ResolveImport(const Module* module,
+ int32_t ordinal) const {
+ for (const auto& import_table_ref : module_import_tables_) {
+ if (import_table_ref.first == module) {
+ const auto& import_table = import_table_ref.second;
+ if (ordinal >= import_table.size()) {
+ return NotFoundErrorBuilder(IREE_LOC)
+ << "Import ordinal " << ordinal
+ << " out of bounds of import table (" << import_table.size()
+ << ")";
+ }
+ return import_table[ordinal];
+ }
+ }
+ return NotFoundErrorBuilder(IREE_LOC)
+ << "Import ordinal " << ordinal << " not found";
+}
+
void Context::RegisterInvocation(Invocation* invocation) {
{
absl::MutexLock lock(&invocations_mutex_);
diff --git a/iree/rt/context.h b/iree/rt/context.h
index 83b7ee4..d67b79a 100644
--- a/iree/rt/context.h
+++ b/iree/rt/context.h
@@ -80,6 +80,11 @@
// reference is valid for the lifetime of the context.
StatusOr<const Function> ResolveFunction(absl::string_view full_name) const;
+ // Resolves an imported function by import ordinal. The function reference is
+ // valid for the lifetime of the context.
+ StatusOr<const Function> ResolveImport(const Module* module,
+ int32_t ordinal) const;
+
private:
// Resolves imports for the given module.
StatusOr<ModuleImportTable> ResolveImports(Module* module);
diff --git a/iree/rt/disassembler.h b/iree/rt/disassembler.h
new file mode 100644
index 0000000..52d91ee
--- /dev/null
+++ b/iree/rt/disassembler.h
@@ -0,0 +1,64 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef IREE_RT_DISASSEMBLER_H_
+#define IREE_RT_DISASSEMBLER_H_
+
+#include <cstdint>
+#include <ostream>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "iree/base/status.h"
+#include "iree/rt/function.h"
+#include "iree/rt/source_location.h"
+
+namespace iree {
+namespace rt {
+
+// A single disassembled instruction.
+struct Instruction {
+ // Offset of the instruction within the function.
+ // The meaning of this is backend-dependent.
+ SourceOffset offset;
+
+ // The first line of |long_text|.
+ absl::string_view short_text;
+
+ // Human-readable text of the instruction. May contain multiple lines.
+ std::string long_text;
+};
+
+// Disassembles functions into instructions.
+//
+// Thread-safe.
+class Disassembler {
+ public:
+ virtual ~Disassembler() = default;
+
+ // Disassembles one or more instructions within the given function based on
+ // source offsets.
+ virtual StatusOr<std::vector<Instruction>> DisassembleInstructions(
+ const Function& function, SourceOffset offset,
+ int32_t instruction_count = INT32_MAX) const = 0;
+
+ protected:
+ Disassembler() = default;
+};
+
+} // namespace rt
+} // namespace iree
+
+#endif // IREE_RT_DISASSEMBLER_H_
diff --git a/iree/rt/instance.h b/iree/rt/instance.h
index f5e3bc8..61fd544 100644
--- a/iree/rt/instance.h
+++ b/iree/rt/instance.h
@@ -21,14 +21,7 @@
#include "iree/base/ref_ptr.h"
#include "iree/hal/device_manager.h"
#include "iree/rt/context.h"
-
-namespace iree {
-namespace rt {
-namespace debug {
-class DebugServer;
-} // namespace debug
-} // namespace rt
-} // namespace iree
+#include "iree/rt/debug/debug_server.h"
namespace iree {
namespace rt {
@@ -46,7 +39,8 @@
class Instance final : public RefObject<Instance> {
public:
// Creates an instance with an optional attached |debug_server|.
- explicit Instance(std::unique_ptr<debug::DebugServer> debug_server = nullptr);
+ Instance() : Instance(nullptr) {}
+ explicit Instance(std::unique_ptr<debug::DebugServer> debug_server);
~Instance();
Instance(const Instance&) = delete;
Instance& operator=(const Instance&) = delete;
diff --git a/iree/rt/invocation.cc b/iree/rt/invocation.cc
index f35671e..0abe667 100644
--- a/iree/rt/invocation.cc
+++ b/iree/rt/invocation.cc
@@ -72,7 +72,7 @@
// TODO(benvanik): fiber scheduling and such.
auto execute_status = function.module()->Execute(
- function, std::move(arguments), &results_value);
+ &invocation->stack_, function, std::move(arguments), &results_value);
if (execute_status.ok()) {
invocation->CompleteSuccess(std::move(results_value));
} else {
@@ -82,12 +82,33 @@
return invocation;
}
+// static
+StatusOr<ref_ptr<Invocation>> Invocation::Create(
+ ref_ptr<Context> context, const Function function, ref_ptr<Policy> policy,
+ absl::Span<const ref_ptr<Invocation>> dependencies,
+ absl::Span<const hal::BufferView> arguments) {
+ absl::InlinedVector<ref_ptr<Invocation>, 4> dependency_list;
+ dependency_list.reserve(dependencies.size());
+ for (auto& dependency : dependencies) {
+ dependency_list.push_back(add_ref(dependency));
+ }
+ absl::InlinedVector<hal::BufferView, 8> argument_list;
+ argument_list.reserve(arguments.size());
+ for (auto& buffer_view : arguments) {
+ argument_list.push_back(buffer_view);
+ }
+ return Invocation::Create(std::move(context), function, std::move(policy),
+ std::move(dependency_list),
+ std::move(argument_list));
+}
+
Invocation::Invocation(ref_ptr<Context> context, const Function function,
ref_ptr<Policy> policy)
: id_(NextUniqueInvocationId()),
context_(std::move(context)),
function_(function),
- policy_(std::move(policy)) {
+ policy_(std::move(policy)),
+ stack_(context_.get()) {
IREE_TRACE_SCOPE0("Invocation::ctor");
context_->RegisterInvocation(this);
}
diff --git a/iree/rt/invocation.h b/iree/rt/invocation.h
index b2e79a5..600fd8a 100644
--- a/iree/rt/invocation.h
+++ b/iree/rt/invocation.h
@@ -27,6 +27,7 @@
#include "iree/hal/buffer_view.h"
#include "iree/rt/function.h"
#include "iree/rt/policy.h"
+#include "iree/rt/stack.h"
#include "iree/rt/stack_trace.h"
namespace iree {
@@ -63,6 +64,10 @@
absl::InlinedVector<hal::BufferView, 8> arguments,
absl::optional<absl::InlinedVector<hal::BufferView, 8>> results =
absl::nullopt);
+ static StatusOr<ref_ptr<Invocation>> Create(
+ ref_ptr<Context> context, const Function function, ref_ptr<Policy> policy,
+ absl::Span<const ref_ptr<Invocation>> dependencies,
+ absl::Span<const hal::BufferView> arguments);
~Invocation();
@@ -126,6 +131,8 @@
const Function function_;
ref_ptr<Policy> policy_;
+ Stack stack_;
+
absl::Mutex status_mutex_;
Status completion_status_ ABSL_GUARDED_BY(status_mutex_) =
UnavailableErrorBuilder(IREE_LOC);
diff --git a/iree/rt/module.h b/iree/rt/module.h
index d81572e..1878d9d 100644
--- a/iree/rt/module.h
+++ b/iree/rt/module.h
@@ -27,7 +27,9 @@
namespace iree {
namespace rt {
+class Disassembler;
class SourceResolver;
+class Stack;
// Abstract compiled module interface for resolving functions.
//
@@ -50,6 +52,11 @@
// May be nullptr if debugging info has been stripped.
virtual SourceResolver* source_resolver() const = 0;
+ // Returns a disassembler that can be used to disassemble functions in the
+ // module. May be nullptr if debugging info has been stripped or disassembly
+ // has been disabled as a compile option.
+ virtual Disassembler* disassembler() const = 0;
+
// A short human-readable string that matches the compiler formatting.
virtual std::string DebugStringShort() const = 0;
@@ -82,7 +89,7 @@
// Temporary until scheduler is built.
virtual Status Execute(
- const Function function,
+ Stack* stack, const Function function,
absl::InlinedVector<hal::BufferView, 8> arguments,
absl::InlinedVector<hal::BufferView, 8>* results) const = 0;
diff --git a/iree/rt/module_printer.cc b/iree/rt/module_printer.cc
new file mode 100644
index 0000000..dd0267e
--- /dev/null
+++ b/iree/rt/module_printer.cc
@@ -0,0 +1,65 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "iree/rt/module_printer.h"
+
+#include <iomanip>
+
+#include "iree/rt/disassembler.h"
+#include "iree/rt/source_resolver.h"
+
+namespace iree {
+namespace rt {
+
+Status PrintModuleToStream(const Module& module, PrintModuleFlagBitfield flags,
+ std::ostream* stream) {
+ *stream << "Imports:\n";
+ for (int i = 0; i < module.signature().import_function_count(); ++i) {
+ ASSIGN_OR_RETURN(auto function, module.LookupFunctionByOrdinal(
+ Function::Linkage::kImport, i));
+ *stream << " " << i << ": " << function << "\n";
+ }
+ *stream << "Exports:\n";
+ for (int i = 0; i < module.signature().export_function_count(); ++i) {
+ ASSIGN_OR_RETURN(auto function, module.LookupFunctionByOrdinal(
+ Function::Linkage::kExport, i));
+ *stream << " " << i << ": " << function << "\n";
+ }
+ if (module.signature().internal_function_count()) {
+ *stream << "Internal:\n";
+ auto* disassembler = module.disassembler();
+ for (int i = 0; i < module.signature().internal_function_count(); ++i) {
+ ASSIGN_OR_RETURN(auto function, module.LookupFunctionByOrdinal(
+ Function::Linkage::kInternal, i));
+ *stream << " " << i << ": " << function << "\n";
+ if (disassembler && AllBitsSet(flags, PrintModuleFlag::kDisassemble)) {
+ auto instructions_or =
+ disassembler->DisassembleInstructions(function, 0);
+ if (IsUnavailable(instructions_or.status())) continue;
+ for (const auto& instruction : instructions_or.ValueOrDie()) {
+ *stream << " " << std::setw(6) << instruction.offset << ": "
+ << instruction.long_text << "\n";
+ }
+ }
+ }
+ }
+ return OkStatus();
+}
+
+Status PrintModuleToStream(const Module& module, std::ostream* stream) {
+ return PrintModuleToStream(module, PrintModuleFlag::kNone, stream);
+}
+
+} // namespace rt
+} // namespace iree
diff --git a/iree/vm/module_printer.h b/iree/rt/module_printer.h
similarity index 67%
rename from iree/vm/module_printer.h
rename to iree/rt/module_printer.h
index ee35fb3..945dbbd 100644
--- a/iree/vm/module_printer.h
+++ b/iree/rt/module_printer.h
@@ -12,33 +12,31 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef IREE_VM_MODULE_PRINTER_H_
-#define IREE_VM_MODULE_PRINTER_H_
+#ifndef IREE_RT_MODULE_PRINTER_H_
+#define IREE_RT_MODULE_PRINTER_H_
#include <ostream>
#include "iree/base/bitfield.h"
#include "iree/base/status.h"
-#include "iree/vm/module.h"
-#include "iree/vm/opcode_info.h"
+#include "iree/rt/module.h"
namespace iree {
-namespace vm {
+namespace rt {
enum class PrintModuleFlag {
kNone = 0,
- kIncludeSourceMapping = 1,
+ kDisassemble = 1 << 0,
};
IREE_BITFIELD(PrintModuleFlag);
using PrintModuleFlagBitfield = PrintModuleFlag;
// Prints all functions within the module to the given |stream|.
-Status PrintModuleToStream(OpcodeTable opcode_table, const Module& module,
+Status PrintModuleToStream(const Module& module, std::ostream* stream);
+Status PrintModuleToStream(const Module& module, PrintModuleFlagBitfield flags,
std::ostream* stream);
-Status PrintModuleToStream(OpcodeTable opcode_table, const Module& module,
- PrintModuleFlagBitfield flags, std::ostream* stream);
-} // namespace vm
+} // namespace rt
} // namespace iree
-#endif // IREE_VM_MODULE_PRINTER_H_
+#endif // IREE_RT_MODULE_PRINTER_H_
diff --git a/iree/rt/source_location.cc b/iree/rt/source_location.cc
index c61645f..835905b 100644
--- a/iree/rt/source_location.cc
+++ b/iree/rt/source_location.cc
@@ -14,14 +14,18 @@
#include "iree/rt/source_location.h"
+#include <sstream>
+
#include "iree/rt/source_resolver.h"
namespace iree {
namespace rt {
std::string SourceLocation::DebugStringShort() const {
- // TODO(benvanik): ask source resolver.
- return "<source>";
+ if (is_unknown()) return "(unknown)";
+ std::ostringstream stream;
+ resolver_->PrintSourceLocation(resolver_args_, &stream);
+ return stream.str();
}
} // namespace rt
diff --git a/iree/rt/source_location.h b/iree/rt/source_location.h
index 9939e15..7db98ec 100644
--- a/iree/rt/source_location.h
+++ b/iree/rt/source_location.h
@@ -15,6 +15,7 @@
#ifndef IREE_RT_SOURCE_LOCATION_H_
#define IREE_RT_SOURCE_LOCATION_H_
+#include <array>
#include <cstdint>
#include <cstring>
#include <ostream>
@@ -31,6 +32,10 @@
// hash table.
using SourceOffset = int64_t;
+// Implementation-defined opaque args stored within source locations that can be
+// used by a SourceResolver to map back to its internal storage.
+using SourceResolverArgs = std::array<uint64_t, 2>;
+
// A location within a source file.
// Only valid for the lifetime of the SourceResolver that returned it.
class SourceLocation final {
@@ -40,15 +45,12 @@
// Returns true if the two source locations reference the same target.
inline static bool Equal(const SourceLocation& a, const SourceLocation& b) {
- return a.resolver_ == b.resolver_ &&
- std::memcmp(a.resolver_args_, b.resolver_args_,
- sizeof(a.resolver_args_)) == 0;
+ return a.resolver_ == b.resolver_ && a.resolver_args_ == b.resolver_args_;
}
SourceLocation() = default;
- SourceLocation(SourceResolver* resolver, uintptr_t resolver_args[2])
- : resolver_(resolver),
- resolver_args_{resolver_args[0], resolver_args[1]} {}
+ SourceLocation(SourceResolver* resolver, SourceResolverArgs resolver_args)
+ : resolver_(resolver), resolver_args_(resolver_args) {}
// A short one-line human readable string (such as file/line number).
std::string DebugStringShort() const;
@@ -63,7 +65,7 @@
private:
SourceResolver* resolver_ = nullptr;
- uintptr_t resolver_args_[2] = {0, 0};
+ SourceResolverArgs resolver_args_ = {0, 0};
};
inline bool operator==(const SourceLocation& a, const SourceLocation& b) {
diff --git a/iree/rt/source_resolver.h b/iree/rt/source_resolver.h
index fd677a2..3ceb1b9 100644
--- a/iree/rt/source_resolver.h
+++ b/iree/rt/source_resolver.h
@@ -15,14 +15,21 @@
#ifndef IREE_RT_SOURCE_RESOLVER_H_
#define IREE_RT_SOURCE_RESOLVER_H_
+#include <cstdint>
+#include <ostream>
+#include <vector>
+
+#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
+#include "iree/base/status.h"
#include "iree/rt/function.h"
#include "iree/rt/source_location.h"
namespace iree {
namespace rt {
-// Resolves offsets within functions to SourceLocations.
+// Resolves offsets within functions to SourceLocations and provides source
+// language services.
//
// Thread-safe.
class SourceResolver {
@@ -34,6 +41,11 @@
virtual absl::optional<SourceLocation> ResolveFunctionOffset(
const Function& function, SourceOffset offset) = 0;
+ // Converts a source location to a human-readable string, commonly in a single
+ // line denoting an original source file location (such as path:line:col).
+ virtual void PrintSourceLocation(SourceResolverArgs resolver_args,
+ std::ostream* stream) const = 0;
+
// TODO(benvanik): query local variable names.
// TODO(benvanik): step target calculation (relative mapping).
diff --git a/iree/rt/stack.cc b/iree/rt/stack.cc
new file mode 100644
index 0000000..f4f300f
--- /dev/null
+++ b/iree/rt/stack.cc
@@ -0,0 +1,60 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "iree/rt/stack.h"
+
+#include <iterator>
+
+#include "absl/strings/str_join.h"
+#include "iree/base/status.h"
+
+namespace iree {
+namespace rt {
+
+constexpr int Stack::kMaxStackDepth;
+
+Stack::Stack(Context* context) : context_(context) {}
+
+Stack::~Stack() = default;
+
+StatusOr<StackFrame*> Stack::PushFrame(Function function) {
+ if (stack_depth_ + 1 > kMaxStackDepth) {
+ return InternalErrorBuilder(IREE_LOC)
+ << "Max stack depth of " << kMaxStackDepth << " exceeded";
+ }
+ frames_[stack_depth_++] = StackFrame(function);
+
+ // TODO(benvanik): WTF scope enter.
+
+ return current_frame();
+}
+
+Status Stack::PopFrame() {
+ if (stack_depth_ == 0) {
+ return InternalErrorBuilder(IREE_LOC) << "Unbalanced stack pop";
+ }
+
+ // TODO(benvanik): WTF scope leave.
+
+ --stack_depth_;
+ frames_[stack_depth_] = {};
+ return OkStatus();
+}
+
+std::string Stack::DebugString() const {
+ return absl::StrJoin(frames(), "\n", StackFrameFormatter());
+}
+
+} // namespace rt
+} // namespace iree
diff --git a/iree/rt/stack.h b/iree/rt/stack.h
new file mode 100644
index 0000000..a9547fe
--- /dev/null
+++ b/iree/rt/stack.h
@@ -0,0 +1,85 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef IREE_RT_STACK_H_
+#define IREE_RT_STACK_H_
+
+#include <functional>
+
+#include "absl/types/span.h"
+#include "iree/base/status.h"
+#include "iree/rt/stack_frame.h"
+
+namespace iree {
+namespace rt {
+
+class Context;
+
+// A runtime call stack for managing stack frames.
+// The frames within a stack may be from different backends and may provide
+// varying levels of information based on capabilities.
+//
+// Thread-compatible. Do not attempt to investigate a stack while another thread
+// may be mutating it!
+class Stack final {
+ public:
+ static constexpr int kMaxStackDepth = 32;
+
+ explicit Stack(Context* context);
+ Stack(const Stack&) = delete;
+ Stack& operator=(const Stack&) = delete;
+ ~Stack();
+
+ // Context defining the module and global workspaces.
+ Context* context() const { return context_; }
+
+ // All stack frames within the stack.
+ absl::Span<StackFrame> frames() {
+ return absl::MakeSpan(frames_).subspan(0, stack_depth_);
+ }
+ absl::Span<const StackFrame> frames() const {
+ return absl::MakeConstSpan(frames_).subspan(0, stack_depth_);
+ }
+
+ // The current stack frame.
+ StackFrame* current_frame() {
+ return stack_depth_ > 0 ? &frames_[stack_depth_ - 1] : nullptr;
+ }
+
+ // The stack frame of the caller of the current function.
+ StackFrame* caller_frame() {
+ return stack_depth_ > 1 ? &frames_[stack_depth_ - 2] : nullptr;
+ }
+
+ StatusOr<StackFrame*> PushFrame(Function function);
+ Status PopFrame();
+
+ // Returns a full stack frame listing in human-readable form.
+ std::string DebugString() const;
+
+ private:
+ Context* context_ = nullptr;
+ std::array<StackFrame, kMaxStackDepth> frames_;
+ int stack_depth_ = 0;
+};
+
+inline std::ostream& operator<<(std::ostream& stream, const Stack& stack) {
+ stream << stack.DebugString();
+ return stream;
+}
+
+} // namespace rt
+} // namespace iree
+
+#endif // IREE_RT_STACK_H_
diff --git a/iree/rt/stack_frame.h b/iree/rt/stack_frame.h
index 573e48e..bb77ef4 100644
--- a/iree/rt/stack_frame.h
+++ b/iree/rt/stack_frame.h
@@ -17,6 +17,7 @@
#include <ostream>
+#include "absl/types/span.h"
#include "iree/rt/function.h"
#include "iree/rt/module.h"
#include "iree/rt/source_location.h"
@@ -24,6 +25,12 @@
namespace iree {
namespace rt {
+// TODO(benvanik): allocate in-place from an arena.
+// Register table used within a stack frame.
+struct Registers {
+ std::vector<hal::BufferView> buffer_views;
+};
+
// A single frame on the call stack containing current execution state and
// register values.
//
@@ -35,12 +42,15 @@
// but instead just routing to the real storage via indirection. If the debugger
// is not attached and no errors are hit then no additional bookkeeping is done.
//
-// Thread-compatible, as is the owning StackTrace.
+// Thread-compatible, as is the owning Stack/StackTrace.
class StackFrame final {
public:
StackFrame() = default;
- explicit StackFrame(Function function, SourceOffset offset)
- : function_(function), offset_(offset) {}
+ explicit StackFrame(Function function) : function_(function) {}
+ StackFrame(Function function, SourceOffset offset, Registers registers)
+ : function_(function),
+ offset_(offset),
+ registers_(std::move(registers)) {}
StackFrame(const StackFrame&) = delete;
StackFrame& operator=(const StackFrame&) = delete;
StackFrame(StackFrame&&) = default;
@@ -57,15 +67,17 @@
// treat them as opaque and must use the SourceResolver to compute new
// offsets (such as 'next offset').
SourceOffset offset() const { return offset_; }
+ SourceOffset* mutable_offset() { return &offset_; }
// Returns a source location, if available, for the current offset within the
// target function.
absl::optional<SourceLocation> source_location() const;
- // TODO(benvanik): register access:
- // query total register layout for stack frame
- // get register in stack frame
- // set register in stack frame
+ // Registers used within the stack frame.
+ // Storage is implementation-defined and is valid only for the lifetime of the
+ // frame.
+ const Registers& registers() const { return registers_; }
+ Registers* mutable_registers() { return ®isters_; }
// A short human-readable string for the frame; a single line.
std::string DebugStringShort() const;
@@ -73,6 +85,13 @@
private:
Function function_;
SourceOffset offset_ = 0;
+ Registers registers_;
+};
+
+struct StackFrameFormatter {
+ void operator()(std::string* out, const StackFrame& stack_frame) const {
+ out->append(stack_frame.DebugStringShort());
+ }
};
inline std::ostream& operator<<(std::ostream& stream,
diff --git a/iree/rt/stack_trace.cc b/iree/rt/stack_trace.cc
index a5fdf33..ace8803 100644
--- a/iree/rt/stack_trace.cc
+++ b/iree/rt/stack_trace.cc
@@ -20,14 +20,6 @@
namespace iree {
namespace rt {
-namespace {
-struct StackFrameFormatter {
- void operator()(std::string* out, const StackFrame& stack_frame) const {
- out->append(stack_frame.DebugStringShort());
- }
-};
-} // namespace
-
std::string StackTrace::DebugString() const {
return absl::StrJoin(frames_, "\n", StackFrameFormatter());
}
diff --git a/iree/rt/stack_trace.h b/iree/rt/stack_trace.h
index 0c0612b..beca466 100644
--- a/iree/rt/stack_trace.h
+++ b/iree/rt/stack_trace.h
@@ -25,12 +25,13 @@
namespace iree {
namespace rt {
-// A snapshot of the runtime callstack providing access to stack frames.
+// A snapshot of a stack at a point in time.
// The frames within a stack may be from different backends and may provide
// varying levels of information based on capabilities.
//
-// Thread-compatible. Execution on one thread and stack manipulation on another
-// must be externally synchronized by the caller.
+// Depending on the capture options the trace may contain references to register
+// values (such as buffers) from the time of capture. If the buffers were
+// modified after the capture was taken those results will be reflected!
class StackTrace final {
public:
StackTrace() = default;
@@ -45,16 +46,6 @@
return absl::MakeConstSpan(frames_);
}
- // The current stack frame.
- const StackFrame* current_frame() const {
- return !frames_.empty() ? &frames_[frames_.size() - 1] : nullptr;
- }
-
- // The stack frame of the caller of the current function.
- const StackFrame* caller_frame() const {
- return frames_.size() > 1 ? &frames_[frames_.size() - 2] : nullptr;
- }
-
// Returns a full stack frame listing in human-readable form.
std::string DebugString() const;
diff --git a/iree/samples/CMakeLists.txt b/iree/samples/CMakeLists.txt
index 48bf62c..ae75ec9 100644
--- a/iree/samples/CMakeLists.txt
+++ b/iree/samples/CMakeLists.txt
@@ -13,4 +13,4 @@
# limitations under the License.
add_subdirectory(hal)
-add_subdirectory(vm)
+add_subdirectory(rt)
diff --git a/iree/samples/hal/BUILD b/iree/samples/hal/BUILD
index f29844b..8fa22bf 100644
--- a/iree/samples/hal/BUILD
+++ b/iree/samples/hal/BUILD
@@ -2,14 +2,14 @@
# These do not rely on higher layers of the system (such as the VM or runtime).
load("//iree:build_defs.bzl", "PLATFORM_VULKAN_TEST_DEPS")
-load("//iree/tools:compilation.bzl", "iree_module")
+load("//iree/tools:compilation.bzl", "iree_bytecode_module")
package(
default_visibility = ["//visibility:public"],
licenses = ["notice"], # Apache 2.0
)
-iree_module(
+iree_bytecode_module(
name = "simple_compute_test_module",
srcs = ["simple_compute_test.mlir"],
cc_namespace = "iree::hal::samples",
diff --git a/iree/samples/hal/simple_compute_test.cc b/iree/samples/hal/simple_compute_test.cc
index ac2986b..43f0c48 100644
--- a/iree/samples/hal/simple_compute_test.cc
+++ b/iree/samples/hal/simple_compute_test.cc
@@ -21,8 +21,8 @@
// imports requiring runtime support, uses floats exclusively (as that's assumed
// available everywhere), etc.
//
-// The `iree_module` build rule is used to translate the MLIR to the module
-// flatbuffer. Additional target support can be defined there.
+// The `iree_bytecode_module` build rule is used to translate the MLIR to the
+// module flatbuffer. Additional target support can be defined there.
#include "gmock/gmock.h"
#include "gtest/gtest.h"
diff --git a/iree/samples/vm/BUILD b/iree/samples/rt/BUILD
similarity index 69%
rename from iree/samples/vm/BUILD
rename to iree/samples/rt/BUILD
index 2a1a94c..2712b07 100644
--- a/iree/samples/vm/BUILD
+++ b/iree/samples/rt/BUILD
@@ -1,21 +1,21 @@
-# Samples demonstrating use of the VM API.
+# Samples demonstrating use of the RT API.
-load("//iree/tools:compilation.bzl", "iree_module")
+load("//iree/tools:compilation.bzl", "iree_bytecode_module")
package(
default_visibility = ["//visibility:public"],
licenses = ["notice"], # Apache 2.0
)
-iree_module(
- name = "simple_module_test_module",
+iree_bytecode_module(
+ name = "simple_module_test_bytecode_module",
srcs = ["simple_module_test.mlir"],
- cc_namespace = "iree::vm::samples",
+ cc_namespace = "iree::rt::samples",
)
cc_test(
- name = "simple_module_test",
- srcs = ["simple_module_test.cc"],
+ name = "bytecode_module_test",
+ srcs = ["bytecode_module_test.cc"],
data = [
# When building with --config=asan you must specify the following
# envvar when using Vulkan + a local Nvidia GPU:
@@ -23,20 +23,18 @@
"//iree/tools:sanitizer_suppressions.txt",
],
deps = [
- ":simple_module_test_module_cc",
+ ":simple_module_test_bytecode_module_cc",
"@com_google_googletest//:gtest_main",
"@com_google_absl//absl/strings",
"//iree/base:flatbuffer_util",
+ "//iree/base:status",
"//iree/base:status_matchers",
"//iree/hal:buffer_view",
- "//iree/hal:command_buffer",
- "//iree/hal:command_queue",
"//iree/hal:driver_registry",
+ "//iree/rt",
"//iree/schemas",
- "//iree/base:status",
- "//iree/vm:fiber_state",
- "//iree/vm:instance",
- "//iree/vm:sequencer_context",
+ "//iree/vm:bytecode_module",
+ "//iree/vm:sequencer_module",
# These are the drivers we support running with and can produce
# executables for from the source MLIR.
diff --git a/iree/samples/vm/CMakeLists.txt b/iree/samples/rt/CMakeLists.txt
similarity index 82%
rename from iree/samples/vm/CMakeLists.txt
rename to iree/samples/rt/CMakeLists.txt
index 1c36407..ec6ee74 100644
--- a/iree/samples/vm/CMakeLists.txt
+++ b/iree/samples/rt/CMakeLists.txt
@@ -14,9 +14,9 @@
iree_cc_test(
NAME
- simple_module_test
+ bytecode_module_test
SRCS
- "simple_module_test.cc"
+ "bytecode_module_test.cc"
DEPS
absl::strings
gtest_main
@@ -24,13 +24,10 @@
iree::base::status
iree::base::status_matchers
iree::hal::buffer_view
- iree::hal::command_buffer
- iree::hal::command_queue
iree::hal::driver_registry
iree::schemas
- iree::vm::fiber_state
- iree::vm::instance
- iree::vm::sequencer_context
+ iree::rt
+ iree::vm::bytecode_module
# Enabled drivers:
iree::hal::interpreter::interpreter_driver_module
iree::hal::vulkan::vulkan_driver_module
diff --git a/iree/samples/vm/simple_module_test.cc b/iree/samples/rt/bytecode_module_test.cc
similarity index 79%
rename from iree/samples/vm/simple_module_test.cc
rename to iree/samples/rt/bytecode_module_test.cc
index 8db859e..2fdc7cf 100644
--- a/iree/samples/vm/simple_module_test.cc
+++ b/iree/samples/rt/bytecode_module_test.cc
@@ -25,6 +25,8 @@
// The `iree_module` build rule is used to translate the MLIR to the module
// flatbuffer. Additional HAL backend target support can be defined there.
+#include "iree/vm/bytecode_module.h"
+
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/strings/str_replace.h"
@@ -32,23 +34,20 @@
#include "iree/base/status.h"
#include "iree/base/status_matchers.h"
#include "iree/hal/buffer_view.h"
-#include "iree/hal/command_buffer.h"
-#include "iree/hal/command_queue.h"
#include "iree/hal/driver_registry.h"
-#include "iree/samples/vm/simple_module_test_module.h"
+#include "iree/rt/context.h"
+#include "iree/rt/instance.h"
+#include "iree/samples/rt/simple_module_test_bytecode_module.h"
#include "iree/schemas/module_def_generated.h"
-#include "iree/vm/fiber_state.h"
-#include "iree/vm/instance.h"
-#include "iree/vm/sequencer_context.h"
+#include "iree/vm/sequencer_module.h"
namespace iree {
-namespace vm {
+namespace rt {
namespace samples {
namespace {
-using iree::hal::BufferView;
-
-using ModuleFile = FlatBufferFile<ModuleDef>;
+using ::iree::hal::BufferView;
+using ::iree::vm::ModuleFile;
struct TestParams {
// HAL driver to use for the test.
@@ -77,7 +76,7 @@
};
TEST_P(SimpleModuleTest, RunOnce) {
- auto instance = std::make_shared<Instance>();
+ auto instance = make_ref<Instance>();
// Create driver for this test (based on params) and then get a default
// device.
@@ -105,22 +104,20 @@
// Make a new context and load the precompiled module file (from
// simple_module_test.mlir) into it.
LOG(INFO) << "Loading simple_module_test.mlir...";
- SequencerContext context(instance);
- const auto* module_file_toc = simple_module_test_module_create();
- ASSERT_OK_AND_ASSIGN(
- auto module_file,
- ModuleFile::WrapBuffer(ModuleDefIdentifier(),
- absl::MakeSpan(reinterpret_cast<const uint8_t*>(
- module_file_toc->data),
- module_file_toc->size)));
+ auto policy = make_ref<Policy>();
+ Context context(add_ref(instance), add_ref(policy));
+ const auto* module_file_toc = simple_module_test_bytecode_module_create();
+ ASSERT_OK_AND_ASSIGN(auto module_file,
+ vm::ModuleFile::WrapBuffer(
+ ModuleDefIdentifier(),
+ absl::MakeSpan(reinterpret_cast<const uint8_t*>(
+ module_file_toc->data),
+ module_file_toc->size)));
ASSERT_OK_AND_ASSIGN(auto main_module,
- Module::FromFile(std::move(module_file)));
+ vm::SequencerModule::FromFile(std::move(module_file)));
ASSERT_OK(context.RegisterModule(std::move(main_module)));
LOG(INFO) << "Module loaded and context is ready for use";
- // In this sample we just have a single fiber.
- FiberState fiber_state(instance);
-
// Allocate buffers that can be mapped on the CPU and that can also be used
// on the device. Not all devices support this, but the ones we have now do.
LOG(INFO) << "Creating I/O buffers...";
@@ -140,14 +137,17 @@
// Call into the @simple_mul function.
LOG(INFO) << "Calling @simple_mul...";
- std::vector<BufferView> args{
+ absl::InlinedVector<BufferView, 8> args{
BufferView{add_ref(arg0_buffer), {kElementCount}, sizeof(float)},
BufferView{add_ref(arg1_buffer), {kElementCount}, sizeof(float)},
};
- std::vector<BufferView> results{1};
- ASSERT_OK_AND_ASSIGN(auto simple_mul, context.LookupExport("simple_mul"));
- ASSERT_OK(context.Invoke(&fiber_state, simple_mul, absl::MakeSpan(args),
- absl::MakeSpan(results)));
+ ASSERT_OK_AND_ASSIGN(auto simple_mul,
+ context.ResolveFunction("module.simple_mul"));
+ ASSERT_OK_AND_ASSIGN(auto invocation,
+ Invocation::Create(add_ref(&context), simple_mul,
+ nullptr, {}, std::move(args)));
+ ASSERT_OK(invocation->Await(absl::InfiniteFuture()));
+ ASSERT_OK_AND_ASSIGN(auto results, invocation->ConsumeResults());
// Read back the results and ensure we got the right values.
LOG(INFO) << "Reading back results...";
@@ -166,5 +166,5 @@
} // namespace
} // namespace samples
-} // namespace vm
+} // namespace rt
} // namespace iree
diff --git a/iree/samples/vm/simple_module_test.mlir b/iree/samples/rt/simple_module_test.mlir
similarity index 100%
rename from iree/samples/vm/simple_module_test.mlir
rename to iree/samples/rt/simple_module_test.mlir
diff --git a/iree/tools/BUILD b/iree/tools/BUILD
index 6d15ade..3fa849c 100644
--- a/iree/tools/BUILD
+++ b/iree/tools/BUILD
@@ -37,6 +37,8 @@
"@com_google_absl//absl/flags:flag",
"@com_google_absl//absl/strings",
"//iree/base:source_location",
+ "//iree/rt",
+ "//iree/vm:sequencer_module",
"@llvm//:support",
"@local_config_mlir//:IR",
"@local_config_mlir//:Parser",
@@ -48,19 +50,14 @@
"//iree/compiler/Translation/SPIRV",
"//iree/hal:buffer_view_string_util",
"//iree/hal:driver_registry",
+ "//iree/schemas",
+ "//iree/rt/debug:debug_server_flags",
+ ] + PLATFORM_VULKAN_DEPS + [
"//iree/hal/interpreter:interpreter_driver_module",
- "//iree/hal/vulkan:vulkan_driver_module",
# TODO(b/142004903): enable when Dawn HAL implementation is functional
# "//iree/hal/dawn:dawn_driver_module",
- "//iree/schemas",
- "//iree/vm:bytecode_tables_sequencer",
- "//iree/vm:fiber_state",
- "//iree/vm:instance",
- "//iree/vm:module",
- "//iree/vm:module_printer",
- "//iree/vm:sequencer_context",
- "//iree/rt/debug:debug_server_flags",
- ] + PLATFORM_VULKAN_DEPS,
+ "//iree/hal/vulkan:vulkan_driver_module",
+ ],
)
cc_binary(
@@ -94,16 +91,10 @@
"//iree/hal:buffer_view_string_util",
"//iree/hal:driver_registry",
"//iree/hal/interpreter:interpreter_driver_module",
+ "//iree/rt",
"//iree/rt/debug:debug_server_flags",
"//iree/schemas",
- "//iree/vm:bytecode_printer",
- "//iree/vm:bytecode_tables_sequencer",
- "//iree/vm:fiber_state",
- "//iree/vm:function",
- "//iree/vm:instance",
- "//iree/vm:module",
- "//iree/vm:module_printer",
- "//iree/vm:sequencer_context",
+ "//iree/vm:sequencer_module",
"@com_google_absl//absl/flags:flag",
"@com_google_absl//absl/strings",
],
diff --git a/iree/tools/compilation.bzl b/iree/tools/compilation.bzl
index 5d1ffe5..b232099 100644
--- a/iree/tools/compilation.bzl
+++ b/iree/tools/compilation.bzl
@@ -3,7 +3,7 @@
load("//build_tools/embed_data:build_defs.bzl", "cc_embed_data")
# TODO(benvanik): port to a full starlark rule, document, etc.
-def iree_module(
+def iree_bytecode_module(
name,
srcs,
cc_namespace = None,
diff --git a/iree/tools/debugger/BUILD b/iree/tools/debugger/BUILD
index b1f432b..e3b90a4 100644
--- a/iree/tools/debugger/BUILD
+++ b/iree/tools/debugger/BUILD
@@ -7,7 +7,8 @@
# By default the IREE runtime does not compile in debug support. To link it in
# pass --define=IREE_DEBUG=1 to bazel builds of the runtime.
-load("//third_party/emscripten:split_transition_defs.bzl", "auto_wasm_binary")
+# TODO(benvanik): re-enable debugger after refactoring.
+# load("//third_party/emscripten:split_transition_defs.bzl", "auto_wasm_binary")
package(
default_visibility = ["//visibility:public"],
@@ -41,10 +42,6 @@
# "//iree/base:status",
# "//iree/rt/debug:debug_client",
# "//iree/schemas",
-# "//iree/vm:bytecode_printer",
-# "//iree/vm:bytecode_tables_sequencer",
-# "//iree/vm:module",
-# "//iree/vm:source_map",
# ],
# )
#
diff --git a/iree/tools/debugger/debug_app.cc b/iree/tools/debugger/debug_app.cc
index 793f4a1..303979e 100644
--- a/iree/tools/debugger/debug_app.cc
+++ b/iree/tools/debugger/debug_app.cc
@@ -31,10 +31,8 @@
#include "iree/base/status.h"
#include "iree/rt/debug/debug_client.h"
#include "iree/schemas/debug_service_generated.h"
-#include "iree/vm/bytecode_printer.h"
+#include "iree/vm/bytecode_module.h"
#include "iree/vm/bytecode_tables_sequencer.h"
-#include "iree/vm/module.h"
-#include "iree/vm/source_map.h"
namespace iree {
namespace rt {
@@ -1311,21 +1309,7 @@
auto* remote_module = document->function->module();
auto* remote_function = document->function;
- ASSIGN_OR_RETURN(auto module, vm::Module::FromDef(remote_module->def()));
-
- // TODO(benvanik): source map support.
- // Want line count including source lines, IR lines, and bytecode lines.
- // May want lower level (JIT/etc) lines too.
-
- // TODO(benvanik): bytecode iterator for richer display.
- auto source_map_resolver = vm::SourceMapResolver::FromFunction(
- module->def(), remote_function->ordinal());
- vm::BytecodePrinter printer(vm::sequencer_opcode_table(),
- module->function_table(),
- module->executable_table(), source_map_resolver);
- ASSIGN_OR_RETURN(std::string full_string,
- printer.Print(*remote_function->bytecode()));
- document->bytecode_info.lines = absl::StrSplit(full_string, '\n');
+ document->bytecode_info.lines = remote_function->name();
return OkStatus();
}
diff --git a/iree/tools/run_mlir_main.cc b/iree/tools/run_mlir_main.cc
index 360745e..dfa3486 100644
--- a/iree/tools/run_mlir_main.cc
+++ b/iree/tools/run_mlir_main.cc
@@ -47,14 +47,14 @@
#include "iree/compiler/Translation/Sequencer/SequencerModuleTranslation.h"
#include "iree/hal/buffer_view_string_util.h"
#include "iree/hal/driver_registry.h"
+#include "iree/rt/context.h"
#include "iree/rt/debug/debug_server_flags.h"
+#include "iree/rt/instance.h"
+#include "iree/rt/invocation.h"
+#include "iree/rt/module.h"
+#include "iree/rt/module_printer.h"
#include "iree/schemas/module_def_generated.h"
-#include "iree/vm/bytecode_tables_sequencer.h"
-#include "iree/vm/fiber_state.h"
-#include "iree/vm/instance.h"
-#include "iree/vm/module.h"
-#include "iree/vm/module_printer.h"
-#include "iree/vm/sequencer_context.h"
+#include "iree/vm/sequencer_module.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/SourceMgr.h"
#include "mlir/IR/Attributes.h"
@@ -92,9 +92,8 @@
namespace {
using ::iree::hal::BufferView;
-using ::iree::vm::Function;
-using ::iree::vm::Module;
-using ::iree::vm::ModuleFile;
+using ::iree::rt::Function;
+using ::iree::rt::Module;
// Returns a driver name capable of handling input from the given backend.
std::string BackendToDriverName(std::string backend) {
@@ -107,7 +106,7 @@
}
// Prepares a module for evaluation by running MLIR import and IREE translation.
-StatusOr<std::unique_ptr<Module>> PrepareModule(
+StatusOr<ref_ptr<Module>> PrepareModule(
std::string target_backend,
std::unique_ptr<llvm::MemoryBuffer> file_buffer) {
mlir::MLIRContext context;
@@ -142,9 +141,9 @@
// Wrap module in a file handle.
ASSIGN_OR_RETURN(auto iree_module_file,
- ModuleFile::FromBuffer(ModuleDefIdentifier(),
- std::move(iree_module_bytes)));
- return Module::FromFile(std::move(iree_module_file));
+ vm::ModuleFile::FromBuffer(ModuleDefIdentifier(),
+ std::move(iree_module_bytes)));
+ return vm::SequencerModule::FromFile(std::move(iree_module_file));
}
// Parses a list of input shapes and values from a string of newline-separated
@@ -196,25 +195,22 @@
}
// Evaluates a single function in its own fiber, printing the results to stdout.
-Status EvaluateFunction(std::shared_ptr<vm::Instance> instance,
- vm::SequencerContext* context,
+Status EvaluateFunction(const ref_ptr<rt::Context>& context,
hal::Allocator* allocator, const Function& function) {
- // Setup our dummy fiber we will run with.
- vm::FiberState fiber_state(instance);
-
std::cout << "EXEC @" << function.name() << std::endl;
- // Marshal inputs.
- ASSIGN_OR_RETURN(std::vector<BufferView> args,
- ParseInputsFromFlags(allocator));
- std::vector<BufferView> results;
- results.resize(function.result_count());
+ // Create invocation that will perform the execution.
+ ASSIGN_OR_RETURN(auto arguments, ParseInputsFromFlags(allocator));
+ ASSIGN_OR_RETURN(
+ auto invocation,
+ rt::Invocation::Create(add_ref(context), function, make_ref<rt::Policy>(),
+ {}, absl::MakeConstSpan(arguments)));
- // Call into the main function.
- RETURN_IF_ERROR(context->Invoke(&fiber_state, function, absl::MakeSpan(args),
- absl::MakeSpan(results)));
+ // Wait until invocation completes.
+ RETURN_IF_ERROR(invocation->Await(absl::InfiniteFuture()));
// Print outputs.
+ ASSIGN_OR_RETURN(auto results, invocation->ConsumeResults());
RETURN_IF_ERROR(OutputFunctionResults(function, absl::MakeSpan(results)));
return OkStatus();
@@ -222,35 +218,33 @@
// Evaluates all exported functions within given module.
Status EvaluateFunctions(absl::string_view target_backend,
- std::unique_ptr<Module> module) {
+ ref_ptr<Module> module) {
// Create the context we'll use for this (ensuring that we can't interfere
// with other running evaluations, such as when in a multithreaded test
// runner).
ASSIGN_OR_RETURN(auto debug_server, rt::debug::CreateDebugServerFromFlags());
- auto instance = std::make_shared<vm::Instance>();
+ auto instance = make_ref<rt::Instance>(std::move(debug_server));
ASSIGN_OR_RETURN(auto driver, hal::DriverRegistry::shared_registry()->Create(
target_backend));
ASSIGN_OR_RETURN(auto device, driver->CreateDefaultDevice());
RETURN_IF_ERROR(instance->device_manager()->RegisterDevice(device));
- vm::SequencerContext context(instance);
if (absl::GetFlag(FLAGS_print_bytecode)) {
- vm::PrintModuleFlagBitfield print_flags = vm::PrintModuleFlag::kNone;
- RETURN_IF_ERROR(vm::PrintModuleToStream(vm::sequencer_opcode_table(),
- *module, print_flags, &std::cout));
+ RETURN_IF_ERROR(rt::PrintModuleToStream(
+ *module, rt::PrintModuleFlag::kDisassemble, &std::cout));
}
- // Register module with the context.
- RETURN_IF_ERROR(context.RegisterModule(std::move(module)));
-
// Evaluate all exported functions.
- for (auto& module : context.modules()) {
- for (int function_ordinal : *module->def().function_table()->exports()) {
- ASSIGN_OR_RETURN(auto function, module->function_table().LookupFunction(
- function_ordinal));
- RETURN_IF_ERROR(
- EvaluateFunction(instance, &context, device->allocator(), function));
- }
+ auto policy = make_ref<rt::Policy>();
+ for (int i = 0; i < module->signature().export_function_count(); ++i) {
+ // Setup a new context for this invocation.
+ auto context = make_ref<rt::Context>(add_ref(instance), add_ref(policy));
+ RETURN_IF_ERROR(context->RegisterModule(add_ref(module)));
+
+ // Invoke the function and print results.
+ ASSIGN_OR_RETURN(auto function, module->LookupFunctionByOrdinal(
+ rt::Function::Linkage::kExport, i));
+ RETURN_IF_ERROR(EvaluateFunction(context, device->allocator(), function));
}
RETURN_IF_ERROR(instance->device_manager()->UnregisterDevice(device.get()));
diff --git a/iree/tools/run_module_main.cc b/iree/tools/run_module_main.cc
index 5fefbfc..be634ee 100644
--- a/iree/tools/run_module_main.cc
+++ b/iree/tools/run_module_main.cc
@@ -27,23 +27,19 @@
#include "iree/base/status.h"
#include "iree/hal/buffer_view_string_util.h"
#include "iree/hal/driver_registry.h"
+#include "iree/rt/context.h"
#include "iree/rt/debug/debug_server_flags.h"
+#include "iree/rt/instance.h"
+#include "iree/rt/module_printer.h"
#include "iree/schemas/module_def_generated.h"
-#include "iree/vm/bytecode_printer.h"
-#include "iree/vm/bytecode_tables_sequencer.h"
-#include "iree/vm/fiber_state.h"
-#include "iree/vm/function.h"
-#include "iree/vm/instance.h"
-#include "iree/vm/module.h"
-#include "iree/vm/module_printer.h"
-#include "iree/vm/sequencer_context.h"
+#include "iree/vm/sequencer_module.h"
ABSL_FLAG(std::string, main_module, "", "Main module with entry point.");
ABSL_FLAG(std::string, main_function, "",
"Function within the main module to execute.");
-ABSL_FLAG(bool, print_source_info, false,
- "Prints source map information in bytecode output.");
+ABSL_FLAG(bool, print_disassembly, true,
+ "Prints bytecode disassembly for the module.");
ABSL_FLAG(std::string, input_values, "", "Input shapes and optional values.");
ABSL_FLAG(std::string, input_file, "",
@@ -54,18 +50,15 @@
"binary/signed int/unsigned int/float).");
namespace iree {
-namespace vm {
namespace {
-using ::iree::hal::BufferView;
-
// Parses a list of input shapes and values from a string of newline-separated
// inputs. Expects the contents to have one value per line with each value
// listed as
// [shape]xtype=[value]
// Example:
// 4x4xi8=0,1,2,3
-StatusOr<std::vector<BufferView>> ParseInputsFromFlags(
+StatusOr<std::vector<hal::BufferView>> ParseInputsFromFlags(
hal::Allocator* allocator) {
std::string file_contents;
if (!absl::GetFlag(FLAGS_input_values).empty()) {
@@ -75,7 +68,7 @@
ASSIGN_OR_RETURN(file_contents,
file_io::GetFileContents(absl::GetFlag(FLAGS_input_file)));
}
- std::vector<BufferView> inputs;
+ std::vector<hal::BufferView> inputs;
for (const auto& line :
absl::StrSplit(file_contents, '\n', absl::SkipWhitespace())) {
ASSIGN_OR_RETURN(auto input,
@@ -89,81 +82,67 @@
Status Run() {
ASSIGN_OR_RETURN(auto debug_server, rt::debug::CreateDebugServerFromFlags());
- auto instance = std::make_shared<Instance>();
+ auto instance = make_ref<rt::Instance>(std::move(debug_server));
ASSIGN_OR_RETURN(auto driver, hal::DriverRegistry::shared_registry()->Create(
"interpreter"));
ASSIGN_OR_RETURN(auto device, driver->CreateDefaultDevice());
RETURN_IF_ERROR(instance->device_manager()->RegisterDevice(device));
- SequencerContext context(instance);
+ auto policy = make_ref<rt::Policy>();
+ auto context = make_ref<rt::Context>(add_ref(instance), std::move(policy));
// Load main module.
ASSIGN_OR_RETURN(
auto main_module_file,
- ModuleFile::LoadFile(ModuleDefIdentifier(),
- absl::GetFlag(FLAGS_main_module)),
+ vm::ModuleFile::LoadFile(ModuleDefIdentifier(),
+ absl::GetFlag(FLAGS_main_module)),
_ << "while loading module file " << absl::GetFlag(FLAGS_main_module));
ASSIGN_OR_RETURN(auto main_module,
- Module::FromFile(std::move(main_module_file)));
-
- // Add native functions for use by the module.
- RETURN_IF_ERROR(context.RegisterNativeFunction(
- "fabsf",
- [](Stack* stack, absl::Span<const BufferView> args,
- absl::Span<BufferView> results) -> Status {
- // TODO(benvanik): example native functions.
- LOG(INFO) << "fabsf";
- return OkStatus();
- }));
+ vm::SequencerModule::FromFile(std::move(main_module_file)));
// Register the main module with the context.
// We could add additional modules (specializations, shared libraries, etc).
// ModuleFioles are stateless so we could have the same module_file used by
// multiple contexts simultaneously.
- auto* main_module_ptr = main_module.get();
- RETURN_IF_ERROR(context.RegisterModule(std::move(main_module)));
+ RETURN_IF_ERROR(context->RegisterModule(add_ref(main_module)));
// Dump the registered modules.
- PrintModuleFlagBitfield print_flags = PrintModuleFlag::kNone;
- if (absl::GetFlag(FLAGS_print_source_info)) {
- print_flags |= PrintModuleFlag::kIncludeSourceMapping;
+ rt::PrintModuleFlagBitfield print_flags = rt::PrintModuleFlag::kNone;
+ if (absl::GetFlag(FLAGS_print_disassembly)) {
+ print_flags |= rt::PrintModuleFlag::kDisassemble;
}
- for (const auto& module : context.modules()) {
- RETURN_IF_ERROR(PrintModuleToStream(sequencer_opcode_table(), *module,
- print_flags, &std::cout));
+ for (const auto& module : context->modules()) {
+ RETURN_IF_ERROR(PrintModuleToStream(*module, print_flags, &std::cout));
}
- // Setup a new fiber.
- FiberState fiber_state(instance);
-
- // Setup arguments and storage for results.
- Function main_function;
+ rt::Function main_function;
if (!absl::GetFlag(FLAGS_main_function).empty()) {
// User-specified main function.
- ASSIGN_OR_RETURN(main_function,
- context.LookupExport(absl::GetFlag(FLAGS_main_function)));
+ ASSIGN_OR_RETURN(main_function, main_module->LookupFunctionByName(
+ rt::Function::Linkage::kExport,
+ absl::GetFlag(FLAGS_main_function)));
} else {
// No main function specified; to prevent non-deterministic behavior we
// require one unless there's exactly one exported function in the module.
- auto* exports = main_module_ptr->function_table().def().exports();
- if (exports && exports->size() == 1) {
- ASSIGN_OR_RETURN(
- main_function,
- main_module_ptr->function_table().LookupFunction(exports->Get(0)));
+ if (main_module->signature().export_function_count() == 1) {
+ ASSIGN_OR_RETURN(main_function, main_module->LookupFunctionByOrdinal(
+ rt::Function::Linkage::kExport, 0));
} else {
return InvalidArgumentErrorBuilder(IREE_LOC)
<< "--main_function= must be specified to disambiguate the "
"function to run";
}
}
- ASSIGN_OR_RETURN(std::vector<BufferView> args,
- ParseInputsFromFlags(device->allocator()));
- std::vector<BufferView> results;
- results.resize(main_function.result_count());
// Call into the main function.
- RETURN_IF_ERROR(context.Invoke(&fiber_state, main_function,
- absl::MakeSpan(args),
- absl::MakeSpan(results)));
+ ASSIGN_OR_RETURN(auto arguments, ParseInputsFromFlags(device->allocator()));
+ ASSIGN_OR_RETURN(auto invocation,
+ rt::Invocation::Create(add_ref(context), main_function,
+ make_ref<rt::Policy>(), {},
+ absl::MakeConstSpan(arguments)));
+
+ // Wait until invocation completes.
+ RETURN_IF_ERROR(invocation->Await(absl::InfiniteFuture()));
+ ASSIGN_OR_RETURN(auto results, invocation->ConsumeResults());
// Dump all results to stdout.
std::vector<std::string> output_types =
@@ -201,5 +180,4 @@
return 0;
}
-} // namespace vm
} // namespace iree
diff --git a/iree/tools/web/BUILD b/iree/tools/web/BUILD
index 3737e05..f55ef9d 100644
--- a/iree/tools/web/BUILD
+++ b/iree/tools/web/BUILD
@@ -1,12 +1,12 @@
# IREE web tools.
+load("//third_party/emscripten:split_transition_defs.bzl", "auto_wasm_binary")
+
package(
default_visibility = ["//visibility:public"],
licenses = ["notice"], # Apache 2.0
)
-load("//third_party/emscripten:split_transition_defs.bzl", "auto_wasm_binary")
-
EMSCRIPTEN_LINKOPTS_COMMON = [
# Error at compile time on unresolved symbols.
"-s ERROR_ON_UNDEFINED_SYMBOLS=1",
@@ -58,9 +58,8 @@
"//iree/hal:buffer_view_string_util",
"//iree/hal:driver_registry",
"//iree/hal/interpreter:interpreter_driver_module",
- "//iree/vm:bytecode_tables_sequencer",
- "//iree/vm:instance",
- "//iree/vm:sequencer_context",
+ "//iree/rt",
+ "//iree/vm:sequencer_module",
"//third_party/emscripten:embind",
],
)
diff --git a/iree/tools/web/run_module_emscripten.cc b/iree/tools/web/run_module_emscripten.cc
index f713807..49d88a7 100644
--- a/iree/tools/web/run_module_emscripten.cc
+++ b/iree/tools/web/run_module_emscripten.cc
@@ -26,14 +26,10 @@
#include "iree/hal/buffer_view.h"
#include "iree/hal/buffer_view_string_util.h"
#include "iree/hal/driver_registry.h"
+#include "iree/rt/context.h"
+#include "iree/rt/instance.h"
#include "iree/schemas/module_def_generated.h"
-#include "iree/vm/bytecode_tables_sequencer.h"
-#include "iree/vm/fiber_state.h"
-#include "iree/vm/function.h"
-#include "iree/vm/instance.h"
-#include "iree/vm/module.h"
-#include "iree/vm/module_printer.h"
-#include "iree/vm/sequencer_context.h"
+#include "iree/vm/sequencer_module.h"
namespace iree {
@@ -59,52 +55,49 @@
// Runs an IREE module with the provided inputs and returns its outputs.
StatusOr<std::string> RunIreeModule(std::string module_file_data,
absl::string_view inputs_string) {
- auto instance = std::make_shared<vm::Instance>();
+ auto instance = make_ref<rt::Instance>();
// Create driver and device.
ASSIGN_OR_RETURN(auto driver, hal::DriverRegistry::shared_registry()->Create(
"interpreter"));
ASSIGN_OR_RETURN(auto device, driver->CreateDefaultDevice());
RETURN_IF_ERROR(instance->device_manager()->RegisterDevice(device));
- vm::SequencerContext context(instance);
+
+ auto policy = make_ref<rt::Policy>();
+ auto context = make_ref<rt::Context>(add_ref(instance), std::move(policy));
// Load main module FlatBuffer.
ASSIGN_OR_RETURN(auto main_module_file,
FlatBufferFile<ModuleDef>::FromString(ModuleDefIdentifier(),
module_file_data));
ASSIGN_OR_RETURN(auto main_module,
- vm::Module::FromFile(std::move(main_module_file)));
+ vm::SequencerModule::FromFile(std::move(main_module_file)));
// Register the main module with the context.
- RETURN_IF_ERROR(context.RegisterModule(std::move(main_module)));
-
- // Dump the registered modules.
- vm::PrintModuleFlagBitfield print_flags =
- vm::PrintModuleFlag::kIncludeSourceMapping;
- for (const auto& module : context.modules()) {
- RETURN_IF_ERROR(vm::PrintModuleToStream(vm::sequencer_opcode_table(),
- *module, print_flags, &std::cout));
- }
-
- // Setup a new fiber.
- vm::FiberState fiber_state(instance);
+ RETURN_IF_ERROR(context->RegisterModule(add_ref(main_module)));
// Setup arguments and storage for results.
- // TODO(scotttodd): Receive main function name from JS
- ASSIGN_OR_RETURN(vm::Function main_function, context.LookupExport("main"));
+ // TODO(scotttodd): Receive main function name from JS.
+ ASSIGN_OR_RETURN(auto main_function,
+ main_module->LookupFunctionByName(
+ rt::Function::Linkage::kExport, "main"));
- ASSIGN_OR_RETURN(std::vector<hal::BufferView> args,
+ ASSIGN_OR_RETURN(auto arguments,
ParseInputs(inputs_string, device->allocator()));
- std::vector<hal::BufferView> results;
- results.resize(main_function.result_count());
// Call into the main function.
- RETURN_IF_ERROR(context.Invoke(&fiber_state, main_function,
- absl::MakeSpan(args),
- absl::MakeSpan(results)));
+ ASSIGN_OR_RETURN(auto invocation,
+ rt::Invocation::Create(add_ref(context), main_function,
+ make_ref<rt::Policy>(), {},
+ absl::MakeConstSpan(arguments)));
+
+ // Wait until invocation completes.
+ // TODO(scotttodd): make this an async callback.
+ RETURN_IF_ERROR(invocation->Await(absl::InfiniteFuture()));
+ ASSIGN_OR_RETURN(auto results, invocation->ConsumeResults());
// Dump all results to stdout.
- // TODO(scotttodd): Receive output types / print mode from JS
+ // TODO(scotttodd): Receive output types / print mode from JS.
// TODO(scotttodd): Return list of outputs instead of just the first (proto?)
for (int i = 0; i < results.size(); ++i) {
const auto& result = results[i];
diff --git a/iree/vm/BUILD b/iree/vm/BUILD
index d65e151..9da6c77 100644
--- a/iree/vm/BUILD
+++ b/iree/vm/BUILD
@@ -6,22 +6,30 @@
)
cc_library(
- name = "bytecode_printer",
- srcs = ["bytecode_printer.cc"],
- hdrs = ["bytecode_printer.h"],
+ name = "bytecode_module",
+ srcs = [
+ "bytecode_disassembler.cc",
+ "bytecode_module.cc",
+ ],
+ hdrs = [
+ "bytecode_disassembler.h",
+ "bytecode_module.h",
+ ],
deps = [
":bytecode_util",
- ":executable_table",
- ":function_table",
- ":module",
":opcode_info",
- ":source_map",
+ ":source_map_resolver",
":type",
+ "//iree/base:flatbuffer_util",
"//iree/base:status",
+ "//iree/base:tracing",
+ "//iree/hal:buffer_view",
+ "//iree/rt",
"//iree/schemas",
"//iree/schemas/bytecode:bytecode_v0",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:inlined_vector",
+ "@com_google_absl//absl/memory",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/types:span",
],
@@ -32,13 +40,13 @@
srcs = ["bytecode_reader.cc"],
hdrs = ["bytecode_reader.h"],
deps = [
- ":function",
- ":stack",
+ ":bytecode_module",
":type",
"//iree/base:shape",
"//iree/base:status",
"//iree/hal:buffer_view",
"//iree/hal:heap_buffer",
+ "//iree/rt",
"//iree/schemas/bytecode:bytecode_v0",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:inlined_vector",
@@ -80,122 +88,13 @@
srcs = ["bytecode_validator.cc"],
hdrs = ["bytecode_validator.h"],
deps = [
- ":context",
- ":module",
+ ":bytecode_module",
"//iree/base:status",
"//iree/schemas",
],
)
cc_library(
- name = "context",
- srcs = ["context.cc"],
- hdrs = ["context.h"],
- deps = [
- ":function",
- ":module",
- "//iree/base:flatbuffer_util",
- "//iree/base:status",
- "@com_google_absl//absl/strings",
- "@com_google_absl//absl/types:span",
- ],
-)
-
-cc_library(
- name = "executable_table",
- srcs = ["executable_table.cc"],
- hdrs = ["executable_table.h"],
- deps = [
- "//iree/base:flatbuffer_util",
- "//iree/base:source_location",
- "//iree/base:status",
- "//iree/schemas",
- ],
-)
-
-cc_library(
- name = "fiber_state",
- srcs = ["fiber_state.cc"],
- hdrs = ["fiber_state.h"],
- deps = [
- ":instance",
- ":stack",
- "//iree/base:status",
- "@com_google_absl//absl/strings",
- "@com_google_absl//absl/types:span",
- ],
-)
-
-cc_library(
- name = "function",
- srcs = ["function.cc"],
- hdrs = ["function.h"],
- deps = [
- "//iree/base:flatbuffer_util",
- "//iree/base:status",
- "//iree/hal:buffer_view",
- "//iree/schemas",
- "@com_google_absl//absl/strings",
- "@com_google_absl//absl/types:span",
- ],
-)
-
-cc_library(
- name = "function_table",
- srcs = ["function_table.cc"],
- hdrs = ["function_table.h"],
- deps = [
- ":function",
- "//iree/base:flatbuffer_util",
- "//iree/base:status",
- "//iree/schemas",
- "@com_google_absl//absl/container:flat_hash_map",
- "@com_google_absl//absl/strings",
- "@com_google_absl//absl/types:span",
- ],
-)
-
-cc_library(
- name = "instance",
- srcs = ["instance.cc"],
- hdrs = ["instance.h"],
- deps = [
- "//iree/base:source_location",
- "//iree/base:status",
- "//iree/hal:device_manager",
- "@com_google_absl//absl/memory",
- ],
-)
-
-cc_library(
- name = "module",
- srcs = ["module.cc"],
- hdrs = ["module.h"],
- deps = [
- ":executable_table",
- ":function_table",
- "//iree/base:flatbuffer_util",
- "//iree/base:status",
- "//iree/schemas",
- "@com_google_absl//absl/memory",
- ],
-)
-
-cc_library(
- name = "module_printer",
- srcs = ["module_printer.cc"],
- hdrs = ["module_printer.h"],
- deps = [
- ":bytecode_printer",
- ":module",
- ":opcode_info",
- ":source_map",
- "//iree/base:bitfield",
- "//iree/base:status",
- ],
-)
-
-cc_library(
name = "opcode_info",
hdrs = ["opcode_info.h"],
deps = [
@@ -207,35 +106,15 @@
)
cc_library(
- name = "sequencer_context",
- srcs = ["sequencer_context.cc"],
- hdrs = ["sequencer_context.h"],
- deps = [
- ":context",
- ":fiber_state",
- ":function",
- ":instance",
- ":module",
- ":sequencer_dispatch",
- "//iree/base:flatbuffer_util",
- "//iree/base:status",
- "//iree/hal:buffer_view",
- "@com_google_absl//absl/strings",
- "@com_google_absl//absl/types:span",
- ],
-)
-
-cc_library(
name = "sequencer_dispatch",
srcs = ["sequencer_dispatch.cc"],
hdrs = ["sequencer_dispatch.h"],
deps = [
+ ":bytecode_module",
":bytecode_reader",
":bytecode_tables_sequencer",
":bytecode_util",
- ":function",
":opcode_info",
- ":stack",
"//iree/base:logging",
"//iree/base:memory",
"//iree/base:status",
@@ -244,6 +123,7 @@
"//iree/hal:device",
"//iree/hal:device_placement",
"//iree/hal:heap_buffer",
+ "//iree/rt",
"//iree/schemas/bytecode:sequencer_bytecode_v0",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:inlined_vector",
@@ -254,35 +134,32 @@
)
cc_library(
- name = "source_map",
- srcs = ["source_map.cc"],
- hdrs = ["source_map.h"],
+ name = "sequencer_module",
+ srcs = ["sequencer_module.cc"],
+ hdrs = ["sequencer_module.h"],
deps = [
- "//iree/base:flatbuffer_util",
+ ":bytecode_module",
+ ":bytecode_tables_sequencer",
+ ":sequencer_dispatch",
"//iree/base:status",
- "//iree/schemas",
- "@com_google_absl//absl/strings",
- "@com_google_absl//absl/types:optional",
+ "//iree/base:tracing",
+ "//iree/hal:buffer_view",
+ "//iree/rt",
+ "@com_google_absl//absl/memory",
],
)
cc_library(
- name = "stack",
- srcs = [
- "stack.cc",
- "stack_frame.cc",
- ],
- hdrs = [
- "stack.h",
- "stack_frame.h",
- ],
+ name = "source_map_resolver",
+ srcs = ["source_map_resolver.cc"],
+ hdrs = ["source_map_resolver.h"],
deps = [
- ":function",
- ":module",
+ "//iree/base:flatbuffer_util",
"//iree/base:status",
- "//iree/hal:buffer_view",
+ "//iree/rt",
+ "//iree/schemas",
"@com_google_absl//absl/strings",
- "@com_google_absl//absl/types:span",
+ "@com_google_absl//absl/types:optional",
],
)
diff --git a/iree/vm/CMakeLists.txt b/iree/vm/CMakeLists.txt
index 4a357f3..ab8c873 100644
--- a/iree/vm/CMakeLists.txt
+++ b/iree/vm/CMakeLists.txt
@@ -12,14 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
iree_cc_library(
NAME
- bytecode_printer
+ bytecode_disassembler
SRCS
- "bytecode_printer.cc"
+ "bytecode_disassembler.cc"
HDRS
- "bytecode_printer.h"
+ "bytecode_disassembler.h"
DEPS
absl::core_headers
absl::inlined_vector
@@ -28,18 +27,34 @@
iree::base::status
iree::schemas
iree::schemas::bytecode::bytecode_v0
+ iree::rt
iree::vm::bytecode_util
- iree::vm::executable_table
- iree::vm::function_table
- iree::vm::module
iree::vm::opcode_info
- iree::vm::source_map
+ iree::vm::source_map_resolver
iree::vm::type
PUBLIC
)
iree_cc_library(
NAME
+ bytecode_module
+ SRCS
+ "bytecode_module.cc"
+ HDRS
+ "bytecode_module.h"
+ DEPS
+ absl::memory
+ iree::base::flatbuffer_util
+ iree::base::status
+ iree::rt
+ iree::schemas
+ iree::vm::bytecode_disassembler
+ iree::vm::source_map_resolver
+ PUBLIC
+)
+
+iree_cc_library(
+ NAME
bytecode_reader
SRCS
"bytecode_reader.cc"
@@ -52,9 +67,9 @@
iree::base::status
iree::hal::buffer_view
iree::hal::heap_buffer
+ iree::rt
iree::schemas::bytecode::bytecode_v0
- iree::vm::function
- iree::vm::stack
+ iree::vm::bytecode_module
iree::vm::type
PUBLIC
)
@@ -115,137 +130,6 @@
iree_cc_library(
NAME
- context
- SRCS
- "context.cc"
- HDRS
- "context.h"
- DEPS
- absl::strings
- absl::span
- iree::base::flatbuffer_util
- iree::base::status
- iree::vm::function
- iree::vm::module
- PUBLIC
-)
-
-iree_cc_library(
- NAME
- executable_table
- SRCS
- "executable_table.cc"
- HDRS
- "executable_table.h"
- DEPS
- iree::base::flatbuffer_util
- iree::base::status
- iree::schemas
- PUBLIC
-)
-
-iree_cc_library(
- NAME
- fiber_state
- SRCS
- "fiber_state.cc"
- HDRS
- "fiber_state.h"
- DEPS
- absl::strings
- absl::span
- iree::base::status
- iree::vm::instance
- iree::vm::stack
- PUBLIC
-)
-
-iree_cc_library(
- NAME
- function
- SRCS
- "function.cc"
- HDRS
- "function.h"
- DEPS
- absl::strings
- absl::span
- iree::base::flatbuffer_util
- iree::base::status
- iree::hal::buffer_view
- iree::schemas
- PUBLIC
-)
-
-iree_cc_library(
- NAME
- function_table
- SRCS
- "function_table.cc"
- HDRS
- "function_table.h"
- DEPS
- absl::flat_hash_map
- absl::strings
- absl::span
- iree::base::flatbuffer_util
- iree::base::status
- iree::schemas
- iree::vm::function
- PUBLIC
-)
-
-iree_cc_library(
- NAME
- instance
- SRCS
- "instance.cc"
- HDRS
- "instance.h"
- DEPS
- absl::memory
- iree::base::source_location
- iree::base::status
- iree::hal::device_manager
- PUBLIC
-)
-
-iree_cc_library(
- NAME
- module
- SRCS
- "module.cc"
- HDRS
- "module.h"
- DEPS
- absl::memory
- iree::base::flatbuffer_util
- iree::base::status
- iree::schemas
- iree::vm::executable_table
- iree::vm::function_table
- PUBLIC
-)
-
-iree_cc_library(
- NAME
- module_printer
- SRCS
- "module_printer.cc"
- HDRS
- "module_printer.h"
- DEPS
- iree::base::bitfield
- iree::base::status
- iree::vm::bytecode_printer
- iree::vm::module
- iree::vm::opcode_info
- iree::vm::source_map
- PUBLIC
-)
-
-iree_cc_library(
- NAME
opcode_info
HDRS
"opcode_info.h"
@@ -259,28 +143,6 @@
iree_cc_library(
NAME
- sequencer_context
- SRCS
- "sequencer_context.cc"
- HDRS
- "sequencer_context.h"
- DEPS
- absl::strings
- absl::span
- iree::base::flatbuffer_util
- iree::base::status
- iree::hal::buffer_view
- iree::vm::context
- iree::vm::fiber_state
- iree::vm::function
- iree::vm::instance
- iree::vm::module
- iree::vm::sequencer_dispatch
- PUBLIC
-)
-
-iree_cc_library(
- NAME
sequencer_dispatch
SRCS
"sequencer_dispatch.cc"
@@ -300,53 +162,53 @@
iree::hal::device
iree::hal::device_placement
iree::hal::heap_buffer
+ iree::rt
iree::schemas::bytecode::sequencer_bytecode_v0
+ iree::vm::bytecode_module
iree::vm::bytecode_reader
iree::vm::bytecode_tables_sequencer
iree::vm::bytecode_util
- iree::vm::function
iree::vm::opcode_info
- iree::vm::stack
PUBLIC
)
iree_cc_library(
NAME
- source_map
+ sequencer_module
SRCS
- "source_map.cc"
+ "sequencer_module.cc"
HDRS
- "source_map.h"
+ "sequencer_module.h"
+ DEPS
+ absl::core_headers
+ iree::base::status
+ iree::hal::buffer_view
+ iree::rt
+ iree::schemas::bytecode::sequencer_bytecode_v0
+ iree::vm::bytecode_module
+ iree::vm::sequencer_dispatch
+ PUBLIC
+)
+
+iree_cc_library(
+ NAME
+ source_map_resolver
+ SRCS
+ "source_map_resolver.cc"
+ HDRS
+ "source_map_resolver.h"
DEPS
absl::strings
absl::optional
iree::base::flatbuffer_util
iree::base::status
+ iree::rt
iree::schemas
PUBLIC
)
iree_cc_library(
NAME
- stack
- SRCS
- "stack.cc"
- "stack_frame.cc"
- HDRS
- "stack.h"
- "stack_frame.h"
- DEPS
- absl::strings
- absl::span
- iree::base::status
- iree::hal::buffer_view
- iree::vm::function
- iree::vm::module
- PUBLIC
-)
-
-iree_cc_library(
- NAME
type
SRCS
"type.cc"
diff --git a/iree/vm/bytecode_printer.cc b/iree/vm/bytecode_disassembler.cc
similarity index 73%
rename from iree/vm/bytecode_printer.cc
rename to iree/vm/bytecode_disassembler.cc
index 136d257..4868792 100644
--- a/iree/vm/bytecode_printer.cc
+++ b/iree/vm/bytecode_disassembler.cc
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "iree/vm/bytecode_printer.h"
+#include "iree/vm/bytecode_disassembler.h"
#include <iomanip>
#include <sstream>
@@ -25,8 +25,8 @@
#include "iree/base/status.h"
#include "iree/schemas/bytecode/bytecode_v0.h"
#include "iree/schemas/source_map_def_generated.h"
+#include "iree/vm/bytecode_module.h"
#include "iree/vm/bytecode_util.h"
-#include "iree/vm/module.h"
#include "iree/vm/type.h"
namespace iree {
@@ -34,8 +34,10 @@
namespace {
+using ::iree::rt::SourceOffset;
+
template <typename T>
-StatusOr<T> ReadValue(absl::Span<const uint8_t> data, int* offset) {
+StatusOr<T> ReadValue(absl::Span<const uint8_t> data, SourceOffset* offset) {
if (*offset + sizeof(T) > data.size()) {
return OutOfRangeErrorBuilder(IREE_LOC) << "Bytecode data underrun";
}
@@ -44,16 +46,19 @@
return value;
}
-StatusOr<const Type> ReadType(absl::Span<const uint8_t> data, int* offset) {
+StatusOr<const Type> ReadType(absl::Span<const uint8_t> data,
+ SourceOffset* offset) {
ASSIGN_OR_RETURN(uint8_t type_index, ReadValue<uint8_t>(data, offset));
return Type::FromTypeIndex(type_index);
}
-StatusOr<uint8_t> ReadCount(absl::Span<const uint8_t> data, int* offset) {
+StatusOr<uint8_t> ReadCount(absl::Span<const uint8_t> data,
+ SourceOffset* offset) {
return ReadValue<uint8_t>(data, offset);
}
-StatusOr<uint16_t> ReadValueSlot(absl::Span<const uint8_t> data, int* offset) {
+StatusOr<uint16_t> ReadValueSlot(absl::Span<const uint8_t> data,
+ SourceOffset* offset) {
return ReadValue<uint16_t>(data, offset);
}
@@ -103,55 +108,30 @@
} // namespace
-// static
-std::string BytecodePrinter::ToString(
- OpcodeTable opcode_table, const FunctionTable& function_table,
- const ExecutableTable& executable_table,
- const SourceMapResolver& source_map_resolver,
- const BytecodeDef& bytecode_def) {
- BytecodePrinter printer(opcode_table, function_table, executable_table,
- source_map_resolver);
- auto result = printer.Print(bytecode_def);
- if (!result.ok()) {
- return result.status().ToString();
- }
- return result.ValueOrDie();
-}
+StatusOr<std::vector<rt::Instruction>>
+BytecodeDisassembler::DisassembleInstructions(const rt::Function& function,
+ SourceOffset offset,
+ int32_t instruction_count) const {
+ std::vector<rt::Instruction> instructions;
-StatusOr<std::string> BytecodePrinter::Print(
- const BytecodeDef& bytecode_def) const {
- std::ostringstream stream;
- RETURN_IF_ERROR(PrintToStream(bytecode_def, &stream)) << stream.str();
- return stream.str();
-}
-
-Status BytecodePrinter::PrintToStream(const BytecodeDef& bytecode_def,
- std::ostream* stream) const {
- if (!bytecode_def.contents()) {
- return OkStatus();
+ ASSIGN_OR_RETURN(
+ auto* function_def,
+ static_cast<const BytecodeModule*>(function.module())
+ ->GetFunctionDef(function.linkage(), function.ordinal()));
+ auto* bytecode_def = function_def->bytecode();
+ if (!bytecode_def) {
+ return UnavailableErrorBuilder(IREE_LOC) << "Function contains no body";
}
auto data = absl::MakeSpan(
- reinterpret_cast<const uint8_t*>(bytecode_def.contents()->data()),
- bytecode_def.contents()->size());
- return PrintToStream(data, stream);
-}
+ reinterpret_cast<const uint8_t*>(bytecode_def->contents()->data()),
+ bytecode_def->contents()->size());
-Status BytecodePrinter::PrintToStream(absl::Span<const uint8_t> data,
- std::ostream* stream) const {
// TODO(benvanik): scan and find all branch offsets to insert labels
- int offset = 0;
- absl::optional<SourceLocation> previous_location;
- while (offset < data.length()) {
- auto source_location = source_map_resolver_.ResolveBytecodeOffset(offset);
- if (source_location.has_value()) {
- if (previous_location != source_location) {
- *stream << std::setw(10) << "; " << source_location.value() << "\n";
- }
- previous_location = source_location;
- }
-
- *stream << std::setw(6) << offset << ": ";
+ while (offset < data.length() && instructions.size() < instruction_count) {
+ instructions.push_back({});
+ auto& instruction = instructions.back();
+ instruction.offset = offset;
uint8_t opcode = data[offset++];
const auto& opcode_info = GetOpcodeInfo(opcode_table_, opcode);
@@ -161,6 +141,8 @@
}
int payload_offset = offset;
+ std::ostringstream stream;
+
// Print out return values, if any.
int base_result_index = 0;
int printed_result_count = 0;
@@ -168,7 +150,7 @@
++i) {
if (opcode_info.operands[i] == OperandEncoding::kNone) break;
if (printed_result_count > 0) {
- *stream << ", ";
+ stream << ", ";
}
switch (opcode_info.operands[i]) {
default:
@@ -193,20 +175,20 @@
case OperandEncoding::kResultSlot: {
++printed_result_count;
ASSIGN_OR_RETURN(uint16_t slot_ordinal, ReadValueSlot(data, &offset));
- *stream << "%" << slot_ordinal;
+ stream << "%" << slot_ordinal;
break;
}
case OperandEncoding::kVariadicResultSlots: {
++printed_result_count;
- *stream << "[";
+ stream << "[";
ASSIGN_OR_RETURN(int count, ReadCount(data, &offset));
for (int j = 0; j < count; ++j) {
ASSIGN_OR_RETURN(uint16_t slot_ordinal,
ReadValueSlot(data, &offset));
- if (j > 0) *stream << ", ";
- *stream << "%" << slot_ordinal;
+ if (j > 0) stream << ", ";
+ stream << "%" << slot_ordinal;
}
- *stream << "]";
+ stream << "]";
break;
}
case OperandEncoding::kVariadicTransferSlots: {
@@ -268,11 +250,11 @@
}
}
if (printed_result_count > 0) {
- *stream << " = ";
+ stream << " = ";
}
offset = payload_offset;
- *stream << opcode_info.mnemonic;
+ stream << opcode_info.mnemonic;
// Print out operands.
int base_operand_index = 0;
@@ -283,9 +265,9 @@
if (opcode_info.operands[i] != OperandEncoding::kResultSlot &&
opcode_info.operands[i] != OperandEncoding::kVariadicResultSlots) {
if (i == base_operand_index) {
- *stream << " ";
+ stream << " ";
} else if (printed_operand_count > 0) {
- *stream << ", ";
+ stream << ", ";
}
}
switch (opcode_info.operands[i]) {
@@ -298,41 +280,41 @@
case OperandEncoding::kInputSlot: {
++printed_operand_count;
ASSIGN_OR_RETURN(uint16_t slot_ordinal, ReadValueSlot(data, &offset));
- *stream << "%" << slot_ordinal;
+ stream << "%" << slot_ordinal;
break;
}
case OperandEncoding::kVariadicInputSlots: {
++printed_operand_count;
- *stream << "[";
+ stream << "[";
ASSIGN_OR_RETURN(int count, ReadCount(data, &offset));
for (int j = 0; j < count; ++j) {
ASSIGN_OR_RETURN(uint16_t slot_ordinal,
ReadValueSlot(data, &offset));
- if (j > 0) *stream << ", ";
- *stream << "%" << slot_ordinal;
+ if (j > 0) stream << ", ";
+ stream << "%" << slot_ordinal;
}
- *stream << "]";
+ stream << "]";
break;
}
case OperandEncoding::kOutputSlot: {
++printed_operand_count;
ASSIGN_OR_RETURN(uint16_t slot_ordinal, ReadValueSlot(data, &offset));
- *stream << "&"
- << "%" << slot_ordinal;
+ stream << "&"
+ << "%" << slot_ordinal;
break;
}
case OperandEncoding::kVariadicOutputSlots: {
++printed_operand_count;
- *stream << "[";
+ stream << "[";
ASSIGN_OR_RETURN(int count, ReadCount(data, &offset));
for (int j = 0; j < count; ++j) {
ASSIGN_OR_RETURN(uint16_t slot_ordinal,
ReadValueSlot(data, &offset));
- if (j > 0) *stream << ", ";
- *stream << "&"
- << "%" << slot_ordinal;
+ if (j > 0) stream << ", ";
+ stream << "&"
+ << "%" << slot_ordinal;
}
- *stream << "]";
+ stream << "]";
break;
}
case OperandEncoding::kResultSlot: {
@@ -348,17 +330,17 @@
}
case OperandEncoding::kVariadicTransferSlots: {
++printed_operand_count;
- *stream << "[";
+ stream << "[";
ASSIGN_OR_RETURN(int count, ReadCount(data, &offset));
for (int j = 0; j < count; ++j) {
ASSIGN_OR_RETURN(uint16_t src_slot_ordinal,
ReadValueSlot(data, &offset));
ASSIGN_OR_RETURN(uint16_t dst_slot_ordinal,
ReadValueSlot(data, &offset));
- if (j > 0) *stream << ", ";
- *stream << "%" << src_slot_ordinal << "=>%" << dst_slot_ordinal;
+ if (j > 0) stream << ", ";
+ stream << "%" << src_slot_ordinal << "=>%" << dst_slot_ordinal;
}
- *stream << "]";
+ stream << "]";
break;
}
case OperandEncoding::kConstant: {
@@ -374,7 +356,7 @@
}
ASSIGN_OR_RETURN(auto encoding,
ReadValue<ConstantEncoding>(data, &offset));
- *stream << ConstantEncodingToString(encoding);
+ stream << ConstantEncodingToString(encoding);
int serialized_element_count = 1;
switch (encoding) {
case ConstantEncoding::kDense:
@@ -388,27 +370,29 @@
<< "Unimplemented constant encoding "
<< static_cast<int>(encoding);
}
- *stream << " buffer_view<";
+ stream << " buffer_view<";
if (!shape.empty()) {
- *stream << absl::StrJoin(shape, "x") << "x";
+ stream << absl::StrJoin(shape, "x") << "x";
}
- *stream << type << ">{";
+ stream << type << ">{";
size_t element_size = type.element_size();
auto bytes = data.subspan(
offset, std::min(serialized_element_count, 1024) * element_size);
- *stream << ConstantToString(type, bytes);
- if (serialized_element_count > 1024) *stream << "...";
+ stream << ConstantToString(type, bytes);
+ if (serialized_element_count > 1024) stream << "...";
offset += serialized_element_count * element_size;
- *stream << "}";
+ stream << "}";
break;
}
case OperandEncoding::kFunctionOrdinal: {
++printed_operand_count;
ASSIGN_OR_RETURN(auto function_ordinal,
ReadValue<uint32_t>(data, &offset));
- ASSIGN_OR_RETURN(auto function,
- function_table_.LookupFunction(function_ordinal));
- *stream << "@" << function_ordinal << " " << function.name();
+ ASSIGN_OR_RETURN(
+ auto target_function,
+ function.module()->LookupFunctionByOrdinal(
+ rt::Function::Linkage::kInternal, function_ordinal));
+ stream << "@" << function_ordinal << " " << target_function.name();
break;
}
case OperandEncoding::kDispatchOrdinal: {
@@ -418,88 +402,80 @@
ASSIGN_OR_RETURN(auto export_ordinal,
ReadValue<uint16_t>(data, &offset));
// TODO(benvanik): lookup in executable table.
- *stream << "@" << dispatch_ordinal << ":" << export_ordinal;
+ stream << "@" << dispatch_ordinal << ":" << export_ordinal;
break;
}
case OperandEncoding::kImportOrdinal: {
++printed_operand_count;
ASSIGN_OR_RETURN(auto import_ordinal,
ReadValue<uint32_t>(data, &offset));
- ASSIGN_OR_RETURN(auto* function,
- function_table_.LookupImport(import_ordinal));
- *stream << "@i" << import_ordinal << " ";
- switch (function->link_type()) {
- default:
- *stream << "??";
- break;
- case ImportFunction::LinkType::kNativeFunction:
- *stream << "<native>";
- break;
- case ImportFunction::LinkType::kModule:
- *stream << function->linked_function().module().name() << ":"
- << function->linked_function().name();
- break;
- }
+ ASSIGN_OR_RETURN(auto target_function,
+ function.module()->LookupFunctionByOrdinal(
+ rt::Function::Linkage::kImport, import_ordinal));
+ stream << "@i" << import_ordinal << " " << target_function.name();
break;
}
case OperandEncoding::kBlockOffset: {
++printed_operand_count;
ASSIGN_OR_RETURN(uint32_t block_offset,
ReadValue<uint32_t>(data, &offset));
- *stream << ":" << block_offset;
+ stream << ":" << block_offset;
break;
}
case OperandEncoding::kTypeIndex: {
++printed_operand_count;
ASSIGN_OR_RETURN(auto type, ReadType(data, &offset));
- *stream << type;
+ stream << type;
break;
}
case OperandEncoding::kIndex: {
++printed_operand_count;
ASSIGN_OR_RETURN(auto index, ReadValue<int32_t>(data, &offset));
- *stream << "#" << index;
+ stream << "#" << index;
break;
}
case OperandEncoding::kIndexList: {
++printed_operand_count;
- *stream << "{";
+ stream << "{";
ASSIGN_OR_RETURN(int count, ReadCount(data, &offset));
for (int j = 0; j < count; ++j) {
ASSIGN_OR_RETURN(auto dim, ReadValue<int32_t>(data, &offset));
- if (j > 0) *stream << ",";
- *stream << dim;
+ if (j > 0) stream << ",";
+ stream << dim;
}
- *stream << "}";
+ stream << "}";
break;
}
case OperandEncoding::kCmpIPredicate: {
++printed_operand_count;
ASSIGN_OR_RETURN(auto predicate_value,
ReadValue<uint8_t>(data, &offset));
- *stream << "<"
- << PredicateToString(
- static_cast<CmpIPredicate>(predicate_value))
- << ">";
+ stream << "<"
+ << PredicateToString(
+ static_cast<CmpIPredicate>(predicate_value))
+ << ">";
break;
}
case OperandEncoding::kCmpFPredicate: {
++printed_operand_count;
ASSIGN_OR_RETURN(auto predicate_value,
ReadValue<uint8_t>(data, &offset));
- *stream << "<"
- << PredicateToString(
- static_cast<CmpFPredicate>(predicate_value))
- << ">";
+ stream << "<"
+ << PredicateToString(
+ static_cast<CmpFPredicate>(predicate_value))
+ << ">";
break;
}
}
}
- *stream << "\n";
+ stream << "\n";
+
+ instruction.long_text = stream.str();
+ instruction.short_text = instruction.long_text;
}
- return OkStatus();
+ return instructions;
}
} // namespace vm
diff --git a/iree/vm/bytecode_disassembler.h b/iree/vm/bytecode_disassembler.h
new file mode 100644
index 0000000..633e290
--- /dev/null
+++ b/iree/vm/bytecode_disassembler.h
@@ -0,0 +1,46 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef IREE_VM_BYTECODE_DISASSEMBLER_H_
+#define IREE_VM_BYTECODE_DISASSEMBLER_H_
+
+#include <ostream>
+
+#include "iree/base/status.h"
+#include "iree/rt/disassembler.h"
+#include "iree/schemas/bytecode_def_generated.h"
+#include "iree/schemas/source_map_def_generated.h"
+#include "iree/vm/opcode_info.h"
+
+namespace iree {
+namespace vm {
+
+// Disassembles bytecode with a specific op set to text.
+class BytecodeDisassembler final : public rt::Disassembler {
+ public:
+ explicit BytecodeDisassembler(OpcodeTable opcode_table)
+ : opcode_table_(opcode_table) {}
+
+ StatusOr<std::vector<rt::Instruction>> DisassembleInstructions(
+ const rt::Function& function, rt::SourceOffset offset,
+ int32_t instruction_count) const override;
+
+ private:
+ OpcodeTable opcode_table_;
+};
+
+} // namespace vm
+} // namespace iree
+
+#endif // IREE_VM_BYTECODE_DISASSEMBLER_H_
diff --git a/iree/vm/bytecode_module.cc b/iree/vm/bytecode_module.cc
new file mode 100644
index 0000000..7812cb6
--- /dev/null
+++ b/iree/vm/bytecode_module.cc
@@ -0,0 +1,310 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "iree/vm/bytecode_module.h"
+
+#include "absl/memory/memory.h"
+#include "iree/base/status.h"
+#include "iree/base/tracing.h"
+#include "iree/hal/buffer_view.h"
+#include "iree/vm/bytecode_disassembler.h"
+
+namespace iree {
+namespace vm {
+
+namespace {
+
+using ::iree::hal::BufferView;
+using ::iree::rt::Function;
+using ::iree::rt::FunctionSignature;
+using ::iree::rt::Module;
+using ::iree::rt::ModuleSignature;
+
+Status ValidateElementSize(int element_bit_width,
+ const ElementTypeDef& expected_element_type) {
+ switch (expected_element_type.type_union_type()) {
+ case ElementTypeDefUnion::FloatTypeDef: {
+ auto expected_bit_width =
+ expected_element_type.type_union_as_FloatTypeDef()->width();
+ if (element_bit_width != expected_bit_width) {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "Has element bit width " << element_bit_width
+ << " but expected " << expected_bit_width;
+ }
+ return OkStatus();
+ }
+ case ElementTypeDefUnion::IntegerTypeDef: {
+ auto expected_bit_width =
+ expected_element_type.type_union_as_IntegerTypeDef()->width();
+ if (element_bit_width != expected_bit_width) {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "Has element bit width " << element_bit_width
+ << " but expected " << expected_bit_width;
+ }
+ return OkStatus();
+ }
+ case ElementTypeDefUnion::UnknownTypeDef:
+ case ElementTypeDefUnion::NONE: {
+ }
+ }
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "Defined type has unsupported element type "
+ << EnumNameElementTypeDefUnion(
+ expected_element_type.type_union_type());
+}
+
+Status ValidateTypeStructure(const FunctionTypeDef& type_def) {
+ // Ensure all fields are populated.
+ return OkStatus();
+}
+
+Status ValidateFunctionTableStructure(
+ const FunctionTableDef& function_table_def) {
+ if (!function_table_def.functions()) {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "Function table is missing the function listing";
+ }
+
+ // All functions must contain a valid type.
+ const auto& functions = *function_table_def.functions();
+ for (int i = 0; i < functions.size(); ++i) {
+ const auto* function = functions[i];
+ if (!function) {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "Function ordinal " << i << " is missing its contents";
+ }
+ if (!function->type()) {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "Function ordinal " << i << " is missing its type";
+ }
+ RETURN_IF_ERROR(ValidateTypeStructure(*function->type()));
+ }
+
+ // Imports must also have a name (that we can use to resolve it).
+ if (function_table_def.imports()) {
+ const auto& imports = *function_table_def.imports();
+ for (int i = 0; i < imports.size(); ++i) {
+ int function_index = imports[i];
+ if (!functions[function_index]->name()) {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "Import ordinal " << i << " is missing its contents";
+ }
+ }
+ }
+
+ // Exports must also have a name (that others will use to look it up).
+ if (function_table_def.exports()) {
+ const auto& exports = *function_table_def.exports();
+ for (int i = 0; i < exports.size(); ++i) {
+ int function_index = exports[i];
+ if (!functions[function_index]->name()) {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "Export ordinal " << i << " is missing its contents";
+ }
+ }
+ }
+
+ return OkStatus();
+}
+
+Status ValidateExecutableTableStructure(
+ const ExecutableTableDef& executable_table_def) {
+ if (!executable_table_def.multi_arch_executables()) {
+ // May have sequencer only fns. Fine to not have dispatchable executables.
+ return OkStatus();
+ }
+
+ // All fat executables need at least one device-specific executable.
+ const auto& multi_arch_executables =
+ *executable_table_def.multi_arch_executables();
+ for (int i = 0; i < multi_arch_executables.size(); ++i) {
+ const auto* multi_arch_executable = multi_arch_executables[i];
+ if (!multi_arch_executable || !multi_arch_executable->executables() ||
+ multi_arch_executable->executables()->size() == 0) {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "Multi-arch executable ordinal " << i
+ << " is missing its contents";
+ }
+ }
+
+ return OkStatus();
+}
+
+} // namespace
+
+// static
+Status BytecodeModule::ValidateStructure(const ModuleDef& module_def) {
+ IREE_TRACE_SCOPE0("BytecodeModule::ValidateStructure");
+
+ // Must have a function table.
+ if (module_def.function_table()) {
+ RETURN_IF_ERROR(
+ ValidateFunctionTableStructure(*module_def.function_table()));
+ } else {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "ModuleDef is missing a function table";
+ }
+
+ // Must have an executable table.
+ if (module_def.executable_table()) {
+ RETURN_IF_ERROR(
+ ValidateExecutableTableStructure(*module_def.executable_table()));
+ } else {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "ModuleDef is missing an executable table";
+ }
+
+ return OkStatus();
+}
+
+BytecodeModule::BytecodeModule(std::unique_ptr<ModuleFile> module_file,
+ OpcodeTable opcode_table)
+ : module_file_(std::move(module_file)),
+ module_def_(*module_file_->root()),
+ source_resolver_(SourceMapResolver::FromModule(module_def_)),
+ disassembler_(absl::make_unique<BytecodeDisassembler>(opcode_table)) {}
+
+BytecodeModule::~BytecodeModule() = default;
+
+const ModuleSignature BytecodeModule::signature() const {
+ return ModuleSignature(function_table_def().imports()->size(),
+ function_table_def().exports()->size(),
+ function_table_def().functions()->size(), 0);
+}
+
+std::string BytecodeModule::DebugStringShort() const {
+ return std::string(name());
+}
+
+StatusOr<int32_t> BytecodeModule::MapFunctionOrdinal(Function::Linkage linkage,
+ int32_t ordinal) const {
+ const auto& function_table = function_table_def();
+ switch (linkage) {
+ case Function::Linkage::kImport:
+ if (ordinal < 0 || ordinal >= function_table.imports()->size()) {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "Import ordinal " << ordinal
+ << " is outside the valid range [0, "
+ << function_table.imports()->size() << ")";
+ }
+ ordinal = function_table.imports()->Get(ordinal);
+ break;
+ case Function::Linkage::kExport:
+ if (ordinal < 0 || ordinal >= function_table.exports()->size()) {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "Export ordinal " << ordinal
+ << " is outside the valid range [0, "
+ << function_table.exports()->size() << ")";
+ }
+ ordinal = function_table.exports()->Get(ordinal);
+ break;
+ default:
+ break;
+ }
+ if (ordinal < 0 || ordinal >= function_table.functions()->size()) {
+ return OutOfRangeErrorBuilder(IREE_LOC)
+ << "Function ordinal " << ordinal
+ << " is outside the valid range [0, "
+ << function_table.functions()->size() << ")";
+ }
+ return ordinal;
+}
+
+StatusOr<const Function> BytecodeModule::LookupFunctionByOrdinal(
+ Function::Linkage linkage, int32_t ordinal) const {
+ ASSIGN_OR_RETURN(ordinal, MapFunctionOrdinal(linkage, ordinal));
+ return Function(this, Function::Linkage::kInternal, ordinal);
+}
+
+StatusOr<const Function> BytecodeModule::LookupFunctionByName(
+ Function::Linkage linkage, absl::string_view name) const {
+ const auto& functions = *function_table_def().functions();
+ for (int i = 0; i < functions.size(); ++i) {
+ const auto* function_def = functions.Get(i);
+ if (WrapString(function_def->name()) == name) {
+ return LookupFunctionByOrdinal(Function::Linkage::kInternal, i);
+ }
+ }
+ return NotFoundErrorBuilder(IREE_LOC)
+ << "Function '" << name
+ << "' not found in function table (or names have been stripped)";
+}
+
+StatusOr<absl::string_view> BytecodeModule::GetFunctionName(
+ Function::Linkage linkage, int32_t ordinal) const {
+ ASSIGN_OR_RETURN(ordinal, MapFunctionOrdinal(linkage, ordinal));
+ const auto* function_def = function_table_def().functions()->Get(ordinal);
+ return WrapString(function_def->name());
+}
+
+StatusOr<const FunctionSignature> BytecodeModule::GetFunctionSignature(
+ Function::Linkage linkage, int32_t ordinal) const {
+ ASSIGN_OR_RETURN(ordinal, MapFunctionOrdinal(linkage, ordinal));
+ const auto* function_def = function_table_def().functions()->Get(ordinal);
+ const auto* type_def = function_def->type();
+ return FunctionSignature(
+ type_def->inputs() ? type_def->inputs()->size() : 0,
+ type_def->results() ? type_def->results()->size() : 0);
+}
+
+StatusOr<const FunctionDef*> BytecodeModule::GetFunctionDef(
+ rt::Function::Linkage linkage, int32_t ordinal) const {
+ ASSIGN_OR_RETURN(ordinal, MapFunctionOrdinal(linkage, ordinal));
+ const auto& function_defs = *function_table_def().functions();
+ if (ordinal >= function_defs.size()) {
+ return OutOfRangeErrorBuilder(IREE_LOC)
+ << "Internal function ordinal " << ordinal
+ << " out of range of table (" << function_defs.size() << ")";
+ }
+ return function_defs.Get(ordinal);
+}
+
+StatusOr<const MultiArchExecutableDef*>
+BytecodeModule::LookupMultiArchExecutable(int executable_ordinal) const {
+ if (executable_ordinal < 0 ||
+ executable_ordinal >=
+ executable_table_def().multi_arch_executables()->size()) {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "Invalid multi-arch executable ordinal " << executable_ordinal;
+ }
+ return executable_table_def().multi_arch_executables()->Get(
+ executable_ordinal);
+}
+
+// static
+Status BytecodeModule::ValidateArgType(const BufferView& arg,
+ const MemRefTypeDef& expected_type) {
+ RETURN_IF_ERROR(
+ ValidateElementSize(arg.element_size * 8, *expected_type.element_type()));
+
+ auto expected_shape = expected_type.shape();
+ if (arg.shape.size() != expected_shape->size()) {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "Argument should have rank " << expected_shape->size()
+ << " but has rank " << arg.shape.size();
+ }
+ for (int i = 0; i < expected_shape->size(); ++i) {
+ auto dim_size = arg.shape[i];
+ auto expected_dim_size = expected_shape->Get(i);
+ if (dim_size != expected_dim_size) {
+ return InvalidArgumentErrorBuilder(IREE_LOC)
+ << "Argument dimension " << i << " should have size "
+ << expected_dim_size << " but has size " << dim_size;
+ }
+ }
+ return OkStatus();
+}
+
+} // namespace vm
+} // namespace iree
diff --git a/iree/vm/bytecode_module.h b/iree/vm/bytecode_module.h
new file mode 100644
index 0000000..36d034e
--- /dev/null
+++ b/iree/vm/bytecode_module.h
@@ -0,0 +1,103 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef IREE_VM_BYTECODE_MODULE_H_
+#define IREE_VM_BYTECODE_MODULE_H_
+
+#include <memory>
+
+#include "iree/base/flatbuffer_util.h"
+#include "iree/rt/function.h"
+#include "iree/rt/module.h"
+#include "iree/schemas/executable_table_def_generated.h"
+#include "iree/schemas/function_table_def_generated.h"
+#include "iree/schemas/module_def_generated.h"
+#include "iree/vm/opcode_info.h"
+#include "iree/vm/source_map_resolver.h"
+
+namespace iree {
+namespace vm {
+
+using ModuleFile = FlatBufferFile<ModuleDef>;
+
+// A loaded bytecode module backed by a FlatBuffer.
+class BytecodeModule : public rt::Module {
+ public:
+ static Status ValidateStructure(const ModuleDef& module_def);
+
+ ~BytecodeModule() override;
+
+ const ModuleDef& def() const { return module_def_; }
+ const FunctionTableDef& function_table_def() const {
+ return *module_def_.function_table();
+ }
+ const ExecutableTableDef& executable_table_def() const {
+ return *module_def_.executable_table();
+ }
+
+ absl::string_view name() const override {
+ return WrapString(module_def_.name());
+ }
+
+ const rt::ModuleSignature signature() const override;
+
+ rt::SourceResolver* source_resolver() const override {
+ return &source_resolver_;
+ }
+
+ rt::Disassembler* disassembler() const override {
+ return disassembler_.get();
+ }
+
+ std::string DebugStringShort() const override;
+
+ StatusOr<const rt::Function> LookupFunctionByOrdinal(
+ rt::Function::Linkage linkage, int32_t ordinal) const override;
+
+ StatusOr<const rt::Function> LookupFunctionByName(
+ rt::Function::Linkage linkage, absl::string_view name) const override;
+
+ StatusOr<absl::string_view> GetFunctionName(rt::Function::Linkage linkage,
+ int32_t ordinal) const override;
+
+ StatusOr<const rt::FunctionSignature> GetFunctionSignature(
+ rt::Function::Linkage linkage, int32_t ordinal) const override;
+
+ StatusOr<const FunctionDef*> GetFunctionDef(rt::Function::Linkage linkage,
+ int32_t ordinal) const;
+
+ StatusOr<const MultiArchExecutableDef*> LookupMultiArchExecutable(
+ int executable_ordinal) const;
+
+ protected:
+ BytecodeModule(std::unique_ptr<ModuleFile> module_file,
+ OpcodeTable opcode_table);
+
+ static Status ValidateArgType(const hal::BufferView& arg,
+ const MemRefTypeDef& expected_type);
+
+ private:
+ StatusOr<int32_t> MapFunctionOrdinal(rt::Function::Linkage linkage,
+ int32_t ordinal) const;
+
+ std::unique_ptr<ModuleFile> module_file_;
+ const ModuleDef& module_def_;
+ mutable SourceMapResolver source_resolver_;
+ mutable std::unique_ptr<rt::Disassembler> disassembler_;
+};
+
+} // namespace vm
+} // namespace iree
+
+#endif // IREE_VM_BYTECODE_MODULE_H_
diff --git a/iree/vm/bytecode_printer.h b/iree/vm/bytecode_printer.h
deleted file mode 100644
index 2f2cd5b..0000000
--- a/iree/vm/bytecode_printer.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef IREE_VM_BYTECODE_PRINTER_H_
-#define IREE_VM_BYTECODE_PRINTER_H_
-
-#include <ostream>
-
-#include "iree/base/status.h"
-#include "iree/schemas/bytecode_def_generated.h"
-#include "iree/schemas/source_map_def_generated.h"
-#include "iree/vm/executable_table.h"
-#include "iree/vm/function_table.h"
-#include "iree/vm/opcode_info.h"
-#include "iree/vm/source_map.h"
-
-namespace iree {
-namespace vm {
-
-// Prints bytecode in a text format to enable human-inspection.
-// Optionally can interleave original source location information if a SourceMap
-// is available.
-class BytecodePrinter {
- public:
- static std::string ToString(OpcodeTable opcode_table,
- const FunctionTable& function_table,
- const ExecutableTable& executable_table,
- const SourceMapResolver& source_map_resolver,
- const BytecodeDef& bytecode_def);
-
- explicit BytecodePrinter(OpcodeTable opcode_table,
- const FunctionTable& function_table,
- const ExecutableTable& executable_table,
- const SourceMapResolver& source_map_resolver)
- : opcode_table_(opcode_table),
- function_table_(function_table),
- executable_table_(executable_table),
- source_map_resolver_(source_map_resolver) {}
-
- StatusOr<std::string> Print(const BytecodeDef& bytecode_def) const;
-
- Status PrintToStream(const BytecodeDef& bytecode_def,
- std::ostream* stream) const;
- Status PrintToStream(absl::Span<const uint8_t> data,
- std::ostream* stream) const;
-
- private:
- OpcodeTable opcode_table_;
- const FunctionTable& function_table_;
- const ExecutableTable& executable_table_;
- const SourceMapResolver& source_map_resolver_;
-};
-
-} // namespace vm
-} // namespace iree
-
-#endif // IREE_VM_BYTECODE_PRINTER_H_
diff --git a/iree/vm/bytecode_reader.cc b/iree/vm/bytecode_reader.cc
index cd1e0bf..65e69f3 100644
--- a/iree/vm/bytecode_reader.cc
+++ b/iree/vm/bytecode_reader.cc
@@ -17,12 +17,16 @@
#include "iree/base/shape.h"
#include "iree/base/status.h"
#include "iree/hal/heap_buffer.h"
+#include "iree/vm/bytecode_module.h"
namespace iree {
namespace vm {
namespace {
+
using ::iree::hal::BufferView;
+using ::iree::rt::StackFrame;
+
} // namespace
StatusOr<const uint8_t*> BytecodeReader::AdvanceOffset() {
@@ -30,18 +34,10 @@
// TODO(benvanik): make a flag and/or remove.
DVLOG(1) << "dispatch(" << stack_frame_->function().name() << "@" << offset()
<< "): " << int(*bytecode_pc_);
- for (int i = 0; i < locals_.size(); ++i) {
- DVLOG(1) << "local[" << i << "] " << locals_[i].DebugStringShort();
+ for (int i = 0; i < registers_->buffer_views.size(); ++i) {
+ DVLOG(1) << "local[" << i << "] "
+ << registers_->buffer_views[i].DebugStringShort();
}
-
- if (breakpoint_table_) {
- auto it = breakpoint_table_->find(offset());
- if (it != breakpoint_table_->end()) {
- // Breakpoint hit!
- RETURN_IF_ERROR(it->second(*stack_));
- }
- }
-
return bytecode_pc_++;
}
@@ -128,29 +124,26 @@
// Setup state pointers for faster dereferencing.
const auto& function = new_stack_frame->function();
- const auto& bytecode = *function.def().bytecode();
+ ASSIGN_OR_RETURN(
+ const auto* function_def,
+ static_cast<const BytecodeModule*>(function.module())
+ ->GetFunctionDef(function.linkage(), function.ordinal()));
+ const auto& bytecode = *function_def->bytecode();
bytecode_base_ = bytecode.contents()->Data();
bytecode_limit_ = bytecode_base_ + bytecode.contents()->size();
bytecode_pc_ = bytecode_base_ + new_stack_frame->offset();
- locals_ = new_stack_frame->mutable_locals();
- // TODO(benvanik): reimplement breakpoints as bytecode rewriting.
- int function_ordinal = function.module()
- .function_table()
- .LookupFunctionOrdinal(function)
- .ValueOrDie();
- breakpoint_table_ =
- function.module().function_table().GetFunctionBreakpointTable(
- function_ordinal);
+ registers_ = new_stack_frame->mutable_registers();
return OkStatus();
}
Status BytecodeReader::CopyInputsAndSwitchStackFrame(
StackFrame* src_stack_frame, StackFrame* dst_stack_frame) {
- ASSIGN_OR_RETURN(int32_t src_count, ReadCount());
- for (int i = 0; i < src_count; ++i) {
+ ASSIGN_OR_RETURN(size_t src_count, ReadCount());
+ auto& dst_buffer_views = dst_stack_frame->mutable_registers()->buffer_views;
+ for (int i = 0; i < std::min(src_count, dst_buffer_views.size()); ++i) {
ASSIGN_OR_RETURN(auto* src_local,
- ReadLocal(src_stack_frame->mutable_locals()));
- *dst_stack_frame->mutable_local(i) = *src_local;
+ ReadLocal(src_stack_frame->mutable_registers()));
+ dst_buffer_views[i] = *src_local;
}
return SwitchStackFrame(dst_stack_frame);
}
@@ -162,7 +155,7 @@
absl::InlinedVector<BufferView*, 8> src_locals(src_count);
for (int i = 0; i < src_count; ++i) {
ASSIGN_OR_RETURN(src_locals[i],
- ReadLocal(src_stack_frame->mutable_locals()));
+ ReadLocal(src_stack_frame->mutable_registers()));
}
RETURN_IF_ERROR(SwitchStackFrame(dst_stack_frame));
ASSIGN_OR_RETURN(int32_t dst_count, ReadCount());
@@ -173,7 +166,7 @@
}
for (int i = 0; i < dst_count; ++i) {
ASSIGN_OR_RETURN(auto* dst_local,
- ReadLocal(dst_stack_frame->mutable_locals()));
+ ReadLocal(dst_stack_frame->mutable_registers()));
*dst_local = *src_locals[i];
}
return OkStatus();
@@ -183,9 +176,9 @@
ASSIGN_OR_RETURN(int32_t count, ReadCount());
for (int i = 0; i < count; ++i) {
ASSIGN_OR_RETURN(auto* src_local,
- ReadLocal(stack_frame_->mutable_locals()));
+ ReadLocal(stack_frame_->mutable_registers()));
ASSIGN_OR_RETURN(auto* dst_local,
- ReadLocal(stack_frame_->mutable_locals()));
+ ReadLocal(stack_frame_->mutable_registers()));
*dst_local = *src_local;
}
return OkStatus();
diff --git a/iree/vm/bytecode_reader.h b/iree/vm/bytecode_reader.h
index 6ba8227..f2b85fd 100644
--- a/iree/vm/bytecode_reader.h
+++ b/iree/vm/bytecode_reader.h
@@ -19,10 +19,10 @@
#include "absl/container/inlined_vector.h"
#include "iree/base/status.h"
#include "iree/hal/buffer_view.h"
+#include "iree/rt/context.h"
+#include "iree/rt/stack.h"
+#include "iree/rt/stack_frame.h"
#include "iree/schemas/bytecode/bytecode_v0.h"
-#include "iree/vm/function.h"
-#include "iree/vm/stack.h"
-#include "iree/vm/stack_frame.h"
#include "iree/vm/type.h"
namespace iree {
@@ -30,19 +30,19 @@
class BytecodeReader {
public:
- explicit BytecodeReader(Stack* stack) : stack_(stack) {}
+ explicit BytecodeReader(rt::Stack* stack) : stack_(stack) {}
int offset() const { return static_cast<int>(bytecode_pc_ - bytecode_base_); }
StatusOr<const uint8_t*> AdvanceOffset();
- Status SwitchStackFrame(StackFrame* new_stack_frame);
+ Status SwitchStackFrame(rt::StackFrame* new_stack_frame);
Status BranchToOffset(int32_t offset);
- Status CopyInputsAndSwitchStackFrame(StackFrame* src_stack_frame,
- StackFrame* dst_stack_frame);
- Status CopyResultsAndSwitchStackFrame(StackFrame* src_stack_frame,
- StackFrame* dst_stack_frame);
+ Status CopyInputsAndSwitchStackFrame(rt::StackFrame* src_stack_frame,
+ rt::StackFrame* dst_stack_frame);
+ Status CopyResultsAndSwitchStackFrame(rt::StackFrame* src_stack_frame,
+ rt::StackFrame* dst_stack_frame);
Status CopySlots();
StatusOr<hal::BufferView> ReadConstant();
@@ -56,32 +56,33 @@
return Type::FromTypeIndex(type_index);
}
- ABSL_ATTRIBUTE_ALWAYS_INLINE StatusOr<const Function> ReadFunction() {
+ ABSL_ATTRIBUTE_ALWAYS_INLINE StatusOr<const rt::Function> ReadFunction() {
ASSIGN_OR_RETURN(auto value, ReadValue<uint32_t>());
const auto& module = stack_frame_->module();
- return module.function_table().LookupFunction(value);
+ return module.LookupFunctionByOrdinal(rt::Function::Linkage::kInternal,
+ value);
}
- ABSL_ATTRIBUTE_ALWAYS_INLINE StatusOr<const ImportFunction*>
+ ABSL_ATTRIBUTE_ALWAYS_INLINE StatusOr<const rt::Function>
ReadImportFunction() {
ASSIGN_OR_RETURN(auto value, ReadValue<uint32_t>());
const auto& module = stack_frame_->module();
- return module.function_table().LookupImport(value);
+ return stack_->context()->ResolveImport(&module, value);
}
ABSL_ATTRIBUTE_ALWAYS_INLINE StatusOr<hal::BufferView*> ReadLocal(
- absl::Span<hal::BufferView> locals) {
+ rt::Registers* registers) {
ASSIGN_OR_RETURN(auto value, ReadValue<uint16_t>());
- if (value > locals.size()) {
+ if (value > registers->buffer_views.size()) {
return OutOfRangeErrorBuilder(IREE_LOC)
<< "Out of bounds local access " << value << " of "
- << locals.size();
+ << registers->buffer_views.size();
}
- return &locals[value];
+ return ®isters->buffer_views[value];
}
ABSL_ATTRIBUTE_ALWAYS_INLINE StatusOr<hal::BufferView*> ReadLocal() {
- return ReadLocal(locals_);
+ return ReadLocal(registers_);
}
Status SkipLocals(int count);
@@ -105,7 +106,7 @@
template <typename T, size_t N = 8>
ABSL_ATTRIBUTE_ALWAYS_INLINE StatusOr<absl::InlinedVector<T, N>>
ReadSlotElements() {
- ASSIGN_OR_RETURN(auto* local, ReadLocal(locals_));
+ ASSIGN_OR_RETURN(auto* local, ReadLocal(registers_));
absl::InlinedVector<T, N> result(local->shape.element_count());
if (sizeof(T) == local->element_size) {
// Fast(ish) path: requested element size matches the actual element size.
@@ -154,13 +155,12 @@
return value;
}
- Stack* stack_ = nullptr;
- StackFrame* stack_frame_ = nullptr;
+ rt::Stack* stack_ = nullptr;
+ rt::StackFrame* stack_frame_ = nullptr;
const uint8_t* bytecode_base_ = nullptr;
const uint8_t* bytecode_limit_ = nullptr;
const uint8_t* bytecode_pc_ = nullptr;
- absl::Span<hal::BufferView> locals_;
- FunctionTable::BreakpointTable* breakpoint_table_ = nullptr;
+ rt::Registers* registers_ = nullptr;
};
} // namespace vm
diff --git a/iree/vm/bytecode_validator.cc b/iree/vm/bytecode_validator.cc
index c8a3bbd..968b193 100644
--- a/iree/vm/bytecode_validator.cc
+++ b/iree/vm/bytecode_validator.cc
@@ -18,7 +18,7 @@
namespace vm {
// static
-Status BytecodeValidator::Validate(const Context& context, const Module& module,
+Status BytecodeValidator::Validate(const BytecodeModule& module,
const BytecodeDef& bytecode_def) {
// TODO(benvanik): validate bytecode.
return OkStatus();
diff --git a/iree/vm/bytecode_validator.h b/iree/vm/bytecode_validator.h
index bf435dc..429c754 100644
--- a/iree/vm/bytecode_validator.h
+++ b/iree/vm/bytecode_validator.h
@@ -17,8 +17,7 @@
#include "iree/base/status.h"
#include "iree/schemas/bytecode_def_generated.h"
-#include "iree/vm/context.h"
-#include "iree/vm/module.h"
+#include "iree/vm/bytecode_module.h"
namespace iree {
namespace vm {
@@ -28,7 +27,7 @@
// be resolved with matching signatures.
class BytecodeValidator {
public:
- static Status Validate(const Context& context, const Module& module,
+ static Status Validate(const BytecodeModule& module,
const BytecodeDef& bytecode_def);
};
diff --git a/iree/vm/context.cc b/iree/vm/context.cc
deleted file mode 100644
index bae330a..0000000
--- a/iree/vm/context.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "iree/vm/context.h"
-
-#include "iree/base/flatbuffer_util.h"
-#include "iree/base/status.h"
-
-namespace iree {
-namespace vm {
-
-namespace {
-
-int NextUniqueId() {
- static int next_id = 0;
- return ++next_id;
-}
-
-} // namespace
-
-Context::Context() : id_(NextUniqueId()) {}
-
-Context::~Context() = default;
-
-Status Context::RegisterNativeFunction(std::string name,
- NativeFunction native_function) {
- native_functions_.emplace_back(std::move(name), std::move(native_function));
- return OkStatus();
-}
-
-Status Context::RegisterModule(std::unique_ptr<Module> module) {
- // Attempt to link the module.
- RETURN_IF_ERROR(module->mutable_function_table()->ResolveImports(
- [&](const Module& importing_module,
- const FunctionDef& import_function_def) -> StatusOr<ImportFunction> {
- absl::string_view export_name = WrapString(import_function_def.name());
-
- // Try to find a native function (we prefer these).
- for (const auto& native_function : native_functions_) {
- if (native_function.first == export_name) {
- LOG(INFO) << "Resolved import '" << export_name
- << "' to native function";
- return ImportFunction(importing_module, import_function_def,
- native_function.second);
- }
- }
-
- // Try to find an export in an existing module.
- // We prefer the more recently registered modules.
- // NOTE: slow O(n*m) search through all modules * exports.
- for (auto it = modules_.rbegin(); it != modules_.rend(); ++it) {
- const auto& module = *it;
- auto export_or = module->function_table().LookupExport(export_name);
- if (export_or.ok()) {
- LOG(INFO) << "Resolved import '" << export_name << "' to module "
- << module->name();
- return ImportFunction(importing_module, import_function_def,
- export_or.ValueOrDie());
- }
- }
-
- return NotFoundErrorBuilder(IREE_LOC)
- << "Import '" << export_name << "' could not be resolved";
- }));
-
- modules_.push_back(std::move(module));
- return OkStatus();
-}
-
-StatusOr<const Module*> Context::LookupModule(
- absl::string_view module_name) const {
- return const_cast<Context*>(this)->LookupModule(module_name);
-}
-
-StatusOr<Module*> Context::LookupModule(absl::string_view module_name) {
- for (const auto& module : modules_) {
- if (module->name() == module_name) {
- return module.get();
- }
- }
- return NotFoundErrorBuilder(IREE_LOC)
- << "No module with the name '" << module_name
- << "' has been registered";
-}
-
-StatusOr<const Function> Context::LookupExport(
- absl::string_view export_name) const {
- for (const auto& module : modules_) {
- auto export_or = module->function_table().LookupExport(export_name);
- if (export_or.ok()) {
- return export_or.ValueOrDie();
- }
- }
- return NotFoundErrorBuilder(IREE_LOC)
- << "No export with the name '" << export_name
- << "' is present in the context";
-}
-
-} // namespace vm
-} // namespace iree
diff --git a/iree/vm/context.h b/iree/vm/context.h
deleted file mode 100644
index 6c3682b..0000000
--- a/iree/vm/context.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef IREE_VM_CONTEXT_H_
-#define IREE_VM_CONTEXT_H_
-
-#include <memory>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/span.h"
-#include "iree/base/status.h"
-#include "iree/vm/function.h"
-#include "iree/vm/module.h"
-
-namespace iree {
-namespace vm {
-
-// An isolated execution context.
-// Effectively a sandbox where modules can be loaded and run with restricted
-// visibility. Each context may have its own set of imports that modules can
-// access and its own resource constraints.
-//
-// The function namespace is shared within a context, meaning that an import of
-// function 'a' from a module will resolve to an export of function 'a' from
-// another. Functions internal to a module are not resolved through the
-// namespace and may share names (or have no names at all).
-//
-// Modules have imports resolved automatically when loaded by searching existing
-// modules. This means that load order is important to ensure overrides are
-// respected. For example, target-specific modules should be loaded prior to
-// generic modules that may import functions defined there and if a function is
-// not available in the target-specific modules the fallback provided by the
-// generic module will be used.
-//
-// TODO(benvanik): evaluate if worth making thread-safe (epochs/generational).
-// Contexts are thread-compatible; const methods may be called concurrently from
-// any thread (including Invoke), however no threads must be using a shared
-// Context while new native functions or modules are registered.
-class Context {
- public:
- Context();
- Context(const Context&) = delete;
- Context& operator=(const Context&) = delete;
- Context(Context&&) = default;
- Context& operator=(Context&&) = default;
- virtual ~Context();
-
- // A process-unique ID for the context.
- int id() const { return id_; }
-
- // TODO(benvanik): make immutable by moving to a static Create fn.
- virtual Status RegisterNativeFunction(std::string name,
- NativeFunction native_function);
-
- virtual Status RegisterModule(std::unique_ptr<Module> module);
-
- const std::vector<std::pair<std::string, NativeFunction>>& native_functions()
- const {
- return native_functions_;
- }
-
- const std::vector<std::unique_ptr<Module>>& modules() const {
- return modules_;
- }
-
- StatusOr<const Module*> LookupModule(absl::string_view module_name) const;
- StatusOr<Module*> LookupModule(absl::string_view module_name);
- StatusOr<const Function> LookupExport(absl::string_view export_name) const;
-
- private:
- int id_;
- std::vector<std::pair<std::string, NativeFunction>> native_functions_;
- std::vector<std::unique_ptr<Module>> modules_;
-};
-
-} // namespace vm
-} // namespace iree
-
-#endif // IREE_VM_CONTEXT_H_
diff --git a/iree/vm/executable_table.cc b/iree/vm/executable_table.cc
deleted file mode 100644
index 0752fa3..0000000
--- a/iree/vm/executable_table.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "iree/vm/executable_table.h"
-
-#include "iree/base/flatbuffer_util.h"
-#include "iree/base/status.h"
-
-namespace iree {
-namespace vm {
-
-// static
-Status ExecutableTable::ValidateStructure(
- const ExecutableTableDef& executable_table_def) {
- if (!executable_table_def.multi_arch_executables()) {
- // May have sequencer only fns. Fine to not have dispatchable executables.
- return OkStatus();
- }
-
- // All fat executables need at least one device-specific executable.
- const auto& multi_arch_executables =
- *executable_table_def.multi_arch_executables();
- for (int i = 0; i < multi_arch_executables.size(); ++i) {
- const auto* multi_arch_executable = multi_arch_executables[i];
- if (!multi_arch_executable || !multi_arch_executable->executables() ||
- multi_arch_executable->executables()->size() == 0) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Multi-arch executable ordinal " << i
- << " is missing its contents";
- }
- }
-
- return OkStatus();
-}
-
-ExecutableTable::ExecutableTable(const ExecutableTableDef& executable_table_def)
- : executable_table_def_(executable_table_def) {}
-
-ExecutableTable::~ExecutableTable() = default;
-
-StatusOr<const MultiArchExecutableDef*>
-ExecutableTable::LookupMultiArchExecutable(int executable_ordinal) const {
- if (executable_ordinal < 0 ||
- executable_ordinal >=
- executable_table_def_.multi_arch_executables()->size()) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Invalid multi-arch executable ordinal " << executable_ordinal;
- }
- return executable_table_def_.multi_arch_executables()->Get(
- executable_ordinal);
-}
-
-} // namespace vm
-} // namespace iree
diff --git a/iree/vm/executable_table.h b/iree/vm/executable_table.h
deleted file mode 100644
index e26918d..0000000
--- a/iree/vm/executable_table.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef IREE_VM_EXECUTABLE_TABLE_H_
-#define IREE_VM_EXECUTABLE_TABLE_H_
-
-#include "iree/base/status.h"
-#include "iree/schemas/executable_table_def_generated.h"
-
-namespace iree {
-namespace vm {
-
-// A table of executables present within a module.
-// Manages lookup and selection of executables based on target devices.
-//
-// Thread-safe.
-class ExecutableTable {
- public:
- static Status ValidateStructure(
- const ExecutableTableDef& executable_table_def);
-
- explicit ExecutableTable(const ExecutableTableDef& executable_table_def);
- ExecutableTable(const ExecutableTable&) = delete;
- ExecutableTable& operator=(const ExecutableTable&) = delete;
- ~ExecutableTable();
-
- const ExecutableTableDef& def() const { return executable_table_def_; }
-
- StatusOr<const MultiArchExecutableDef*> LookupMultiArchExecutable(
- int executable_ordinal) const;
-
- // TODO(benvanik): resolve executable by ID+format+features (ExecutableDef).
-
- // TODO(benvanik): insert/get HAL executables (thread-safe!).
-
- private:
- const ExecutableTableDef& executable_table_def_;
-};
-
-} // namespace vm
-} // namespace iree
-
-#endif // IREE_VM_EXECUTABLE_TABLE_H_
diff --git a/iree/vm/fiber_state.cc b/iree/vm/fiber_state.cc
deleted file mode 100644
index 90d9fd4..0000000
--- a/iree/vm/fiber_state.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "iree/vm/fiber_state.h"
-
-#include <iterator>
-
-#include "absl/strings/str_join.h"
-#include "iree/base/status.h"
-
-namespace iree {
-namespace vm {
-
-FiberState::FiberState(std::shared_ptr<Instance> instance)
- : instance_(std::move(instance)), id_(Instance::NextUniqueId()) {
-}
-
-FiberState::~FiberState() {
-}
-
-bool FiberState::is_suspended() {
- // TODO(benvanik): implement.
- return false;
-}
-
-Status FiberState::Suspend(SuspendCallback suspend_callback) {
- DVLOG(1) << "Suspending fiber " << id();
- return OkStatus();
-}
-
-Status FiberState::Resume() {
- DVLOG(1) << "Resuming fiber " << id();
- return OkStatus();
-}
-
-Status FiberState::Step(StepTarget step_target,
- SuspendCallback suspend_callback) {
- return UnimplementedErrorBuilder(IREE_LOC) << "Step not yet implemented";
-}
-
-namespace {
-struct StackFrameFormatter {
- void operator()(std::string* out, const StackFrame& stack_frame) const {
- out->append(absl::StrCat(stack_frame.module().name(), ":",
- stack_frame.function().name(), "@",
- stack_frame.offset()));
- }
-};
-} // namespace
-
-std::string FiberState::DebugString() const {
- auto frames = stack_.frames();
- return absl::StrJoin(frames.begin(), frames.end(), "\n",
- StackFrameFormatter());
-}
-
-} // namespace vm
-} // namespace iree
diff --git a/iree/vm/fiber_state.h b/iree/vm/fiber_state.h
deleted file mode 100644
index 5799831..0000000
--- a/iree/vm/fiber_state.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef IREE_VM_FIBER_STATE_H_
-#define IREE_VM_FIBER_STATE_H_
-
-#include <functional>
-
-#include "absl/types/span.h"
-#include "iree/base/status.h"
-#include "iree/vm/instance.h"
-#include "iree/vm/stack.h"
-
-namespace iree {
-namespace vm {
-
-// Fiber call stack and state machine model.
-// Fibers may not line up with host application threads and execution may move
-// across threads.
-//
-// Fibers are thread-compatible. Certain methods, such as Suspend and Resume
-// (and others that explicitly call them) may be called from other threads,
-// however members and other methods should be assumed safe to use only from
-// the owning thread or when is_suspended returns true.
-class FiberState {
- public:
- // Called when a fiber completes suspending (in response to a Suspend or Step
- // request). The |suspend_status| will indicate if the suspension was
- // successful.
- using SuspendCallback = std::function<void(Status suspend_status)>;
-
- struct StepTarget {
- // TODO(benvanik): step target info (matching RPC message).
- // module / function / offset
- // relative to current: once, out, return, etc
- };
-
- explicit FiberState(std::shared_ptr<Instance> instance);
- FiberState(const FiberState&) = delete;
- FiberState& operator=(const FiberState&) = delete;
- ~FiberState();
-
- // A process-unique ID for the fiber.
- int id() const { return id_; }
-
- const std::shared_ptr<Instance>& instance() const { return instance_; }
-
- // VM call stack.
- // NOTE: only valid while suspended.
- const Stack& stack() const { return stack_; }
- Stack* mutable_stack() { return &stack_; }
-
- // Returns true if the fiber is suspended.
- // This only returns true if the fiber has been requested to suspend with
- // Suspend and the runtime has acked the suspend. Once suspended (and until
- // resumed) fiber state will not change and may be observed from any thread.
- //
- // Safe to call from any thread.
- bool is_suspended();
-
- // Suspends the fiber at the next possible chance.
- //
- // Fibers have a suspension depth and each call to Suspend must be matched
- // with a call to Resume. Fibers will only resume excution when all prior
- // Suspend calls have their matching Resume called.
- //
- // Optionally callers may provide a |suspend_callback| that will be called
- // from a random thread when the fiber is suspended (or fails to suspend).
- //
- // Safe to call from any thread.
- Status Suspend(SuspendCallback suspend_callback = nullptr);
-
- // Resumes the fiber if it is suspended (or cancels a pending suspend).
- // This may wake threads if they are currently waiting on the fiber to
- // execute.
- //
- // Safe to call from any thread.
- Status Resume();
-
- // Steps fiber execution.
- // This will attempt to resume the fiber and will complete asynchronously.
- // Upon returning the fiber should be assumed resumed and callers must query
- // is_suspended to wait until the fiber suspends again. Optionally callers may
- // provide a |suspend_callback| that will be called from a random thread when
- // the fiber is suspended (or fails to suspend).
- //
- // Safe to call from any thread while the fiber is suspended.
- Status Step(StepTarget step_target,
- SuspendCallback suspend_callback = nullptr);
-
- std::string DebugString() const;
-
- private:
- std::shared_ptr<Instance> instance_;
- int id_;
- Stack stack_;
-};
-
-} // namespace vm
-} // namespace iree
-
-#endif // IREE_VM_FIBER_STATE_H_
diff --git a/iree/vm/function.cc b/iree/vm/function.cc
deleted file mode 100644
index 1e92c28..0000000
--- a/iree/vm/function.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "iree/vm/function.h"
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_join.h"
-#include "iree/base/flatbuffer_util.h"
-#include "iree/schemas/type_def_generated.h"
-
-namespace iree {
-namespace vm {
-
-namespace {
-
-struct TypeFormatter {
- void operator()(std::string* out, const TypeDef* type_def) const {
- switch (type_def->type_union_type()) {
- case TypeDefUnion::MemRefTypeDef:
- (*this)(out, type_def->type_union_as_MemRefTypeDef());
- return;
- case TypeDefUnion::DeviceTypeDef:
- out->append("device");
- return;
- case TypeDefUnion::CommandBufferTypeDef:
- out->append("command_buffer");
- return;
- case TypeDefUnion::EventTypeDef:
- out->append("event");
- return;
- case TypeDefUnion::SemaphoreTypeDef:
- out->append("semaphore");
- return;
- case TypeDefUnion::FenceTypeDef:
- out->append("fence");
- return;
- default:
- out->append("<invalid>");
- return;
- }
- }
-
- void operator()(std::string* out,
- const MemRefTypeDef* mem_ref_type_def) const {
- out->append("memref<");
- if (mem_ref_type_def->shape()) {
- for (int dim : *mem_ref_type_def->shape()) {
- out->append(std::to_string(dim));
- out->append("x");
- }
- } else {
- out->append("?x");
- }
- (*this)(out, mem_ref_type_def->element_type());
- out->append(">");
- }
-
- void operator()(std::string* out, const ElementTypeDef* type_def) const {
- switch (type_def->type_union_type()) {
- case ElementTypeDefUnion::FloatTypeDef: {
- const auto* float_type_def = type_def->type_union_as_FloatTypeDef();
- out->append("f");
- out->append(std::to_string(float_type_def->width()));
- break;
- }
- case ElementTypeDefUnion::IntegerTypeDef: {
- const auto* int_type_def = type_def->type_union_as_IntegerTypeDef();
- out->append("i");
- out->append(std::to_string(int_type_def->width()));
- break;
- }
- case ElementTypeDefUnion::UnknownTypeDef: {
- const auto* unknown_type_def = type_def->type_union_as_UnknownTypeDef();
- out->append("unknown<");
- auto dialect_str = WrapString(unknown_type_def->dialect());
- out->append(dialect_str.data(), dialect_str.size());
- auto type_data_str = WrapString(unknown_type_def->type_data());
- out->append(type_data_str.data(), type_data_str.size());
- out->append(">");
- break;
- }
- default:
- out->append("<invalid>");
- return;
- }
- }
-};
-
-} // namespace
-
-std::string Function::DebugStringShort() const {
- return absl::StrCat(
- name(), "(",
- type_def().inputs()
- ? absl::StrJoin(*type_def().inputs(), ", ", TypeFormatter())
- : "",
- ") -> (",
- type_def().results()
- ? absl::StrJoin(*type_def().results(), ", ", TypeFormatter())
- : "",
- ")");
-}
-
-std::string ImportFunction::DebugStringShort() const {
- // TODO(benvanik): import function strings.
- return "(IMPORT)";
-}
-
-} // namespace vm
-} // namespace iree
diff --git a/iree/vm/function.h b/iree/vm/function.h
deleted file mode 100644
index 7f590a0..0000000
--- a/iree/vm/function.h
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef IREE_VM_FUNCTION_H_
-#define IREE_VM_FUNCTION_H_
-
-#include <functional>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/span.h"
-#include "iree/base/flatbuffer_util.h"
-#include "iree/base/status.h"
-#include "iree/hal/buffer_view.h"
-#include "iree/schemas/function_def_generated.h"
-#include "iree/schemas/type_def_generated.h"
-
-namespace iree {
-namespace vm {
-
-class Stack;
-class Module;
-
-// TODO(benvanik): reorganize this; I don't like it. maybe ImportFunction
-// shouldn't derive from Function at all?
-
-// A function defined within a Module.
-// Imported functions may be of the ImportFunction type and contain additional
-// runtime linkage information.
-class Function {
- public:
- Function() = default;
- Function(const Module& module, const FunctionDef& function_def)
- : module_(&module), function_def_(&function_def) {}
-
- absl::string_view name() const { return WrapString(function_def_->name()); }
-
- const Module& module() const { return *module_; }
- const FunctionDef& def() const { return *function_def_; }
- const FunctionTypeDef& type_def() const { return *def().type(); }
-
- int input_count() const {
- return type_def().inputs() ? type_def().inputs()->size() : 0;
- }
- int result_count() const {
- return type_def().results() ? type_def().results()->size() : 0;
- }
-
- std::string DebugStringShort() const;
-
- private:
- const Module* module_ = nullptr;
- const FunctionDef* function_def_ = nullptr;
-};
-
-inline std::ostream& operator<<(std::ostream& stream,
- const Function& function) {
- stream << function.DebugStringShort();
- return stream;
-}
-
-// TODO(benvanik): make an interface as well.
-// TODO(benvanik): pass through additional attributes.
-using NativeFunction =
- std::function<Status(Stack* stack, absl::Span<hal::BufferView> args,
- absl::Span<hal::BufferView> results)>;
-
-// A function imported into a Module from either a native function or other
-// module.
-class ImportFunction : public Function {
- public:
- enum class LinkType {
- kNativeFunction,
- kModule,
- };
-
- ImportFunction() = default;
- ImportFunction(const Module& module, const FunctionDef& function_def,
- NativeFunction native_function)
- : Function(module, function_def),
- link_type_(LinkType::kNativeFunction),
- native_function_(std::move(native_function)) {}
- ImportFunction(const Module& module, const FunctionDef& function_def,
- Function linked_function)
- : Function(module, function_def),
- link_type_(LinkType::kModule),
- linked_function_(std::move(linked_function)) {}
- ImportFunction(const ImportFunction&) = delete;
- ImportFunction& operator=(const ImportFunction&) = delete;
- ImportFunction(ImportFunction&&) = default;
- ImportFunction& operator=(ImportFunction&&) = default;
-
- LinkType link_type() const { return link_type_; }
- const NativeFunction& native_function() const { return native_function_; }
- const Function& linked_function() const { return linked_function_; }
-
- std::string DebugStringShort() const;
-
- private:
- LinkType link_type_;
- NativeFunction native_function_;
- Function linked_function_;
-};
-
-inline std::ostream& operator<<(std::ostream& stream,
- const ImportFunction& function) {
- stream << function.DebugStringShort();
- return stream;
-}
-
-} // namespace vm
-} // namespace iree
-
-#endif // IREE_VM_FUNCTION_H_
diff --git a/iree/vm/function_table.cc b/iree/vm/function_table.cc
deleted file mode 100644
index 1e629bd..0000000
--- a/iree/vm/function_table.cc
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "iree/vm/function_table.h"
-
-#include "absl/container/flat_hash_map.h"
-#include "iree/base/flatbuffer_util.h"
-#include "iree/base/status.h"
-
-namespace iree {
-namespace vm {
-
-namespace {
-
-Status ValidateType(const FunctionTypeDef& type_def) {
- // Ensure all fields are populated.
- return OkStatus();
-}
-
-} // namespace
-
-// static
-Status FunctionTable::ValidateStructure(
- const FunctionTableDef& function_table_def) {
- if (!function_table_def.functions()) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Function table is missing the function listing";
- }
-
- // All functions must contain a valid type.
- const auto& functions = *function_table_def.functions();
- for (int i = 0; i < functions.size(); ++i) {
- const auto* function = functions[i];
- if (!function) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Function ordinal " << i << " is missing its contents";
- }
- if (!function->type()) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Function ordinal " << i << " is missing its type";
- }
- RETURN_IF_ERROR(ValidateType(*function->type()));
- }
-
- // Imports must also have a name (that we can use to resolve it).
- if (function_table_def.imports()) {
- const auto& imports = *function_table_def.imports();
- for (int i = 0; i < imports.size(); ++i) {
- int function_index = imports[i];
- if (!functions[function_index]->name()) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Import ordinal " << i << " is missing its contents";
- }
- }
- }
-
- // Exports must also have a name (that others will use to look it up).
- if (function_table_def.exports()) {
- const auto& exports = *function_table_def.exports();
- for (int i = 0; i < exports.size(); ++i) {
- int function_index = exports[i];
- if (!functions[function_index]->name()) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Export ordinal " << i << " is missing its contents";
- }
- }
- }
-
- return OkStatus();
-}
-
-FunctionTable::FunctionTable(const Module& module,
- const FunctionTableDef& function_table_def)
- : module_(module), function_table_def_(function_table_def) {}
-
-FunctionTable::~FunctionTable() = default;
-
-Status FunctionTable::ResolveImports(ImportResolver import_resolver) {
- if (!function_table_def_.imports()) {
- // No imports to resolve.
- return OkStatus();
- }
-
- const auto& imports = *function_table_def_.imports();
- const auto& functions = *function_table_def_.functions();
- for (int i = 0; i < imports.size(); ++i) {
- const auto* function_def = functions[imports[i]];
- ASSIGN_OR_RETURN(auto import_function,
- import_resolver(module_, *function_def));
- import_functions_.push_back(std::move(import_function));
- }
-
- return OkStatus();
-}
-
-StatusOr<int> FunctionTable::LookupImportOrdinal(
- absl::string_view import_name) const {
- if (function_table_def_.imports()) {
- const auto& imports = *function_table_def_.imports();
- const auto& functions = *function_table_def_.functions();
- for (int i = 0; i < imports.size(); ++i) {
- if (WrapString(functions[imports[i]]->name()) == import_name) {
- return i;
- }
- }
- }
- return NotFoundErrorBuilder(IREE_LOC)
- << "Import with the name '" << import_name << "' not found in module";
-}
-
-StatusOr<const ImportFunction*> FunctionTable::LookupImport(
- absl::string_view import_name) const {
- ASSIGN_OR_RETURN(int import_ordinal, LookupImportOrdinal(import_name));
- return LookupImport(import_ordinal);
-}
-
-StatusOr<const ImportFunction*> FunctionTable::LookupImport(
- int import_ordinal) const {
- if (import_ordinal < 0 || import_ordinal >= import_functions_.size()) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Import ordinal " << import_ordinal
- << " is outside the valid range [0, " << import_functions_.size()
- << ")";
- }
- return {&import_functions_[import_ordinal]};
-}
-
-StatusOr<int> FunctionTable::LookupExportFunctionOrdinal(
- absl::string_view export_name) const {
- // NOTE: this is a linear scan of the export table, but since export count
- // is usually small and the only time this lookup should happen is on module
- // load it's (probably) fine.
- if (function_table_def_.exports()) {
- const auto& exports = *function_table_def_.exports();
- for (int i = 0; i < exports.size(); ++i) {
- int export_ordinal = exports.Get(i);
- const auto& function_def =
- *function_table_def_.functions()->Get(export_ordinal);
- if (WrapString(function_def.name()) == export_name) {
- return export_ordinal;
- }
- }
- }
- return NotFoundErrorBuilder(IREE_LOC)
- << "Export with the name '" << export_name << "' not found in module";
-}
-
-StatusOr<const Function> FunctionTable::LookupExport(
- absl::string_view export_name) const {
- ASSIGN_OR_RETURN(int export_ordinal,
- LookupExportFunctionOrdinal(export_name));
- return LookupFunction(export_ordinal);
-}
-
-StatusOr<const Function> FunctionTable::LookupExport(int export_ordinal) const {
- if (!function_table_def_.exports() || export_ordinal < 0 ||
- export_ordinal >= function_table_def_.exports()->size()) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Export ordinal " << export_ordinal
- << " is outside the valid range [0, "
- << function_table_def_.exports()->size() << ")";
- }
- const auto& exports = *function_table_def_.exports();
- int function_ordinal = exports.Get(export_ordinal);
- return LookupFunction(function_ordinal);
-}
-
-StatusOr<const Function> FunctionTable::LookupFunction(int ordinal) const {
- if (ordinal < 0 || ordinal >= function_table_def_.functions()->size()) {
- return OutOfRangeErrorBuilder(IREE_LOC)
- << "Function ordinal " << ordinal
- << " is outside the valid range [0, "
- << function_table_def_.functions()->size() << ")";
- }
- const auto* function_def = function_table_def_.functions()->Get(ordinal);
- return Function(module_, *function_def);
-}
-
-StatusOr<int> FunctionTable::LookupFunctionOrdinal(
- const Function& function) const {
- const auto& functions = *function_table_def_.functions();
- for (int i = 0; i < functions.size(); ++i) {
- if (&function.def() == functions.Get(i)) {
- return i;
- }
- }
- return NotFoundErrorBuilder(IREE_LOC) << "Function not a member of module";
-}
-
-StatusOr<int> FunctionTable::LookupFunctionOrdinalByName(
- absl::string_view name) const {
- for (int i = 0; i < function_table_def_.functions()->size(); ++i) {
- const auto* function_def = function_table_def_.functions()->Get(i);
- if (WrapString(function_def->name()) == name) {
- return i;
- }
- }
- return NotFoundErrorBuilder(IREE_LOC)
- << "Function '" << name
- << "' not found in function table (or names have been stripped)";
-}
-
-Status FunctionTable::RegisterBreakpoint(int function_ordinal, int offset,
- BreakpointCallback callback) {
- if (breakpoint_tables_.empty()) {
- breakpoint_tables_.resize(function_table_def_.functions()->size());
- }
- if (function_ordinal < 0 || function_ordinal > breakpoint_tables_.size()) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Function ordinal " << function_ordinal << " out of bounds";
- }
- if (!breakpoint_tables_[function_ordinal]) {
- breakpoint_tables_[function_ordinal] =
- absl::make_unique<absl::flat_hash_map<int, BreakpointCallback>>();
- }
- auto& function_table = *breakpoint_tables_[function_ordinal];
- function_table[offset] = std::move(callback);
- return OkStatus();
-}
-
-Status FunctionTable::UnregisterBreakpoint(int function_ordinal, int offset) {
- if (function_ordinal < 0 || function_ordinal > breakpoint_tables_.size()) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Function ordinal " << function_ordinal << " out of bounds";
- }
- auto* function_table = breakpoint_tables_[function_ordinal].get();
- if (function_table) {
- auto it = function_table->find(offset);
- if (it != function_table->end()) {
- function_table->erase(it);
- }
- }
- return OkStatus();
-}
-
-Status FunctionTable::UnregisterAllBreakpoints() {
- breakpoint_tables_.clear();
- return OkStatus();
-}
-
-FunctionTable::BreakpointTable* FunctionTable::GetFunctionBreakpointTable(
- int function_ordinal) const {
- if (function_ordinal < 0 || function_ordinal >= breakpoint_tables_.size()) {
- return nullptr;
- }
- return breakpoint_tables_[function_ordinal].get();
-}
-
-} // namespace vm
-} // namespace iree
diff --git a/iree/vm/function_table.h b/iree/vm/function_table.h
deleted file mode 100644
index e7a1034..0000000
--- a/iree/vm/function_table.h
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef IREE_VM_FUNCTION_TABLE_H_
-#define IREE_VM_FUNCTION_TABLE_H_
-
-#include <functional>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/span.h"
-#include "iree/base/status.h"
-#include "iree/schemas/function_table_def_generated.h"
-#include "iree/vm/function.h"
-
-namespace iree {
-namespace vm {
-
-class Stack;
-class Module;
-
-// A table of functions present within a module.
-// Manages the import table, local function resolution, and breakpoints.
-//
-// Function tables are normally thread-compatible. Debugging-specific methods
-// like RegisterBreakpoint must only be called when the debugger has suspended
-// all fibers that could be executing functions from the table.
-class FunctionTable {
- public:
- static Status ValidateStructure(const FunctionTableDef& function_table_def);
-
- FunctionTable(const Module& module,
- const FunctionTableDef& function_table_def);
- FunctionTable(const FunctionTable&) = delete;
- FunctionTable& operator=(const FunctionTable&) = delete;
- ~FunctionTable();
-
- const FunctionTableDef& def() const { return function_table_def_; }
-
- using ImportResolver = std::function<StatusOr<ImportFunction>(
- const Module& importing_module, const FunctionDef& import_function_def)>;
- Status ResolveImports(ImportResolver import_resolver);
-
- StatusOr<const ImportFunction*> LookupImport(
- absl::string_view import_name) const;
- StatusOr<const ImportFunction*> LookupImport(int import_ordinal) const;
-
- StatusOr<const Function> LookupExport(absl::string_view export_name) const;
- StatusOr<const Function> LookupExport(int export_ordinal) const;
-
- StatusOr<const Function> LookupFunction(int ordinal) const;
-
- StatusOr<int> LookupFunctionOrdinal(const Function& function) const;
- StatusOr<int> LookupFunctionOrdinalByName(absl::string_view name) const;
-
- // Handles breakpoints that are encountered during execution.
- // The current function and offset within the function will be provided.
- // The fiber is set as suspended prior to issuing the callback and resumed
- // if the callback returns ok.
- //
- // Implementations can use the return status to indicate intended program
- // flow:
- // - return ok to resume the fiber and continue execution
- // - return abort to terminate the fiber
- // - return an error to propagate via normal error handling logic
- using BreakpointCallback = std::function<Status(const Stack& stack)>;
-
- // Registers a breakpoint for an operation offset within a function.
- // The provided callback will be issued when the breakpoint is hit. If a
- // breakpoint already exists for the given offset it will be replaced.
- //
- // The global debug lock must be held and all fibers must be suspended.
- Status RegisterBreakpoint(int function_ordinal, int offset,
- BreakpointCallback callback);
-
- // Unregisters a breakpoint, if one has been registered.
- //
- // The global debug lock must be held and all fibers must be suspended.
- Status UnregisterBreakpoint(int function_ordinal, int offset);
-
- // Unregisters all breakpoints in the function table.
- //
- // The global debug lock must be held and all fibers must be suspended.
- Status UnregisterAllBreakpoints();
-
- using BreakpointTable = absl::flat_hash_map<int, BreakpointCallback>;
-
- // Returns the breakpoint table mapping offset to breakpoint callback.
- // Returns nullptr if the given function does not have a breakpoint table.
- //
- // This table is not synchronized and while the debug lock is held it must not
- // be accessed by any other threads. Reading is otherwise safe.
- BreakpointTable* GetFunctionBreakpointTable(int function_ordinal) const;
-
- private:
- StatusOr<int> LookupImportOrdinal(absl::string_view import_name) const;
- StatusOr<int> LookupExportFunctionOrdinal(
- absl::string_view export_name) const;
-
- const Module& module_;
- const FunctionTableDef& function_table_def_;
- std::vector<ImportFunction> import_functions_;
-
- // One slot per function in the function table. The hash map contains the
- // breakpoints for that particular function mapped by offset within the
- // function.
- std::vector<std::unique_ptr<BreakpointTable>> breakpoint_tables_;
-};
-
-} // namespace vm
-} // namespace iree
-
-#endif // IREE_VM_FUNCTION_TABLE_H_
diff --git a/iree/vm/instance.cc b/iree/vm/instance.cc
deleted file mode 100644
index 7668d73..0000000
--- a/iree/vm/instance.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "iree/vm/instance.h"
-
-#include "absl/memory/memory.h"
-#include "iree/base/source_location.h"
-#include "iree/base/status.h"
-
-namespace iree {
-namespace vm {
-
-// static
-int Instance::NextUniqueId() {
- static int next_id = 0;
- return ++next_id;
-}
-
-Instance::Instance()
- : device_manager_(absl::make_unique<hal::DeviceManager>()) {}
-
-Instance::~Instance() = default;
-
-} // namespace vm
-} // namespace iree
diff --git a/iree/vm/instance.h b/iree/vm/instance.h
deleted file mode 100644
index 68c4524..0000000
--- a/iree/vm/instance.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef IREE_VM_INSTANCE_H_
-#define IREE_VM_INSTANCE_H_
-
-#include <memory>
-
-#include "iree/hal/device_manager.h"
-
-namespace iree {
-namespace vm {
-
-// Shared runtime instance responsible for routing Context events, enumerating
-// and creating hardware device interfaces, and managing thread pools.
-//
-// A single runtime instance can service multiple contexts and hosting
-// applications should try to reuse a runtime as much as possible. This ensures
-// that resource allocation across contexts is handled and extraneous device
-// interaction is avoided.
-class Instance {
- public:
- // Allocates a global unique ID.
- static int NextUniqueId();
-
- Instance();
- ~Instance();
- Instance(const Instance&) = delete;
- Instance& operator=(const Instance&) = delete;
-
- hal::DeviceManager* device_manager() const { return device_manager_.get(); }
-
- private:
- std::unique_ptr<hal::DeviceManager> device_manager_;
-};
-
-} // namespace vm
-} // namespace iree
-
-#endif // IREE_VM_INSTANCE_H_
diff --git a/iree/vm/module.cc b/iree/vm/module.cc
deleted file mode 100644
index 4aaa634..0000000
--- a/iree/vm/module.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "iree/vm/module.h"
-
-#include "absl/memory/memory.h"
-#include "iree/base/status.h"
-
-namespace iree {
-namespace vm {
-
-// static
-Status Module::ValidateStructure(const ModuleDef& module_def) {
- // Must have a function table.
- if (module_def.function_table()) {
- RETURN_IF_ERROR(
- FunctionTable::ValidateStructure(*module_def.function_table()));
- } else {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "ModuleDef is missing a function table";
- }
-
- // May optionally have an executable table.
- if (module_def.executable_table()) {
- RETURN_IF_ERROR(
- ExecutableTable::ValidateStructure(*module_def.executable_table()));
- }
-
- return OkStatus();
-}
-
-// static
-StatusOr<std::unique_ptr<Module>> Module::FromDef(const ModuleDef& module_def) {
- ASSIGN_OR_RETURN(auto module_file, ModuleFile::Create(&module_def, []() {}));
- return FromFile(std::move(module_file));
-}
-
-// static
-StatusOr<std::unique_ptr<Module>> Module::FromFile(
- std::unique_ptr<ModuleFile> module_file) {
- if (module_file->root() == nullptr) {
- return InvalidArgumentErrorBuilder(IREE_LOC) << "No root ModuleDef present";
- }
- const auto& module_def = *module_file->root();
-
- // Validates the structure of the module (but not bytecode).
- // This ensures we don't have flatbuffer vectors will null entries, etc.
- RETURN_IF_ERROR(Module::ValidateStructure(module_def));
-
- auto module = absl::WrapUnique(new Module(std::move(module_file)));
-
- // TODO(benvanik): validate internals here? or make explicit?
-
- return {std::move(module)};
-}
-
-Module::Module(std::unique_ptr<ModuleFile> module_file)
- : module_file_(std::move(module_file)),
- module_def_(*module_file_->root()),
- function_table_(*this, *module_def_.function_table()),
- executable_table_(*module_def_.executable_table()) {}
-
-Module::~Module() = default;
-
-} // namespace vm
-} // namespace iree
diff --git a/iree/vm/module.h b/iree/vm/module.h
deleted file mode 100644
index 01cfc0d..0000000
--- a/iree/vm/module.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef IREE_VM_MODULE_H_
-#define IREE_VM_MODULE_H_
-
-#include <memory>
-
-#include "iree/base/flatbuffer_util.h"
-#include "iree/schemas/module_def_generated.h"
-#include "iree/vm/executable_table.h"
-#include "iree/vm/function_table.h"
-
-namespace iree {
-namespace vm {
-
-using ModuleFile = FlatBufferFile<ModuleDef>;
-
-// A loaded bytecode module.
-class Module {
- public:
- static Status ValidateStructure(const ModuleDef& module_def);
-
- static StatusOr<std::unique_ptr<Module>> FromDef(const ModuleDef& module_def);
- static StatusOr<std::unique_ptr<Module>> FromFile(
- std::unique_ptr<ModuleFile> module_file);
-
- Module(const Module&) = delete;
- Module& operator=(const Module&) = delete;
- ~Module();
-
- absl::string_view name() const { return WrapString(module_def_.name()); }
-
- const ModuleDef& def() const { return module_def_; }
- const FunctionTable& function_table() const { return function_table_; }
- FunctionTable* mutable_function_table() { return &function_table_; }
- const ExecutableTable& executable_table() const { return executable_table_; }
- ExecutableTable* mutable_executable_table() { return &executable_table_; }
-
- private:
- explicit Module(std::unique_ptr<ModuleFile> module_file);
-
- std::unique_ptr<ModuleFile> module_file_;
- const ModuleDef& module_def_;
- FunctionTable function_table_;
- ExecutableTable executable_table_;
-};
-
-} // namespace vm
-} // namespace iree
-
-#endif // IREE_VM_MODULE_H_
diff --git a/iree/vm/module_printer.cc b/iree/vm/module_printer.cc
deleted file mode 100644
index 2304d33..0000000
--- a/iree/vm/module_printer.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "iree/vm/module_printer.h"
-
-#include "iree/vm/bytecode_printer.h"
-#include "iree/vm/source_map.h"
-
-namespace iree {
-namespace vm {
-
-Status PrintModuleToStream(OpcodeTable opcode_table, const Module& module,
- PrintModuleFlagBitfield flags,
- std::ostream* stream) {
- // TODO(benvanik): custom FunctionTable Function iterator.
- for (int i = 0; i < module.function_table().def().functions()->size(); ++i) {
- ASSIGN_OR_RETURN(const auto& function,
- module.function_table().LookupFunction(i));
- if (function.def().bytecode()) {
- auto source_map_resolver =
- AllBitsSet(flags, PrintModuleFlag::kIncludeSourceMapping)
- ? SourceMapResolver::FromFunction(module.def(), i)
- : SourceMapResolver();
- BytecodePrinter printer(opcode_table, module.function_table(),
- module.executable_table(), source_map_resolver);
- *stream << "Function " << i << ": " << function << "\n";
- RETURN_IF_ERROR(
- printer.PrintToStream(*function.def().bytecode(), stream));
- *stream << "\n";
- } else {
- *stream << "Function " << i << ": " << function.name() << " (import)\n";
- }
- }
- return OkStatus();
-}
-
-Status PrintModuleToStream(OpcodeTable opcode_table, const Module& module,
- std::ostream* stream) {
- return PrintModuleToStream(opcode_table, module, PrintModuleFlag::kNone,
- stream);
-}
-
-} // namespace vm
-} // namespace iree
diff --git a/iree/vm/sequencer_context.cc b/iree/vm/sequencer_context.cc
deleted file mode 100644
index a8bda41..0000000
--- a/iree/vm/sequencer_context.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "iree/vm/sequencer_context.h"
-
-#include "iree/base/flatbuffer_util.h"
-#include "iree/base/status.h"
-#include "iree/hal/buffer_view.h"
-#include "iree/vm/fiber_state.h"
-#include "iree/vm/sequencer_dispatch.h"
-
-namespace iree {
-namespace vm {
-
-namespace {
-
-using ::iree::hal::BufferView;
-
-Status ValidateElementSize(int element_bit_width,
- const ElementTypeDef& expected_element_type) {
- switch (expected_element_type.type_union_type()) {
- case ElementTypeDefUnion::FloatTypeDef: {
- auto expected_bit_width =
- expected_element_type.type_union_as_FloatTypeDef()->width();
- if (element_bit_width != expected_bit_width) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Has element bit width " << element_bit_width
- << " but expected " << expected_bit_width;
- }
- return OkStatus();
- }
- case ElementTypeDefUnion::IntegerTypeDef: {
- auto expected_bit_width =
- expected_element_type.type_union_as_IntegerTypeDef()->width();
- if (element_bit_width != expected_bit_width) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Has element bit width " << element_bit_width
- << " but expected " << expected_bit_width;
- }
- return OkStatus();
- }
- case ElementTypeDefUnion::UnknownTypeDef:
- case ElementTypeDefUnion::NONE: {
- }
- }
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Defined type has unsupported element type "
- << EnumNameElementTypeDefUnion(
- expected_element_type.type_union_type());
-}
-
-Status ValidateArgType(const BufferView& arg,
- const MemRefTypeDef& expected_type) {
- RETURN_IF_ERROR(
- ValidateElementSize(arg.element_size * 8, *expected_type.element_type()));
-
- auto expected_shape = expected_type.shape();
- if (arg.shape.size() != expected_shape->size()) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Argument should have rank " << expected_shape->size()
- << " but has rank " << arg.shape.size();
- }
- for (int i = 0; i < expected_shape->size(); ++i) {
- auto dim_size = arg.shape[i];
- auto expected_dim_size = expected_shape->Get(i);
- if (dim_size != expected_dim_size) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Argument dimension " << i << " should have size "
- << expected_dim_size << " but has size " << dim_size;
- }
- }
- return OkStatus();
-}
-
-} // namespace
-
-SequencerContext::SequencerContext(std::shared_ptr<Instance> instance)
- : instance_(std::move(instance)) {}
-
-SequencerContext::~SequencerContext() = default;
-
-Status SequencerContext::RegisterNativeFunction(
- std::string name, NativeFunction native_function) {
- // TODO(benvanik): provide to debugger.
- return Context::RegisterNativeFunction(std::move(name),
- std::move(native_function));
-}
-
-Status SequencerContext::RegisterModule(std::unique_ptr<Module> module) {
- RETURN_IF_ERROR(Context::RegisterModule(std::move(module)));
- return OkStatus();
-}
-
-Status SequencerContext::Invoke(FiberState* fiber_state, Function function,
- absl::Span<BufferView> args,
- absl::Span<BufferView> results) const {
- // Verify arg/result counts.
- if (args.size() != function.input_count()) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Function " << function.name() << " requires "
- << function.input_count() << " inputs but " << args.size()
- << " provided";
- }
- if (results.size() != function.result_count()) {
- return InvalidArgumentErrorBuilder(IREE_LOC)
- << "Function " << function.name() << " requires "
- << function.result_count() << " outputs but " << results.size()
- << " provided";
- }
-
- // Push stack frame for the function we are calling.
- auto* stack = fiber_state->mutable_stack();
- ASSIGN_OR_RETURN(auto* callee_stack_frame, stack->PushFrame(function));
-
- // Marshal input arguments.
- for (int i = 0; i < args.size(); ++i) {
- auto arg = args[i];
- auto expected_arg_type = function.type_def().inputs()->Get(i);
- RETURN_IF_ERROR(
- ValidateArgType(arg, *expected_arg_type->type_union_as_MemRefTypeDef()))
- << "Function " << function.name() << " argument " << i;
- *callee_stack_frame->mutable_local(i) = std::move(arg);
- }
-
- // TODO(benvanik): change to:
- // get command queue (any command queue)
- // make command buffer
- // record dispatch
- // submit
- // wait on fence
- ASSIGN_OR_RETURN(auto placement,
- instance_->device_manager()->ResolvePlacement({}));
- RETURN_IF_ERROR(
- DispatchSequence(placement, stack, callee_stack_frame, results));
-
- // Pop the callee frame to balance out the stack.
- RETURN_IF_ERROR(stack->PopFrame());
-
- return OkStatus();
-}
-
-} // namespace vm
-} // namespace iree
diff --git a/iree/vm/sequencer_context.h b/iree/vm/sequencer_context.h
deleted file mode 100644
index dbc4bc9..0000000
--- a/iree/vm/sequencer_context.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef IREE_VM_SEQUENCER_CONTEXT_H_
-#define IREE_VM_SEQUENCER_CONTEXT_H_
-
-#include <memory>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/span.h"
-#include "iree/base/status.h"
-#include "iree/hal/buffer_view.h"
-#include "iree/vm/context.h"
-#include "iree/vm/fiber_state.h"
-#include "iree/vm/function.h"
-#include "iree/vm/instance.h"
-#include "iree/vm/module.h"
-
-namespace iree {
-namespace vm {
-
-class SequencerContext final : public Context {
- public:
- explicit SequencerContext(std::shared_ptr<Instance> instance);
- ~SequencerContext() override;
-
- Status RegisterNativeFunction(std::string name,
- NativeFunction native_function) override;
-
- Status RegisterModule(std::unique_ptr<Module> module) override;
-
- // TODO(benvanik): helpers to make passing args easier
- Status Invoke(FiberState* fiber_state, vm::Function function,
- absl::Span<hal::BufferView> args,
- absl::Span<hal::BufferView> results) const;
-
- private:
- std::shared_ptr<Instance> instance_;
-};
-
-} // namespace vm
-} // namespace iree
-
-#endif // IREE_VM_CONTEXT_H_
diff --git a/iree/vm/sequencer_dispatch.cc b/iree/vm/sequencer_dispatch.cc
index 90065b9..ce5a408 100644
--- a/iree/vm/sequencer_dispatch.cc
+++ b/iree/vm/sequencer_dispatch.cc
@@ -32,10 +32,10 @@
#include "iree/hal/device.h"
#include "iree/hal/heap_buffer.h"
#include "iree/schemas/bytecode/sequencer_bytecode_v0.h"
+#include "iree/vm/bytecode_module.h"
#include "iree/vm/bytecode_reader.h"
#include "iree/vm/bytecode_tables_sequencer.h"
#include "iree/vm/bytecode_util.h"
-#include "iree/vm/function.h"
#include "iree/vm/opcode_info.h"
namespace iree {
@@ -65,15 +65,17 @@
}
// TODO(benvanik): insert fence callbacks and wait on fence.
-Status CallNativeFunction(Stack* stack, const ImportFunction& function) {
- auto* stack_frame = stack->current_frame();
-
+Status CallExternalFunction(rt::Stack* stack, const rt::Function& function) {
// Marshal inputs and outputs.
- auto args = stack_frame->mutable_locals().subspan(0, function.input_count());
- auto results = stack_frame->mutable_locals().subspan(args.size());
-
- const auto& fn = function.native_function();
- return fn(stack, args, results);
+ const auto* stack_frame = stack->current_frame();
+ auto buffer_views = absl::MakeSpan(stack_frame->registers().buffer_views);
+ absl::InlinedVector<hal::BufferView, 8> arguments(
+ buffer_views.begin(),
+ buffer_views.begin() + function.signature().argument_count());
+ absl::InlinedVector<hal::BufferView, 8> results(
+ buffer_views.begin() + arguments.size(), buffer_views.end());
+ return function.module()->Execute(stack, function, std::move(arguments),
+ &results);
}
// Pretty prints an array, e.g. [1, 2, 3, 4]
@@ -109,8 +111,8 @@
} // namespace
-Status DispatchSequence(const hal::DevicePlacement& placement, Stack* stack,
- StackFrame* entry_stack_frame,
+Status DispatchSequence(const hal::DevicePlacement& placement, rt::Stack* stack,
+ rt::StackFrame* entry_stack_frame,
absl::Span<BufferView> entry_results) {
// Dispatch table mapping 1:1 with bytecode ops.
// Each entry is a label within this function that can be used for computed
@@ -164,7 +166,15 @@
DISPATCH_CORE_OPCODE(kCall, {
auto* old_stack_frame = stack->current_frame();
ASSIGN_OR_RETURN(const auto& target_function, reader.ReadFunction());
+ // TODO(benvanik): rework register storage interface.
+ ASSIGN_OR_RETURN(
+ const auto* function_def,
+ static_cast<const BytecodeModule*>(target_function.module())
+ ->GetFunctionDef(target_function.linkage(),
+ target_function.ordinal()));
ASSIGN_OR_RETURN(auto* new_stack_frame, stack->PushFrame(target_function));
+ new_stack_frame->mutable_registers()->buffer_views.resize(
+ function_def->bytecode()->local_count());
RETURN_IF_ERROR(
reader.CopyInputsAndSwitchStackFrame(old_stack_frame, new_stack_frame));
DVLOG(1) << "Call; stack now: " << stack->DebugString();
@@ -172,30 +182,20 @@
DISPATCH_CORE_OPCODE(kCallImport, {
auto* old_stack_frame = stack->current_frame();
- ASSIGN_OR_RETURN(const auto* target_function, reader.ReadImportFunction());
- switch (target_function->link_type()) {
- case ImportFunction::LinkType::kModule: {
- ASSIGN_OR_RETURN(auto* new_stack_frame,
- stack->PushFrame(target_function->linked_function()));
- RETURN_IF_ERROR(reader.CopyInputsAndSwitchStackFrame(old_stack_frame,
- new_stack_frame));
- DVLOG(1) << "Call module import; stack now: " << stack->DebugString();
- break;
- }
- case ImportFunction::LinkType::kNativeFunction: {
- ASSIGN_OR_RETURN(auto* new_stack_frame,
- stack->PushFrame(*target_function));
- RETURN_IF_ERROR(reader.CopyInputsAndSwitchStackFrame(old_stack_frame,
- new_stack_frame));
- DVLOG(1) << "Call native import; stack now: " << stack->DebugString();
- RETURN_IF_ERROR(CallNativeFunction(stack, *target_function));
- RETURN_IF_ERROR(reader.CopyResultsAndSwitchStackFrame(old_stack_frame,
- new_stack_frame));
- RETURN_IF_ERROR(stack->PopFrame());
- DVLOG(1) << "Return from native; stack now: " << stack->DebugString();
- break;
- }
- }
+ ASSIGN_OR_RETURN(const auto& target_function, reader.ReadImportFunction());
+ ASSIGN_OR_RETURN(auto* new_stack_frame, stack->PushFrame(target_function));
+ // TODO(benvanik): rework register storage interface.
+ const auto& signature = target_function.signature();
+ new_stack_frame->mutable_registers()->buffer_views.resize(
+ signature.argument_count() + signature.result_count());
+ RETURN_IF_ERROR(
+ reader.CopyInputsAndSwitchStackFrame(old_stack_frame, new_stack_frame));
+ DVLOG(1) << "Call native import; stack now: " << stack->DebugString();
+ RETURN_IF_ERROR(CallExternalFunction(stack, target_function));
+ RETURN_IF_ERROR(reader.CopyResultsAndSwitchStackFrame(old_stack_frame,
+ new_stack_frame));
+ RETURN_IF_ERROR(stack->PopFrame());
+ DVLOG(1) << "Return from native; stack now: " << stack->DebugString();
});
DISPATCH_CORE_OPCODE(kCallIndirect, {
@@ -209,8 +209,9 @@
// Returning from entry function. Marshal results from the return stmt.
ASSIGN_OR_RETURN(int32_t src_count, reader.ReadCount());
for (int i = 0; i < src_count; ++i) {
- ASSIGN_OR_RETURN(auto* src_local,
- reader.ReadLocal(old_stack_frame->mutable_locals()));
+ ASSIGN_OR_RETURN(
+ auto* src_local,
+ reader.ReadLocal(old_stack_frame->mutable_registers()));
entry_results[i] = std::move(*src_local);
}
DVLOG(1) << "Returning to entry";
@@ -259,11 +260,10 @@
// TODO(benvanik): the real sequencer :)
ASSIGN_OR_RETURN(auto dispatch_ordinal, reader.ReadInt32());
ASSIGN_OR_RETURN(auto export_ordinal, reader.ReadUint16_t());
- auto& executable_table =
- stack->current_frame()->module().executable_table();
ASSIGN_OR_RETURN(
- auto* multi_arch_executable_def,
- executable_table.LookupMultiArchExecutable(dispatch_ordinal));
+ const auto* multi_arch_executable_def,
+ static_cast<const BytecodeModule&>(stack->current_frame()->module())
+ .LookupMultiArchExecutable(dispatch_ordinal));
if (export_ordinal >= multi_arch_executable_def->entry_point_count()) {
return InvalidArgumentErrorBuilder(IREE_LOC)
<< "Invalid executable export ordinal " << export_ordinal;
diff --git a/iree/vm/sequencer_dispatch.h b/iree/vm/sequencer_dispatch.h
index fc664db..0251c17 100644
--- a/iree/vm/sequencer_dispatch.h
+++ b/iree/vm/sequencer_dispatch.h
@@ -18,15 +18,15 @@
#include "iree/base/status.h"
#include "iree/hal/buffer_view.h"
#include "iree/hal/device_placement.h"
-#include "iree/vm/stack.h"
-#include "iree/vm/stack_frame.h"
+#include "iree/rt/stack.h"
+#include "iree/rt/stack_frame.h"
namespace iree {
namespace vm {
// TODO(benvanik): API that supports yielding.
-Status DispatchSequence(const hal::DevicePlacement& placement, Stack* stack,
- StackFrame* entry_stack_frame,
+Status DispatchSequence(const hal::DevicePlacement& placement, rt::Stack* stack,
+ rt::StackFrame* entry_stack_frame,
absl::Span<hal::BufferView> entry_results);
} // namespace vm
diff --git a/iree/vm/sequencer_module.cc b/iree/vm/sequencer_module.cc
new file mode 100644
index 0000000..1906ef6
--- /dev/null
+++ b/iree/vm/sequencer_module.cc
@@ -0,0 +1,112 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "iree/vm/sequencer_module.h"
+
+#include "absl/memory/memory.h"
+#include "iree/base/status.h"
+#include "iree/base/tracing.h"
+#include "iree/hal/buffer_view.h"
+#include "iree/rt/context.h"
+#include "iree/rt/instance.h"
+#include "iree/vm/bytecode_tables_sequencer.h"
+#include "iree/vm/sequencer_dispatch.h"
+
+namespace iree {
+namespace vm {
+
+namespace {
+
+using ::iree::hal::BufferView;
+using ::iree::rt::Function;
+using ::iree::rt::Module;
+
+} // namespace
+
+// static
+StatusOr<ref_ptr<rt::Module>> SequencerModule::FromDef(
+ const ModuleDef& module_def) {
+ ASSIGN_OR_RETURN(auto module_file, ModuleFile::Create(&module_def, []() {}));
+ return FromFile(std::move(module_file));
+}
+
+// static
+StatusOr<ref_ptr<rt::Module>> SequencerModule::FromFile(
+ std::unique_ptr<ModuleFile> module_file) {
+ if (module_file->root() == nullptr) {
+ return InvalidArgumentErrorBuilder(IREE_LOC) << "No root ModuleDef present";
+ }
+ const auto& module_def = *module_file->root();
+
+ // Validates the structure of the module (but not bytecode).
+ // This ensures we don't have flatbuffer vectors will null entries, etc.
+ RETURN_IF_ERROR(BytecodeModule::ValidateStructure(module_def));
+
+ auto module = assign_ref(new SequencerModule(std::move(module_file)));
+
+ // TODO(benvanik): validate internals here? or make explicit?
+
+ return {std::move(module)};
+}
+
+SequencerModule::SequencerModule(std::unique_ptr<ModuleFile> module_file)
+ : BytecodeModule(std::move(module_file), sequencer_opcode_table()) {}
+
+SequencerModule::~SequencerModule() = default;
+
+Status SequencerModule::Execute(
+ rt::Stack* stack, const Function function,
+ absl::InlinedVector<hal::BufferView, 8> arguments,
+ absl::InlinedVector<hal::BufferView, 8>* results) const {
+ IREE_TRACE_SCOPE0("SequencerModule::Execute");
+
+ // Push stack frame for the function we are calling.
+ ASSIGN_OR_RETURN(auto* callee_stack_frame, stack->PushFrame(function));
+
+ // TODO(benvanik): rework register storage interface.
+ ASSIGN_OR_RETURN(const auto* function_def,
+ GetFunctionDef(function.linkage(), function.ordinal()));
+ auto* registers = callee_stack_frame->mutable_registers();
+ registers->buffer_views.resize(function_def->bytecode()->local_count());
+
+ // Marshal input arguments.
+ for (int i = 0; i < arguments.size(); ++i) {
+ auto arg = arguments[i];
+ auto expected_arg_type = function_def->type()->inputs()->Get(i);
+ RETURN_IF_ERROR(BytecodeModule::ValidateArgType(
+ arg, *expected_arg_type->type_union_as_MemRefTypeDef()))
+ << "Function " << function.name() << " argument " << i;
+ registers->buffer_views[i] = std::move(arg);
+ }
+
+ // TODO(benvanik): change to:
+ // get command queue (any command queue)
+ // make command buffer
+ // record dispatch
+ // submit
+ // wait on fence
+ ASSIGN_OR_RETURN(
+ auto placement,
+ stack->context()->instance()->device_manager()->ResolvePlacement({}));
+ RETURN_IF_ERROR(
+ DispatchSequence(placement, stack, callee_stack_frame, results));
+
+ // Pop the callee frame to balance out the stack.
+ RETURN_IF_ERROR(stack->PopFrame());
+
+ return OkStatus();
+}
+
+} // namespace vm
+} // namespace iree
diff --git a/iree/vm/sequencer_module.h b/iree/vm/sequencer_module.h
new file mode 100644
index 0000000..b9bb176
--- /dev/null
+++ b/iree/vm/sequencer_module.h
@@ -0,0 +1,46 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef IREE_VM_SEQUENCER_MODULE_H_
+#define IREE_VM_SEQUENCER_MODULE_H_
+
+#include <memory>
+
+#include "iree/vm/bytecode_module.h"
+
+namespace iree {
+namespace vm {
+
+// A module using the sequencer bytecode ops.
+class SequencerModule final : public BytecodeModule {
+ public:
+ static StatusOr<ref_ptr<rt::Module>> FromDef(const ModuleDef& module_def);
+ static StatusOr<ref_ptr<rt::Module>> FromFile(
+ std::unique_ptr<ModuleFile> module_file);
+
+ ~SequencerModule() override;
+
+ Status Execute(
+ rt::Stack* stack, const rt::Function function,
+ absl::InlinedVector<hal::BufferView, 8> arguments,
+ absl::InlinedVector<hal::BufferView, 8>* results) const override;
+
+ private:
+ explicit SequencerModule(std::unique_ptr<ModuleFile> module_file);
+};
+
+} // namespace vm
+} // namespace iree
+
+#endif // IREE_VM_SEQUENCER_MODULE_H_
diff --git a/iree/vm/source_map.h b/iree/vm/source_map.h
deleted file mode 100644
index 32cd41e..0000000
--- a/iree/vm/source_map.h
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef IREE_VM_SOURCE_MAP_H_
-#define IREE_VM_SOURCE_MAP_H_
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "iree/base/status.h"
-#include "iree/schemas/module_def_generated.h"
-#include "iree/schemas/source_map_def_generated.h"
-
-namespace iree {
-namespace vm {
-
-class SourceLocation {
- public:
- static bool Equal(const SourceLocation& a, const SourceLocation& b);
-
- SourceLocation() = default;
- SourceLocation(const SourceMapDef& source_map_def,
- const FunctionSourceMapDef& function_source_map,
- int location_ordinal)
- : source_map_def_(&source_map_def),
- function_source_map_(&function_source_map),
- location_ordinal_(location_ordinal) {}
-
- std::string DebugStringShort() const;
-
- bool empty() const { return source_map_def_ == nullptr; }
-
- private:
- const SourceMapDef* source_map_def_ = nullptr;
- const FunctionSourceMapDef* function_source_map_ = nullptr;
- int location_ordinal_ = 0;
-};
-
-inline bool operator==(const SourceLocation& a, const SourceLocation& b) {
- return SourceLocation::Equal(a, b);
-}
-
-inline bool operator!=(const SourceLocation& a, const SourceLocation& b) {
- return !(a == b);
-}
-
-class SourceMap {
- public:
- static SourceMap FromModule(const ModuleDef& module_def);
-
- SourceMap() = default;
- explicit SourceMap(const SourceMapDef& source_map_def)
- : source_map_def_(&source_map_def) {}
-
- bool empty() const { return source_map_def_ == nullptr; }
- const SourceMapDef* def() const { return source_map_def_; }
-
- StatusOr<absl::string_view> GetUniqueString(int string_index) const;
-
- StatusOr<const FunctionSourceMapDef*> GetFunctionSourceMap(
- int function_ordinal) const;
-
- private:
- const SourceMapDef* source_map_def_ = nullptr;
-};
-inline std::ostream& operator<<(std::ostream& stream,
- const SourceLocation& location) {
- stream << location.DebugStringShort();
- return stream;
-}
-
-class SourceMapResolver {
- public:
- static SourceMapResolver FromFunction(const ModuleDef& module_def,
- int function_ordinal);
-
- SourceMapResolver() = default;
-
- absl::optional<SourceLocation> ResolveBytecodeOffset(int offset) const;
-
- private:
- SourceMapResolver(SourceMap source_map,
- const FunctionSourceMapDef& function_source_map)
- : source_map_(std::move(source_map)),
- function_source_map_(&function_source_map) {}
-
- SourceMap source_map_;
- const FunctionSourceMapDef* function_source_map_ = nullptr;
-};
-
-} // namespace vm
-} // namespace iree
-
-#endif // IREE_VM_SOURCE_MAP_H_
diff --git a/iree/vm/source_map.cc b/iree/vm/source_map_resolver.cc
similarity index 72%
rename from iree/vm/source_map.cc
rename to iree/vm/source_map_resolver.cc
index 4b8467f..96025e4 100644
--- a/iree/vm/source_map.cc
+++ b/iree/vm/source_map_resolver.cc
@@ -12,23 +12,22 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "iree/vm/source_map.h"
-
-#include <sstream>
+#include "iree/vm/source_map_resolver.h"
#include "iree/base/flatbuffer_util.h"
#include "iree/base/status.h"
+#include "iree/schemas/source_map_def_generated.h"
namespace iree {
namespace vm {
namespace {
-Status PrintLocation(const SourceMap& source_map,
+Status PrintLocation(const SourceMapResolver& source_map,
const FunctionSourceMapDef& function_source_map,
const LocationDef& location, std::ostream* stream);
-Status PrintFileLocation(const SourceMap& source_map,
+Status PrintFileLocation(const SourceMapResolver& source_map,
const FunctionSourceMapDef& function_source_map,
const FileLocationDef& location,
std::ostream* stream) {
@@ -38,7 +37,7 @@
return OkStatus();
}
-Status PrintNameLocation(const SourceMap& source_map,
+Status PrintNameLocation(const SourceMapResolver& source_map,
const FunctionSourceMapDef& function_source_map,
const NameLocationDef& location,
std::ostream* stream) {
@@ -47,7 +46,7 @@
return OkStatus();
}
-Status PrintCallSiteLocation(const SourceMap& source_map,
+Status PrintCallSiteLocation(const SourceMapResolver& source_map,
const FunctionSourceMapDef& function_source_map,
const CallSiteLocationDef& location,
std::ostream* stream) {
@@ -55,7 +54,7 @@
return OkStatus();
}
-Status PrintFusedLocation(const SourceMap& source_map,
+Status PrintFusedLocation(const SourceMapResolver& source_map,
const FunctionSourceMapDef& function_source_map,
const FusedLocationDef& location,
std::ostream* stream) {
@@ -74,7 +73,7 @@
return OkStatus();
}
-Status PrintLocation(const SourceMap& source_map,
+Status PrintLocation(const SourceMapResolver& source_map,
const FunctionSourceMapDef& function_source_map,
const LocationDef& location, std::ostream* stream) {
switch (location.location_union_type()) {
@@ -104,36 +103,15 @@
} // namespace
// static
-bool SourceLocation::Equal(const SourceLocation& a, const SourceLocation& b) {
- return a.source_map_def_ == b.source_map_def_ &&
- a.function_source_map_ == b.function_source_map_ &&
- a.location_ordinal_ == b.location_ordinal_;
-}
-
-std::string SourceLocation::DebugStringShort() const {
- if (empty()) {
- return "<unknown>";
- }
- std::ostringstream stream;
- const auto& location =
- *function_source_map_->location_table()->Get(location_ordinal_);
- auto status = PrintLocation(SourceMap(*source_map_def_),
- *function_source_map_, location, &stream);
- if (!status.ok()) {
- stream << status;
- }
- return stream.str();
-}
-
-// static
-SourceMap SourceMap::FromModule(const ModuleDef& module_def) {
+SourceMapResolver SourceMapResolver::FromModule(const ModuleDef& module_def) {
if (module_def.source_map()) {
- return SourceMap{*module_def.source_map()};
+ return SourceMapResolver{*module_def.source_map()};
}
return {};
}
-StatusOr<absl::string_view> SourceMap::GetUniqueString(int string_index) const {
+StatusOr<absl::string_view> SourceMapResolver::GetUniqueString(
+ int string_index) const {
if (empty()) {
return NotFoundErrorBuilder(IREE_LOC) << "No source map present";
}
@@ -145,7 +123,7 @@
<< "String index " << string_index << " not present in string table";
}
-StatusOr<const FunctionSourceMapDef*> SourceMap::GetFunctionSourceMap(
+StatusOr<const FunctionSourceMapDef*> SourceMapResolver::GetFunctionSourceMap(
int function_ordinal) const {
if (empty()) {
return NotFoundErrorBuilder(IREE_LOC) << "No source map present";
@@ -163,28 +141,16 @@
<< " source map not present in function table";
}
-// static
-SourceMapResolver SourceMapResolver::FromFunction(const ModuleDef& module_def,
- int function_ordinal) {
- auto source_map = SourceMap::FromModule(module_def);
- if (source_map.empty()) {
- return {};
- }
- auto function_source_map_or =
- source_map.GetFunctionSourceMap(function_ordinal);
+absl::optional<rt::SourceLocation> SourceMapResolver::ResolveFunctionOffset(
+ const rt::Function& function, rt::SourceOffset offset) {
+ if (empty()) return absl::nullopt;
+ auto function_source_map_or = GetFunctionSourceMap(function.ordinal());
if (!function_source_map_or.ok()) {
- return {};
+ return absl::nullopt;
}
- return SourceMapResolver(source_map, *function_source_map_or.ValueOrDie());
-}
-
-absl::optional<SourceLocation> SourceMapResolver::ResolveBytecodeOffset(
- int offset) const {
- if (!function_source_map_) {
- return {};
- }
-
- const auto* bytecode_map = function_source_map_->bytecode_map();
+ const auto* function_source_map = function_source_map_or.ValueOrDie();
+ const auto* bytecode_map = function_source_map->bytecode_map();
+ if (!bytecode_map) return absl::nullopt;
// TODO(benvanik): allow fuzzy offset matching/table sparsity.
int location_ordinal = -1;
@@ -195,11 +161,33 @@
}
}
if (location_ordinal == -1) {
- return {};
+ return absl::nullopt;
}
- return SourceLocation(*source_map_.def(), *function_source_map_,
- location_ordinal);
+ return rt::SourceLocation(this,
+ {
+ reinterpret_cast<uint64_t>(function_source_map),
+ static_cast<uint64_t>(location_ordinal),
+ });
+}
+
+void SourceMapResolver::PrintSourceLocation(
+ rt::SourceResolverArgs resolver_args, std::ostream* stream) const {
+ if (empty()) {
+ *stream << "<unknown>";
+ return;
+ }
+
+ auto* function_source_map =
+ reinterpret_cast<FunctionSourceMapDef*>(resolver_args[0]);
+ int location_ordinal = static_cast<int>(resolver_args[1]);
+
+ const auto& location =
+ *function_source_map->location_table()->Get(location_ordinal);
+ auto status = PrintLocation(*this, *function_source_map, location, stream);
+ if (!status.ok()) {
+ *stream << status;
+ }
}
} // namespace vm
diff --git a/iree/vm/source_map_resolver.h b/iree/vm/source_map_resolver.h
new file mode 100644
index 0000000..5c8f7c2
--- /dev/null
+++ b/iree/vm/source_map_resolver.h
@@ -0,0 +1,57 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef IREE_VM_SOURCE_MAP_RESOLVER_H_
+#define IREE_VM_SOURCE_MAP_RESOLVER_H_
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "iree/base/status.h"
+#include "iree/rt/source_resolver.h"
+#include "iree/schemas/module_def_generated.h"
+#include "iree/schemas/source_map_def_generated.h"
+
+namespace iree {
+namespace vm {
+
+class SourceMapResolver final : public rt::SourceResolver {
+ public:
+ static SourceMapResolver FromModule(const ModuleDef& module_def);
+
+ SourceMapResolver() = default;
+ explicit SourceMapResolver(const SourceMapDef& source_map_def)
+ : source_map_def_(&source_map_def) {}
+
+ bool empty() const { return source_map_def_ == nullptr; }
+ const SourceMapDef* def() const { return source_map_def_; }
+
+ StatusOr<absl::string_view> GetUniqueString(int string_index) const;
+
+ StatusOr<const FunctionSourceMapDef*> GetFunctionSourceMap(
+ int function_ordinal) const;
+
+ absl::optional<rt::SourceLocation> ResolveFunctionOffset(
+ const rt::Function& function, rt::SourceOffset offset) override;
+
+ void PrintSourceLocation(rt::SourceResolverArgs resolver_args,
+ std::ostream* stream) const override;
+
+ private:
+ const SourceMapDef* source_map_def_ = nullptr;
+};
+
+} // namespace vm
+} // namespace iree
+
+#endif // IREE_VM_SOURCE_MAP_RESOLVER_H_
diff --git a/iree/vm/stack.cc b/iree/vm/stack.cc
deleted file mode 100644
index 5912173..0000000
--- a/iree/vm/stack.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "iree/vm/stack.h"
-
-#include <iterator>
-
-#include "absl/strings/str_join.h"
-#include "iree/base/status.h"
-
-namespace iree {
-namespace vm {
-
-constexpr int Stack::kMaxStackDepth;
-
-Stack::Stack() = default;
-
-Stack::~Stack() = default;
-
-StatusOr<StackFrame*> Stack::PushFrame(Function function) {
- if (stack_depth_ + 1 > kMaxStackDepth) {
- return InternalErrorBuilder(IREE_LOC)
- << "Max stack depth of " << kMaxStackDepth << " exceeded";
- }
- stack_[stack_depth_++] = StackFrame(function);
-
- // TODO(benvanik): WTF scope enter.
-
- return current_frame();
-}
-
-StatusOr<StackFrame*> Stack::PushFrame(const ImportFunction& function) {
- if (stack_depth_ + 1 > kMaxStackDepth) {
- return InternalErrorBuilder(IREE_LOC)
- << "Max stack depth of " << kMaxStackDepth << " exceeded";
- }
- stack_[stack_depth_++] = StackFrame(function);
-
- // TODO(benvanik): WTF scope enter.
-
- return current_frame();
-}
-
-Status Stack::PopFrame() {
- if (stack_depth_ == 0) {
- return InternalErrorBuilder(IREE_LOC) << "Unbalanced stack pop";
- }
-
- // TODO(benvanik): WTF scope leave.
-
- --stack_depth_;
- return OkStatus();
-}
-
-namespace {
-struct StackFrameFormatter {
- void operator()(std::string* out, const StackFrame& stack_frame) const {
- out->append(absl::StrCat(stack_frame.module().name(), ":",
- stack_frame.function().name(), "@",
- stack_frame.offset()));
- }
-};
-} // namespace
-
-std::string Stack::DebugString() const {
- return absl::StrJoin(std::begin(stack_), std::begin(stack_) + stack_depth_,
- "\n", StackFrameFormatter());
-}
-
-} // namespace vm
-} // namespace iree
diff --git a/iree/vm/stack.h b/iree/vm/stack.h
deleted file mode 100644
index 7228742..0000000
--- a/iree/vm/stack.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef IREE_VM_STACK_H_
-#define IREE_VM_STACK_H_
-
-#include <functional>
-
-#include "absl/types/span.h"
-#include "iree/base/status.h"
-#include "iree/vm/stack_frame.h"
-
-namespace iree {
-namespace vm {
-
-// VM call stack.
-//
-// Stacks are thread-compatible.
-class Stack {
- public:
- static constexpr int kMaxStackDepth = 32;
-
- Stack();
- Stack(const Stack&) = delete;
- Stack& operator=(const Stack&) = delete;
- ~Stack();
-
- absl::Span<const StackFrame> frames() const {
- return absl::MakeConstSpan(stack_, stack_depth_);
- }
- absl::Span<StackFrame> mutable_frames() {
- return absl::MakeSpan(stack_, stack_depth_);
- }
-
- StackFrame* current_frame() {
- return stack_depth_ > 0 ? &stack_[stack_depth_ - 1] : nullptr;
- }
- const StackFrame* current_frame() const {
- return stack_depth_ > 0 ? &stack_[stack_depth_ - 1] : nullptr;
- }
- StackFrame* caller_frame() {
- return stack_depth_ > 1 ? &stack_[stack_depth_ - 2] : nullptr;
- }
- const StackFrame* caller_frame() const {
- return stack_depth_ > 1 ? &stack_[stack_depth_ - 2] : nullptr;
- }
-
- StatusOr<StackFrame*> PushFrame(Function function);
- StatusOr<StackFrame*> PushFrame(const ImportFunction& function);
- Status PopFrame();
-
- std::string DebugString() const;
-
- private:
- StackFrame stack_[kMaxStackDepth];
- int stack_depth_ = 0;
-};
-
-} // namespace vm
-} // namespace iree
-
-#endif // IREE_VM_STACK_H_
diff --git a/iree/vm/stack_frame.cc b/iree/vm/stack_frame.cc
deleted file mode 100644
index 3974470..0000000
--- a/iree/vm/stack_frame.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "iree/vm/stack_frame.h"
-
-#include "iree/base/status.h"
-
-namespace iree {
-namespace vm {
-
-StackFrame::StackFrame(Function function) : function_(function) {
- const auto* bytecode_def = function_.def().bytecode();
- if (bytecode_def) {
- offset_limit_ = bytecode_def->contents()->Length();
- locals_.resize(bytecode_def->local_count());
- } else {
- locals_.resize(function_.input_count() + function_.result_count());
- }
-}
-
-StackFrame::StackFrame(const ImportFunction& function)
- : function_(function), import_function_(&function) {}
-
-Status StackFrame::set_offset(int offset) {
- if (offset < 0 || offset > offset_limit_) {
- return OutOfRangeErrorBuilder(IREE_LOC)
- << "Offset " << offset
- << " is outside of the bytecode body limit of " << offset_limit_;
- }
- offset_ = offset;
- return OkStatus();
-}
-
-} // namespace vm
-} // namespace iree
diff --git a/iree/vm/stack_frame.h b/iree/vm/stack_frame.h
deleted file mode 100644
index a39c789..0000000
--- a/iree/vm/stack_frame.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef IREE_VM_STACK_FRAME_H_
-#define IREE_VM_STACK_FRAME_H_
-
-#include <vector>
-
-#include "absl/types/span.h"
-#include "iree/hal/buffer_view.h"
-#include "iree/vm/function.h"
-#include "iree/vm/module.h"
-
-namespace iree {
-namespace vm {
-
-// A single frame on the call stack containing current execution state and
-// local values.
-//
-// StackFrames are designed to be serialized so that suspend and resume is
-// possible. This means that most state is stored either entirely within the
-// frame or references to non-pointer values (such as other function indices).
-// BufferViews require special care to allow rendezvous and liveness tracking.
-class StackFrame {
- public:
- StackFrame() = default;
- explicit StackFrame(Function function);
- explicit StackFrame(const ImportFunction& function);
- StackFrame(const StackFrame&) = delete;
- StackFrame& operator=(const StackFrame&) = delete;
- StackFrame(StackFrame&&) = default;
- StackFrame& operator=(StackFrame&&) = default;
-
- const Module& module() const { return function_.module(); }
- const Function& function() const { return function_; }
-
- inline int offset() const { return offset_; }
- Status set_offset(int offset);
- inline int* mutable_offset() { return &offset_; }
-
- inline const hal::BufferView& local(int ordinal) { return locals_[ordinal]; }
- inline hal::BufferView* mutable_local(int ordinal) {
- return &locals_[ordinal];
- }
-
- inline absl::Span<const hal::BufferView> locals() const {
- return absl::MakeConstSpan(locals_);
- }
- inline absl::Span<hal::BufferView> mutable_locals() {
- return absl::MakeSpan(locals_);
- }
-
- private:
- Function function_;
- const ImportFunction* import_function_;
- int offset_ = 0;
- int offset_limit_ = 0;
-
- // TODO(benvanik): replace with a placed allocation.
- std::vector<hal::BufferView> locals_;
-};
-
-} // namespace vm
-} // namespace iree
-
-#endif // IREE_VM_STACK_FRAME_H_