-
-
Notifications
You must be signed in to change notification settings - Fork 89
Add RISC-V JIT backend #5002
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
Merged
Merged
Add RISC-V JIT backend #5002
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This commit adds minimalistic scaffold for `test_runner.py`. Most tests do not pass because we haven't implemented the assembler yer. Test: ./pytest.py rpython/jit/backend/riscv/test/test_runner.py
This commit adds essential build blocks (e.g. assembler, opassembler, regalloc)
to compile and run our first loop.
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_compile_linear_loop
This commit supports greater range of integer immediates (64-bit).
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_compile_linear_float_loop
This commit adds support for int_is_true, int_neg, int_invert, and int_is_zero.
This commit also passes test_int_operations.
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_int_operations
This commit adds supports to cast_int_to_float and cast_float_to_int.
This commit also passes test_float_operations.
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_float_operations
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py -k test_same_as
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_cast_int_to_ptr
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_cast_ptr_to_int
Progress: 27/156
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_unused_result_int
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_unused_result_float
Progress: 29/156
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_passing_guards
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_failing_guards
As a side-effect, the following test cases pass as well:
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_integers_and_guards2
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_integers_and_guards2_x
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_integers_and_guards
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_integers_and_guards_x
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_integers_and_guards_uint
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_integers_and_guards_uint_x
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_floats_and_guards
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_floats_and_guards_x
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_nan_and_infinity
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_guards_nongc
Progress: 46/156
This commit converts a integer comparison operation followed by a `guard_true`
or `guard_false` operation into a `BLT/BGE/BEQ/BNE` instruction.
Before this commit, int_le + guard_true is lowered into:
slt x1, x2, x3
bne x1, zero, cont
ebreak # bail out (to be patched)
cont:
After this commit, it can be converted into:
blt x2, x3, cont
ebreak # bail out (to be patched)
cont:
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_integers_and_guards
Test: test_zero_array
This commit adds `enter_portal_frame`/`leave_portal_frame`. These ops are needed by `test_basic.py`. It seems that implementing these two as no-op should be fine.
This commit adds support for `keepalive` op. We need this op to pass `test_recursive.py`.
This commit adds shadow stack header/footer to
`_call_header`/`_call_footer`.
Test: pytest.py rpython/jit/backend/riscv/test/test_zrpy_gc.py
-k test_compile_framework_2
pytest.py rpython/jit/backend/riscv/test/test_zrpy_gc.py
-k test_compile_framework_3
pytest.py rpython/jit/backend/riscv/test/test_zrpy_gc.py
-k test_compile_framework_4
Test: pytest.py rpython/jit/backend/riscv/test/test_zrpy_gc.py -v
# Need to `return False` in `can_use_nursery_malloc2`
This commit adds support for `call_malloc_nursery`, `call_malloc_nursery_varsize_frame`, `call_malloc_nursery_varsize` and `nursery_ptr_increment`. These four ops are necessary to pass `test_zrpy_gc.py` when malloc inlining is enabled. Test: pytest.py rpython/jit/backend/riscv/test/test_zrpy_gc.py
This commit adds passing `test_ztranslation_basic`, `test_ztranslation_call_assembler`, and `test_ztranslation_jit_stats`.
This commit changes how we load large integer immediates
(`imm < -SINT32_MIN or imm > SINT32_MAX`) or float immediates.
For large integer immediates, instead of building a full 64-bit integer
with a sequence of `lui + addiw + slli + addi` (up to 8 instructions),
we simply emit `auipc + ld` when the immediate can't be represented as a
32-bit signed integer. For 32-bit signed integer, we continue using
`lui + addiw`.
For float immediates, instead of saving the immediate value in
`MachineDataBlockWrapper`, loading address with `load_int_imm`, and
loading the final float value with a `load_float`, we emit the float
immediate in the constant pool and emit a pc-relative `load_float`.
This saves a word for address and two instructions to load address.
This also avoids pointer chasing.
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_int_operations
Test: pytest.py rpython/jit/backend/riscv/test/test_runner.py \
-k test_float_operations
This commit adds support for large frame slot offsets. Before this commit, the code generator assumes the frame slot offsets is always addressable with signed 12-bit immediate. But, it turns out 12-bit is not enough. `lib_python_tests.py` `test_tarfile` triggers the assertion in the code generator. This commit fixes the problem by emitting `load_imm + ADD` when the immediate is too large for `ADDI`. Test: pypy2.7 testrunner/lib_python_tests.py -v -k test_tarfile
This commit skips several micronumpy test cases that encode extra bits in the significand bits of NaN and/or check the signbit of NaN. RISC-V ISA doesn't preserve the NaN payload bits. Many float instructions may canonicalize NaN into the positive canonical NaN. Thus, these tests don't work in RISC-V.
This commit swaps the order of `x0` and `x10` in JITFrame. In the RISC-V calling convention, the return register is `x10`. However, some data structure (e.g. `AbstractFailDescr`) assumes the returned value being stored to the offset 0. This commit swaps the order so that we can avoid the confusion.
The ResOperation order of `%(align_check)s` and `guard_not_invalidated(descr=...)` in the RISC-V backend is different from the order of other backends. This commit works around the test by using a different "expected" sequence for RISC-V. Note: There is no observable performance difference between `logical_xor` and `logical_and` (on SiFive Unmatched), thus we should be fine. time reduce.logical_xor: 8.49118113518 time reduce.logical_and: 7.69018793106 Test: python testrunner/pypyjit_tests.py -v -k test_reduce_logical_and
|
Thanks. The benchmark results are promising. CI checks are passing. I would lean towards merging this as-is and then, if there are some regressions on other platforms, fixing where needed. |
|
Thanks @loganchien let's put this in. |
|
@loganchien thank you so much for your work! This is really amazing! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This pull request adds a RISC-V JIT backend. This backend targets RV64IMAFD.
The RISC-V backend implementation is quite complete now:
qemu-user-staticwith a Ubuntu 24.04 RISC-V root file system.Please check
rpython/doc/riscv.rstfor the instructions to cross-compile PyPy RISC-V JIT.