Skip to content
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

Introduce baseline JIT compiler #135

Merged
merged 1 commit into from
Jun 15, 2023
Merged

Conversation

qwe661234
Copy link
Collaborator

@qwe661234 qwe661234 commented Jun 1, 2023

The baseline JIT compiler design involves tracing an EBB when its usage frequency exceeds a predetermined threshold. We then utilize a code generator to convert the instruction sequence into C code. The C code is subsequently compiled using mir, and the resulting target machine code is stored in the code cache for future utilization.

The primary objective of introducing the baseline JIT compiler is to enhance the execution speed of RISC-V instructions with minimal modification. This implementation requires three additional components: a code generator, mir compiler, and code cache, while maintaining the original design of the interpreter. Furthermore, this baseline JIT compiler serves as the foundational target for future improvements.

Metric master baseline JIT Speedup
CoreMark 1352.843 (Iterations/Sec) 1740.881 (Iterations/Sec) +28.6%
dhrystone 1146 DMIPS 2368.33DMIPS +106%

src/codegen.c Fixed Show fixed Hide fixed
src/codegen.c Fixed Show fixed Hide fixed
src/codegen.c Fixed Show fixed Hide fixed
src/compile.c Fixed Show fixed Hide fixed
src/compile.c Fixed Show fixed Hide fixed
src/cache.c Outdated Show resolved Hide resolved
Copy link
Contributor

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolve the issues raised by CodeQL in advance.

src/cache.c Outdated Show resolved Hide resolved
src/codegen.c Outdated Show resolved Hide resolved
jserv

This comment was marked as duplicate.

qwe661234 added a commit to qwe661234/rv32emu that referenced this pull request Jun 2, 2023
Makefile Outdated Show resolved Hide resolved
Makefile Outdated Show resolved Hide resolved
block_map_t block_map; /**< basic block map */
#else
struct cache *cache;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To minimize the code changes, is it possible to stick to block_map_t rather than struct cache?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is difficult to stick to block_map_t, because the structure of ARC cache is totally different from block_map_t.

@qwe661234 qwe661234 force-pushed the baseline_JIT branch 2 times, most recently from 8970c95 to 881ac43 Compare June 3, 2023 03:12
@qwe661234 qwe661234 requested a review from jserv June 3, 2023 03:17
.vscode/settings.json Outdated Show resolved Hide resolved
Makefile Outdated Show resolved Hide resolved
src/codegen.c Outdated Show resolved Hide resolved
src/elfdef.h Outdated Show resolved Hide resolved
@qwe661234 qwe661234 force-pushed the baseline_JIT branch 2 times, most recently from 216c4bb to 212c470 Compare June 3, 2023 13:05
@qwe661234 qwe661234 requested a review from jserv June 3, 2023 13:11
@jserv
Copy link
Contributor

jserv commented Jun 3, 2023

The proposed changes aim to achieve the following objectives:

  1. Elimination of code duplication between emulate.c and codegen.c.
  2. Reuse of the RV32 interpreter implementation for the baseline JIT.

These refinements focus on improving code organization and minimizing duplication. By reusing the existing RV32 interpreter implementation, we can expedite the development of the JIT compiler while maintaining consistency between the interpreter and JIT modes of execution.

The new branch wip/jit lays the groundwork for the future development of a baseline JIT compiler. By decoupling the RV32 instructions, we create reusable implementation templates that can be leveraged for code generation in the JIT compiler. This decoupling enables straightforward and flexible code generation strategies, eliminating the need for code duplication between the interpreter and MIR-based JIT compiler.

Assuming the existence of a dedicated shell script capable of generating C-string operations for each RVOP entry in src/codegen.c from src/rv32_template.c, the following procedure can be followed:

  1. Enable the JIT compiler in the top-level configurations.
  2. Generate src/codegen.c from src/rv32_template.c using the aforementioned script.
  3. The file src/emulate.c includes the generated src/codegen.c for the JIT execution path.
  4. The runtime determines the execution path, whether through the interpreter or JIT compilation, based on heuristic algorithms or thresholds.

This pull request should be on top of branch wip/jit, and you will have to rebase it and rework.

@jserv jserv changed the base branch from master to wip/jit June 3, 2023 15:19
src/cache.c Outdated Show resolved Hide resolved
jserv

This comment was marked as duplicate.

Copy link
Contributor

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebase latest wip/jit branch rather than master branch.

src/compile.c Outdated Show resolved Hide resolved
src/compile.c Outdated Show resolved Hide resolved
Makefile Outdated Show resolved Hide resolved
src/compile.c Outdated Show resolved Hide resolved
src/cache.c Outdated Show resolved Hide resolved
src/riscv.c Outdated Show resolved Hide resolved
@qwe661234 qwe661234 force-pushed the baseline_JIT branch 4 times, most recently from 24354c0 to c2c72fb Compare June 11, 2023 09:13
src/compile.c Outdated Show resolved Hide resolved
@jserv
Copy link
Contributor

jserv commented Jun 12, 2023

It fails to build on macOS:

$ make  
Makefile:19: *** missing separator.  Stop.

System information:

$ make --version | head -1
GNU Make 3.81

src/compile.c Outdated Show resolved Hide resolved
src/riscv_private.h Outdated Show resolved Hide resolved
src/compile.c Show resolved Hide resolved
The baseline JIT compiler design involves tracing an EBB when its usage
frequency exceeds a predetermined threshold. We then utilize a code generator
to convert the instruction sequence into C code. The C code is subsequently
compiled using mir, and the resulting target machine code is stored in the
code cache for future utilization.

The primary objective of introducing the baseline JIT compiler is to enhance
the execution speed of RISC-V instructions with minimal modification. This
implementation requires three additional components: a code generator, mir
compiler, and code cache, while maintaining the original design of the interpreter.
Furthermore, this baseline JIT compiler serves as the foundational target
for future improvements.

|  Metric   |        master           |       baseline JIT       |Speedup |
|-----------+-------------------------+--------------------------+--------|
| CoreMark  |1352.843 (Iterations/Sec)|1740.881 (Iterations/Sec) | +28.6% |
| dhrystone |1146 DMIPS               |2368.33 DMIPS             | +106%  |
@qwe661234
Copy link
Collaborator Author

It fails to build on macOS:

$ make  
Makefile:19: *** missing separator.  Stop.

System information:

$ make --version | head -1
GNU Make 3.81

Solved

@qwe661234 qwe661234 closed this Jun 14, 2023
@qwe661234 qwe661234 reopened this Jun 14, 2023
@jserv
Copy link
Contributor

jserv commented Jun 14, 2023

Runtime failure on macOS/Arm64. Reproduce:

$ git clone https://github.com/sysprog21/rv32emu
$ cd rv32emu
$ gh pr checkout 135
$ make ENABLE_JIT=1
$ make check

Error messages:

Assertion failed: (cache->jitcode != MAP_FAILED), function cache_create, file cache.c, line 316.
Assertion failed: (cache->jitcode != MAP_FAILED), function cache_create, file cache.c, line 316.
Assertion failed: (cache->jitcode != MAP_FAILED), function cache_create, file cache.c, line 316.
Running hello.elf ... Failed.

@jserv jserv merged commit 608eb8e into sysprog21:wip/jit Jun 15, 2023
@jserv
Copy link
Contributor

jserv commented Jun 15, 2023

This preliminary work was integrated into wip/jit branch for sake of synchronization with latest master branch.
@qwe661234, You shall work on wip/jit branch for all JIT specific issues and submit pull requests on top of it.

jserv pushed a commit that referenced this pull request Jun 15, 2023
The baseline JIT compiler design involves tracing an EBB when its usage
frequency exceeds a predetermined threshold. We then utilize a code generator
to convert the instruction sequence into C code. The C code is subsequently
compiled using MIR, and the resulting target machine code is stored in the
code cache for future utilization.

