[riscv-port] RFR: 8278322: riscv: Support RVC: compressed instructions

Xiaolin Zheng xlinzheng at openjdk.java.net
Tue Dec 7 04:55:48 UTC 2021


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 (UseCExt && Rs1->is_compressed_valid() && Rs2->is_compressed_valid() &&
        ((src = Rs1, Rs2 == Rd) || (src = Rs2, Rs1 == Rd))) {
      and_c(Rd, Rs2);
      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 polished 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

-------------

Commit messages:
 - Support RVC: compressed instructions

Changes: https://git.openjdk.java.net/riscv-port/pull/24/files
 Webrev: https://webrevs.openjdk.java.net/?repo=riscv-port&pr=24&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8278322
  Stats: 1891 lines in 29 files changed: 1401 ins; 81 del; 409 mod
  Patch: https://git.openjdk.java.net/riscv-port/pull/24.diff
  Fetch: git fetch https://git.openjdk.java.net/riscv-port pull/24/head:pull/24

PR: https://git.openjdk.java.net/riscv-port/pull/24


More information about the riscv-port-dev mailing list