--- old/src/hotspot/share/opto/compile.cpp 2020-04-04 00:22:05.000000000 +0300 +++ new/src/hotspot/share/opto/compile.cpp 2020-04-04 00:22:04.000000000 +0300 @@ -67,6 +67,7 @@ #include "opto/runtime.hpp" #include "opto/stringopts.hpp" #include "opto/type.hpp" +#include "opto/vector.hpp" #include "opto/vectornode.hpp" #include "runtime/arguments.hpp" #include "runtime/sharedRuntime.hpp" @@ -409,6 +410,7 @@ remove_useless_late_inlines(&_string_late_inlines, useful); remove_useless_late_inlines(&_boxing_late_inlines, useful); remove_useless_late_inlines(&_late_inlines, useful); + remove_useless_late_inlines(&_vector_reboxing_late_inlines, useful); debug_only(verify_graph_edges(true/*check for no_dead_code*/);) } @@ -542,6 +544,7 @@ _late_inlines(comp_arena(), 2, 0, NULL), _string_late_inlines(comp_arena(), 2, 0, NULL), _boxing_late_inlines(comp_arena(), 2, 0, NULL), + _vector_reboxing_late_inlines(comp_arena(), 2, 0, NULL), _late_inlines_pos(0), _number_of_mh_late_inlines(0), _print_inlining_stream(NULL), @@ -1884,7 +1887,7 @@ _late_inlines.trunc_to(j); assert(inlining_progress() || _late_inlines.length() == 0, ""); - bool needs_cleanup = do_cleanup() || over_inlining_cutoff(); + bool needs_cleanup = true; set_inlining_progress(false); set_do_cleanup(false); @@ -1940,6 +1943,9 @@ inline_incrementally_cleanup(igvn); + print_method(PHASE_INCREMENTAL_INLINE_STEP, 3); + + if (failing()) return; } assert( igvn._worklist.size() == 0, "should be done with igvn" ); @@ -2054,10 +2060,9 @@ if (AlwaysIncrementalInline) { inline_incrementally(igvn); } + if (failing()) return; print_method(PHASE_INCREMENTAL_BOXING_INLINE, 2); - - if (failing()) return; } // Now that all inlining is over, cut edge from root to loop @@ -2074,6 +2079,16 @@ // so keep only the actual candidates for optimizations. cleanup_expensive_nodes(igvn); + assert(EnableVectorSupport || !has_vbox_nodes(), "sanity"); + if (EnableVectorSupport && has_vbox_nodes()) { + TracePhase tp("", &timers[_t_vector]); + PhaseVector pv(igvn); + pv.optimize_vector_boxes(); + + print_method(PHASE_ITER_GVN_AFTER_VECTOR, 2); + } + assert(!has_vbox_nodes(), "sanity"); + if (!failing() && RenumberLiveNodes && live_nodes() + NodeLimitFudgeFactor < unique()) { Compile::TracePhase tp("", &timers[_t_renumberLive]); initial_gvn()->replace_with(&igvn); @@ -2088,6 +2103,8 @@ igvn.optimize(); } + // FIXME for_igvn() is corrupted from here: new_worklist which is set_for_ignv() was allocated on stack. + // Perform escape analysis if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) { if (has_loops()) { @@ -2244,6 +2261,50 @@ print_method(PHASE_OPTIMIZE_FINISHED, 2); } +void Compile::print_method(CompilerPhaseType cpt, Node* n, int level) { + ResourceMark rm; + stringStream ss; + ss.print_raw(CompilerPhaseTypeHelper::to_string(cpt)); + if (n != NULL) { +#ifndef PRODUCT + ss.print(": %s %d", n->Name(), n->_idx); +#else + ss.print(": %d %d", n->Opcode(), n->_idx); +#endif // !PRODUCT + } else { + ss.print_raw(": NULL"); + } + C->print_method(cpt, ss.as_string(), level); +} + +void Compile::inline_vector_reboxing_calls() { + if (C->_vector_reboxing_late_inlines.length() > 0) { + PhaseGVN* gvn = C->initial_gvn(); + + _late_inlines_pos = C->_late_inlines.length(); + while (_vector_reboxing_late_inlines.length() > 0) { + CallGenerator* cg = _vector_reboxing_late_inlines.pop(); + cg->do_late_inline(); + if (failing()) return; + print_method(PHASE_INLINE_VECTOR_REBOX, cg->call_node()); + } + _vector_reboxing_late_inlines.trunc_to(0); + } +} + +bool Compile::has_vbox_nodes() { + if (C->_vector_reboxing_late_inlines.length() > 0) { + return true; + } + for (int macro_idx = C->macro_count() - 1; macro_idx >= 0; macro_idx--) { + Node * n = C->macro_node(macro_idx); + assert(n->is_macro(), "only macro nodes expected here"); + if (n->Opcode() == Op_VectorUnbox || n->Opcode() == Op_VectorBox || n->Opcode() == Op_VectorBoxAllocate) { + return true; + } + } + return false; +} //------------------------------Code_Gen--------------------------------------- // Given a graph, generate code for it @@ -2270,8 +2331,8 @@ if (failing()) { return; } + print_method(PHASE_AFTER_MATCHING, 3); } - // In debug mode can dump m._nodes.dump() for mapping of ideal to machine // nodes. Mapping is only valid at the root of each matched subtree. NOT_PRODUCT( verify_graph_edges(); ) @@ -2460,7 +2521,8 @@ // 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_MaxI: case Op_MaxL: case Op_MaxF: case Op_MaxD: + case Op_MinI: case Op_MinL: case Op_MinF: case Op_MinD: 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: { @@ -3025,6 +3087,8 @@ case Op_LoadVector: case Op_StoreVector: + case Op_LoadVectorGather: + case Op_StoreVectorScatter: break; case Op_AddReductionVI: