Skip to content
Draft
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
4 changes: 2 additions & 2 deletions src/hotspot/cpu/aarch64/aarch64.ad
Original file line number Diff line number Diff line change
Expand Up @@ -14216,7 +14216,7 @@ instruct clearArray_reg_reg_immL0(iRegL_R11 cnt, iRegP_R10 base, immL0 zero, Uni

instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, iRegL val, Universe dummy, rFlagsReg cr)
%{
predicate(((ClearArrayNode*)n)->word_copy_only());
predicate(((ClearArrayNode*)n)->requires_word_fill());
match(Set dummy (ClearArray (Binary cnt base) val));
effect(USE_KILL cnt, USE_KILL base, KILL cr);

Expand All @@ -14234,7 +14234,7 @@ instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, iRegL_R11 temp, immL0 zero
%{
predicate((uint64_t)n->in(2)->in(1)->get_long()
< (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)
&& !((ClearArrayNode*)n)->word_copy_only());
&& !((ClearArrayNode*)n)->requires_word_fill());
match(Set dummy (ClearArray (Binary cnt base) zero));
effect(TEMP temp, USE_KILL base, KILL cr);

Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/cpu/ppc/ppc.ad
Original file line number Diff line number Diff line change
Expand Up @@ -11186,8 +11186,8 @@ instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, immL_0 zero, Univer
%}

