8291000: C2: Purge LoadPLocked and Store*Conditional nodes

Reviewed-by: eosterlund, kvn
This commit is contained in:
Aleksey Shipilev 2022-07-28 08:15:53 +00:00
parent 07f0612c9a
commit dd69a68d09
17 changed files with 4 additions and 556 deletions

View file

@ -9230,103 +9230,6 @@ instruct castVVMask(pRegGov dst)
// ============================================================================ // ============================================================================
// Atomic operation instructions // Atomic operation instructions
// //
// Intel and SPARC both implement Ideal Node LoadPLocked and
// Store{PIL}Conditional instructions using a normal load for the
// LoadPLocked and a CAS for the Store{PIL}Conditional.
//
// The ideal code appears only to use LoadPLocked/StorePLocked as a
// pair to lock object allocations from Eden space when not using
// TLABs.
//
// There does not appear to be a Load{IL}Locked Ideal Node and the
// Ideal code appears to use Store{IL}Conditional as an alias for CAS
// and to use StoreIConditional only for 32-bit and StoreLConditional
// only for 64-bit.
//
// We implement LoadPLocked and StorePLocked instructions using,
// respectively the AArch64 hw load-exclusive and store-conditional
// instructions. Whereas we must implement each of
// Store{IL}Conditional using a CAS which employs a pair of
// instructions comprising a load-exclusive followed by a
// store-conditional.
// Locked-load (linked load) of the current heap-top
// used when updating the eden heap top
// implemented using ldaxr on AArch64
instruct loadPLocked(iRegPNoSp dst, indirect mem)
%{
match(Set dst (LoadPLocked mem));
ins_cost(VOLATILE_REF_COST);
format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %}
ins_encode(aarch64_enc_ldaxr(dst, mem));
ins_pipe(pipe_serial);
%}
// Conditional-store of the updated heap-top.
// Used during allocation of the shared heap.
// Sets flag (EQ) on success.
// implemented using stlxr on AArch64.
instruct storePConditional(memory8 heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr)
%{
match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
ins_cost(VOLATILE_REF_COST);
// TODO
// do we need to do a store-conditional release or can we just use a
// plain store-conditional?
format %{
"stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release"
"cmpw rscratch1, zr\t# EQ on successful write"
%}
ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr));
ins_pipe(pipe_serial);
%}
instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr)
%{
match(Set cr (StoreLConditional mem (Binary oldval newval)));
ins_cost(VOLATILE_REF_COST);
format %{
"cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval"
"cmpw rscratch1, zr\t# EQ on successful write"
%}
ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval));
ins_pipe(pipe_slow);
%}
// storeIConditional also has acquire semantics, for no better reason
// than matching storeLConditional. At the time of writing this
// comment storeIConditional was not used anywhere by AArch64.
instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr)
%{
match(Set cr (StoreIConditional mem (Binary oldval newval)));
ins_cost(VOLATILE_REF_COST);
format %{
"cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval"
"cmpw rscratch1, zr\t# EQ on successful write"
%}
ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval));
ins_pipe(pipe_slow);
%}
// standard CompareAndSwapX when we are using barriers // standard CompareAndSwapX when we are using barriers
// these have higher priority than the rules selected by a predicate // these have higher priority than the rules selected by a predicate

View file

