< prev index next >

src/hotspot/share/opto/loopnode.cpp

Print this page

        

*** 38,47 **** --- 38,51 ---- #include "opto/idealGraphPrinter.hpp" #include "opto/loopnode.hpp" #include "opto/mulnode.hpp" #include "opto/rootnode.hpp" #include "opto/superword.hpp" + #include "utilities/macros.hpp" + #if INCLUDE_SHENANDOAHGC + #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp" + #endif //============================================================================= //------------------------------is_loop_iv------------------------------------- // Determine if a node is Counted loop induction variable. // The method is declared in node.hpp.
*** 994,1007 **** } } assert(found_sfpt, "no node in loop that's not input to safepoint"); } } - CountedLoopEndNode* cle = inner_out->in(0)->as_CountedLoopEnd(); - assert(cle == inner->loopexit_or_null(), "mismatch"); bool has_skeleton = outer_le->in(1)->bottom_type()->singleton() && outer_le->in(1)->bottom_type()->is_int()->get_con() == 0; if (has_skeleton) { assert(expect_skeleton == 1 || expect_skeleton == -1, "unexpected skeleton node"); assert(outer->outcnt() == 2, "only phis"); } else { assert(expect_skeleton == 0 || expect_skeleton == -1, "no skeleton node?"); uint phis = 0; --- 998,1011 ---- } } assert(found_sfpt, "no node in loop that's not input to safepoint"); } } bool has_skeleton = outer_le->in(1)->bottom_type()->singleton() && outer_le->in(1)->bottom_type()->is_int()->get_con() == 0; if (has_skeleton) { + CountedLoopEndNode* cle = inner_out->in(0)->as_CountedLoopEnd(); + assert(cle == inner->loopexit_or_null(), "mismatch"); assert(expect_skeleton == 1 || expect_skeleton == -1, "unexpected skeleton node"); assert(outer->outcnt() == 2, "only phis"); } else { assert(expect_skeleton == 0 || expect_skeleton == -1, "no skeleton node?"); uint phis = 0;
*** 1799,1809 **** old_phi->add_req(p); // Check for the special case of making the old phi useless and // disappear it. In JavaGrande I have a case where this useless // Phi is the loop limit and prevents recognizing a CountedLoop // which in turn prevents removing an empty loop. ! Node *id_old_phi = old_phi->Identity( &igvn ); if( id_old_phi != old_phi ) { // Found a simple identity? // Note that I cannot call 'replace_node' here, because // that will yank the edge from old_phi to the Region and // I'm mid-iteration over the Region's uses. for (DUIterator_Last imin, i = old_phi->last_outs(imin); i >= imin; ) { --- 1803,1813 ---- old_phi->add_req(p); // Check for the special case of making the old phi useless and // disappear it. In JavaGrande I have a case where this useless // Phi is the loop limit and prevents recognizing a CountedLoop // which in turn prevents removing an empty loop. ! Node *id_old_phi = igvn.apply_identity(old_phi); if( id_old_phi != old_phi ) { // Found a simple identity? // Note that I cannot call 'replace_node' here, because // that will yank the edge from old_phi to the Region and // I'm mid-iteration over the Region's uses. for (DUIterator_Last imin, i = old_phi->last_outs(imin); i >= imin; ) {
*** 2711,2721 **** //============================================================================= //----------------------------build_and_optimize------------------------------- // Create a PhaseLoop. Build the ideal Loop tree. Map each Ideal Node to // its corresponding LoopNode. If 'optimize' is true, do some loop cleanups. ! void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool skip_loop_opts, bool last_round) { ResourceMark rm; int old_progress = C->major_progress(); uint orig_worklist_size = _igvn._worklist.size(); --- 2715,2730 ---- //============================================================================= //----------------------------build_and_optimize------------------------------- // Create a PhaseLoop. Build the ideal Loop tree. Map each Ideal Node to // its corresponding LoopNode. If 'optimize' is true, do some loop cleanups. ! void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) { ! bool do_split_ifs = (mode == LoopOptsDefault || mode == LoopOptsZgcLastRound); ! bool skip_loop_opts = (mode == LoopOptsNone) ; ! bool shenandoah_opts = (mode == LoopOptsShenandoahExpand || ! mode == LoopOptsShenandoahPostExpand); ! ResourceMark rm; int old_progress = C->major_progress(); uint orig_worklist_size = _igvn._worklist.size();
*** 2775,2785 **** } return; } // Nothing to do, so get out ! bool stop_early = !C->has_loops() && !skip_loop_opts && !do_split_ifs && !_verify_me && !_verify_only; bool do_expensive_nodes = C->should_optimize_expensive_nodes(_igvn); if (stop_early && !do_expensive_nodes) { _igvn.optimize(); // Cleanup NeverBranches return; } --- 2784,2794 ---- } return; } // Nothing to do, so get out ! bool stop_early = !C->has_loops() && !skip_loop_opts && !do_split_ifs && !_verify_me && !_verify_only && !shenandoah_opts; bool do_expensive_nodes = C->should_optimize_expensive_nodes(_igvn); if (stop_early && !do_expensive_nodes) { _igvn.optimize(); // Cleanup NeverBranches return; }
*** 2854,2874 **** visited.set( C->top()->_idx ); // Set C->top() as visited now build_loop_early( visited, worklist, nstack ); // Given early legal placement, try finding counted loops. This placement // is good enough to discover most loop invariants. ! if( !_verify_me && !_verify_only ) ! _ltree_root->counted_loop( this ); // Find latest loop placement. Find ideal loop placement. visited.Clear(); init_dom_lca_tags(); // Need C->root() on worklist when processing outs worklist.push( C->root() ); NOT_PRODUCT( C->verify_graph_edges(); ) worklist.push( C->top() ); ! build_loop_late( visited, worklist, nstack ); if (_verify_only) { // restore major progress flag for (int i = 0; i < old_progress; i++) C->set_major_progress(); --- 2863,2884 ---- visited.set( C->top()->_idx ); // Set C->top() as visited now build_loop_early( visited, worklist, nstack ); // Given early legal placement, try finding counted loops. This placement // is good enough to discover most loop invariants. ! if (!_verify_me && !_verify_only && !shenandoah_opts) { ! _ltree_root->counted_loop(this); ! } // Find latest loop placement. Find ideal loop placement. visited.Clear(); init_dom_lca_tags(); // Need C->root() on worklist when processing outs worklist.push( C->root() ); NOT_PRODUCT( C->verify_graph_edges(); ) worklist.push( C->top() ); ! build_loop_late(visited, worklist, nstack, !shenandoah_opts); if (_verify_only) { // restore major progress flag for (int i = 0; i < old_progress; i++) C->set_major_progress();
*** 2926,2935 **** --- 2936,2955 ---- log_loop_tree(_ltree_root, _ltree_root, C->log()); } return; } + #if INCLUDE_SHENANDOAHGC + if (UseShenandoahGC && ((ShenandoahBarrierSetC2*) BarrierSet::barrier_set()->barrier_set_c2())->optimize_loops(this, mode, visited, nstack, worklist)) { + _igvn.optimize(); + if (C->log() != NULL) { + log_loop_tree(_ltree_root, _ltree_root, C->log()); + } + return; + } + #endif + if (ReassociateInvariants) { // Reassociate invariants and prep for split_thru_phi for (LoopTreeIterator iter(_ltree_root); !iter.done(); iter.next()) { IdealLoopTree* lpt = iter.current(); bool is_counted = lpt->is_counted();
*** 2953,2965 **** // Check for aggressive application of split-if and other transforms // that require basic-block info (like cloning through Phi's) if( SplitIfBlocks && do_split_ifs ) { visited.Clear(); ! split_if_with_blocks( visited, nstack, last_round ); NOT_PRODUCT( if( VerifyLoopOptimizations ) verify(); ); ! if (last_round) { C->set_major_progress(); } } if (!C->major_progress() && do_expensive_nodes && process_expensive_nodes()) { --- 2973,2985 ---- // Check for aggressive application of split-if and other transforms // that require basic-block info (like cloning through Phi's) if( SplitIfBlocks && do_split_ifs ) { visited.Clear(); ! split_if_with_blocks( visited, nstack, mode == LoopOptsZgcLastRound ); NOT_PRODUCT( if( VerifyLoopOptimizations ) verify(); ); ! if (mode == LoopOptsZgcLastRound) { C->set_major_progress(); } } if (!C->major_progress() && do_expensive_nodes && process_expensive_nodes()) {
*** 3956,3966 **** Node* s = mem->fast_out(i); worklist.push(s); } while(worklist.size() != 0 && LCA != early) { Node* s = worklist.pop(); ! if (s->is_Load() || s->Opcode() == Op_SafePoint) { continue; } else if (s->is_MergeMem()) { for (DUIterator_Fast imax, i = s->fast_outs(imax); i < imax; i++) { Node* s1 = s->fast_out(i); worklist.push(s1); --- 3976,3987 ---- Node* s = mem->fast_out(i); worklist.push(s); } while(worklist.size() != 0 && LCA != early) { Node* s = worklist.pop(); ! if (s->is_Load() || s->is_ShenandoahBarrier() || s->Opcode() == Op_SafePoint || ! (UseShenandoahGC && s->is_CallStaticJava() && s->as_CallStaticJava()->uncommon_trap_request() != 0)) { continue; } else if (s->is_MergeMem()) { for (DUIterator_Fast imax, i = s->fast_outs(imax); i < imax; i++) { Node* s1 = s->fast_out(i); worklist.push(s1);
*** 4083,4093 **** } //------------------------------build_loop_late-------------------------------- // Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping. // Second pass finds latest legal placement, and ideal loop placement. ! void PhaseIdealLoop::build_loop_late( VectorSet &visited, Node_List &worklist, Node_Stack &nstack ) { while (worklist.size() != 0) { Node *n = worklist.pop(); // Only visit once if (visited.test_set(n->_idx)) continue; uint cnt = n->outcnt(); --- 4104,4114 ---- } //------------------------------build_loop_late-------------------------------- // Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping. // Second pass finds latest legal placement, and ideal loop placement. ! void PhaseIdealLoop::build_loop_late(VectorSet &visited, Node_List &worklist, Node_Stack &nstack, bool verify_strip_mined) { while (worklist.size() != 0) { Node *n = worklist.pop(); // Only visit once if (visited.test_set(n->_idx)) continue; uint cnt = n->outcnt();
*** 4119,4129 **** // push dead code onto a worklist _deadlist.push(use); } } else { // All of n's children have been processed, complete post-processing. ! build_loop_late_post(n); if (nstack.is_empty()) { // Finished all nodes on stack. // Process next node on the worklist. break; } --- 4140,4150 ---- // push dead code onto a worklist _deadlist.push(use); } } else { // All of n's children have been processed, complete post-processing. ! build_loop_late_post(n, verify_strip_mined); if (nstack.is_empty()) { // Finished all nodes on stack. // Process next node on the worklist. break; }
*** 4170,4180 **** //------------------------------build_loop_late_post--------------------------- // Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping. // Second pass finds latest legal placement, and ideal loop placement. ! void PhaseIdealLoop::build_loop_late_post( Node *n ) { if (n->req() == 2 && (n->Opcode() == Op_ConvI2L || n->Opcode() == Op_CastII) && !C->major_progress() && !_verify_only) { _igvn._worklist.push(n); // Maybe we'll normalize it, if no more loops. } --- 4191,4201 ---- //------------------------------build_loop_late_post--------------------------- // Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping. // Second pass finds latest legal placement, and ideal loop placement. ! void PhaseIdealLoop::build_loop_late_post(Node *n, bool verify_strip_mined) { if (n->req() == 2 && (n->Opcode() == Op_ConvI2L || n->Opcode() == Op_CastII) && !C->major_progress() && !_verify_only) { _igvn._worklist.push(n); // Maybe we'll normalize it, if no more loops. }
*** 4326,4336 **** } #endif // Assign discovered "here or above" point least = find_non_split_ctrl(least); ! verify_strip_mined_scheduling(n, least); set_ctrl(n, least); // Collect inner loop bodies IdealLoopTree *chosen_loop = get_loop(least); if( !chosen_loop->_child ) // Inner loop? --- 4347,4359 ---- } #endif // Assign discovered "here or above" point least = find_non_split_ctrl(least); ! if (verify_strip_mined && !_verify_only) { ! verify_strip_mined_scheduling(n, least); ! } set_ctrl(n, least); // Collect inner loop bodies IdealLoopTree *chosen_loop = get_loop(least); if( !chosen_loop->_child ) // Inner loop?
*** 4488,4497 **** --- 4511,4521 ---- } } } } } + #endif // Collect a R-P-O for the whole CFG. // Result list is in post-order (scan backwards for RPO) void PhaseIdealLoop::rpo( Node *start, Node_Stack &stk, VectorSet &visited, Node_List &rpo_list ) const { stk.push(start, 0);
*** 4510,4520 **** rpo_list.push(m); stk.pop(); } } } - #endif //============================================================================= //------------------------------LoopTreeIterator----------------------------------- --- 4534,4543 ----
< prev index next >