Skip to content

Commit

Permalink
8277846: Implement fast-path for ASCII-compatible CharsetEncoders on …
Browse files Browse the repository at this point in the history
…ppc64

Backport-of: a5f2a58ba4ac25f4bd66f1f1f4c036a4f0024229
  • Loading branch information
TheRealMDoerr committed Jan 14, 2022
1 parent 061bf8f commit 3c279bd
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 32 deletions.
44 changes: 37 additions & 7 deletions src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp
Expand Up @@ -41,17 +41,18 @@
// Compress char[] to byte[] by compressing 16 bytes at once.
void C2_MacroAssembler::string_compress_16(Register src, Register dst, Register cnt,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5,
Label& Lfailure) {
Label& Lfailure, bool ascii) {

const Register tmp0 = R0;
const int byte_mask = ascii ? 0x7F : 0xFF;
assert_different_registers(src, dst, cnt, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5);
Label Lloop, Lslow;

// Check if cnt >= 8 (= 16 bytes)
lis(tmp1, 0xFF); // tmp1 = 0x00FF00FF00FF00FF
lis(tmp1, byte_mask); // tmp1 = 0x00FF00FF00FF00FF (non ascii case)
srwi_(tmp2, cnt, 3);
beq(CCR0, Lslow);
ori(tmp1, tmp1, 0xFF);
ori(tmp1, tmp1, byte_mask);
rldimi(tmp1, tmp1, 32, 0);
mtctr(tmp2);

Expand All @@ -67,7 +68,7 @@ void C2_MacroAssembler::string_compress_16(Register src, Register dst, Register
rldimi(tmp4, tmp4, 2*8, 2*8); // _4_6_7_7

andc_(tmp0, tmp0, tmp1);
bne(CCR0, Lfailure); // Not latin1.
bne(CCR0, Lfailure); // Not latin1/ascii.
addi(src, src, 16);

rlwimi(tmp3, tmp2, 0*8, 24, 31);// _____1_3
Expand All @@ -87,20 +88,49 @@ void C2_MacroAssembler::string_compress_16(Register src, Register dst, Register
}

// Compress char[] to byte[]. cnt must be positive int.
void C2_MacroAssembler::string_compress(Register src, Register dst, Register cnt, Register tmp, Label& Lfailure) {
void C2_MacroAssembler::string_compress(Register src, Register dst, Register cnt, Register tmp,
Label& Lfailure, bool ascii) {
const int byte_mask = ascii ? 0x7F : 0xFF;
Label Lloop;
mtctr(cnt);

bind(Lloop);
lhz(tmp, 0, src);
cmplwi(CCR0, tmp, 0xff);
bgt(CCR0, Lfailure); // Not latin1.
cmplwi(CCR0, tmp, byte_mask);
bgt(CCR0, Lfailure); // Not latin1/ascii.
addi(src, src, 2);
stb(tmp, 0, dst);
addi(dst, dst, 1);
bdnz(Lloop);
}

void C2_MacroAssembler::encode_iso_array(Register src, Register dst, Register len,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5,
Register result, bool ascii) {
Label Lslow, Lfailure1, Lfailure2, Ldone;

string_compress_16(src, dst, len, tmp1, tmp2, tmp3, tmp4, tmp5, Lfailure1, ascii);
rldicl_(result, len, 0, 64-3); // Remaining characters.
beq(CCR0, Ldone);
bind(Lslow);
string_compress(src, dst, result, tmp2, Lfailure2, ascii);
li(result, 0);
b(Ldone);

bind(Lfailure1);
mr(result, len);
mfctr(tmp1);
rldimi_(result, tmp1, 3, 0); // Remaining characters.
beq(CCR0, Ldone);
b(Lslow);

bind(Lfailure2);
mfctr(result); // Remaining characters.

bind(Ldone);
subf(result, result, len);
}

// Inflate byte[] to char[] by inflating 16 bytes at once.
void C2_MacroAssembler::string_inflate_16(Register src, Register dst, Register cnt,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5) {
Expand Down
10 changes: 8 additions & 2 deletions src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.hpp
Expand Up @@ -32,10 +32,16 @@
// Compress char[] to byte[] by compressing 16 bytes at once.
void string_compress_16(Register src, Register dst, Register cnt,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5,
Label& Lfailure);
Label& Lfailure, bool ascii = false);

// Compress char[] to byte[]. cnt must be positive int.
void string_compress(Register src, Register dst, Register cnt, Register tmp, Label& Lfailure);
void string_compress(Register src, Register dst, Register cnt, Register tmp,
Label& Lfailure, bool ascii = false);

// Encode UTF16 to ISO_8859_1 or ASCII. Return len on success or position of first mismatch.
void encode_iso_array(Register src, Register dst, Register len,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5,
Register result, bool ascii);

// Inflate byte[] to char[] by inflating 16 bytes at once.
void string_inflate_16(Register src, Register dst, Register cnt,
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/cpu/ppc/matcher_ppc.hpp
Expand Up @@ -157,6 +157,6 @@
}

// 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;

#endif // CPU_PPC_MATCHER_PPC_HPP
40 changes: 18 additions & 22 deletions src/hotspot/cpu/ppc/ppc.ad
Expand Up @@ -12798,30 +12798,26 @@ instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst r
effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
ins_cost(300);
format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
format %{ "Encode iso array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
ins_encode %{
Label Lslow, Lfailure1, Lfailure2, Ldone;
__ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
$tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1);
__ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters.
__ beq(CCR0, Ldone);
__ bind(Lslow);
__ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2);
__ li($result$$Register, 0);
__ b(Ldone);

__ bind(Lfailure1);
__ mr($result$$Register, $len$$Register);
__ mfctr($tmp1$$Register);
__ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters.
__ beq(CCR0, Ldone);
__ b(Lslow);

__ bind(Lfailure2);
__ mfctr($result$$Register); // Remaining characters.
__ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
$tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false);
%}
ins_pipe(pipe_class_default);
%}

__ bind(Ldone);
__ subf($result$$Register, $result$$Register, $len$$Register);
// encode char[] to byte[] in ASCII
instruct encode_ascii_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
predicate(((EncodeISOArrayNode*)n)->is_ascii());
match(Set result (EncodeISOArray src (Binary dst len)));
effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
ins_cost(300);
format %{ "Encode ascii array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
ins_encode %{
__ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register,
$tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, true);
%}
ins_pipe(pipe_class_default);
%}
Expand Down

1 comment on commit 3c279bd

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.