8245955: Shenandoah: Remove LRB/is_redundant optimization
Reviewed-by: roland, shade
This commit is contained in:
parent
57388f807f
commit
6f4f6a2a59
src/hotspot/share/gc/shenandoah
@ -1096,9 +1096,6 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
|
||||
Node_List clones;
|
||||
for (int i = state->load_reference_barriers_count() - 1; i >= 0; i--) {
|
||||
ShenandoahLoadReferenceBarrierNode* lrb = state->load_reference_barrier(i);
|
||||
if (lrb->is_redundant()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Node* ctrl = phase->get_ctrl(lrb);
|
||||
Node* val = lrb->in(ShenandoahLoadReferenceBarrierNode::ValueIn);
|
||||
@ -1290,9 +1287,6 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
|
||||
|
||||
for (int i = 0; i < state->load_reference_barriers_count(); i++) {
|
||||
ShenandoahLoadReferenceBarrierNode* lrb = state->load_reference_barrier(i);
|
||||
if (lrb->is_redundant()) {
|
||||
continue;
|
||||
}
|
||||
Node* ctrl = phase->get_ctrl(lrb);
|
||||
IdealLoopTree* loop = phase->get_loop(ctrl);
|
||||
if (loop->_head->is_OuterStripMinedLoop()) {
|
||||
@ -1309,10 +1303,6 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
|
||||
Unique_Node_List uses_to_ignore;
|
||||
for (int i = state->load_reference_barriers_count() - 1; i >= 0; i--) {
|
||||
ShenandoahLoadReferenceBarrierNode* lrb = state->load_reference_barrier(i);
|
||||
if (lrb->is_redundant()) {
|
||||
phase->igvn().replace_node(lrb, lrb->in(ShenandoahLoadReferenceBarrierNode::ValueIn));
|
||||
continue;
|
||||
}
|
||||
uint last = phase->C->unique();
|
||||
Node* ctrl = phase->get_ctrl(lrb);
|
||||
Node* val = lrb->in(ShenandoahLoadReferenceBarrierNode::ValueIn);
|
||||
@ -3026,163 +3016,3 @@ bool ShenandoahLoadReferenceBarrierNode::needs_barrier_impl(PhaseGVN* phase, Nod
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShenandoahLoadReferenceBarrierNode::is_redundant() {
|
||||
Unique_Node_List visited;
|
||||
Node_Stack stack(0);
|
||||
stack.push(this, 0);
|
||||
|
||||
// Check if the barrier is actually useful: go over nodes looking for useful uses
|
||||
// (e.g. memory accesses). Stop once we detected a required use. Otherwise, walk
|
||||
// until we ran out of nodes, and then declare the barrier redundant.
|
||||
while (stack.size() > 0) {
|
||||
Node* n = stack.node();
|
||||
if (visited.member(n)) {
|
||||
stack.pop();
|
||||
continue;
|
||||
}
|
||||
visited.push(n);
|
||||
bool visit_users = false;
|
||||
switch (n->Opcode()) {
|
||||
case Op_CallStaticJava:
|
||||
case Op_CallDynamicJava:
|
||||
case Op_CallLeaf:
|
||||
case Op_CallLeafNoFP:
|
||||
case Op_CompareAndSwapL:
|
||||
case Op_CompareAndSwapI:
|
||||
case Op_CompareAndSwapB:
|
||||
case Op_CompareAndSwapS:
|
||||
case Op_CompareAndSwapN:
|
||||
case Op_CompareAndSwapP:
|
||||
case Op_CompareAndExchangeL:
|
||||
case Op_CompareAndExchangeI:
|
||||
case Op_CompareAndExchangeB:
|
||||
case Op_CompareAndExchangeS:
|
||||
case Op_CompareAndExchangeN:
|
||||
case Op_CompareAndExchangeP:
|
||||
case Op_WeakCompareAndSwapL:
|
||||
case Op_WeakCompareAndSwapI:
|
||||
case Op_WeakCompareAndSwapB:
|
||||
case Op_WeakCompareAndSwapS:
|
||||
case Op_WeakCompareAndSwapN:
|
||||
case Op_WeakCompareAndSwapP:
|
||||
case Op_ShenandoahCompareAndSwapN:
|
||||
case Op_ShenandoahCompareAndSwapP:
|
||||
case Op_ShenandoahWeakCompareAndSwapN:
|
||||
case Op_ShenandoahWeakCompareAndSwapP:
|
||||
case Op_ShenandoahCompareAndExchangeN:
|
||||
case Op_ShenandoahCompareAndExchangeP:
|
||||
case Op_GetAndSetL:
|
||||
case Op_GetAndSetI:
|
||||
case Op_GetAndSetB:
|
||||
case Op_GetAndSetS:
|
||||
case Op_GetAndSetP:
|
||||
case Op_GetAndSetN:
|
||||
case Op_GetAndAddL:
|
||||
case Op_GetAndAddI:
|
||||
case Op_GetAndAddB:
|
||||
case Op_GetAndAddS:
|
||||
case Op_ShenandoahEnqueueBarrier:
|
||||
case Op_FastLock:
|
||||
case Op_FastUnlock:
|
||||
case Op_Rethrow:
|
||||
case Op_Return:
|
||||
case Op_StoreB:
|
||||
case Op_StoreC:
|
||||
case Op_StoreD:
|
||||
case Op_StoreF:
|
||||
case Op_StoreL:
|
||||
case Op_StoreLConditional:
|
||||
case Op_StoreI:
|
||||
case Op_StoreIConditional:
|
||||
case Op_StoreN:
|
||||
case Op_StoreP:
|
||||
case Op_StoreVector:
|
||||
case Op_StrInflatedCopy:
|
||||
case Op_StrCompressedCopy:
|
||||
case Op_EncodeP:
|
||||
case Op_CastP2X:
|
||||
case Op_SafePoint:
|
||||
case Op_EncodeISOArray:
|
||||
case Op_AryEq:
|
||||
case Op_StrEquals:
|
||||
case Op_StrComp:
|
||||
case Op_StrIndexOf:
|
||||
case Op_StrIndexOfChar:
|
||||
case Op_HasNegatives:
|
||||
// Known to require barriers
|
||||
return false;
|
||||
case Op_CmpP: {
|
||||
if (n->in(1)->bottom_type()->higher_equal(TypePtr::NULL_PTR) ||
|
||||
n->in(2)->bottom_type()->higher_equal(TypePtr::NULL_PTR)) {
|
||||
// One of the sides is known null, no need for barrier.
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Op_LoadB:
|
||||
case Op_LoadUB:
|
||||
case Op_LoadUS:
|
||||
case Op_LoadD:
|
||||
case Op_LoadF:
|
||||
case Op_LoadL:
|
||||
case Op_LoadI:
|
||||
case Op_LoadS:
|
||||
case Op_LoadN:
|
||||
case Op_LoadP:
|
||||
case Op_LoadVector: {
|
||||
const TypePtr* adr_type = n->adr_type();
|
||||
int alias_idx = Compile::current()->get_alias_index(adr_type);
|
||||
Compile::AliasType* alias_type = Compile::current()->alias_type(alias_idx);
|
||||
ciField* field = alias_type->field();
|
||||
bool is_static = field != NULL && field->is_static();
|
||||
bool is_final = field != NULL && field->is_final();
|
||||
|
||||
if (ShenandoahOptimizeStaticFinals && is_static && is_final) {
|
||||
// Loading the constant does not require barriers: it should be handled
|
||||
// as part of GC roots already.
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Op_Conv2B:
|
||||
case Op_LoadRange:
|
||||
case Op_LoadKlass:
|
||||
case Op_LoadNKlass:
|
||||
// Do not require barriers
|
||||
break;
|
||||
case Op_AddP:
|
||||
case Op_CheckCastPP:
|
||||
case Op_CastPP:
|
||||
case Op_CMoveP:
|
||||
case Op_Phi:
|
||||
case Op_ShenandoahLoadReferenceBarrier:
|
||||
// Whether or not these need the barriers depends on their users
|
||||
visit_users = true;
|
||||
break;
|
||||
default: {
|
||||
#ifdef ASSERT
|
||||
fatal("Unknown node in is_redundant: %s", NodeClassNames[n->Opcode()]);
|
||||
#else
|
||||
// Default to have excess barriers, rather than miss some.
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
stack.pop();
|
||||
if (visit_users) {
|
||||
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
|
||||
Node* user = n->fast_out(i);
|
||||
if (user != NULL) {
|
||||
stack.push(user, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No need for barrier found.
|
||||
return true;
|
||||
}
|
||||
|
@ -250,8 +250,6 @@ public:
|
||||
virtual uint hash() const;
|
||||
virtual bool cmp( const Node &n ) const;
|
||||
|
||||
bool is_redundant();
|
||||
|
||||
private:
|
||||
bool needs_barrier(PhaseGVN* phase, Node* n);
|
||||
bool needs_barrier_impl(PhaseGVN* phase, Node* n, Unique_Node_List &visited);
|
||||
|
@ -351,11 +351,6 @@
|
||||
" 1 - parallel iterator;" \
|
||||
" 2 - parallel iterator with cset filters;") \
|
||||
\
|
||||
diagnostic(bool, ShenandoahOptimizeStaticFinals, true, \
|
||||
"Optimize barriers on static final fields. " \
|
||||
"Turn it off for maximum compatibility with reflection or JNI " \
|
||||
"code that manipulates final fields.") \
|
||||
\
|
||||
develop(bool, ShenandoahVerifyOptoBarriers, false, \
|
||||
"Verify no missing barriers in C2.") \
|
||||
\
|
||||
|
Loading…
x
Reference in New Issue
Block a user