src/share/vm/opto/graphKit.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/share/vm/opto/graphKit.cpp

src/share/vm/opto/graphKit.cpp

Print this page
rev 6519 : 8026796: Make replace_in_map() on parent maps generic
Summary: propagate node replacements along control flow edges to callers
Reviewed-by:
rev 6520 : [mq]: replaceinmap-8026796-reviews

*** 430,439 **** --- 430,440 ---- _gvn.set_type(phi, dsttype); } } } } + phi_map->merge_replaced_nodes_with(ex_map); } //--------------------------use_exception_state-------------------------------- Node* GraphKit::use_exception_state(SafePointNode* phi_map) { if (failing()) { stop(); return top(); }
*** 643,653 **** debug_only(kit->verify_map()); _kit = kit; _map = kit->map(); // preserve the map _sp = kit->sp(); kit->set_map(clone_map ? kit->clone_map() : NULL); - Compile::current()->inc_preserve_jvm_state(); #ifdef ASSERT _bci = kit->bci(); Parse* parser = kit->is_Parse(); int block = (parser == NULL || parser->block() == NULL) ? -1 : parser->block()->rpo(); _block = block; --- 644,653 ----
*** 661,671 **** int block = (parser == NULL || parser->block() == NULL) ? -1 : parser->block()->rpo(); assert(block == _block, "block must not shift"); #endif kit->set_map(_map); kit->set_sp(_sp); - Compile::current()->dec_preserve_jvm_state(); } //-----------------------------BuildCutout------------------------------------- BuildCutout::BuildCutout(GraphKit* kit, Node* p, float prob, float cnt) --- 661,670 ----
*** 1401,1464 **** // Note: This operation potentially replaces any edge // on the map. This includes locals, stack, and monitors // of the current (innermost) JVM state. ! if (!ReplaceInParentMaps) { ! return; ! } ! ! // PreserveJVMState doesn't do a deep copy so we can't modify ! // parents ! if (Compile::current()->has_preserve_jvm_state()) { ! return; ! } ! Parse* parser = is_Parse(); ! bool progress = true; ! Node* ctrl = map()->in(0); ! // Follow the chain of parsers and see whether the update can be ! // done in the map of callers. We can do the replace for a caller if ! // the current control post dominates the control of a caller. ! while (parser != NULL && parser->caller() != NULL && progress) { ! progress = false; ! Node* parent_map = parser->caller()->map(); ! assert(parser->exits().map()->jvms()->depth() == parser->caller()->depth(), "map mismatch"); ! ! Node* parent_ctrl = parent_map->in(0); ! ! while (parent_ctrl->is_Region()) { ! Node* n = parent_ctrl->as_Region()->is_copy(); ! if (n == NULL) { ! break; ! } ! parent_ctrl = n; ! } ! for (;;) { ! if (ctrl == parent_ctrl) { ! // update the map of the exits which is the one that will be ! // used when compilation resume after inlining ! parser->exits().map()->replace_edge(old, neww); ! progress = true; ! break; ! } ! if (ctrl->is_Proj() && ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none)) { ! ctrl = ctrl->in(0)->in(0); ! } else if (ctrl->is_Region()) { ! Node* n = ctrl->as_Region()->is_copy(); ! if (n == NULL) { ! break; ! } ! ctrl = n; ! } else { ! break; ! } } ! parser = parser->parent_parser(); ! } } //============================================================================= //--------------------------------memory--------------------------------------- --- 1400,1420 ---- // Note: This operation potentially replaces any edge // on the map. This includes locals, stack, and monitors // of the current (innermost) JVM state. ! // don't let inconsistent types from profiling escape this ! // method ! const Type* told = _gvn.type(old); ! const Type* tnew = _gvn.type(neww); ! if (!tnew->higher_equal(told)) { ! return; } ! map()->record_replaced_node(old, neww); } //============================================================================= //--------------------------------memory---------------------------------------
*** 1862,1877 **** } } // Replace the call with the current state of the kit. ! void GraphKit::replace_call(CallNode* call, Node* result) { JVMState* ejvms = NULL; if (has_exceptions()) { ejvms = transfer_exceptions_into_jvms(); } SafePointNode* final_state = stop(); // Find all the needed outputs of this call CallProjections callprojs; call->extract_projections(&callprojs, true); --- 1818,1837 ---- } } // Replace the call with the current state of the kit. ! void GraphKit::replace_call(CallNode* call, Node* result, bool do_replaced_nodes) { JVMState* ejvms = NULL; if (has_exceptions()) { ejvms = transfer_exceptions_into_jvms(); } + ReplacedNodes replaced_nodes = map()->replaced_nodes(); + ReplacedNodes replaced_nodes_exception; + Node* ex_ctl = top(); + SafePointNode* final_state = stop(); // Find all the needed outputs of this call CallProjections callprojs; call->extract_projections(&callprojs, true);
*** 1884,1893 **** --- 1844,1857 ---- // Replace all the old call edges with the edges from the inlining result if (callprojs.fallthrough_catchproj != NULL) { C->gvn_replace_by(callprojs.fallthrough_catchproj, final_ctl); } if (callprojs.fallthrough_memproj != NULL) { + if (final_mem->is_MergeMem()) { + // Parser's exits MergeMem was not transformed but may be optimized + final_mem = _gvn.transform(final_mem); + } C->gvn_replace_by(callprojs.fallthrough_memproj, final_mem); } if (callprojs.fallthrough_ioproj != NULL) { C->gvn_replace_by(callprojs.fallthrough_ioproj, final_io); }
*** 1915,1928 **** --- 1879,1895 ---- } else { GraphKit ekit(ejvms); // Load my combined exception state into the kit, with all phis transformed: SafePointNode* ex_map = ekit.combine_and_pop_all_exception_states(); + replaced_nodes_exception = ex_map->replaced_nodes(); Node* ex_oop = ekit.use_exception_state(ex_map); + if (callprojs.catchall_catchproj != NULL) { C->gvn_replace_by(callprojs.catchall_catchproj, ekit.control()); + ex_ctl = ekit.control(); } if (callprojs.catchall_memproj != NULL) { C->gvn_replace_by(callprojs.catchall_memproj, ekit.reset_memory()); } if (callprojs.catchall_ioproj != NULL) {
*** 1951,1960 **** --- 1918,1934 ---- } while (wl.size() > 0) { _gvn.transform(wl.pop()); } } + + if (callprojs.fallthrough_catchproj != NULL && !final_ctl->is_top() && do_replaced_nodes) { + replaced_nodes.apply(C, final_ctl); + } + if (!ex_ctl->is_top() && do_replaced_nodes) { + replaced_nodes_exception.apply(C, ex_ctl); + } } //------------------------------increment_counter------------------------------ // for statistics: increment a VM counter by 1
src/share/vm/opto/graphKit.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File