[riscv-port] RFR: 8278322: riscv: Support RVC: compressed instructions
Xiaolin Zheng
xlinzheng at openjdk.java.net
Thu Dec 9 09:42:25 UTC 2021
On Tue, 7 Dec 2021 04:46:10 GMT, Xiaolin Zheng <xlinzheng at openjdk.org> wrote:
> Hi team,
>
> This patch support RISC-V RVC extension. It can introduce:
> * 21% code size reduction in template interpreter generated code
> * 20%~25% code size reduction in C1 generated code, evaluated by a common SpringBoot program
> * 15%~20% code size reduction in C2 generated code, evaluated by a common SpringBoot program
>
> In my observation, the code size footprint could be reduced to nearly a level of the AArch64 back-end. About the performance, there seems a stable ~0.7% performance improvement on SPECjbb2015 on one HiFive Unleashed board, considering the code density increase. I think the performance aspect might be a speculative behavior on different hardware implementations because C910's performance might be better than that, but HiFive Unleashed may be more general.
>
> Things about this patch:
> * If an instruction is compressible, then we will implicitly emit a 16-bit compressed instruction instead of the 32-bit instruction in Assembler.
> * About the `_nc` postfix of some of Assembler instructions: we know a bunch of places should be reserved for patching, where we cannot change them into compressed instructions. `_nc` is short for `not compressible` - with this, those instructions should keep their origin 4-byte form and remain uncompressed.
> * There are things not easy to compress like MachBranchNodes. Please see the comments in the code - currently this patch does not support this. We will support this improvement in patches coming afterward.
>
> The macros after their expansion might be like:
>
> void andr(Register Rd, Register Rs1, Register Rs2) {
> + {
> + Register src = noreg;
> + if (UseRVC && Rs1->is_compressed_valid() && Rs2->is_compressed_valid() &&
> + ((src = Rs1, Rs2 == Rd) || (src = Rs2, Rs1 == Rd))) {
> + and_c(Rd, src);
> + return;
> + }
> + }
> unsigned insn = 0;
> patch((address)&insn, 6, 0, 0b0110011);
> patch((address)&insn, 14, 12, 0b111);
> patch((address)&insn, 31, 25, 0b0000000);
> patch_reg((address)&insn, 7, Rd);
> patch_reg((address)&insn, 15, Rs1);
> patch_reg((address)&insn, 20, Rs2);
> emit(insn);
> };
>
>
> For further information, please see comments in `assembler_riscv_cext.hpp`.
>
> --
>
> This patch may need some time to acquire a review. I have been polishing this patch for quite a long time and it might seem stable under a bunch of full-tier tests and some tier1 jdk/hotspot jtreg tests. But I think we might mark it `experimental` at first, though it is turned on by default. [The original patch](https://github.com/riscv-collab/riscv-openjdk/pull/7), just for reference, might be quite different from the current one.
>
> I am pleased to receive any suggestion.
>
> Thanks,
> Xiaolin
Thank you for your explanation, Felix. :-) Seems we finally reach a consensus now.
> I guess maybe the best places to do this would be C1 and C2.
I think I could get your meaning this time.
> I think we can then further consider the "CompressibleRegion" solution suggested by Yadong.
Yadong's plan works for me. I am quite in favor of his strategy.
I will implement this approach ASAP. Maybe next week I might open another PR including this implementation and the definition of compressed instructions presented in the `assembler_riscv_cext.hpp` part for a better review. I wonder if this is okay for you.
I am going to close this PR, save it for future reference, and may open another PR and start from scratch. Before that, just one more question: would you mind my keeping definitions of C-Ext instructions into one separate file like `assembler_riscv_cext.hpp`, as the current implementation? I think we might better keep different RISCV extensions into different files.
-------------
PR: https://git.openjdk.java.net/riscv-port/pull/24
More information about the riscv-port-dev
mailing list