< 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 >