-
Notifications
You must be signed in to change notification settings - Fork 469
[arcilator] Add JIT runtime environment library and stdio hooks #7445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
bde442f
704cd6e
139700b
bde3a08
c8ea000
2a8d7f7
0e413e0
7230394
330e445
d5db8f6
faa0b2b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| // RUN: arcilator %s --run --jit-entry=main 2>&1 >/dev/null | FileCheck -strict-whitespace %s | ||
| // REQUIRES: arcilator-jit | ||
|
|
||
| // CHECK: Hello World!{{[[:space:]]}} | ||
|
|
||
| module { | ||
|
|
||
| llvm.func @_arc_env_get_print_stream(i32) -> !llvm.ptr | ||
| llvm.func @_arc_libc_fprintf(!llvm.ptr, !llvm.ptr, ...) -> i32 | ||
| llvm.func @_arc_libc_fputc(i32, !llvm.ptr) -> i32 | ||
| llvm.func @_arc_libc_fputs(!llvm.ptr, !llvm.ptr) -> i32 | ||
|
|
||
| llvm.mlir.global internal constant @global_hello("He%c%co \00") {addr_space = 0 : i32} | ||
| llvm.mlir.global internal constant @global_world("World\00") {addr_space = 0 : i32} | ||
|
|
||
| arc.model @dut io !hw.modty<> { | ||
| ^bb0(%arg0: !arc.storage): | ||
| %cst0 = llvm.mlir.constant(0 : i32) : i32 | ||
| %ascii_em = llvm.mlir.constant(33 : i32) : i32 | ||
| %ascii_lf = llvm.mlir.constant(10 : i32) : i32 | ||
| %ascii_l = llvm.mlir.constant(108 : i32) : i32 | ||
| %stderr = llvm.call @_arc_env_get_print_stream(%cst0) : (i32) -> !llvm.ptr | ||
|
|
||
| %hello = llvm.mlir.addressof @global_hello : !llvm.ptr | ||
| %0 = llvm.call @_arc_libc_fprintf(%stderr, %hello, %ascii_l, %ascii_l) vararg(!llvm.func<i32 (ptr, ptr, ...)>) : (!llvm.ptr, !llvm.ptr, i32, i32) -> i32 | ||
|
|
||
| %world = llvm.mlir.addressof @global_world : !llvm.ptr | ||
| %1 = llvm.call @_arc_libc_fputs(%world, %stderr) : (!llvm.ptr, !llvm.ptr) -> i32 | ||
|
|
||
| %2 = llvm.call @_arc_libc_fputc(%ascii_em, %stderr) : (i32, !llvm.ptr) -> i32 | ||
| %3 = llvm.call @_arc_libc_fputc(%ascii_lf, %stderr) : (i32, !llvm.ptr) -> i32 | ||
| } | ||
|
|
||
| func.func @main() { | ||
| arc.sim.instantiate @dut as %arg0 { | ||
| arc.sim.step %arg0 : !arc.sim.instance<@dut> | ||
| } | ||
| return | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,63 @@ | ||
| // NOLINTBEGIN | ||
| #pragma once | ||
| #include <array> | ||
| #include <cstdarg> | ||
| #include <cstdint> | ||
| #include <cstdio> | ||
| #include <cstring> | ||
| #include <functional> | ||
| #include <ostream> | ||
| #include <vector> | ||
|
|
||
| // Sanity checks for binary compatibility | ||
| #ifdef __BYTE_ORDER__ | ||
| #if (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__) | ||
| #error Unsupported endianess | ||
| #endif | ||
| #endif | ||
| static_assert(sizeof(int) == 4, "Unsupported ABI"); | ||
| static_assert(sizeof(long long) == 8, "Unsupported ABI"); | ||
|
|
||
| // --- Exports to the IR --- | ||
|
|
||
| #ifdef _WIN32 | ||
| #define ARCEXPORT(rtype) extern "C" __declspec(dllexport) rtype __cdecl | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've no clue about those windows specific things, but thanks for making this work with Windows as well! 🚀 |
||
| #else | ||
| #define ARCEXPORT(rtype) extern "C" rtype | ||
| #endif | ||
|
|
||
| // libc Adapters | ||
| ARCEXPORT(int) _arc_libc_fprintf(FILE *stream, const char *format, ...) { | ||
| int result; | ||
| va_list args; | ||
| va_start(args, format); | ||
| result = vfprintf(stream, format, args); | ||
| va_end(args); | ||
| return result; | ||
| } | ||
|
|
||
| ARCEXPORT(int) _arc_libc_fputs(const char *str, FILE *stream) { | ||
| return fputs(str, stream); | ||
| } | ||
|
|
||
| ARCEXPORT(int) _arc_libc_fputc(int ch, FILE *stream) { | ||
| return fputc(ch, stream); | ||
| } | ||
|
|
||
| // Runtime Environment calls | ||
|
|
||
| #define ARC_ENV_DECL_GET_PRINT_STREAM(idarg) \ | ||
| ARCEXPORT(FILE *) _arc_env_get_print_stream(uint32_t idarg) | ||
|
|
||
| #ifndef ARC_NO_DEFAULT_GET_PRINT_STREAM | ||
| ARC_ENV_DECL_GET_PRINT_STREAM(id) { | ||
| (void)id; | ||
| return stderr; | ||
| } | ||
|
Comment on lines
+57
to
+60
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering if it would make sense to let the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I've added this in anticipation of #7111. The problem is, AFAIK we don't have any lowering path that would support this, let alone an agreed on concept for file descriptors / output streams in the IR. I had a short exchange with @seldridge on this in the discord channel some weeks ago. For now we could at best add a command line flag to control this globally.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah I see. I was just thinking about adding an if-statement here to allow the LLVM call operation to choose between stderr and stdout when writing MLIR integration tests and examples by hand. But this is not important at all. We can also just leave it as is until we have a proper story for file descriptors. |
||
| #endif // ARC_NO_DEFAULT_GET_PRINT_STREAM | ||
|
|
||
| // ---------------- | ||
|
|
||
| struct Signal { | ||
| const char *name; | ||
| unsigned offset; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| add_library(arc-jit-env SHARED arcilator-jit-env.cpp) | ||
|
|
||
| if(WIN32) | ||
| # Put the DLL into the binary directory so we don't have | ||
| # to worry about it not being found. | ||
| set_target_properties(arc-jit-env | ||
| PROPERTIES | ||
| LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib | ||
| RUNTIME_OUTPUT_DIRECTORY ${CIRCT_TOOLS_DIR}$<0:> | ||
| CXX_VISIBILITY_PRESET "default" | ||
| ) | ||
| install(TARGETS arc-jit-env | ||
| RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} | ||
| LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||
| COMPONENT arc-jit-env | ||
| ) | ||
|
|
||
| else() | ||
|
|
||
| set_target_properties(arc-jit-env | ||
| PROPERTIES | ||
| LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib | ||
| RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib | ||
| CXX_VISIBILITY_PRESET "default" | ||
| ) | ||
| install(TARGETS arc-jit-env | ||
| DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||
| COMPONENT arc-jit-env | ||
| ) | ||
|
|
||
| endif() | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===- arcilator-jit-env.cpp - Internal arcilator JIT API -----------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // Implementation of the arcilator JIT runtime environment API facing | ||
| // the arcilator.cpp. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "../arcilator-runtime.h" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should probably add the standard header comments here. |
||
|
|
||
| #define ARCJITENV_EXPORTS | ||
| #include "arcilator-jit-env.h" | ||
|
|
||
| ARCJITENV_API int arc_jit_runtime_env_init(void) { return 0; } | ||
| ARCJITENV_API void arc_jit_runtime_env_deinit(void) { return; } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| //===- arcilator-jit-env.h - Internal arcilator JIT API -------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // Declarations of the JIT runtime environment API facing the arcilator.cpp. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #pragma once | ||
|
|
||
| #ifdef _WIN32 | ||
|
|
||
| #ifdef ARCJITENV_EXPORTS | ||
| #define ARCJITENV_API extern "C" __declspec(dllexport) | ||
| #else | ||
| #define ARCJITENV_API extern "C" __declspec(dllimport) | ||
| #endif // ARCJITENV_EXPORTS | ||
|
|
||
| #else | ||
|
|
||
| #define ARCJITENV_API extern "C" | ||
|
|
||
| #endif // _WIN32 | ||
|
|
||
| // These don't do anything at the moment. It is still | ||
| // required to call them to make sure the library | ||
| // is linked and loaded before the JIT engine starts. | ||
|
|
||
| ARCJITENV_API int arc_jit_runtime_env_init(void); | ||
| ARCJITENV_API void arc_jit_runtime_env_deinit(void); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you make this consistent with
MLIR_RUNNERUTILS_EXPORTmacro?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MLIR_RUNNERUTILS_EXPORTdoes not includeextern "C"yet it looks like it is prefixed withextern "C"every time it is used. That seems odd to me.The
__cdeclis probably not required. It don't have access to my Windows PC right now, I'll check later today. Basically, I've just used every magic incantation here that I could come up with to increase the likelihood of it linking. 😅