@ -5430,63 +5430,6 @@ instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
ins_pipe(ialu_reg_imm); ins_pipe(ialu_reg_imm);
%} %}
//----------Conditional_store--------------------------------------------------
// Conditional-store of the updated heap-top.
// Used during allocation of the shared heap.
// Sets flags (EQ) on success.
// LoadP-locked.
instruct loadPLocked(iRegP dst, memoryex mem) %{
match(Set dst (LoadPLocked mem));
size(4);
format %{ "LDREX $dst,$mem" %}
ins_encode %{
__ ldrex($dst$$Register,$mem$$Address);
%}
ins_pipe(iload_mem);
%}
instruct storePConditional( memoryex heap_top_ptr, iRegP oldval, iRegP newval, iRegI tmp, flagsRegP pcc ) %{
predicate(_kids[1]->_kids[0]->_leaf->Opcode() == Op_LoadPLocked); // only works in conjunction with a LoadPLocked node
match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));
effect( TEMP tmp );
size(8);
format %{ "STREX $tmp,$newval,$heap_top_ptr\n\t"
"CMP $tmp, 0" %}
ins_encode %{
__ strex($tmp$$Register, $newval$$Register, $heap_top_ptr$$Address);
__ cmp($tmp$$Register, 0);
%}
ins_pipe( long_memory_op );
%}
// Conditional-store of an intx value.
instruct storeXConditional( memoryex mem, iRegX oldval, iRegX newval, iRegX tmp, flagsReg icc ) %{
match(Set icc (StoreIConditional mem (Binary oldval newval)));
effect( TEMP tmp );
size(28);
format %{ "loop: \n\t"
"LDREX $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
"XORS $tmp,$tmp, $oldval\n\t"
"STREX.eq $tmp, $newval, $mem\n\t"
"CMP.eq $tmp, 1 \n\t"
"B.eq loop \n\t"
"TEQ $tmp, 0\n\t"
"membar LoadStore|LoadLoad" %}
ins_encode %{
Label loop;
__ bind(loop);
__ ldrex($tmp$$Register, $mem$$Address);
__ eors($tmp$$Register, $tmp$$Register, $oldval$$Register);
__ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
__ cmp($tmp$$Register, 1, eq);
__ b(loop, eq);
__ teq($tmp$$Register, 0);
__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadStore | MacroAssembler::LoadLoad), noreg);
%}
ins_pipe( long_memory_op );
%}
// No flag versions for CompareAndSwap{P,I,L} because matcher can't match them // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{ instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{

View file

@ -7453,62 +7453,6 @@ instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{
ins_pipe(pipe_class_default); ins_pipe(pipe_class_default);
%} %}
//----------Conditional_store--------------------------------------------------
// Conditional-store of the updated heap-top.
// Used during allocation of the shared heap.
// Sets flags (EQ) on success. Implemented with a CASA on Sparc.
// As compareAndSwapL, but return flag register instead of boolean value in
// int register.
// Used by sun/misc/AtomicLongCSImpl.java.
// Mem_ptr must be a memory operand, else this node does not get
// Flag_needs_anti_dependence_check set by adlc. If this is not set this node
// can be rematerialized which leads to errors.
instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{
match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal)));
effect(TEMP cr0);
format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
ins_encode %{
__ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(),
noreg, NULL, true);
%}
ins_pipe(pipe_class_default);
%}
// As compareAndSwapP, but return flag register instead of boolean value in
// int register.
// This instruction is matched if UseTLAB is off.
// Mem_ptr must be a memory operand, else this node does not get
// Flag_needs_anti_dependence_check set by adlc. If this is not set this node
// can be rematerialized which leads to errors.
instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{
match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal)));
ins_cost(2*MEMORY_REF_COST);
predicate(n->as_LoadStore()->barrier_data() == 0);
format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
ins_encode %{
__ stdcx_($newVal$$Register, $mem_ptr$$Register);
%}
ins_pipe(pipe_class_memory);
%}
// Implement LoadPLocked. Must be ordered against changes of the memory location
// by storePConditional.
// Don't know whether this is ever used.
instruct loadPLocked(iRegPdst dst, memory mem) %{
match(Set dst (LoadPLocked mem));
ins_cost(2*MEMORY_REF_COST);
format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %}
size(4);
ins_encode %{
__ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
%}
ins_pipe(pipe_class_memory);
%}
//----------Compare-And-Swap--------------------------------------------------- //----------Compare-And-Swap---------------------------------------------------
// CompareAndSwap{P,I,L} have more than one output, therefore "CmpI // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI

View file

