Skip to content

Commit 6d9ece7

Browse files
committed
8351949: RISC-V: Cleanup and enable store-load peephole for membars
Reviewed-by: fyang, fjiang, mli
1 parent 97ed536 commit 6d9ece7

File tree

4 files changed

+120
-76
lines changed

4 files changed

+120
-76
lines changed

src/hotspot/cpu/riscv/assembler_riscv.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ class Assembler : public AbstractAssembler {
815815
emit(insn);
816816
}
817817

818-
public:
818+
protected:
819819

820820
enum barrier {
821821
i = 0b1000, o = 0b0100, r = 0b0010, w = 0b0001,
@@ -846,6 +846,8 @@ class Assembler : public AbstractAssembler {
846846
emit(insn);
847847
}
848848

849+
public:
850+
849851
#define INSN(NAME, op, funct3, funct7) \
850852
void NAME() { \
851853
unsigned insn = 0; \

src/hotspot/cpu/riscv/macroAssembler_riscv.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ void MacroAssembler::set_membar_kind(address addr, uint32_t order_kind) {
183183
Assembler::sd_instr(membar, insn);
184184
}
185185

186-
187186
static void pass_arg0(MacroAssembler* masm, Register arg) {
188187
if (c_rarg0 != arg) {
189188
masm->mv(c_rarg0, arg);
@@ -3556,6 +3555,14 @@ void MacroAssembler::lookup_virtual_method(Register recv_klass,
35563555
}
35573556

35583557
void MacroAssembler::membar(uint32_t order_constraint) {
3558+
if (UseZtso && ((order_constraint & StoreLoad) != StoreLoad)) {
3559+
// TSO allows for stores to be reordered after loads. When the compiler
3560+
// generates a fence to disallow that, we are required to generate the
3561+
// fence for correctness.
3562+
BLOCK_COMMENT("elided tso membar");
3563+
return;
3564+
}
3565+
35593566
address prev = pc() - MacroAssembler::instruction_size;
35603567
address last = code()->last_insn();
35613568

@@ -3564,15 +3571,14 @@ void MacroAssembler::membar(uint32_t order_constraint) {
35643571
// can do this simply by ORing them together.
35653572
set_membar_kind(prev, get_membar_kind(prev) | order_constraint);
35663573
BLOCK_COMMENT("merged membar");
3567-
} else {
3568-
code()->set_last_insn(pc());
3569-
3570-
uint32_t predecessor = 0;
3571-
uint32_t successor = 0;
3572-
3573-
membar_mask_to_pred_succ(order_constraint, predecessor, successor);
3574-
fence(predecessor, successor);
3574+
return;
35753575
}
3576+
3577+
code()->set_last_insn(pc());
3578+
uint32_t predecessor = 0;
3579+
uint32_t successor = 0;
3580+
membar_mask_to_pred_succ(order_constraint, predecessor, successor);
3581+
fence(predecessor, successor);
35763582
}
35773583

35783584
void MacroAssembler::cmodx_fence() {

src/hotspot/cpu/riscv/macroAssembler_riscv.hpp

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -417,15 +417,17 @@ class MacroAssembler: public Assembler {
417417
// We used four bit to indicate the read and write bits in the predecessors and successors,
418418
// and extended i for r, o for w if UseConservativeFence enabled.
419419
enum Membar_mask_bits {
420-
StoreStore = 0b0101, // (pred = ow + succ = ow)
421-
LoadStore = 0b1001, // (pred = ir + succ = ow)
422-
StoreLoad = 0b0110, // (pred = ow + succ = ir)
423-
LoadLoad = 0b1010, // (pred = ir + succ = ir)
424-
AnyAny = LoadStore | StoreLoad // (pred = iorw + succ = iorw)
420+
StoreStore = 0b0101, // (pred = w + succ = w)
421+
LoadStore = 0b1001, // (pred = r + succ = w)
422+
StoreLoad = 0b0110, // (pred = w + succ = r)
423+
LoadLoad = 0b1010, // (pred = r + succ = r)
424+
AnyAny = LoadStore | StoreLoad // (pred = rw + succ = rw)
425425
};
426426

427427
void membar(uint32_t order_constraint);
428428

429+
private:
430+
429431
static void membar_mask_to_pred_succ(uint32_t order_constraint,
430432
uint32_t& predecessor, uint32_t& successor) {
431433
predecessor = (order_constraint >> 2) & 0x3;
@@ -437,33 +439,21 @@ class MacroAssembler: public Assembler {
437439
// 11(rw)-> 1111(iorw)
438440
if (UseConservativeFence) {
439441
predecessor |= predecessor << 2;
440-
successor |= successor << 2;
442+
successor |= successor << 2;
441443
}
442444
}
443445

444446
static int pred_succ_to_membar_mask(uint32_t predecessor, uint32_t successor) {
445447
return ((predecessor & 0x3) << 2) | (successor & 0x3);
446448
}
447449

448-
void fence(uint32_t predecessor, uint32_t successor) {
449-
if (UseZtso) {
450-
if ((pred_succ_to_membar_mask(predecessor, successor) & StoreLoad) == StoreLoad) {
451-
// TSO allows for stores to be reordered after loads. When the compiler
452-
// generates a fence to disallow that, we are required to generate the
453-
// fence for correctness.
454-
Assembler::fence(predecessor, successor);
455-
} else {
456-
// TSO guarantees other fences already.
457-
}
458-
} else {
459-
// always generate fence for RVWMO
460-
Assembler::fence(predecessor, successor);
461-
}
462-
}
450+
public:
463451

464452
void cmodx_fence();
465453

466454
void pause() {
455+
// Zihintpause
456+
// PAUSE is encoded as a FENCE instruction with pred=W, succ=0, fm=0, rd=x0, and rs1=x0.
467457
Assembler::fence(w, 0);
468458
}
469459

src/hotspot/cpu/riscv/riscv.ad

Lines changed: 91 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4397,6 +4397,12 @@ pipe_class pipe_slow()
43974397
LDST : MEM;
43984398
%}
43994399

4400+
// The real do-nothing guy
4401+
pipe_class real_empty()
4402+
%{
4403+
instruction_count(0);
4404+
%}
4405+
44004406
// Empty pipeline class
44014407
pipe_class pipe_class_empty()
44024408
%{
@@ -7902,113 +7908,153 @@ instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{
79027908
// ============================================================================
79037909
// MemBar Instruction
79047910

7905-
instruct load_fence() %{
7911+
// RVTSO
7912+
7913+
instruct unnecessary_membar_rvtso() %{
7914+
predicate(UseZtso);
79067915
match(LoadFence);
7907-
ins_cost(ALU_COST);
7916+
match(StoreFence);
7917+
match(StoreStoreFence);
7918+
match(MemBarAcquire);
7919+
match(MemBarRelease);
7920+
match(MemBarStoreStore);
7921+
match(MemBarAcquireLock);
7922+
match(MemBarReleaseLock);
79087923

7909-
format %{ "#@load_fence" %}
7924+
ins_cost(0);
7925+
7926+
size(0);
79107927

7928+
format %{ "#@unnecessary_membar_rvtso elided/tso (empty encoding)" %}
79117929
ins_encode %{
7912-
__ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
7930+
__ block_comment("unnecessary_membar_rvtso");
79137931
%}
7914-
ins_pipe(pipe_serial);
7932+
ins_pipe(real_empty);
79157933
%}
79167934

7917-
instruct membar_acquire() %{
7918-
match(MemBarAcquire);
7919-
ins_cost(ALU_COST);
7935+
instruct membar_volatile_rvtso() %{
7936+
predicate(UseZtso);
7937+
match(MemBarVolatile);
7938+
ins_cost(VOLATILE_REF_COST);
79207939

7921-
format %{ "#@membar_acquire\n\t"
7922-
"fence ir iorw" %}
7940+
format %{ "#@membar_volatile_rvtso\n\t"
7941+
"fence w, r"%}
79237942

79247943
ins_encode %{
7925-
__ block_comment("membar_acquire");
7926-
__ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
7944+
__ block_comment("membar_volatile_rvtso");
7945+
__ membar(MacroAssembler::StoreLoad);
79277946
%}
79287947

7929-
ins_pipe(pipe_serial);
7948+
ins_pipe(pipe_slow);
79307949
%}
79317950

7932-
instruct membar_acquire_lock() %{
7933-
match(MemBarAcquireLock);
7951+
instruct unnecessary_membar_volatile_rvtso() %{
7952+
predicate(UseZtso && Matcher::post_store_load_barrier(n));
7953+
match(MemBarVolatile);
79347954
ins_cost(0);
79357955

7936-
format %{ "#@membar_acquire_lock (elided)" %}
7937-
7956+
size(0);
7957+
7958+
format %{ "#@unnecessary_membar_volatile_rvtso (unnecessary so empty encoding)" %}
79387959
ins_encode %{
7939-
__ block_comment("membar_acquire_lock (elided)");
7960+
__ block_comment("unnecessary_membar_volatile_rvtso");
79407961
%}
7941-
7942-
ins_pipe(pipe_serial);
7962+
ins_pipe(real_empty);
79437963
%}
79447964

7945-
instruct store_fence() %{
7946-
match(StoreFence);
7947-
ins_cost(ALU_COST);
7965+
// RVWMO
7966+
7967+
instruct membar_aqcuire_rvwmo() %{
7968+
predicate(!UseZtso);
7969+
match(LoadFence);
7970+
match(MemBarAcquire);
7971+
ins_cost(VOLATILE_REF_COST);
79487972

7949-
format %{ "#@store_fence" %}
7973+
format %{ "#@membar_aqcuire_rvwmo\n\t"
7974+
"fence r, rw" %}
79507975

79517976
ins_encode %{
7952-
__ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore);
7977+
__ block_comment("membar_aqcuire_rvwmo");
7978+
__ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
79537979
%}
79547980
ins_pipe(pipe_serial);
79557981
%}
79567982

7957-
instruct membar_release() %{
7983+
instruct membar_release_rvwmo() %{
7984+
predicate(!UseZtso);
7985+
match(StoreFence);
79587986
match(MemBarRelease);
7959-
ins_cost(ALU_COST);
7987+
ins_cost(VOLATILE_REF_COST);
79607988

7961-
format %{ "#@membar_release\n\t"
7962-
"fence iorw ow" %}
7989+
format %{ "#@membar_release_rvwmo\n\t"
7990+
"fence rw, w" %}
79637991

79647992
ins_encode %{
7965-
__ block_comment("membar_release");
7993+
__ block_comment("membar_release_rvwmo");
79667994
__ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore);
79677995
%}
79687996
ins_pipe(pipe_serial);
79697997
%}
79707998

7971-
instruct membar_storestore() %{
7999+
instruct membar_storestore_rvwmo() %{
8000+
predicate(!UseZtso);
79728001
match(MemBarStoreStore);
79738002
match(StoreStoreFence);
7974-
ins_cost(ALU_COST);
8003+
ins_cost(VOLATILE_REF_COST);
79758004

7976-
format %{ "MEMBAR-store-store\t#@membar_storestore" %}
8005+
format %{ "#@membar_storestore_rvwmo\n\t"
8006+
"fence w, w" %}
79778007

79788008
ins_encode %{
79798009
__ membar(MacroAssembler::StoreStore);
79808010
%}
79818011
ins_pipe(pipe_serial);
79828012
%}
79838013

7984-
instruct membar_release_lock() %{
7985-
match(MemBarReleaseLock);
7986-
ins_cost(0);
8014+
instruct membar_volatile_rvwmo() %{
8015+
predicate(!UseZtso);
8016+
match(MemBarVolatile);
8017+
ins_cost(VOLATILE_REF_COST);
79878018

7988-
format %{ "#@membar_release_lock (elided)" %}
8019+
format %{ "#@membar_volatile_rvwmo\n\t"
8020+
"fence w, r"%}
79898021

79908022
ins_encode %{
7991-
__ block_comment("membar_release_lock (elided)");
8023+
__ block_comment("membar_volatile_rvwmo");
8024+
__ membar(MacroAssembler::StoreLoad);
79928025
%}
79938026

79948027
ins_pipe(pipe_serial);
79958028
%}
79968029

7997-
instruct membar_volatile() %{
7998-
match(MemBarVolatile);
7999-
ins_cost(ALU_COST);
8030+
instruct membar_lock_rvwmo() %{
8031+
predicate(!UseZtso);
8032+
match(MemBarAcquireLock);
8033+
match(MemBarReleaseLock);
8034+
ins_cost(0);
80008035

8001-
format %{ "#@membar_volatile\n\t"
8002-
"fence iorw iorw"%}
8036+
format %{ "#@membar_lock_rvwmo (elided)" %}
80038037

80048038
ins_encode %{
8005-
__ block_comment("membar_volatile");
8006-
__ membar(MacroAssembler::StoreLoad);
8039+
__ block_comment("membar_lock_rvwmo (elided)");
80078040
%}
80088041

80098042
ins_pipe(pipe_serial);
80108043
%}
80118044

8045+
instruct unnecessary_membar_volatile_rvwmo() %{
8046+
predicate(!UseZtso && Matcher::post_store_load_barrier(n));
8047+
match(MemBarVolatile);
8048+
ins_cost(0);
8049+
8050+
size(0);
8051+
format %{ "#@unnecessary_membar_volatile_rvwmo (unnecessary so empty encoding)" %}
8052+
ins_encode %{
8053+
__ block_comment("unnecessary_membar_volatile_rvwmo");
8054+
%}
8055+
ins_pipe(real_empty);
8056+
%}
8057+
80128058
instruct spin_wait() %{
80138059
predicate(UseZihintpause);
80148060
match(OnSpinWait);

0 commit comments

Comments
 (0)