< prev index next >
src/share/vm/opto/compile.cpp
Print this page
*** 1921,1931 ****
// checks and uncommon_traps will be eliminated from the ideal graph
void Compile::cleanup_loop_predicates(PhaseIterGVN &igvn) {
if (predicate_count()==0) return;
for (int i = predicate_count(); i > 0; i--) {
Node * n = predicate_opaque1_node(i-1);
! assert(n->Opcode() == Op_Opaque1, "must be");
igvn.replace_node(n, n->in(1));
}
assert(predicate_count()==0, "should be clean!");
}
--- 1921,1931 ----
// checks and uncommon_traps will be eliminated from the ideal graph
void Compile::cleanup_loop_predicates(PhaseIterGVN &igvn) {
if (predicate_count()==0) return;
for (int i = predicate_count(); i > 0; i--) {
Node * n = predicate_opaque1_node(i-1);
! assert(n->Opcode() == Opcodes::Op_Opaque1, "must be");
igvn.replace_node(n, n->in(1));
}
assert(predicate_count()==0, "should be clean!");
}
*** 2604,2614 ****
#endif
// Eliminate trivially redundant StoreCMs and accumulate their
// precedence edges.
void Compile::eliminate_redundant_card_marks(Node* n) {
! assert(n->Opcode() == Op_StoreCM, "expected StoreCM");
if (n->in(MemNode::Address)->outcnt() > 1) {
// There are multiple users of the same address so it might be
// possible to eliminate some of the StoreCMs
Node* mem = n->in(MemNode::Memory);
Node* adr = n->in(MemNode::Address);
--- 2604,2614 ----
#endif
// Eliminate trivially redundant StoreCMs and accumulate their
// precedence edges.
void Compile::eliminate_redundant_card_marks(Node* n) {
! assert(n->Opcode() == Opcodes::Op_StoreCM, "expected StoreCM");
if (n->in(MemNode::Address)->outcnt() > 1) {
// There are multiple users of the same address so it might be
// possible to eliminate some of the StoreCMs
Node* mem = n->in(MemNode::Memory);
Node* adr = n->in(MemNode::Address);
*** 2617,2627 ****
bool done = false;
// Walk the chain of StoreCMs eliminating ones that match. As
// long as it's a chain of single users then the optimization is
// safe. Eliminating partially redundant StoreCMs would require
// cloning copies down the other paths.
! while (mem->Opcode() == Op_StoreCM && mem->outcnt() == 1 && !done) {
if (adr == mem->in(MemNode::Address) &&
val == mem->in(MemNode::ValueIn)) {
// redundant StoreCM
if (mem->req() > MemNode::OopStore) {
// Hasn't been processed by this code yet.
--- 2617,2627 ----
bool done = false;
// Walk the chain of StoreCMs eliminating ones that match. As
// long as it's a chain of single users then the optimization is
// safe. Eliminating partially redundant StoreCMs would require
// cloning copies down the other paths.
! while (mem->Opcode() == Opcodes::Op_StoreCM && mem->outcnt() == 1 && !done) {
if (adr == mem->in(MemNode::Address) &&
val == mem->in(MemNode::ValueIn)) {
// redundant StoreCM
if (mem->req() > MemNode::OopStore) {
// Hasn't been processed by this code yet.
*** 2652,2677 ****
//------------------------------final_graph_reshaping_impl----------------------
// Implement items 1-5 from final_graph_reshaping below.
void Compile::final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc) {
if ( n->outcnt() == 0 ) return; // dead node
! uint nop = n->Opcode();
// Check for 2-input instruction with "last use" on right input.
// Swap to left input. Implements item (2).
if( n->req() == 3 && // two-input instruction
n->in(1)->outcnt() > 1 && // left use is NOT a last use
(!n->in(1)->is_Phi() || n->in(1)->in(2) != n) && // it is not data loop
n->in(2)->outcnt() == 1 &&// right use IS a last use
!n->in(2)->is_Con() ) { // right use is not a constant
// Check for commutative opcode
switch( nop ) {
! case Op_AddI: case Op_AddF: case Op_AddD: case Op_AddL:
! case Op_MaxI: case Op_MinI:
! case Op_MulI: case Op_MulF: case Op_MulD: case Op_MulL:
! case Op_AndL: case Op_XorL: case Op_OrL:
! case Op_AndI: case Op_XorI: case Op_OrI: {
// Move "last use" input to left by swapping inputs
n->swap_edges(1, 2);
break;
}
default:
--- 2652,2677 ----
//------------------------------final_graph_reshaping_impl----------------------
// Implement items 1-5 from final_graph_reshaping below.
void Compile::final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc) {
if ( n->outcnt() == 0 ) return; // dead node
! Opcodes nop = n->Opcode();
// Check for 2-input instruction with "last use" on right input.
// Swap to left input. Implements item (2).
if( n->req() == 3 && // two-input instruction
n->in(1)->outcnt() > 1 && // left use is NOT a last use
(!n->in(1)->is_Phi() || n->in(1)->in(2) != n) && // it is not data loop
n->in(2)->outcnt() == 1 &&// right use IS a last use
!n->in(2)->is_Con() ) { // right use is not a constant
// Check for commutative opcode
switch( nop ) {
! case Opcodes::Op_AddI: case Opcodes::Op_AddF: case Opcodes::Op_AddD: case Opcodes::Op_AddL:
! case Opcodes::Op_MaxI: case Opcodes::Op_MinI:
! case Opcodes::Op_MulI: case Opcodes::Op_MulF: case Opcodes::Op_MulD: case Opcodes::Op_MulL:
! case Opcodes::Op_AndL: case Opcodes::Op_XorL: case Opcodes::Op_OrL:
! case Opcodes::Op_AndI: case Opcodes::Op_XorI: case Opcodes::Op_OrI: {
// Move "last use" input to left by swapping inputs
n->swap_edges(1, 2);
break;
}
default:
*** 2690,2845 ****
}
#endif
// Count FPU ops and common calls, implements item (3)
switch( nop ) {
// Count all float operations that may use FPU
! case Op_AddF:
! case Op_SubF:
! case Op_MulF:
! case Op_DivF:
! case Op_NegF:
! case Op_ModF:
! case Op_ConvI2F:
! case Op_ConF:
! case Op_CmpF:
! case Op_CmpF3:
// case Op_ConvL2F: // longs are split into 32-bit halves
frc.inc_float_count();
break;
! case Op_ConvF2D:
! case Op_ConvD2F:
frc.inc_float_count();
frc.inc_double_count();
break;
// Count all double operations that may use FPU
! case Op_AddD:
! case Op_SubD:
! case Op_MulD:
! case Op_DivD:
! case Op_NegD:
! case Op_ModD:
! case Op_ConvI2D:
! case Op_ConvD2I:
// case Op_ConvL2D: // handled by leaf call
// case Op_ConvD2L: // handled by leaf call
! case Op_ConD:
! case Op_CmpD:
! case Op_CmpD3:
frc.inc_double_count();
break;
! case Op_Opaque1: // Remove Opaque Nodes before matching
! case Op_Opaque2: // Remove Opaque Nodes before matching
! case Op_Opaque3:
n->subsume_by(n->in(1), this);
break;
! case Op_CallStaticJava:
! case Op_CallJava:
! case Op_CallDynamicJava:
frc.inc_java_call_count(); // Count java call site;
! case Op_CallRuntime:
! case Op_CallLeaf:
! case Op_CallLeafNoFP: {
assert( n->is_Call(), "" );
CallNode *call = n->as_Call();
// Count call sites where the FP mode bit would have to be flipped.
// Do not count uncommon runtime calls:
// uncommon_trap, _complete_monitor_locking, _complete_monitor_unlocking,
// _new_Java, _new_typeArray, _new_objArray, _rethrow_Java, ...
if( !call->is_CallStaticJava() || !call->as_CallStaticJava()->_name ) {
frc.inc_call_count(); // Count the call site
} else { // See if uncommon argument is shared
Node *n = call->in(TypeFunc::Parms);
! int nop = n->Opcode();
// Clone shared simple arguments to uncommon calls, item (1).
if( n->outcnt() > 1 &&
!n->is_Proj() &&
! nop != Op_CreateEx &&
! nop != Op_CheckCastPP &&
! nop != Op_DecodeN &&
! nop != Op_DecodeNKlass &&
!n->is_Mem() ) {
Node *x = n->clone();
call->set_req( TypeFunc::Parms, x );
}
}
break;
}
! case Op_StoreD:
! case Op_LoadD:
! case Op_LoadD_unaligned:
frc.inc_double_count();
goto handle_mem;
! case Op_StoreF:
! case Op_LoadF:
frc.inc_float_count();
goto handle_mem;
! case Op_StoreCM:
{
// Convert OopStore dependence into precedence edge
Node* prec = n->in(MemNode::OopStore);
n->del_req(MemNode::OopStore);
n->add_prec(prec);
eliminate_redundant_card_marks(n);
}
// fall through
! case Op_StoreB:
! case Op_StoreC:
! case Op_StorePConditional:
! case Op_StoreI:
! case Op_StoreL:
! case Op_StoreIConditional:
! case Op_StoreLConditional:
! case Op_CompareAndSwapB:
! case Op_CompareAndSwapS:
! case Op_CompareAndSwapI:
! case Op_CompareAndSwapL:
! case Op_CompareAndSwapP:
! case Op_CompareAndSwapN:
! case Op_WeakCompareAndSwapB:
! case Op_WeakCompareAndSwapS:
! case Op_WeakCompareAndSwapI:
! case Op_WeakCompareAndSwapL:
! case Op_WeakCompareAndSwapP:
! case Op_WeakCompareAndSwapN:
! case Op_CompareAndExchangeB:
! case Op_CompareAndExchangeS:
! case Op_CompareAndExchangeI:
! case Op_CompareAndExchangeL:
! case Op_CompareAndExchangeP:
! case Op_CompareAndExchangeN:
! case Op_GetAndAddS:
! case Op_GetAndAddB:
! case Op_GetAndAddI:
! case Op_GetAndAddL:
! case Op_GetAndSetS:
! case Op_GetAndSetB:
! case Op_GetAndSetI:
! case Op_GetAndSetL:
! case Op_GetAndSetP:
! case Op_GetAndSetN:
! case Op_StoreP:
! case Op_StoreN:
! case Op_StoreNKlass:
! case Op_LoadB:
! case Op_LoadUB:
! case Op_LoadUS:
! case Op_LoadI:
! case Op_LoadKlass:
! case Op_LoadNKlass:
! case Op_LoadL:
! case Op_LoadL_unaligned:
! case Op_LoadPLocked:
! case Op_LoadP:
! case Op_LoadN:
! case Op_LoadRange:
! case Op_LoadS: {
handle_mem:
#ifdef ASSERT
if( VerifyOptoOopOffsets ) {
assert( n->is_Mem(), "" );
MemNode *mem = (MemNode*)n;
--- 2690,2845 ----
}
#endif
// Count FPU ops and common calls, implements item (3)
switch( nop ) {
// Count all float operations that may use FPU
! case Opcodes::Op_AddF:
! case Opcodes::Op_SubF:
! case Opcodes::Op_MulF:
! case Opcodes::Op_DivF:
! case Opcodes::Op_NegF:
! case Opcodes::Op_ModF:
! case Opcodes::Op_ConvI2F:
! case Opcodes::Op_ConF:
! case Opcodes::Op_CmpF:
! case Opcodes::Op_CmpF3:
// case Op_ConvL2F: // longs are split into 32-bit halves
frc.inc_float_count();
break;
! case Opcodes::Op_ConvF2D:
! case Opcodes::Op_ConvD2F:
frc.inc_float_count();
frc.inc_double_count();
break;
// Count all double operations that may use FPU
! case Opcodes::Op_AddD:
! case Opcodes::Op_SubD:
! case Opcodes::Op_MulD:
! case Opcodes::Op_DivD:
! case Opcodes::Op_NegD:
! case Opcodes::Op_ModD:
! case Opcodes::Op_ConvI2D:
! case Opcodes::Op_ConvD2I:
// case Op_ConvL2D: // handled by leaf call
// case Op_ConvD2L: // handled by leaf call
! case Opcodes::Op_ConD:
! case Opcodes::Op_CmpD:
! case Opcodes::Op_CmpD3:
frc.inc_double_count();
break;
! case Opcodes::Op_Opaque1: // Remove Opaque Nodes before matching
! case Opcodes::Op_Opaque2: // Remove Opaque Nodes before matching
! case Opcodes::Op_Opaque3:
n->subsume_by(n->in(1), this);
break;
! case Opcodes::Op_CallStaticJava:
! case Opcodes::Op_CallJava:
! case Opcodes::Op_CallDynamicJava:
frc.inc_java_call_count(); // Count java call site;
! case Opcodes::Op_CallRuntime:
! case Opcodes::Op_CallLeaf:
! case Opcodes::Op_CallLeafNoFP: {
assert( n->is_Call(), "" );
CallNode *call = n->as_Call();
// Count call sites where the FP mode bit would have to be flipped.
// Do not count uncommon runtime calls:
// uncommon_trap, _complete_monitor_locking, _complete_monitor_unlocking,
// _new_Java, _new_typeArray, _new_objArray, _rethrow_Java, ...
if( !call->is_CallStaticJava() || !call->as_CallStaticJava()->_name ) {
frc.inc_call_count(); // Count the call site
} else { // See if uncommon argument is shared
Node *n = call->in(TypeFunc::Parms);
! Opcodes nop = n->Opcode();
// Clone shared simple arguments to uncommon calls, item (1).
if( n->outcnt() > 1 &&
!n->is_Proj() &&
! nop != Opcodes::Op_CreateEx &&
! nop != Opcodes::Op_CheckCastPP &&
! nop != Opcodes::Op_DecodeN &&
! nop != Opcodes::Op_DecodeNKlass &&
!n->is_Mem() ) {
Node *x = n->clone();
call->set_req( TypeFunc::Parms, x );
}
}
break;
}
! case Opcodes::Op_StoreD:
! case Opcodes::Op_LoadD:
! case Opcodes::Op_LoadD_unaligned:
frc.inc_double_count();
goto handle_mem;
! case Opcodes::Op_StoreF:
! case Opcodes::Op_LoadF:
frc.inc_float_count();
goto handle_mem;
! case Opcodes::Op_StoreCM:
{
// Convert OopStore dependence into precedence edge
Node* prec = n->in(MemNode::OopStore);
n->del_req(MemNode::OopStore);
n->add_prec(prec);
eliminate_redundant_card_marks(n);
}
// fall through
! case Opcodes::Op_StoreB:
! case Opcodes::Op_StoreC:
! case Opcodes::Op_StorePConditional:
! case Opcodes::Op_StoreI:
! case Opcodes::Op_StoreL:
! case Opcodes::Op_StoreIConditional:
! case Opcodes::Op_StoreLConditional:
! case Opcodes::Op_CompareAndSwapB:
! case Opcodes::Op_CompareAndSwapS:
! case Opcodes::Op_CompareAndSwapI:
! case Opcodes::Op_CompareAndSwapL:
! case Opcodes::Op_CompareAndSwapP:
! case Opcodes::Op_CompareAndSwapN:
! case Opcodes::Op_WeakCompareAndSwapB:
! case Opcodes::Op_WeakCompareAndSwapS:
! case Opcodes::Op_WeakCompareAndSwapI:
! case Opcodes::Op_WeakCompareAndSwapL:
! case Opcodes::Op_WeakCompareAndSwapP:
! case Opcodes::Op_WeakCompareAndSwapN:
! case Opcodes::Op_CompareAndExchangeB:
! case Opcodes::Op_CompareAndExchangeS:
! case Opcodes::Op_CompareAndExchangeI:
! case Opcodes::Op_CompareAndExchangeL:
! case Opcodes::Op_CompareAndExchangeP:
! case Opcodes::Op_CompareAndExchangeN:
! case Opcodes::Op_GetAndAddS:
! case Opcodes::Op_GetAndAddB:
! case Opcodes::Op_GetAndAddI:
! case Opcodes::Op_GetAndAddL:
! case Opcodes::Op_GetAndSetS:
! case Opcodes::Op_GetAndSetB:
! case Opcodes::Op_GetAndSetI:
! case Opcodes::Op_GetAndSetL:
! case Opcodes::Op_GetAndSetP:
! case Opcodes::Op_GetAndSetN:
! case Opcodes::Op_StoreP:
! case Opcodes::Op_StoreN:
! case Opcodes::Op_StoreNKlass:
! case Opcodes::Op_LoadB:
! case Opcodes::Op_LoadUB:
! case Opcodes::Op_LoadUS:
! case Opcodes::Op_LoadI:
! case Opcodes::Op_LoadKlass:
! case Opcodes::Op_LoadNKlass:
! case Opcodes::Op_LoadL:
! case Opcodes::Op_LoadL_unaligned:
! case Opcodes::Op_LoadPLocked:
! case Opcodes::Op_LoadP:
! case Opcodes::Op_LoadN:
! case Opcodes::Op_LoadRange:
! case Opcodes::Op_LoadS: {
handle_mem:
#ifdef ASSERT
if( VerifyOptoOopOffsets ) {
assert( n->is_Mem(), "" );
MemNode *mem = (MemNode*)n;
*** 2849,2878 ****
}
#endif
break;
}
! case Op_AddP: { // Assert sane base pointers
Node *addp = n->in(AddPNode::Address);
assert( !addp->is_AddP() ||
addp->in(AddPNode::Base)->is_top() || // Top OK for allocation
addp->in(AddPNode::Base) == n->in(AddPNode::Base),
"Base pointers must match (addp %u)", addp->_idx );
#ifdef _LP64
if ((UseCompressedOops || UseCompressedClassPointers) &&
! addp->Opcode() == Op_ConP &&
addp == n->in(AddPNode::Base) &&
n->in(AddPNode::Offset)->is_Con()) {
// Use addressing with narrow klass to load with offset on x86.
// On sparc loading 32-bits constant and decoding it have less
// instructions (4) then load 64-bits constant (7).
// Do this transformation here since IGVN will convert ConN back to ConP.
const Type* t = addp->bottom_type();
if (t->isa_oopptr() || t->isa_klassptr()) {
Node* nn = NULL;
! int op = t->isa_oopptr() ? Op_ConN : Op_ConNKlass;
// Look for existing ConN node of the same exact type.
Node* r = root();
uint cnt = r->outcnt();
for (uint i = 0; i < cnt; i++) {
--- 2849,2878 ----
}
#endif
break;
}
! case Opcodes::Op_AddP: { // Assert sane base pointers
Node *addp = n->in(AddPNode::Address);
assert( !addp->is_AddP() ||
addp->in(AddPNode::Base)->is_top() || // Top OK for allocation
addp->in(AddPNode::Base) == n->in(AddPNode::Base),
"Base pointers must match (addp %u)", addp->_idx );
#ifdef _LP64
if ((UseCompressedOops || UseCompressedClassPointers) &&
! addp->Opcode() == Opcodes::Op_ConP &&
addp == n->in(AddPNode::Base) &&
n->in(AddPNode::Offset)->is_Con()) {
// Use addressing with narrow klass to load with offset on x86.
// On sparc loading 32-bits constant and decoding it have less
// instructions (4) then load 64-bits constant (7).
// Do this transformation here since IGVN will convert ConN back to ConP.
const Type* t = addp->bottom_type();
if (t->isa_oopptr() || t->isa_klassptr()) {
Node* nn = NULL;
! Opcodes op = t->isa_oopptr() ? Opcodes::Op_ConN : Opcodes::Op_ConNKlass;
// Look for existing ConN node of the same exact type.
Node* r = root();
uint cnt = r->outcnt();
for (uint i = 0; i < cnt; i++) {
*** 2918,2928 ****
// platform dependent reshaping of the address expression
reshape_address(n->as_AddP());
break;
}
! case Op_CastPP: {
// Remove CastPP nodes to gain more freedom during scheduling but
// keep the dependency they encode as control or precedence edges
// (if control is set already) on memory operations. Some CastPP
// nodes don't have a control (don't carry a dependency): skip
// those.
--- 2918,2928 ----
// platform dependent reshaping of the address expression
reshape_address(n->as_AddP());
break;
}
! case Opcodes::Op_CastPP: {
// Remove CastPP nodes to gain more freedom during scheduling but
// keep the dependency they encode as control or precedence edges
// (if control is set already) on memory operations. Some CastPP
// nodes don't have a control (don't carry a dependency): skip
// those.
*** 2936,2950 ****
Node* use = m->fast_out(i);
if (use->is_Mem() || use->is_EncodeNarrowPtr()) {
use->ensure_control_or_add_prec(n->in(0));
} else {
switch(use->Opcode()) {
! case Op_AddP:
! case Op_DecodeN:
! case Op_DecodeNKlass:
! case Op_CheckCastPP:
! case Op_CastPP:
wq.push(use);
break;
}
}
}
--- 2936,2950 ----
Node* use = m->fast_out(i);
if (use->is_Mem() || use->is_EncodeNarrowPtr()) {
use->ensure_control_or_add_prec(n->in(0));
} else {
switch(use->Opcode()) {
! case Opcodes::Op_AddP:
! case Opcodes::Op_DecodeN:
! case Opcodes::Op_DecodeNKlass:
! case Opcodes::Op_CheckCastPP:
! case Opcodes::Op_CastPP:
wq.push(use);
break;
}
}
}
*** 2991,3001 ****
}
}
break;
}
#ifdef _LP64
! case Op_CmpP:
// Do this transformation here to preserve CmpPNode::sub() and
// other TypePtr related Ideal optimizations (for example, ptr nullness).
if (n->in(1)->is_DecodeNarrowPtr() || n->in(2)->is_DecodeNarrowPtr()) {
Node* in1 = n->in(1);
Node* in2 = n->in(2);
--- 2991,3001 ----
}
}
break;
}
#ifdef _LP64
! case Opcodes::Op_CmpP:
// Do this transformation here to preserve CmpPNode::sub() and
// other TypePtr related Ideal optimizations (for example, ptr nullness).
if (n->in(1)->is_DecodeNarrowPtr() || n->in(2)->is_DecodeNarrowPtr()) {
Node* in1 = n->in(1);
Node* in2 = n->in(2);
*** 3007,3017 ****
Node* new_in2 = NULL;
if (in2->is_DecodeNarrowPtr()) {
assert(in2->Opcode() == in1->Opcode(), "must be same node type");
new_in2 = in2->in(1);
! } else if (in2->Opcode() == Op_ConP) {
const Type* t = in2->bottom_type();
if (t == TypePtr::NULL_PTR) {
assert(in1->is_DecodeN(), "compare klass to null?");
// Don't convert CmpP null check into CmpN if compressed
// oops implicit null check is not generated.
--- 3007,3017 ----
Node* new_in2 = NULL;
if (in2->is_DecodeNarrowPtr()) {
assert(in2->Opcode() == in1->Opcode(), "must be same node type");
new_in2 = in2->in(1);
! } else if (in2->Opcode() == Opcodes::Op_ConP) {
const Type* t = in2->bottom_type();
if (t == TypePtr::NULL_PTR) {
assert(in1->is_DecodeN(), "compare klass to null?");
// Don't convert CmpP null check into CmpN if compressed
// oops implicit null check is not generated.
*** 3072,3095 ****
}
}
}
break;
! case Op_DecodeN:
! case Op_DecodeNKlass:
assert(!n->in(1)->is_EncodeNarrowPtr(), "should be optimized out");
// DecodeN could be pinned when it can't be fold into
// an address expression, see the code for Op_CastPP above.
assert(n->in(0) == NULL || (UseCompressedOops && !Matcher::narrow_oop_use_complex_address()), "no control");
break;
! case Op_EncodeP:
! case Op_EncodePKlass: {
Node* in1 = n->in(1);
if (in1->is_DecodeNarrowPtr()) {
n->subsume_by(in1->in(1), this);
! } else if (in1->Opcode() == Op_ConP) {
const Type* t = in1->bottom_type();
if (t == TypePtr::NULL_PTR) {
assert(t->isa_oopptr(), "null klass?");
n->subsume_by(ConNode::make(TypeNarrowOop::NULL_PTR), this);
} else if (t->isa_oopptr()) {
--- 3072,3095 ----
}
}
}
break;
! case Opcodes::Op_DecodeN:
! case Opcodes::Op_DecodeNKlass:
assert(!n->in(1)->is_EncodeNarrowPtr(), "should be optimized out");
// DecodeN could be pinned when it can't be fold into
// an address expression, see the code for Op_CastPP above.
assert(n->in(0) == NULL || (UseCompressedOops && !Matcher::narrow_oop_use_complex_address()), "no control");
break;
! case Opcodes::Op_EncodeP:
! case Opcodes::Op_EncodePKlass: {
Node* in1 = n->in(1);
if (in1->is_DecodeNarrowPtr()) {
n->subsume_by(in1->in(1), this);
! } else if (in1->Opcode() == Opcodes::Op_ConP) {
const Type* t = in1->bottom_type();
if (t == TypePtr::NULL_PTR) {
assert(t->isa_oopptr(), "null klass?");
n->subsume_by(ConNode::make(TypeNarrowOop::NULL_PTR), this);
} else if (t->isa_oopptr()) {
*** 3102,3112 ****
in1->disconnect_inputs(NULL, this);
}
break;
}
! case Op_Proj: {
if (OptimizeStringConcat) {
ProjNode* p = n->as_Proj();
if (p->_is_io_use) {
// Separate projections were used for the exception path which
// are normally removed by a late inline. If it wasn't inlined
--- 3102,3112 ----
in1->disconnect_inputs(NULL, this);
}
break;
}
! case Opcodes::Op_Proj: {
if (OptimizeStringConcat) {
ProjNode* p = n->as_Proj();
if (p->_is_io_use) {
// Separate projections were used for the exception path which
// are normally removed by a late inline. If it wasn't inlined
*** 3126,3136 ****
}
}
break;
}
! case Op_Phi:
if (n->as_Phi()->bottom_type()->isa_narrowoop() || n->as_Phi()->bottom_type()->isa_narrowklass()) {
// The EncodeP optimization may create Phi with the same edges
// for all paths. It is not handled well by Register Allocator.
Node* unique_in = n->in(1);
assert(unique_in != NULL, "");
--- 3126,3136 ----
}
}
break;
}
! case Opcodes::Op_Phi:
if (n->as_Phi()->bottom_type()->isa_narrowoop() || n->as_Phi()->bottom_type()->isa_narrowklass()) {
// The EncodeP optimization may create Phi with the same edges
// for all paths. It is not handled well by Register Allocator.
Node* unique_in = n->in(1);
assert(unique_in != NULL, "");
*** 3148,3173 ****
break;
#endif
#ifdef ASSERT
! case Op_CastII:
// Verify that all range check dependent CastII nodes were removed.
if (n->isa_CastII()->has_range_check()) {
n->dump(3);
assert(false, "Range check dependent CastII node was not removed");
}
break;
#endif
! case Op_ModI:
if (UseDivMod) {
// Check if a%b and a/b both exist
! Node* d = n->find_similar(Op_DivI);
if (d) {
// Replace them with a fused divmod if supported
! if (Matcher::has_match_rule(Op_DivModI)) {
DivModINode* divmod = DivModINode::make(n);
d->subsume_by(divmod->div_proj(), this);
n->subsume_by(divmod->mod_proj(), this);
} else {
// replace a%b with a-((a/b)*b)
--- 3148,3173 ----
break;
#endif
#ifdef ASSERT
! case Opcodes::Op_CastII:
// Verify that all range check dependent CastII nodes were removed.
if (n->isa_CastII()->has_range_check()) {
n->dump(3);
assert(false, "Range check dependent CastII node was not removed");
}
break;
#endif
! case Opcodes::Op_ModI:
if (UseDivMod) {
// Check if a%b and a/b both exist
! Node* d = n->find_similar(Opcodes::Op_DivI);
if (d) {
// Replace them with a fused divmod if supported
! if (Matcher::has_match_rule(Opcodes::Op_DivModI)) {
DivModINode* divmod = DivModINode::make(n);
d->subsume_by(divmod->div_proj(), this);
n->subsume_by(divmod->mod_proj(), this);
} else {
// replace a%b with a-((a/b)*b)
*** 3177,3193 ****
}
}
}
break;
! case Op_ModL:
if (UseDivMod) {
// Check if a%b and a/b both exist
! Node* d = n->find_similar(Op_DivL);
if (d) {
// Replace them with a fused divmod if supported
! if (Matcher::has_match_rule(Op_DivModL)) {
DivModLNode* divmod = DivModLNode::make(n);
d->subsume_by(divmod->div_proj(), this);
n->subsume_by(divmod->mod_proj(), this);
} else {
// replace a%b with a-((a/b)*b)
--- 3177,3193 ----
}
}
}
break;
! case Opcodes::Op_ModL:
if (UseDivMod) {
// Check if a%b and a/b both exist
! Node* d = n->find_similar(Opcodes::Op_DivL);
if (d) {
// Replace them with a fused divmod if supported
! if (Matcher::has_match_rule(Opcodes::Op_DivModL)) {
DivModLNode* divmod = DivModLNode::make(n);
d->subsume_by(divmod->div_proj(), this);
n->subsume_by(divmod->mod_proj(), this);
} else {
// replace a%b with a-((a/b)*b)
*** 3197,3245 ****
}
}
}
break;
! case Op_LoadVector:
! case Op_StoreVector:
break;
! case Op_AddReductionVI:
! case Op_AddReductionVL:
! case Op_AddReductionVF:
! case Op_AddReductionVD:
! case Op_MulReductionVI:
! case Op_MulReductionVL:
! case Op_MulReductionVF:
! case Op_MulReductionVD:
! break;
!
! case Op_PackB:
! case Op_PackS:
! case Op_PackI:
! case Op_PackF:
! case Op_PackL:
! case Op_PackD:
if (n->req()-1 > 2) {
// Replace many operand PackNodes with a binary tree for matching
PackNode* p = (PackNode*) n;
Node* btp = p->binary_tree_pack(1, n->req());
n->subsume_by(btp, this);
}
break;
! case Op_Loop:
! case Op_CountedLoop:
if (n->as_Loop()->is_inner_loop()) {
frc.inc_inner_loop_count();
}
break;
! case Op_LShiftI:
! case Op_RShiftI:
! case Op_URShiftI:
! case Op_LShiftL:
! case Op_RShiftL:
! case Op_URShiftL:
if (Matcher::need_masked_shift_count) {
// The cpu's shift instructions don't restrict the count to the
// lower 5/6 bits. We need to do the masking ourselves.
Node* in2 = n->in(2);
juint mask = (n->bottom_type() == TypeInt::INT) ? (BitsPerInt - 1) : (BitsPerLong - 1);
--- 3197,3245 ----
}
}
}
break;
! case Opcodes::Op_LoadVector:
! case Opcodes::Op_StoreVector:
break;
! case Opcodes::Op_AddReductionVI:
! case Opcodes::Op_AddReductionVL:
! case Opcodes::Op_AddReductionVF:
! case Opcodes::Op_AddReductionVD:
! case Opcodes::Op_MulReductionVI:
! case Opcodes::Op_MulReductionVL:
! case Opcodes::Op_MulReductionVF:
! case Opcodes::Op_MulReductionVD:
! break;
!
! case Opcodes::Op_PackB:
! case Opcodes::Op_PackS:
! case Opcodes::Op_PackI:
! case Opcodes::Op_PackF:
! case Opcodes::Op_PackL:
! case Opcodes::Op_PackD:
if (n->req()-1 > 2) {
// Replace many operand PackNodes with a binary tree for matching
PackNode* p = (PackNode*) n;
Node* btp = p->binary_tree_pack(1, n->req());
n->subsume_by(btp, this);
}
break;
! case Opcodes::Op_Loop:
! case Opcodes::Op_CountedLoop:
if (n->as_Loop()->is_inner_loop()) {
frc.inc_inner_loop_count();
}
break;
! case Opcodes::Op_LShiftI:
! case Opcodes::Op_RShiftI:
! case Opcodes::Op_URShiftI:
! case Opcodes::Op_LShiftL:
! case Opcodes::Op_RShiftL:
! case Opcodes::Op_URShiftL:
if (Matcher::need_masked_shift_count) {
// The cpu's shift instructions don't restrict the count to the
// lower 5/6 bits. We need to do the masking ourselves.
Node* in2 = n->in(2);
juint mask = (n->bottom_type() == TypeInt::INT) ? (BitsPerInt - 1) : (BitsPerLong - 1);
*** 3258,3283 ****
if (in2->outcnt() == 0) { // Remove dead node
in2->disconnect_inputs(NULL, this);
}
}
break;
! case Op_MemBarStoreStore:
! case Op_MemBarRelease:
// Break the link with AllocateNode: it is no longer useful and
// confuses register allocation.
if (n->req() > MemBarNode::Precedent) {
n->set_req(MemBarNode::Precedent, top());
}
break;
! case Op_RangeCheck: {
RangeCheckNode* rc = n->as_RangeCheck();
Node* iff = new IfNode(rc->in(0), rc->in(1), rc->_prob, rc->_fcnt);
n->subsume_by(iff, this);
frc._tests.push(iff);
break;
}
! case Op_ConvI2L: {
if (!Matcher::convi2l_type_required) {
// Code generation on some platforms doesn't need accurate
// ConvI2L types. Widening the type can help remove redundant
// address computations.
n->as_Type()->set_type(TypeLong::INT);
--- 3258,3283 ----
if (in2->outcnt() == 0) { // Remove dead node
in2->disconnect_inputs(NULL, this);
}
}
break;
! case Opcodes::Op_MemBarStoreStore:
! case Opcodes::Op_MemBarRelease:
// Break the link with AllocateNode: it is no longer useful and
// confuses register allocation.
if (n->req() > MemBarNode::Precedent) {
n->set_req(MemBarNode::Precedent, top());
}
break;
! case Opcodes::Op_RangeCheck: {
RangeCheckNode* rc = n->as_RangeCheck();
Node* iff = new IfNode(rc->in(0), rc->in(1), rc->_prob, rc->_fcnt);
n->subsume_by(iff, this);
frc._tests.push(iff);
break;
}
! case Opcodes::Op_ConvI2L: {
if (!Matcher::convi2l_type_required) {
// Code generation on some platforms doesn't need accurate
// ConvI2L types. Widening the type can help remove redundant
// address computations.
n->as_Type()->set_type(TypeLong::INT);
*** 3296,3309 ****
// Push their uses so we get a chance to remove node made
// redundant
for (DUIterator_Fast imax, i = k->fast_outs(imax); i < imax; i++) {
Node* u = k->fast_out(i);
assert(!wq.contains(u), "shouldn't process one node several times");
! if (u->Opcode() == Op_LShiftL ||
! u->Opcode() == Op_AddL ||
! u->Opcode() == Op_SubL ||
! u->Opcode() == Op_AddP) {
wq.push(u);
}
}
// Replace all nodes with identical edges as m with m
k->subsume_by(m, this);
--- 3296,3309 ----
// Push their uses so we get a chance to remove node made
// redundant
for (DUIterator_Fast imax, i = k->fast_outs(imax); i < imax; i++) {
Node* u = k->fast_out(i);
assert(!wq.contains(u), "shouldn't process one node several times");
! if (u->Opcode() == Opcodes::Op_LShiftL ||
! u->Opcode() == Opcodes::Op_AddL ||
! u->Opcode() == Opcodes::Op_SubL ||
! u->Opcode() == Opcodes::Op_AddP) {
wq.push(u);
}
}
// Replace all nodes with identical edges as m with m
k->subsume_by(m, this);
*** 3313,3323 ****
break;
}
default:
assert( !n->is_Call(), "" );
assert( !n->is_Mem(), "" );
! assert( nop != Op_ProfileBoolean, "should be eliminated during IGVN");
break;
}
// Collect CFG split points
if (n->is_MultiBranch() && !n->is_RangeCheck()) {
--- 3313,3323 ----
break;
}
default:
assert( !n->is_Call(), "" );
assert( !n->is_Mem(), "" );
! assert( nop != Opcodes::Op_ProfileBoolean, "should be eliminated during IGVN");
break;
}
// Collect CFG split points
if (n->is_MultiBranch() && !n->is_RangeCheck()) {
*** 3711,3734 ****
// See GraphKit::g1_write_barrier_pre()
if (x->is_If()) {
IfNode *iff = x->as_If();
if (iff->in(1)->is_Bool() && iff->in(1)->in(1)->is_Cmp()) {
CmpNode *cmp = iff->in(1)->in(1)->as_Cmp();
! if (cmp->Opcode() == Op_CmpI && cmp->in(2)->is_Con() && cmp->in(2)->bottom_type()->is_int()->get_con() == 0
&& cmp->in(1)->is_Load()) {
LoadNode* load = cmp->in(1)->as_Load();
! if (load->Opcode() == Op_LoadB && load->in(2)->is_AddP() && load->in(2)->in(2)->Opcode() == Op_ThreadLocal
&& load->in(2)->in(3)->is_Con()
&& load->in(2)->in(3)->bottom_type()->is_intptr_t()->get_con() == marking_offset) {
Node* if_ctrl = iff->in(0);
Node* load_ctrl = load->in(0);
if (if_ctrl != load_ctrl) {
// Skip possible CProj->NeverBranch in infinite loops
! if ((if_ctrl->is_Proj() && if_ctrl->Opcode() == Op_CProj)
! && (if_ctrl->in(0)->is_MultiBranch() && if_ctrl->in(0)->Opcode() == Op_NeverBranch)) {
if_ctrl = if_ctrl->in(0)->in(0);
}
}
assert(load_ctrl != NULL && if_ctrl == load_ctrl, "controls must match");
}
--- 3711,3734 ----
// See GraphKit::g1_write_barrier_pre()
if (x->is_If()) {
IfNode *iff = x->as_If();
if (iff->in(1)->is_Bool() && iff->in(1)->in(1)->is_Cmp()) {
CmpNode *cmp = iff->in(1)->in(1)->as_Cmp();
! if (cmp->Opcode() == Opcodes::Op_CmpI && cmp->in(2)->is_Con() && cmp->in(2)->bottom_type()->is_int()->get_con() == 0
&& cmp->in(1)->is_Load()) {
LoadNode* load = cmp->in(1)->as_Load();
! if (load->Opcode() == Opcodes::Op_LoadB && load->in(2)->is_AddP() && load->in(2)->in(2)->Opcode() == Opcodes::Op_ThreadLocal
&& load->in(2)->in(3)->is_Con()
&& load->in(2)->in(3)->bottom_type()->is_intptr_t()->get_con() == marking_offset) {
Node* if_ctrl = iff->in(0);
Node* load_ctrl = load->in(0);
if (if_ctrl != load_ctrl) {
// Skip possible CProj->NeverBranch in infinite loops
! if ((if_ctrl->is_Proj() && if_ctrl->Opcode() == Opcodes::Op_CProj)
! && (if_ctrl->in(0)->is_MultiBranch() && if_ctrl->in(0)->Opcode() == Opcodes::Op_NeverBranch)) {
if_ctrl = if_ctrl->in(0)->in(0);
}
}
assert(load_ctrl != NULL && if_ctrl == load_ctrl, "controls must match");
}
*** 4290,4300 ****
int Compile::cmp_expensive_nodes(Node* n1, Node* n2) {
if (n1->Opcode() < n2->Opcode()) return -1;
else if (n1->Opcode() > n2->Opcode()) return 1;
! assert(n1->req() == n2->req(), "can't compare %s nodes: n1->req() = %d, n2->req() = %d", NodeClassNames[n1->Opcode()], n1->req(), n2->req());
for (uint i = 1; i < n1->req(); i++) {
if (n1->in(i) < n2->in(i)) return -1;
else if (n1->in(i) > n2->in(i)) return 1;
}
--- 4290,4300 ----
int Compile::cmp_expensive_nodes(Node* n1, Node* n2) {
if (n1->Opcode() < n2->Opcode()) return -1;
else if (n1->Opcode() > n2->Opcode()) return 1;
! assert(n1->req() == n2->req(), "can't compare %s nodes: n1->req() = %d, n2->req() = %d", NodeClassNames[static_cast<uint>(n1->Opcode())], n1->req(), n2->req());
for (uint i = 1; i < n1->req(); i++) {
if (n1->in(i) < n2->in(i)) return -1;
else if (n1->in(i) > n2->in(i)) return 1;
}
< prev index next >