// Clear-array with dynamic array length and non-zero value.
instruct inlineCallClearArrayWordCopy(rarg1RegL cnt, rarg2RegP base, iRegLdst val, Universe dummy, regCTR ctr) %{
predicate(((ClearArrayNode*)n)->word_copy_only());
instruct inlineCallClearArrayWordFill(rarg1RegL cnt, rarg2RegP base, iRegLdst val, Universe dummy, regCTR ctr) %{
predicate(((ClearArrayNode*)n)->requires_word_fill());
match(Set dummy (ClearArray (Binary cnt base) val));
effect(USE_KILL base, KILL ctr);
ins_cost(8 * MEMORY_REF_COST);
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/cpu/riscv/riscv.ad
Original file line number Diff line number Diff line change
Expand Up @@ -11277,7 +11277,7 @@ instruct clearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, iRegL val,
Universe dummy)
%{
// temp registers must match the one used in StubGenerator::generate_zero_blocks()
predicate(((ClearArrayNode*)n)->word_copy_only());
predicate(((ClearArrayNode*)n)->requires_word_fill());
match(Set dummy (ClearArray (Binary cnt base) val));
effect(USE_KILL cnt, USE_KILL base, TEMP tmp1, TEMP tmp2, KILL cr);

Expand All @@ -11296,7 +11296,7 @@ instruct clearArray_imm_reg(immL cnt, iRegP_R28 base, immL0 zero, Universe dummy
predicate(!UseRVV
&& (uint64_t)n->in(2)->in(1)->get_long()
< (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)
&& !((ClearArrayNode*)n)->word_copy_only());
&& !((ClearArrayNode*)n)->requires_word_fill());
match(Set dummy (ClearArray (Binary cnt base) zero));
effect(USE_KILL base, KILL cr);

Expand Down
28 changes: 18 additions & 10 deletions src/hotspot/cpu/x86/macroAssembler_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6506,11 +6506,12 @@ void MacroAssembler::remove_frame(int initial_framesize, bool needs_stack_repair

#ifdef COMPILER2

// clear memory of size 'cnt' qwords, starting at 'base' using XMM/YMM/ZMM registers
void MacroAssembler::xmm_clear_mem(Register base, Register cnt, Register val, XMMRegister xtmp, KRegister mask) {
// Fill memory with 'val', for 'cnt' qwords starting at 'base', using XMM/YMM/ZMM registers.
void MacroAssembler::xmm_fill_mem(Register base, Register cnt, Register val, XMMRegister xtmp, KRegister mask) {
// cnt - number of qwords (8-byte words).
// base - start address, qword aligned.
Label L_zero_64_bytes, L_loop, L_sloop, L_tail, L_end;
// val - qword pattern to fill.
Label L_fill_64_bytes, L_loop, L_sloop, L_tail, L_end;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There are still some references in the .ad file to L_zero_64_bytes that should also be updated to L_fill_64_bytes.

bool use64byteVector = (MaxVectorSize == 64) && (CopyAVX3Threshold == 0);
if (use64byteVector) {
evpbroadcastq(xtmp, val, AVX_512bit);
Expand All @@ -6522,7 +6523,7 @@ void MacroAssembler::xmm_clear_mem(Register base, Register cnt, Register val, XM
movdq(xtmp, val);
punpcklqdq(xtmp, xtmp);
}
jmp(L_zero_64_bytes);
jmp(L_fill_64_bytes);

BIND(L_loop);
if (MaxVectorSize >= 32) {
Expand All @@ -6535,11 +6536,11 @@ void MacroAssembler::xmm_clear_mem(Register base, Register cnt, Register val, XM
}
addptr(base, 64);

BIND(L_zero_64_bytes);
BIND(L_fill_64_bytes);
subptr(cnt, 8);
jccb(Assembler::greaterEqual, L_loop);

// Copy trailing 64 bytes
// Fill trailing 64 bytes.
if (use64byteVector) {
addptr(cnt, 8);
jccb(Assembler::equal, L_end);
Expand Down Expand Up @@ -6665,10 +6666,12 @@ void MacroAssembler::clear_mem(Register base, int cnt, Register rtmp, XMMRegiste
}

void MacroAssembler::clear_mem(Register base, Register cnt, Register val, XMMRegister xtmp,
bool is_large, bool word_copy_only, KRegister mask) {
bool is_large, bool requires_word_fill, KRegister mask) {
// cnt - number of qwords (8-byte words).
// base - start address, qword aligned.
// is_large - if optimizers know cnt is larger than InitArrayShortSize
// requires_word_fill - if true, val contains the qword pattern to fill; if
// false, val is scratch and this method creates zero
assert(base==rdi, "base register must be edi for rep stos");
assert(val==rax, "val register must be eax for rep stos");
assert(cnt==rcx, "cnt register must be ecx for rep stos");
Expand All @@ -6677,6 +6680,10 @@ void MacroAssembler::clear_mem(Register base, Register cnt, Register val, XMMReg

Label DONE;

if (!requires_word_fill) {
xorptr(val, val);
}

if (!is_large) {
Label LOOP, LONG;
cmpptr(cnt, InitArrayShortSize/BytesPerLong);
Expand All @@ -6695,12 +6702,13 @@ void MacroAssembler::clear_mem(Register base, Register cnt, Register val, XMMReg
BIND(LONG);
}

// Use longer rep-prefixed ops for non-small counts:
if (UseFastStosb && !word_copy_only) {
// Use longer rep-prefixed ops for non-small counts. rep stosb is valid only
// for zeroing; an arbitrary qword pattern must be copied in full.
if (UseFastStosb && !requires_word_fill) {
shlptr(cnt, 3); // convert to number of bytes
rep_stosb();
} else if (UseXMMForObjInit) {
xmm_clear_mem(base, cnt, val, xtmp, mask);
xmm_fill_mem(base, cnt, val, xtmp, mask);
} else {
rep_stos();
}
Expand Down
11 changes: 6 additions & 5 deletions src/hotspot/cpu/x86/macroAssembler_x86.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1970,15 +1970,16 @@ class MacroAssembler: public Assembler {
// Inline type specific methods
#include "asm/macroAssembler_common.hpp"

// clear memory of size 'cnt' qwords, starting at 'base';
// if 'is_large' is set, do not try to produce short loop
void clear_mem(Register base, Register cnt, Register val, XMMRegister xtmp, bool is_large, bool word_copy_only, KRegister mask=knoreg);
// Clear or fill 'cnt' qwords starting at 'base'. If 'requires_word_fill' is
// set, use 'val' as the fill value; otherwise, create zero in 'val'. If
// 'is_large' is set, do not try to produce a short loop.
void clear_mem(Register base, Register cnt, Register val, XMMRegister xtmp, bool is_large, bool requires_word_fill, KRegister mask=knoreg);

// clear memory initialization sequence for constant size;
void clear_mem(Register base, int cnt, Register rtmp, XMMRegister xtmp, KRegister mask=knoreg);

// clear memory of size 'cnt' qwords, starting at 'base' using XMM/YMM registers
void xmm_clear_mem(Register base, Register cnt, Register rtmp, XMMRegister xtmp, KRegister mask=knoreg);
// Fill memory with 'val', for 'cnt' qwords starting at 'base', using XMM/YMM/ZMM registers.
void xmm_fill_mem(Register base, Register cnt, Register val, XMMRegister xtmp, KRegister mask=knoreg);

// Fill primitive arrays
void generate_fill(BasicType t, bool aligned,
Expand Down
Loading