RFR: 8302453: RISCV: Add support for small width vector operations
Fei Yang
fyang at openjdk.org
Tue Feb 14 11:42:46 UTC 2023
On Tue, 14 Feb 2023 10:23:29 GMT, Gui Cao <gcao at openjdk.org> wrote:
> HI,
>
> We have added support for small width vector operations, please take a look and have some reviews. Thanks a lot.
>
> #### The first part modifies Matcher::max_vector_size, Matcher::min_vector_size
> In the process of using qemu to open RVV test vector api, currently if you set RVV vlen and java vector api's VectorSpecies are not equal, the instruction set related to RVV will not be used, and the scalar simulation implementation is used. For example, if RVV vlen = 256, the java program will execute normally when the VectorSpecies of the java vector api is SPECIES_256, and if you look at the java compilation log, the compilation log will also show that the current program does use the RVV-related instruction set. However, when RVV vlen = 256 and the VectorSpecies of the java vector api is SPECIES_64 or SPECIES_128, the java program executes normally, but no RVV-related instructions are generated in the compilation log. The reason for this is that Matcher::vector_size_supported function returns false during vectorization compilation, and thus no vectorization compilation is performed. This function is implemented as follows.
>
> static const bool vector_size_supported(const BasicType bt, int size) {
> return (Matcher::max_vector_size(bt) >= size &&
> Matcher::min_vector_size(bt) <= size);
> }
>
> The maximum and minimum values are implemented in the individual architecture AD files, and the current RISC-V implementation is as follows.
>
> // Vector width in bytes.
> const int Matcher::vector_width_in_bytes(BasicType bt) {
> if (UseRVV) {
> // The MaxVectorSize should have been set by detecting RVV max vector register size when check UseRVV.
> // MaxVectorSize == VM_Version::_initial_vector_length
> return MaxVectorSize;
> }
> return 0;
> }
> // Limits on vector size (number of elements) loaded into vector.
> const int Matcher::max_vector_size(const BasicType bt) {
> return vector_width_in_bytes(bt) / type2aelembytes(bt);
> }
> const int Matcher::min_vector_size(const BasicType bt) {
> return max_vector_size(bt);
> }
>
> In the above implementation, we can see that Matcher::max_vector_size, Matcher::min_vector_size are calculated to the maximum value (i.e. the maximum number of elements of that type that can be processed by the current vector register at one time). When RVV vlen and java vector api's VectorSpecies are not equal, the number of elements processed is not the maximum, so Matcher::vector_size_supported returns false during vectorization compilation, resulting in no vectorization compilation and no use of RVV instruction set optimization.
>
> ##### The second part modifies LoadVector, StoreVector node implementation
> java vector api of VectorSpecies actually indicates a vectorization operation memory size, before the operation need to load the data from memory to the register, after the operation need to store the data in the register to memory. However, the current RISC-V operation on vector register data loading and storage is based on the maximum register width, assuming RVV vlen = 256, for loading, it means that all 256 bits of data are loaded into the vector register, for storage, it means that all 256 bits of data in the register are stored in memory, if the java vector api VectorSpecies is SPECIES_128, if the actual data that needs to be stored at this time is 128 bits, then it stores 128 more bits of data, which also destroys other data.
>
> ### Testing:
> Let me share some of the testing results carried out on qemu with UseRVV:
> - [ ] Tier1-3 tests (release)
> - [ ] Tier4 test in progress (release)
Hi, can you tell us the tests which can benefit from this change? I think it will be easier for people to understand if you can show the JIT assembly code at the same time. Thanks.
-------------
PR: https://git.openjdk.org/jdk/pull/12553
More information about the hotspot-compiler-dev
mailing list