@ -5134,108 +5134,6 @@ instruct storeNKlass(iRegN src, memory mem)
// ============================================================================ // ============================================================================
// Atomic operation instructions // Atomic operation instructions
// //
// Intel and SPARC both implement Ideal Node LoadPLocked and
// Store{PIL}Conditional instructions using a normal load for the
// LoadPLocked and a CAS for the Store{PIL}Conditional.
//
// The ideal code appears only to use LoadPLocked/storePConditional as a
// pair to lock object allocations from Eden space when not using
// TLABs.
//
// There does not appear to be a Load{IL}Locked Ideal Node and the
// Ideal code appears to use Store{IL}Conditional as an alias for CAS
// and to use StoreIConditional only for 32-bit and StoreLConditional
// only for 64-bit.
//
// We implement LoadPLocked and storePConditional instructions using,
// respectively the RISCV hw load-reserve and store-conditional
// instructions. Whereas we must implement each of
// Store{IL}Conditional using a CAS which employs a pair of
// instructions comprising a load-reserve followed by a
// store-conditional.
// Locked-load (load reserved) of the current heap-top
// used when updating the eden heap top
// implemented using lr_d on RISCV64
instruct loadPLocked(iRegPNoSp dst, indirect mem)
%{
match(Set dst (LoadPLocked mem));
ins_cost(ALU_COST * 2 + LOAD_COST);
format %{ "lr.d $dst, $mem\t# ptr load reserved, #@loadPLocked" %}
ins_encode %{
__ la(t0, Address(as_Register($mem$$base), $mem$$disp));
__ lr_d($dst$$Register, t0, Assembler::aq);
%}
ins_pipe(pipe_serial);
%}
// Conditional-store of the updated heap-top.
// Used during allocation of the shared heap.
// implemented using sc_d on RISCV64.
instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr)
%{
match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
ins_cost(ALU_COST * 2 + STORE_COST);
format %{
"sc_d t1, $newval $heap_top_ptr,\t# ptr store conditional, #@storePConditional"
%}
ins_encode %{
__ la(t0, Address(as_Register($heap_top_ptr$$base), $heap_top_ptr$$disp));
__ sc_d($cr$$Register, $newval$$Register, t0, Assembler::rl);
%}
ins_pipe(pipe_serial);
%}
instruct storeLConditional(indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr)
%{
match(Set cr (StoreLConditional mem (Binary oldval newval)));
ins_cost(LOAD_COST + STORE_COST + 2 * BRANCH_COST);
format %{
"cmpxchg t1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval"
"xorr $cr, $cr, $oldval\t# $cr == 0 on successful write, #@storeLConditional"
%}
ins_encode %{
__ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64,
/*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $cr$$Register);
__ xorr($cr$$Register,$cr$$Register, $oldval$$Register);
%}
ins_pipe(pipe_slow);
%}
// storeIConditional also has acquire semantics, for no better reason
// than matching storeLConditional.
instruct storeIConditional(indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr)
%{
match(Set cr (StoreIConditional mem (Binary oldval newval)));
ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2);
format %{
"cmpxchgw t1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval"
"xorr $cr, $cr, $oldval\t# $cr == 0 on successful write, #@storeIConditional"
%}
ins_encode %{
__ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32,
/*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $cr$$Register);
__ xorr($cr$$Register,$cr$$Register, $oldval$$Register);
%}
ins_pipe(pipe_slow);
%}
// standard CompareAndSwapX when we are using barriers // standard CompareAndSwapX when we are using barriers
// these have higher priority than the rules selected by a predicate // these have higher priority than the rules selected by a predicate

View file

@ -5290,54 +5290,6 @@ instruct castVV(iRegL dst) %{
ins_pipe(pipe_class_dummy); ins_pipe(pipe_class_dummy);
%} %}
//----------Conditional_store--------------------------------------------------
// Conditional-store of the updated heap-top.
// Used during allocation of the shared heap.
// Sets flags (EQ) on success.
// Implement LoadPLocked. Must be ordered against changes of the memory location
// by storePConditional.
// Don't know whether this is ever used.
instruct loadPLocked(iRegP dst, memory mem) %{
match(Set dst (LoadPLocked mem));
ins_cost(MEMORY_REF_COST);
size(Z_DISP3_SIZE);
format %{ "LG $dst,$mem\t # LoadPLocked" %}
opcode(LG_ZOPC, LG_ZOPC);
ins_encode(z_form_rt_mem_opt(dst, mem));
ins_pipe(pipe_class_dummy);
%}
// As compareAndSwapP, but return flag register instead of boolean value in
// int register.
// This instruction is matched if UseTLAB is off. Needed to pass
// option tests. Mem_ptr must be a memory operand, else this node
// does not get Flag_needs_anti_dependence_check set by adlc. If this
// is not set this node can be rematerialized which leads to errors.
instruct storePConditional(indirect mem_ptr, rarg5RegP oldval, iRegP_N2P newval, flagsReg cr) %{
match(Set cr (StorePConditional mem_ptr (Binary oldval newval)));
effect(KILL oldval);
// TODO: s390 port size(FIXED_SIZE);
format %{ "storePConditional $oldval,$newval,$mem_ptr" %}
ins_encode(z_enc_casL(oldval, newval, mem_ptr));
ins_pipe(pipe_class_dummy);
%}
// As compareAndSwapL, but return flag register instead of boolean value in
// int register.
// Used by sun/misc/AtomicLongCSImpl.java. Mem_ptr must be a memory
// operand, else this node does not get
// Flag_needs_anti_dependence_check set by adlc. If this is not set
// this node can be rematerialized which leads to errors.
instruct storeLConditional(indirect mem_ptr, rarg5RegL oldval, iRegL newval, flagsReg cr) %{
match(Set cr (StoreLConditional mem_ptr (Binary oldval newval)));
effect(KILL oldval);
// TODO: s390 port size(FIXED_SIZE);
format %{ "storePConditional $oldval,$newval,$mem_ptr" %}
ins_encode(z_enc_casL(oldval, newval, mem_ptr));
ins_pipe(pipe_class_dummy);
%}
// No flag versions for CompareAndSwap{P,I,L,N} because matcher can't match them. // No flag versions for CompareAndSwap{P,I,L,N} because matcher can't match them.
instruct compareAndSwapI_bool(iRegP mem_ptr, rarg5RegI oldval, iRegI newval, iRegI res, flagsReg cr) %{ instruct compareAndSwapI_bool(iRegP mem_ptr, rarg5RegI oldval, iRegI newval, iRegI res, flagsReg cr) %{

View file

@ -7257,61 +7257,6 @@ instruct castDD_PR( regDPR dst ) %{
ins_pipe( empty ); ins_pipe( empty );
%} %}
// Load-locked - same as a regular pointer load when used with compare-swap
instruct loadPLocked(eRegP dst, memory mem) %{
match(Set dst (LoadPLocked mem));
ins_cost(125);
format %{ "MOV $dst,$mem\t# Load ptr. locked" %}
opcode(0x8B);
ins_encode( OpcP, RegMem(dst,mem));
ins_pipe( ialu_reg_mem );
%}
// Conditional-store of the updated heap-top.
// Used during allocation of the shared heap.
// Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel.
instruct storePConditional( memory heap_top_ptr, eAXRegP oldval, eRegP newval, eFlagsReg cr ) %{
match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
// EAX is killed if there is contention, but then it's also unused.
// In the common case of no contention, EAX holds the new oop address.
format %{ "CMPXCHG $heap_top_ptr,$newval\t# If EAX==$heap_top_ptr Then store $newval into $heap_top_ptr" %}
ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval,heap_top_ptr) );
ins_pipe( pipe_cmpxchg );
%}
// Conditional-store of an int value.
// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel.
instruct storeIConditional( memory mem, eAXRegI oldval, rRegI newval, eFlagsReg cr ) %{
match(Set cr (StoreIConditional mem (Binary oldval newval)));
effect(KILL oldval);
format %{ "CMPXCHG $mem,$newval\t# If EAX==$mem Then store $newval into $mem" %}
ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval, mem) );
ins_pipe( pipe_cmpxchg );
%}
// Conditional-store of a long value.
// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG8 on Intel.
instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
match(Set cr (StoreLConditional mem (Binary oldval newval)));
effect(KILL oldval);
format %{ "XCHG EBX,ECX\t# correct order for CMPXCHG8 instruction\n\t"
"CMPXCHG8 $mem,ECX:EBX\t# If EDX:EAX==$mem Then store ECX:EBX into $mem\n\t"
"XCHG EBX,ECX"
%}
ins_encode %{
// Note: we need to swap rbx, and rcx before and after the
// cmpxchg8 instruction because the instruction uses
// rcx as the high order word of the new value to store but
// our register encoding uses rbx.
__ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
__ lock();
__ cmpxchg8($mem$$Address);
__ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
%}
ins_pipe( pipe_cmpxchg );
%}
// No flag versions for CompareAndSwap{P,I,L} because matcher can't match them // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{ instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{

View file

@ -8068,71 +8068,6 @@ instruct castDD(regD dst)
ins_pipe(empty); ins_pipe(empty);
%} %}
// LoadP-locked same as a regular LoadP when used with compare-swap
instruct loadPLocked(rRegP dst, memory mem)
%{
match(Set dst (LoadPLocked mem));
ins_cost(125); // XXX
format %{ "movq $dst, $mem\t# ptr locked" %}
ins_encode %{
__ movq($dst$$Register, $mem$$Address);
%}
ins_pipe(ialu_reg_mem); // XXX
%}
// Conditional-store of the updated heap-top.
// Used during allocation of the shared heap.
// Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel.
instruct storePConditional(memory heap_top_ptr,
rax_RegP oldval, rRegP newval,
rFlagsReg cr)
%{
predicate(n->as_LoadStore()->barrier_data() == 0);
match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
"If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
ins_encode %{
__ lock();
__ cmpxchgq($newval$$Register, $heap_top_ptr$$Address);
%}
ins_pipe(pipe_cmpxchg);
%}
// Conditional-store of an int value.
// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr)
%{
match(Set cr (StoreIConditional mem (Binary oldval newval)));
effect(KILL oldval);
format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
opcode(0x0F, 0xB1);
ins_encode(lock_prefix,
REX_reg_mem(newval, mem),
OpcP, OpcS,
reg_mem(newval, mem));
ins_pipe(pipe_cmpxchg);
%}
// Conditional-store of a long value.
// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr)
%{
match(Set cr (StoreLConditional mem (Binary oldval newval)));
effect(KILL oldval);
format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
ins_encode %{
__ lock();
__ cmpxchgq($newval$$Register, $mem$$Address);
%}
ins_pipe(pipe_cmpxchg);
%}
// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
instruct compareAndSwapP(rRegI res, instruct compareAndSwapP(rRegI res,
memory mem_ptr, memory mem_ptr,

View file

@ -262,7 +262,6 @@ Form::DataType Form::is_load_from_memory(const char *opType) const {
if( strcmp(opType,"LoadNKlass")==0 ) return Form::idealNKlass; if( strcmp(opType,"LoadNKlass")==0 ) return Form::idealNKlass;
if( strcmp(opType,"LoadL")==0 ) return Form::idealL; if( strcmp(opType,"LoadL")==0 ) return Form::idealL;
if( strcmp(opType,"LoadL_unaligned")==0 ) return Form::idealL; if( strcmp(opType,"LoadL_unaligned")==0 ) return Form::idealL;
if( strcmp(opType,"LoadPLocked")==0 ) return Form::idealP;
if( strcmp(opType,"LoadP")==0 ) return Form::idealP; if( strcmp(opType,"LoadP")==0 ) return Form::idealP;
if( strcmp(opType,"LoadN")==0 ) return Form::idealN; if( strcmp(opType,"LoadN")==0 ) return Form::idealN;
if( strcmp(opType,"LoadRange")==0 ) return Form::idealI; if( strcmp(opType,"LoadRange")==0 ) return Form::idealI;

View file

@ -3513,8 +3513,6 @@ int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
"StoreVector", "LoadVector", "LoadVectorMasked", "StoreVectorMasked", "StoreVector", "LoadVector", "LoadVectorMasked", "StoreVectorMasked",
"LoadVectorGather", "StoreVectorScatter", "LoadVectorGatherMasked", "StoreVectorScatterMasked", "LoadVectorGather", "StoreVectorScatter", "LoadVectorGatherMasked", "StoreVectorScatterMasked",
"LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned", "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
"LoadPLocked",
"StorePConditional", "StoreIConditional", "StoreLConditional",
"CompareAndSwapB", "CompareAndSwapS", "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN", "CompareAndSwapB", "CompareAndSwapS", "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
"WeakCompareAndSwapB", "WeakCompareAndSwapS", "WeakCompareAndSwapI", "WeakCompareAndSwapL", "WeakCompareAndSwapP", "WeakCompareAndSwapN", "WeakCompareAndSwapB", "WeakCompareAndSwapS", "WeakCompareAndSwapI", "WeakCompareAndSwapL", "WeakCompareAndSwapP", "WeakCompareAndSwapN",
"CompareAndExchangeB", "CompareAndExchangeS", "CompareAndExchangeI", "CompareAndExchangeL", "CompareAndExchangeP", "CompareAndExchangeN", "CompareAndExchangeB", "CompareAndExchangeS", "CompareAndExchangeI", "CompareAndExchangeL", "CompareAndExchangeP", "CompareAndExchangeN",

View file

@ -2822,8 +2822,6 @@ void MemoryGraphFixer::fix_memory_uses(Node* mem, Node* replacement, Node* rep_p
u->Opcode() == Op_Rethrow || u->Opcode() == Op_Rethrow ||
u->Opcode() == Op_Return || u->Opcode() == Op_Return ||
u->Opcode() == Op_SafePoint || u->Opcode() == Op_SafePoint ||
u->Opcode() == Op_StoreIConditional ||
u->Opcode() == Op_StoreLConditional ||
(u->is_CallStaticJava() && u->as_CallStaticJava()->uncommon_trap_request() != 0) || (u->is_CallStaticJava() && u->as_CallStaticJava()->uncommon_trap_request() != 0) ||
(u->is_CallStaticJava() && u->as_CallStaticJava()->_entry_point == OptoRuntime::rethrow_stub()) || (u->is_CallStaticJava() && u->as_CallStaticJava()->_entry_point == OptoRuntime::rethrow_stub()) ||
u->Opcode() == Op_CallLeaf, "%s", u->Name()); u->Opcode() == Op_CallLeaf, "%s", u->Name());

View file

@ -206,7 +206,6 @@ macro(LoadKlass)
macro(LoadNKlass) macro(LoadNKlass)
macro(LoadL) macro(LoadL)
macro(LoadL_unaligned) macro(LoadL_unaligned)
macro(LoadPLocked)
macro(LoadP) macro(LoadP)
macro(LoadN) macro(LoadN)
macro(LoadRange) macro(LoadRange)
@ -337,9 +336,6 @@ macro(StartOSR)
macro(StoreB) macro(StoreB)
macro(StoreC) macro(StoreC)
macro(StoreCM) macro(StoreCM)
macro(StorePConditional)
macro(StoreIConditional)
macro(StoreLConditional)
macro(StoreD) macro(StoreD)
macro(StoreF) macro(StoreF)
macro(StoreI) macro(StoreI)

View file

@ -3237,11 +3237,8 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f
case Op_StoreB: case Op_StoreB:
case Op_StoreC: case Op_StoreC:
case Op_StorePConditional:
case Op_StoreI: case Op_StoreI:
case Op_StoreL: case Op_StoreL:
case Op_StoreIConditional:
case Op_StoreLConditional:
case Op_CompareAndSwapB: case Op_CompareAndSwapB:
case Op_CompareAndSwapS: case Op_CompareAndSwapS:
case Op_CompareAndSwapI: case Op_CompareAndSwapI:
@ -3281,7 +3278,6 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f
case Op_LoadNKlass: case Op_LoadNKlass:
case Op_LoadL: case Op_LoadL:
case Op_LoadL_unaligned: case Op_LoadL_unaligned:
case Op_LoadPLocked:
case Op_LoadP: case Op_LoadP:
case Op_LoadN: case Op_LoadN:
case Op_LoadRange: case Op_LoadRange:

View file

@ -581,8 +581,7 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
break; break;
} }
case Op_LoadP: case Op_LoadP:
case Op_LoadN: case Op_LoadN: {
case Op_LoadPLocked: {
add_objload_to_connection_graph(n, delayed_worklist); add_objload_to_connection_graph(n, delayed_worklist);
break; break;
} }
@ -635,7 +634,6 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
case Op_StoreP: case Op_StoreP:
case Op_StoreN: case Op_StoreN:
case Op_StoreNKlass: case Op_StoreNKlass:
case Op_StorePConditional:
case Op_WeakCompareAndSwapP: case Op_WeakCompareAndSwapP:
case Op_WeakCompareAndSwapN: case Op_WeakCompareAndSwapN:
case Op_CompareAndSwapP: case Op_CompareAndSwapP:
@ -738,8 +736,7 @@ void ConnectionGraph::add_final_edges(Node *n) {
break; break;
} }
case Op_LoadP: case Op_LoadP:
case Op_LoadN: case Op_LoadN: {
case Op_LoadPLocked: {
// Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
// ThreadLocal has RawPtr type. // ThreadLocal has RawPtr type.
assert(_igvn->type(n)->make_ptr() != NULL, "Unexpected node type"); assert(_igvn->type(n)->make_ptr() != NULL, "Unexpected node type");
@ -794,8 +791,7 @@ void ConnectionGraph::add_final_edges(Node *n) {
case Op_WeakCompareAndSwapN: case Op_WeakCompareAndSwapN:
case Op_StoreP: case Op_StoreP:
case Op_StoreN: case Op_StoreN:
case Op_StoreNKlass: case Op_StoreNKlass:{
case Op_StorePConditional:{
add_final_edges_unsafe_access(n, opcode); add_final_edges_unsafe_access(n, opcode);
break; break;
} }

View file

@ -3435,10 +3435,7 @@ void IdealLoopTree::adjust_loop_exit_prob(PhaseIdealLoop *phase) {
if (iff->outcnt() == 2) { // Ignore dead tests if (iff->outcnt() == 2) { // Ignore dead tests
Node *bol = iff->in(1); Node *bol = iff->in(1);
if (bol && bol->req() > 1 && bol->in(1) && if (bol && bol->req() > 1 && bol->in(1) &&
((bol->in(1)->Opcode() == Op_StorePConditional) || ((bol->in(1)->Opcode() == Op_CompareAndExchangeB) ||
(bol->in(1)->Opcode() == Op_StoreIConditional) ||
(bol->in(1)->Opcode() == Op_StoreLConditional) ||
(bol->in(1)->Opcode() == Op_CompareAndExchangeB) ||
(bol->in(1)->Opcode() == Op_CompareAndExchangeS) || (bol->in(1)->Opcode() == Op_CompareAndExchangeS) ||
(bol->in(1)->Opcode() == Op_CompareAndExchangeI) || (bol->in(1)->Opcode() == Op_CompareAndExchangeI) ||
(bol->in(1)->Opcode() == Op_CompareAndExchangeL) || (bol->in(1)->Opcode() == Op_CompareAndExchangeL) ||

View file

@ -2326,9 +2326,6 @@ void Matcher::find_shared_post_visit(Node* n, uint opcode) {
} }
switch(opcode) { // Handle some opcodes special switch(opcode) { // Handle some opcodes special
case Op_StorePConditional:
case Op_StoreIConditional:
case Op_StoreLConditional:
case Op_CompareAndExchangeB: case Op_CompareAndExchangeB:
case Op_CompareAndExchangeS: case Op_CompareAndExchangeS:
case Op_CompareAndExchangeI: case Op_CompareAndExchangeI:

View file

@ -796,19 +796,6 @@ public:
int oop_alias_idx() const { return _oop_alias_idx; } int oop_alias_idx() const { return _oop_alias_idx; }
}; };
//------------------------------LoadPLockedNode---------------------------------
// Load-locked a pointer from memory (either object or array).
// On Sparc & Intel this is implemented as a normal pointer load.
// On PowerPC and friends it's a real load-locked.
class LoadPLockedNode : public LoadPNode {
public:
LoadPLockedNode(Node *c, Node *mem, Node *adr, MemOrd mo)
: LoadPNode(c, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, mo) {}
virtual int Opcode() const;
virtual int store_Opcode() const { return Op_StorePConditional; }
virtual bool depends_only_on_test() const { return true; }
};
//------------------------------SCMemProjNode--------------------------------------- //------------------------------SCMemProjNode---------------------------------------
// This class defines a projection of the memory state of a store conditional node. // This class defines a projection of the memory state of a store conditional node.
// These nodes return a value, but also update memory. // These nodes return a value, but also update memory.
@ -865,39 +852,6 @@ public:
virtual const Type* Value(PhaseGVN* phase) const; virtual const Type* Value(PhaseGVN* phase) const;
}; };
//------------------------------StorePConditionalNode---------------------------
// Conditionally store pointer to memory, if no change since prior
// load-locked. Sets flags for success or failure of the store.
class StorePConditionalNode : public LoadStoreConditionalNode {
public:
StorePConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreConditionalNode(c, mem, adr, val, ll) { }
virtual int Opcode() const;
// Produces flags
virtual uint ideal_reg() const { return Op_RegFlags; }
};
//------------------------------StoreIConditionalNode---------------------------
// Conditionally store int to memory, if no change since prior
// load-locked. Sets flags for success or failure of the store.
class StoreIConditionalNode : public LoadStoreConditionalNode {
public:
StoreIConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ii ) : LoadStoreConditionalNode(c, mem, adr, val, ii) { }
virtual int Opcode() const;
// Produces flags
virtual uint ideal_reg() const { return Op_RegFlags; }
};
//------------------------------StoreLConditionalNode---------------------------
// Conditionally store long to memory, if no change since prior
// load-locked. Sets flags for success or failure of the store.
class StoreLConditionalNode : public LoadStoreConditionalNode {
public:
StoreLConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreConditionalNode(c, mem, adr, val, ll) { }
virtual int Opcode() const;
// Produces flags
virtual uint ideal_reg() const { return Op_RegFlags; }
};
class CompareAndSwapNode : public LoadStoreConditionalNode { class CompareAndSwapNode : public LoadStoreConditionalNode {
private: private:
const MemNode::MemOrd _mem_ord; const MemNode::MemOrd _mem_ord;

View file

@ -1653,11 +1653,8 @@
declare_c2_type(StoreNNode, StoreNode) \ declare_c2_type(StoreNNode, StoreNode) \
declare_c2_type(StoreNKlassNode, StoreNode) \ declare_c2_type(StoreNKlassNode, StoreNode) \
declare_c2_type(StoreCMNode, StoreNode) \ declare_c2_type(StoreCMNode, StoreNode) \
declare_c2_type(LoadPLockedNode, LoadPNode) \
declare_c2_type(SCMemProjNode, ProjNode) \ declare_c2_type(SCMemProjNode, ProjNode) \
declare_c2_type(LoadStoreNode, Node) \ declare_c2_type(LoadStoreNode, Node) \
declare_c2_type(StorePConditionalNode, LoadStoreNode) \
declare_c2_type(StoreLConditionalNode, LoadStoreNode) \
declare_c2_type(CompareAndSwapNode, LoadStoreConditionalNode) \ declare_c2_type(CompareAndSwapNode, LoadStoreConditionalNode) \
declare_c2_type(CompareAndSwapBNode, CompareAndSwapNode) \ declare_c2_type(CompareAndSwapBNode, CompareAndSwapNode) \
declare_c2_type(CompareAndSwapSNode, CompareAndSwapNode) \ declare_c2_type(CompareAndSwapSNode, CompareAndSwapNode) \