The primary objective of introducing the baseline JIT compiler is to enhance
the execution speed of RISC-V instructions with minimal modification. This
implementation requires three additional components: a code generator, MIR
compiler, and code cache, while maintaining the original design of the interpreter.
Furthermore, this baseline JIT compiler serves as the foundational target
for future improvements.

|  Metric   |        master           |       baseline JIT       |Speedup |
|-----------+-------------------------+--------------------------+--------|
| CoreMark  |1352.843 (Iterations/Sec)|1740.881 (Iterations/Sec) | +28.6% |
| dhrystone |1146 DMIPS               |2368.33 DMIPS             | +106%  |

Known issue: this implementation does not work on Arm64 architecture.
jserv pushed a commit that referenced this pull request Jun 15, 2023
The baseline JIT compiler design involves tracing an EBB when its usage
frequency exceeds a predetermined threshold. We then utilize a code generator
to convert the instruction sequence into C code. The C code is subsequently
compiled using MIR, and the resulting target machine code is stored in the
code cache for future utilization.

The primary objective of introducing the baseline JIT compiler is to enhance
the execution speed of RISC-V instructions with minimal modification. This
implementation requires three additional components: a code generator, MIR
compiler, and code cache, while maintaining the original design of the interpreter.
Furthermore, this baseline JIT compiler serves as the foundational target
for future improvements.

|  Metric   |        master           |       baseline JIT       |Speedup |
|-----------+-------------------------+--------------------------+--------|
| CoreMark  |1352.843 (Iterations/Sec)|1740.881 (Iterations/Sec) | +28.6% |
| dhrystone |1146 DMIPS               |2368.33 DMIPS             | +106%  |

Known issue: this implementation does not work on Arm64 architecture.
jserv pushed a commit that referenced this pull request Jun 15, 2023
The baseline JIT compiler design involves tracing an EBB when its usage
frequency exceeds a predetermined threshold. We then utilize a code generator
to convert the instruction sequence into C code. The C code is subsequently
compiled using MIR, and the resulting target machine code is stored in the
code cache for future utilization.

The primary objective of introducing the baseline JIT compiler is to enhance
the execution speed of RISC-V instructions with minimal modification. This
implementation requires three additional components: a code generator, MIR
compiler, and code cache, while maintaining the original design of the interpreter.
Furthermore, this baseline JIT compiler serves as the foundational target
for future improvements.

|  Metric   |        master           |       baseline JIT       |Speedup |
|-----------+-------------------------+--------------------------+--------|
| CoreMark  |1352.843 (Iterations/Sec)|1740.881 (Iterations/Sec) | +28.6% |
| dhrystone |1146 DMIPS               |2368.33 DMIPS             | +106%  |

Known issue: this implementation does not work on Arm64 architecture.
qwe661234 added a commit to qwe661234/rv32emu that referenced this pull request Jun 27, 2023
The baseline JIT compiler design involves tracing an EBB when its usage
frequency exceeds a predetermined threshold. We then utilize a code generator
to convert the instruction sequence into C code. The C code is subsequently
compiled using MIR, and the resulting target machine code is stored in the
code cache for future utilization.

The primary objective of introducing the baseline JIT compiler is to enhance
the execution speed of RISC-V instructions with minimal modification. This
implementation requires three additional components: a code generator, MIR
compiler, and code cache, while maintaining the original design of the interpreter.
Furthermore, this baseline JIT compiler serves as the foundational target
for future improvements.

|  Metric   |        master           |       baseline JIT       |Speedup |
|-----------+-------------------------+--------------------------+--------|
| CoreMark  |1352.843 (Iterations/Sec)|1740.881 (Iterations/Sec) | +28.6% |
| dhrystone |1146 DMIPS               |2368.33 DMIPS             | +106%  |

Known issue: this implementation does not correctly work on Apple M1 MacOS.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants