Skip to content

8309254: Implement fast-path for ASCII-compatible CharsetEncoders on RISC-V #14256

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

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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");
}

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/cpu/riscv/matcher_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
26 changes: 21 additions & 5 deletions src/hotspot/cpu/riscv/riscv_v.ad
Original file line number Diff line number Diff line change
Expand Up @@ -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);
%}
Expand All @@ -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 %{
Expand Down