From 61bb014a8692305c705a4cf0361e319275c35ca3 Mon Sep 17 00:00:00 2001 From: Dingli Zhang Date: Sat, 3 Jun 2023 02:27:18 +0000 Subject: [PATCH] 8309254: Implement fast-path for ASCII-compatible CharsetEncoders on RISC-V Reviewed-by: luhenry, yzhu, fyang, fjiang --- .../cpu/riscv/c2_MacroAssembler_riscv.cpp | 36 +++++++++++++------ .../cpu/riscv/c2_MacroAssembler_riscv.hpp | 2 +- src/hotspot/cpu/riscv/matcher_riscv.hpp | 2 +- src/hotspot/cpu/riscv/riscv_v.ad | 26 +++++++++++--- 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index b3483eca593c7..a45fe0538ea44 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -1521,26 +1521,39 @@ void C2_MacroAssembler::byte_array_inflate_v(Register src, Register dst, Registe // Compress char[] array to byte[]. // result: the array length if every element in array can be encoded; 0, otherwise. -void C2_MacroAssembler::char_array_compress_v(Register src, Register dst, Register len, Register result, Register tmp) { +void C2_MacroAssembler::char_array_compress_v(Register src, Register dst, Register len, + Register result, Register tmp) { Label done; - encode_iso_array_v(src, dst, len, result, tmp); + encode_iso_array_v(src, dst, len, result, tmp, false); beqz(len, done); mv(result, zr); bind(done); } -// result: the number of elements had been encoded. -void C2_MacroAssembler::encode_iso_array_v(Register src, Register dst, Register len, Register result, Register tmp) { - Label loop, DIFFERENCE, DONE; +// Intrinsic for +// +// - sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray +// return the number of characters copied. +// - java/lang/StringUTF16.compress +// return zero (0) if copy fails, otherwise 'len'. +// +// This version always returns the number of characters copied. A successful +// copy will complete with the post-condition: 'res' == 'len', while an +// unsuccessful copy will exit with the post-condition: 0 <= 'res' < 'len'. +// +// Clobbers: src, dst, len, result, t0 +void C2_MacroAssembler::encode_iso_array_v(Register src, Register dst, Register len, + Register result, Register tmp, bool ascii) { + Label loop, fail, done; BLOCK_COMMENT("encode_iso_array_v {"); mv(result, 0); bind(loop); - mv(tmp, 0xff); + mv(tmp, ascii ? 0x7f : 0xff); vsetvli(t0, len, Assembler::e16, Assembler::m2); vle16_v(v2, src); - // if element > 0xff, stop + vmsgtu_vx(v1, v2, tmp); vfirst_m(tmp, v1); vmsbf_m(v0, v1); @@ -1549,18 +1562,19 @@ void C2_MacroAssembler::encode_iso_array_v(Register src, Register dst, Register vncvt_x_x_w(v1, v2, Assembler::v0_t); vse8_v(v1, dst, Assembler::v0_t); - bgez(tmp, DIFFERENCE); + // fail if char > 0x7f/0xff + bgez(tmp, fail); add(result, result, t0); add(dst, dst, t0); sub(len, len, t0); shadd(src, t0, src, t0, 1); bnez(len, loop); - j(DONE); + j(done); - bind(DIFFERENCE); + bind(fail); add(result, result, tmp); - bind(DONE); + bind(done); BLOCK_COMMENT("} encode_iso_array_v"); } diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp index aabfb8504bdae..5e7a9ffa63ae2 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp @@ -175,7 +175,7 @@ void encode_iso_array_v(Register src, Register dst, Register len, Register result, - Register tmp); + Register tmp, bool ascii); void count_positives_v(Register ary, Register len, Register result, Register tmp); diff --git a/src/hotspot/cpu/riscv/matcher_riscv.hpp b/src/hotspot/cpu/riscv/matcher_riscv.hpp index ab3fca9b003cf..dc1432346f13b 100644 --- a/src/hotspot/cpu/riscv/matcher_riscv.hpp +++ b/src/hotspot/cpu/riscv/matcher_riscv.hpp @@ -159,7 +159,7 @@ } // Implements a variant of EncodeISOArrayNode that encode ASCII only - static const bool supports_encode_ascii_array = false; + static const bool supports_encode_ascii_array = true; // Some architecture needs a helper to check for alltrue vector static constexpr bool vectortest_needs_second_argument(bool is_alltrue, bool is_predicate) { diff --git a/src/hotspot/cpu/riscv/riscv_v.ad b/src/hotspot/cpu/riscv/riscv_v.ad index e8ea7accdf167..d29616002b812 100644 --- a/src/hotspot/cpu/riscv/riscv_v.ad +++ b/src/hotspot/cpu/riscv/riscv_v.ad @@ -2839,15 +2839,31 @@ instruct vstring_inflate(Universe dummy, iRegP_R10 src, iRegP_R11 dst, iRegI_R12 instruct vencode_iso_array(iRegP_R12 src, iRegP_R11 dst, iRegI_R13 len, iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0, iRegLNoSp tmp) %{ - predicate(UseRVV); + predicate(UseRVV && !((EncodeISOArrayNode*)n)->is_ascii()); + match(Set result (EncodeISOArray src (Binary dst len))); + effect(TEMP_DEF result, USE_KILL src, USE_KILL dst, USE_KILL len, + TEMP v0, TEMP v1, TEMP v2, TEMP v3, TEMP tmp); + + format %{ "Encode ISO array $src, $dst, $len -> $result # KILL $src, $dst, $len, $tmp, V0-V3" %} + ins_encode %{ + __ encode_iso_array_v($src$$Register, $dst$$Register, $len$$Register, + $result$$Register, $tmp$$Register, false /* ascii */); + %} + ins_pipe(pipe_class_memory); +%} + +instruct vencode_ascii_array(iRegP_R12 src, iRegP_R11 dst, iRegI_R13 len, iRegI_R10 result, + vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0, iRegLNoSp tmp) +%{ + predicate(UseRVV && ((EncodeISOArrayNode*)n)->is_ascii()); match(Set result (EncodeISOArray src (Binary dst len))); effect(TEMP_DEF result, USE_KILL src, USE_KILL dst, USE_KILL len, - TEMP v1, TEMP v2, TEMP v3, TEMP tmp, TEMP v0); + TEMP v0, TEMP v1, TEMP v2, TEMP v3, TEMP tmp); - format %{ "Encode array $src,$dst,$len -> $result" %} + format %{ "Encode ASCII array $src, $dst, $len -> $result # KILL $src, $dst, $len, $tmp, V0-V3" %} ins_encode %{ __ encode_iso_array_v($src$$Register, $dst$$Register, $len$$Register, - $result$$Register, $tmp$$Register); + $result$$Register, $tmp$$Register, true /* ascii */); %} ins_pipe(pipe_class_memory); %} @@ -2859,7 +2875,7 @@ instruct vstring_compress(iRegP_R12 src, iRegP_R11 dst, iRegI_R13 len, iRegI_R10 predicate(UseRVV); match(Set result (StrCompressedCopy src (Binary dst len))); effect(TEMP_DEF result, USE_KILL src, USE_KILL dst, USE_KILL len, - TEMP v1, TEMP v2, TEMP v3, TEMP tmp, TEMP v0); + TEMP v0, TEMP v1, TEMP v2, TEMP v3, TEMP tmp); format %{ "String Compress $src,$dst -> $result // KILL R11, R12, R13" %} ins_encode %{