8379260: C2: Separate volatile barrier and full barrier

Reviewed-by: fyang, mdoerr, amitkumar, aph, dlong
This commit is contained in:
Quan Anh Mai 2026-03-12 08:39:41 +00:00
parent 73424d14ba
commit fd80329bfd
11 changed files with 212 additions and 2 deletions

View File

@ -8024,6 +8024,21 @@ instruct membar_release_lock() %{
ins_pipe(pipe_serial);
%}
instruct membar_storeload() %{
match(MemBarStoreLoad);
ins_cost(VOLATILE_REF_COST*100);
format %{ "MEMBAR-store-load\n\t"
"dmb ish" %}
ins_encode %{
__ block_comment("membar_storeload");
__ membar(Assembler::StoreLoad);
%}
ins_pipe(pipe_serial);
%}
instruct unnecessary_membar_volatile() %{
predicate(unnecessary_volatile(n));
match(MemBarVolatile);
@ -8053,6 +8068,20 @@ instruct membar_volatile() %{
ins_pipe(pipe_serial);
%}
instruct membar_full() %{
match(MemBarFull);
ins_cost(VOLATILE_REF_COST*100);
format %{ "membar_full\n\t"
"dmb ish" %}
ins_encode %{
__ block_comment("membar_full");
__ membar(Assembler::AnyAny);
%}
ins_pipe(pipe_serial);
%}
// ============================================================================
// Cast/Convert Instructions

View File

@ -4440,6 +4440,18 @@ instruct membar_release_lock() %{
ins_pipe(empty);
%}
instruct membar_storeload() %{
match(MemBarStoreLoad);
ins_cost(4*MEMORY_REF_COST);
size(4);
format %{ "MEMBAR-storeload" %}
ins_encode %{
__ membar(MacroAssembler::StoreLoad, noreg);
%}
ins_pipe(long_memory_op);
%}
instruct membar_volatile() %{
match(MemBarVolatile);
ins_cost(4*MEMORY_REF_COST);
@ -4463,6 +4475,18 @@ instruct unnecessary_membar_volatile() %{
ins_pipe(empty);
%}
instruct membar_full() %{
match(MemBarFull);
ins_cost(4*MEMORY_REF_COST);
size(4);
format %{ "MEMBAR-full" %}
ins_encode %{
__ membar(MacroAssembler::StoreLoad, noreg);
%}
ins_pipe(long_memory_op);
%}
//----------Register Move Instructions-----------------------------------------
// Cast Index to Pointer for unsafe natives

View File

@ -7163,6 +7163,18 @@ instruct membar_release_lock() %{
ins_pipe(pipe_class_default);
%}
instruct membar_storeload() %{
match(MemBarStoreLoad);
ins_cost(4*MEMORY_REF_COST);
format %{ "MEMBAR-store-load" %}
size(4);
ins_encode %{
__ fence();
%}
ins_pipe(pipe_class_default);
%}
instruct membar_volatile() %{
match(MemBarVolatile);
ins_cost(4*MEMORY_REF_COST);
@ -7205,6 +7217,18 @@ instruct membar_volatile() %{
// ins_pipe(pipe_class_default);
//%}
instruct membar_full() %{
match(MemBarFull);
ins_cost(4*MEMORY_REF_COST);
format %{ "MEMBAR-full" %}
size(4);
ins_encode %{
__ fence();
%}
ins_pipe(pipe_class_default);
%}
instruct membar_CPUOrder() %{
match(MemBarCPUOrder);
ins_cost(0);

View File

@ -8156,6 +8156,22 @@ instruct unnecessary_membar_rvtso() %{
ins_pipe(real_empty);
%}
instruct membar_storeload_rvtso() %{
predicate(UseZtso);
match(MemBarStoreLoad);
ins_cost(VOLATILE_REF_COST);
format %{ "#@membar_storeload_rvtso\n\t"
"fence w, r"%}
ins_encode %{
__ block_comment("membar_storeload_rvtso");
__ membar(MacroAssembler::StoreLoad);
%}
ins_pipe(pipe_slow);
%}
instruct membar_volatile_rvtso() %{
predicate(UseZtso);
match(MemBarVolatile);
@ -8186,6 +8202,22 @@ instruct unnecessary_membar_volatile_rvtso() %{
ins_pipe(real_empty);
%}
instruct membar_full_rvtso() %{
predicate(UseZtso);
match(MemBarFull);
ins_cost(VOLATILE_REF_COST);
format %{ "#@membar_full_rvtso\n\t"
"fence rw, rw" %}
ins_encode %{
__ block_comment("membar_full_rvtso");
__ membar(MacroAssembler::AnyAny);
%}
ins_pipe(pipe_slow);
%}
// RVWMO
instruct membar_aqcuire_rvwmo() %{
@ -8235,6 +8267,22 @@ instruct membar_storestore_rvwmo() %{
ins_pipe(pipe_serial);
%}
instruct membar_storeload_rvwmo() %{
predicate(!UseZtso);
match(MemBarStoreLoad);
ins_cost(VOLATILE_REF_COST);
format %{ "#@membar_storeload_rvwmo\n\t"
"fence w, r"%}
ins_encode %{
__ block_comment("membar_storeload_rvwmo");
__ membar(MacroAssembler::StoreLoad);
%}
ins_pipe(pipe_serial);
%}
instruct membar_volatile_rvwmo() %{
predicate(!UseZtso);
match(MemBarVolatile);
@ -8279,6 +8327,22 @@ instruct unnecessary_membar_volatile_rvwmo() %{
ins_pipe(real_empty);
%}
instruct membar_full_rvwmo() %{
predicate(!UseZtso);
match(MemBarFull);
ins_cost(VOLATILE_REF_COST);
format %{ "#@membar_full_rvwmo\n\t"
"fence rw, rw" %}
ins_encode %{
__ block_comment("membar_full_rvwmo");
__ membar(MacroAssembler::AnyAny);
%}
ins_pipe(pipe_serial);
%}
instruct spin_wait() %{
predicate(UseZihintpause);
match(OnSpinWait);

View File

@ -5239,6 +5239,15 @@ instruct membar_release_lock() %{
ins_pipe(pipe_class_dummy);
%}
instruct membar_storeload() %{
match(MemBarStoreLoad);
ins_cost(4 * MEMORY_REF_COST);
size(2);
format %{ "MEMBAR-storeload" %}
ins_encode %{ __ z_fence(); %}
ins_pipe(pipe_class_dummy);
%}
instruct membar_volatile() %{
match(MemBarVolatile);
ins_cost(4 * MEMORY_REF_COST);
@ -5258,6 +5267,15 @@ instruct unnecessary_membar_volatile() %{
ins_pipe(pipe_class_dummy);
%}
instruct membar_full() %{
match(MemBarFull);
ins_cost(4 * MEMORY_REF_COST);
size(2);
format %{ "MEMBAR-full" %}
ins_encode %{ __ z_fence(); %}
ins_pipe(pipe_class_dummy);
%}
instruct membar_CPUOrder() %{
match(MemBarCPUOrder);
ins_cost(0);

View File

@ -8852,6 +8852,21 @@ instruct membar_release_lock()
ins_pipe(empty);
%}
instruct membar_storeload(rFlagsReg cr) %{
match(MemBarStoreLoad);
effect(KILL cr);
ins_cost(400);
format %{
$$template
$$emit$$"lock addl [rsp + #0], 0\t! membar_storeload"
%}
ins_encode %{
__ membar(Assembler::StoreLoad);
%}
ins_pipe(pipe_slow);
%}
instruct membar_volatile(rFlagsReg cr) %{
match(MemBarVolatile);
effect(KILL cr);
@ -8879,6 +8894,21 @@ instruct unnecessary_membar_volatile()
ins_pipe(empty);
%}
instruct membar_full(rFlagsReg cr) %{
match(MemBarFull);
effect(KILL cr);
ins_cost(400);
format %{
$$template
$$emit$$"lock addl [rsp + #0], 0\t! membar_full"
%}
ins_encode %{
__ membar(Assembler::StoreLoad);
%}
ins_pipe(pipe_slow);
%}
instruct membar_storestore() %{
match(MemBarStoreStore);
match(StoreStoreFence);

View File

@ -4276,7 +4276,9 @@ bool MatchRule::is_ideal_membar() const {
!strcmp(_opType,"LoadFence" ) ||
!strcmp(_opType,"StoreFence") ||
!strcmp(_opType,"StoreStoreFence") ||
!strcmp(_opType,"MemBarStoreLoad") ||
!strcmp(_opType,"MemBarVolatile") ||
!strcmp(_opType,"MemBarFull") ||
!strcmp(_opType,"MemBarCPUOrder") ||
!strcmp(_opType,"MemBarStoreStore") ||
!strcmp(_opType,"OnSpinWait");

View File

@ -239,8 +239,10 @@ macro(MemBarRelease)
macro(StoreFence)
macro(StoreStoreFence)
macro(MemBarReleaseLock)
macro(MemBarStoreLoad)
macro(MemBarVolatile)
macro(MemBarStoreStore)
macro(MemBarFull)
macro(MergeMem)
macro(MinI)
macro(MinL)

View File

@ -2900,7 +2900,7 @@ bool LibraryCallKit::inline_unsafe_fence(vmIntrinsics::ID id) {
insert_mem_bar(Op_StoreStoreFence);
return true;
case vmIntrinsics::_fullFence:
insert_mem_bar(Op_MemBarVolatile);
insert_mem_bar(Op_MemBarFull);
return true;
default:
fatal_unexpected_iid(id);
@ -3070,7 +3070,7 @@ bool LibraryCallKit::inline_native_vthread_start_transition(address funcAddr, co
Node* vt_addr = basic_plus_adr(vt_oop, java_lang_Thread::is_in_vthread_transition_offset());
access_store_at(nullptr, jt_addr, _gvn.type(jt_addr)->is_ptr(), ideal.ConI(1), TypeInt::BOOL, T_BOOLEAN, IN_NATIVE | MO_UNORDERED);
access_store_at(nullptr, vt_addr, _gvn.type(vt_addr)->is_ptr(), ideal.ConI(1), TypeInt::BOOL, T_BOOLEAN, IN_NATIVE | MO_UNORDERED);
insert_mem_bar(Op_MemBarVolatile);
insert_mem_bar(Op_MemBarStoreLoad);
ideal.sync_kit(this);
Node* global_disable_addr = makecon(TypeRawPtr::make((address)MountUnmountDisabler::global_vthread_transition_disable_count_address()));

View File

@ -4349,7 +4349,9 @@ MemBarNode* MemBarNode::make(Compile* C, int opcode, int atp, Node* pn) {
case Op_StoreStoreFence: return new StoreStoreFenceNode(C, atp, pn);
case Op_MemBarAcquireLock: return new MemBarAcquireLockNode(C, atp, pn);
case Op_MemBarReleaseLock: return new MemBarReleaseLockNode(C, atp, pn);
case Op_MemBarStoreLoad: return new MemBarStoreLoadNode(C, atp, pn);
case Op_MemBarVolatile: return new MemBarVolatileNode(C, atp, pn);
case Op_MemBarFull: return new MemBarFullNode(C, atp, pn);
case Op_MemBarCPUOrder: return new MemBarCPUOrderNode(C, atp, pn);
case Op_OnSpinWait: return new OnSpinWaitNode(C, atp, pn);
case Op_Initialize: return new InitializeNode(C, atp, pn);

View File

@ -1321,6 +1321,13 @@ public:
virtual int Opcode() const;
};
class MemBarStoreLoadNode : public MemBarNode {
public:
MemBarStoreLoadNode(Compile* C, int alias_idx, Node* precedent)
: MemBarNode(C, alias_idx, precedent) {}
virtual int Opcode() const;
};
// Ordering between a volatile store and a following volatile load.
// Requires multi-CPU visibility?
class MemBarVolatileNode: public MemBarNode {
@ -1330,6 +1337,14 @@ public:
virtual int Opcode() const;
};
// A full barrier blocks all loads and stores from moving across it
class MemBarFullNode : public MemBarNode {
public:
MemBarFullNode(Compile* C, int alias_idx, Node* precedent)
: MemBarNode(C, alias_idx, precedent) {}
virtual int Opcode() const;
};
// Ordering within the same CPU. Used to order unsafe memory references
// inside the compiler when we lack alias info. Not needed "outside" the
// compiler because the CPU does all the ordering for us.