diff --git a/src/share/vm/opto/graphKit.cpp b/src/share/vm/opto/graphKit.cpp index b20513e67c1fe38e8675b1868af115429f04182e..4fef2641d40583a835bf3a90ec9190aef33a206d 100644 --- a/src/share/vm/opto/graphKit.cpp +++ b/src/share/vm/opto/graphKit.cpp @@ -3385,12 +3385,17 @@ void GraphKit::add_predicate(int nargs) { #define __ ideal. void GraphKit::sync_kit(IdealKit& ideal) { - // Final sync IdealKit and graphKit. - __ drain_delay_transform(); set_all_memory(__ merged_memory()); + set_i_o(__ i_o()); set_control(__ ctrl()); } +void GraphKit::final_sync(IdealKit& ideal) { + // Final sync IdealKit and graphKit. + __ drain_delay_transform(); + sync_kit(ideal); +} + // vanilla/CMS post barrier // Insert a write-barrier store. This is to let generational GC work; we have // to flag all oop-stores before the next GC point. @@ -3435,7 +3440,7 @@ void GraphKit::write_barrier_post(Node* oop_store, // (Else it's an array (or unknown), and we want more precise card marks.) assert(adr != NULL, ""); - IdealKit ideal(gvn(), control(), merged_memory(), true); + IdealKit ideal(this, true); // Convert the pointer to an int prior to doing math on it Node* cast = __ CastPX(__ ctrl(), adr); @@ -3461,7 +3466,7 @@ void GraphKit::write_barrier_post(Node* oop_store, } // Final sync IdealKit and GraphKit. - sync_kit(ideal); + final_sync(ideal); } // G1 pre/post barriers @@ -3471,7 +3476,7 @@ void GraphKit::g1_write_barrier_pre(Node* obj, Node* val, const TypeOopPtr* val_type, BasicType bt) { - IdealKit ideal(gvn(), control(), merged_memory(), true); + IdealKit ideal(this, true); Node* tls = __ thread(); // ThreadLocalStorage @@ -3548,7 +3553,7 @@ void GraphKit::g1_write_barrier_pre(Node* obj, } __ end_if(); // (!marking) // Final sync IdealKit and GraphKit. - sync_kit(ideal); + final_sync(ideal); } // @@ -3614,7 +3619,7 @@ void GraphKit::g1_write_barrier_post(Node* oop_store, // (Else it's an array (or unknown), and we want more precise card marks.) assert(adr != NULL, ""); - IdealKit ideal(gvn(), control(), merged_memory(), true); + IdealKit ideal(this, true); Node* tls = __ thread(); // ThreadLocalStorage @@ -3688,6 +3693,6 @@ void GraphKit::g1_write_barrier_post(Node* oop_store, } // Final sync IdealKit and GraphKit. - sync_kit(ideal); + final_sync(ideal); } #undef __ diff --git a/src/share/vm/opto/graphKit.hpp b/src/share/vm/opto/graphKit.hpp index 2f7a7d5ab05ad7dbd1ca976b18e57ceb9875993e..0c053f473460fc43a3fb1541ab300e76071aa3da 100644 --- a/src/share/vm/opto/graphKit.hpp +++ b/src/share/vm/opto/graphKit.hpp @@ -662,7 +662,9 @@ class GraphKit : public Phase { && Universe::heap()->can_elide_tlab_store_barriers()); } + // Sync Ideal and Graph kits. void sync_kit(IdealKit& ideal); + void final_sync(IdealKit& ideal); // vanilla/CMS post barrier void write_barrier_post(Node *store, Node* obj, diff --git a/src/share/vm/opto/idealKit.cpp b/src/share/vm/opto/idealKit.cpp index bc7aaaa6a9a8f801b0241fb15c7c9d976621a41f..35c4fffba0c0a645bef39d9df831dc2034239650 100644 --- a/src/share/vm/opto/idealKit.cpp +++ b/src/share/vm/opto/idealKit.cpp @@ -38,15 +38,16 @@ const uint IdealKit::first_var = TypeFunc::Parms + 1; //----------------------------IdealKit----------------------------------------- -IdealKit::IdealKit(PhaseGVN &gvn, Node* control, Node* mem, bool delay_all_transforms, bool has_declarations) : - _gvn(gvn), C(gvn.C) { - _initial_ctrl = control; - _initial_memory = mem; +IdealKit::IdealKit(GraphKit* gkit, bool delay_all_transforms, bool has_declarations) : + _gvn(gkit->gvn()), C(gkit->C) { + _initial_ctrl = gkit->control(); + _initial_memory = gkit->merged_memory(); + _initial_i_o = gkit->i_o(); _delay_all_transforms = delay_all_transforms; _var_ct = 0; _cvstate = NULL; // We can go memory state free or else we need the entire memory state - assert(mem == NULL || mem->Opcode() == Op_MergeMem, "memory must be pre-split"); + assert(_initial_memory == NULL || _initial_memory->Opcode() == Op_MergeMem, "memory must be pre-split"); int init_size = 5; _pending_cvstates = new (C->node_arena()) GrowableArray(C->node_arena(), init_size, 0, 0); _delay_transform = new (C->node_arena()) GrowableArray(C->node_arena(), init_size, 0, 0); @@ -56,6 +57,13 @@ IdealKit::IdealKit(PhaseGVN &gvn, Node* control, Node* mem, bool delay_all_trans } } +//----------------------------sync_kit----------------------------------------- +void IdealKit::sync_kit(GraphKit* gkit) { + set_all_memory(gkit->merged_memory()); + set_i_o(gkit->i_o()); + set_ctrl(gkit->control()); +} + //-------------------------------if_then------------------------------------- // Create: if(left relop right) // / \ @@ -156,16 +164,14 @@ void IdealKit::end_if() { // onto the stack. void IdealKit::loop(GraphKit* gkit, int nargs, IdealVariable& iv, Node* init, BoolTest::mask relop, Node* limit, float prob, float cnt) { assert((state() & (BlockS|LoopS|IfThenS|ElseS)), "bad state for new loop"); - - // Sync IdealKit and graphKit. - gkit->set_all_memory(this->merged_memory()); - gkit->set_control(this->ctrl()); - // Add loop predicate. - gkit->add_predicate(nargs); - // Update IdealKit memory. - this->set_all_memory(gkit->merged_memory()); - this->set_ctrl(gkit->control()); - + if (UseLoopPredicate) { + // Sync IdealKit and graphKit. + gkit->sync_kit(*this); + // Add loop predicate. + gkit->add_predicate(nargs); + // Update IdealKit memory. + sync_kit(gkit); + } set(iv, init); Node* head = make_label(1); bind(head); @@ -280,6 +286,7 @@ void IdealKit::declarations_done() { _cvstate = new_cvstate(); // initialize current cvstate set_ctrl(_initial_ctrl); // initialize control in current cvstate set_all_memory(_initial_memory);// initialize memory in current cvstate + set_i_o(_initial_i_o); // initialize i_o in current cvstate DEBUG_ONLY(_state->push(BlockS)); } @@ -421,6 +428,9 @@ void IdealKit::do_memory_merge(Node* merging, Node* join) { // Get the region for the join state Node* join_region = join->in(TypeFunc::Control); assert(join_region != NULL, "join region must exist"); + if (join->in(TypeFunc::I_O) == NULL ) { + join->set_req(TypeFunc::I_O, merging->in(TypeFunc::I_O)); + } if (join->in(TypeFunc::Memory) == NULL ) { join->set_req(TypeFunc::Memory, merging->in(TypeFunc::Memory)); return; @@ -467,6 +477,20 @@ void IdealKit::do_memory_merge(Node* merging, Node* join) { mms.set_memory(phi); } } + + Node* join_io = join->in(TypeFunc::I_O); + Node* merging_io = merging->in(TypeFunc::I_O); + if (join_io != merging_io) { + PhiNode* phi; + if (join_io->is_Phi() && join_io->as_Phi()->region() == join_region) { + phi = join_io->as_Phi(); + } else { + phi = PhiNode::make(join_region, join_io, Type::ABIO); + phi = (PhiNode*) delay_transform(phi); + join->set_req(TypeFunc::I_O, phi); + } + phi->set_req(slot, merging_io); + } } @@ -477,7 +501,8 @@ void IdealKit::make_leaf_call(const TypeFunc *slow_call_type, const char *leaf_name, Node* parm0, Node* parm1, - Node* parm2) { + Node* parm2, + Node* parm3) { // We only handle taking in RawMem and modifying RawMem const TypePtr* adr_type = TypeRawPtr::BOTTOM; @@ -498,6 +523,55 @@ void IdealKit::make_leaf_call(const TypeFunc *slow_call_type, if (parm0 != NULL) call->init_req(TypeFunc::Parms+0, parm0); if (parm1 != NULL) call->init_req(TypeFunc::Parms+1, parm1); if (parm2 != NULL) call->init_req(TypeFunc::Parms+2, parm2); + if (parm3 != NULL) call->init_req(TypeFunc::Parms+3, parm3); + + // Node *c = _gvn.transform(call); + call = (CallNode *) _gvn.transform(call); + Node *c = call; // dbx gets confused with call call->dump() + + // Slow leaf call has no side-effects, sets few values + + set_ctrl(transform( new (C, 1) ProjNode(call,TypeFunc::Control) )); + + // Make memory for the call + Node* mem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) ); + + // Set the RawPtr memory state only. + set_memory(mem, adr_idx); + + assert(C->alias_type(call->adr_type()) == C->alias_type(adr_type), + "call node must be constructed correctly"); +} + + +void IdealKit::make_leaf_call_no_fp(const TypeFunc *slow_call_type, + address slow_call, + const char *leaf_name, + const TypePtr* adr_type, + Node* parm0, + Node* parm1, + Node* parm2, + Node* parm3) { + + // We only handle taking in RawMem and modifying RawMem + uint adr_idx = C->get_alias_index(adr_type); + + // Slow-path leaf call + int size = slow_call_type->domain()->cnt(); + CallNode *call = (CallNode*)new (C, size) CallLeafNoFPNode( slow_call_type, slow_call, leaf_name, adr_type); + + // Set fixed predefined input arguments + call->init_req( TypeFunc::Control, ctrl() ); + call->init_req( TypeFunc::I_O , top() ) ; // does no i/o + // Narrow memory as only memory input + call->init_req( TypeFunc::Memory , memory(adr_idx)); + call->init_req( TypeFunc::FramePtr, top() /* frameptr() */ ); + call->init_req( TypeFunc::ReturnAdr, top() ); + + if (parm0 != NULL) call->init_req(TypeFunc::Parms+0, parm0); + if (parm1 != NULL) call->init_req(TypeFunc::Parms+1, parm1); + if (parm2 != NULL) call->init_req(TypeFunc::Parms+2, parm2); + if (parm3 != NULL) call->init_req(TypeFunc::Parms+3, parm3); // Node *c = _gvn.transform(call); call = (CallNode *) _gvn.transform(call); diff --git a/src/share/vm/opto/idealKit.hpp b/src/share/vm/opto/idealKit.hpp index 8192a4462887ef854d63d60b5f424e7649290f36..100263a1e56d4cbd3057472cb4aea93955d999a2 100644 --- a/src/share/vm/opto/idealKit.hpp +++ b/src/share/vm/opto/idealKit.hpp @@ -108,6 +108,7 @@ class IdealKit: public StackObj { bool _delay_all_transforms; // flag forcing all transforms to be delayed Node* _initial_ctrl; // saves initial control until variables declared Node* _initial_memory; // saves initial memory until variables declared + Node* _initial_i_o; // saves initial i_o until variables declared PhaseGVN& gvn() const { return _gvn; } // Create a new cvstate filled with nulls @@ -142,17 +143,21 @@ class IdealKit: public StackObj { Node* memory(uint alias_idx); public: - IdealKit(PhaseGVN &gvn, Node* control, Node* memory, bool delay_all_transforms = false, bool has_declarations = false); + IdealKit(GraphKit* gkit, bool delay_all_transforms = false, bool has_declarations = false); ~IdealKit() { stop(); drain_delay_transform(); } + void sync_kit(GraphKit* gkit); + // Control Node* ctrl() { return _cvstate->in(TypeFunc::Control); } void set_ctrl(Node* ctrl) { _cvstate->set_req(TypeFunc::Control, ctrl); } Node* top() { return C->top(); } MergeMemNode* merged_memory() { return _cvstate->in(TypeFunc::Memory)->as_MergeMem(); } void set_all_memory(Node* mem) { _cvstate->set_req(TypeFunc::Memory, mem); } + Node* i_o() { return _cvstate->in(TypeFunc::I_O); } + void set_i_o(Node* c) { _cvstate->set_req(TypeFunc::I_O, c); } void set(IdealVariable& v, Node* rhs) { _cvstate->set_req(first_var + v.id(), rhs); } Node* value(IdealVariable& v) { return _cvstate->in(first_var + v.id()); } void dead(IdealVariable& v) { set(v, (Node*)NULL); } @@ -239,7 +244,18 @@ class IdealKit: public StackObj { const char *leaf_name, Node* parm0, Node* parm1 = NULL, - Node* parm2 = NULL); + Node* parm2 = NULL, + Node* parm3 = NULL); + + void make_leaf_call_no_fp(const TypeFunc *slow_call_type, + address slow_call, + const char *leaf_name, + const TypePtr* adr_type, + Node* parm0, + Node* parm1, + Node* parm2, + Node* parm3); + }; #endif // SHARE_VM_OPTO_IDEALKIT_HPP diff --git a/src/share/vm/opto/library_call.cpp b/src/share/vm/opto/library_call.cpp index be8136bf598b8fa393fc3b4d3d01266a85a73ef2..5977ccd13e51883df982614185f6fdc706a3eaae 100644 --- a/src/share/vm/opto/library_call.cpp +++ b/src/share/vm/opto/library_call.cpp @@ -1120,7 +1120,7 @@ Node* LibraryCallKit::string_indexOf(Node* string_object, ciTypeArray* target_ar const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin)); const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot); - IdealKit kit(gvn(), control(), merged_memory(), false, true); + IdealKit kit(this, false, true); #define __ kit. Node* zero = __ ConI(0); Node* one = __ ConI(1); @@ -1171,7 +1171,7 @@ Node* LibraryCallKit::string_indexOf(Node* string_object, ciTypeArray* target_ar __ bind(return_); // Final sync IdealKit and GraphKit. - sync_kit(kit); + final_sync(kit); Node* result = __ value(rtn); #undef __ C->set_has_loops(true); @@ -2318,22 +2318,20 @@ bool LibraryCallKit::inline_unsafe_access(bool is_native_ptr, bool is_store, Bas // of it. So we need to emit code to conditionally do the proper type of // store. - IdealKit ideal(gvn(), control(), merged_memory()); + IdealKit ideal(this); #define __ ideal. // QQQ who knows what probability is here?? __ if_then(heap_base_oop, BoolTest::ne, null(), PROB_UNLIKELY(0.999)); { // Sync IdealKit and graphKit. - set_all_memory( __ merged_memory()); - set_control(__ ctrl()); + sync_kit(ideal); Node* st = store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type); // Update IdealKit memory. - __ set_all_memory(merged_memory()); - __ set_ctrl(control()); + __ sync_kit(this); } __ else_(); { __ store(__ ctrl(), adr, val, type, alias_type->index(), is_volatile); } __ end_if(); // Final sync IdealKit and GraphKit. - sync_kit(ideal); + final_sync(ideal); #undef __ } }