< prev index next >

src/hotspot/share/opto/loopnode.cpp

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 976,986 **** } wq.clear(); wq.push(u); bool found_sfpt = false; for (uint next = 0; next < wq.size() && !found_sfpt; next++) { ! Node* n = wq.at(next); for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax && !found_sfpt; i++) { Node* u = n->fast_out(i); if (u == sfpt) { found_sfpt = true; } --- 976,986 ---- } wq.clear(); wq.push(u); bool found_sfpt = false; for (uint next = 0; next < wq.size() && !found_sfpt; next++) { ! Node *n = wq.at(next); for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax && !found_sfpt; i++) { Node* u = n->fast_out(i); if (u == sfpt) { found_sfpt = true; }
*** 990,1012 **** } } assert(found_sfpt, "no node in loop that's not input to safepoint"); } } - - if (UseZGC && !inner_out->in(0)->is_CountedLoopEnd()) { - // In some very special cases there can be a load that has no other uses than the - // counted loop safepoint. Then its loadbarrier will be placed between the inner - // loop exit and the safepoint. This is very rare - - Node* ifnode = inner_out->in(1)->in(0); - // Region->IfTrue->If == Region->Iffalse->If - if (ifnode == inner_out->in(2)->in(0)) { - inner_out = ifnode->in(0); - } - } - 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"); --- 990,999 ----
*** 2450,2516 **** assert(loop->_child != this || (loop->_child->_child == NULL && loop->_child->_next == NULL), "would miss some loops"); if (loop->_child && loop->_child != this) loop->_child->counted_loop(phase); if (loop->_next) loop->_next ->counted_loop(phase); } - - // The Estimated Loop Clone Size: - // CloneFactor * (~112% * BodySize + BC) + CC + FanOutTerm, - // where BC and CC are totally ad-hoc/magic "body" and "clone" constants, - // respectively, used to ensure that the node usage estimates made are on the - // safe side, for the most part. The FanOutTerm is an attempt to estimate the - // possible additional/excessive nodes generated due to data and control flow - // merging, for edges reaching outside the loop. - uint IdealLoopTree::est_loop_clone_sz(uint factor) const { - - precond(0 < factor && factor < 16); - - uint const bc = 13; - uint const cc = 17; - uint const sz = _body.size() + (_body.size() + 7) / 8; - uint estimate = factor * (sz + bc) + cc; - - assert((estimate - cc) / factor == sz + bc, "overflow"); - - uint ctrl_edge_out_cnt = 0; - uint data_edge_out_cnt = 0; - - for (uint i = 0; i < _body.size(); i++) { - Node* node = _body.at(i); - uint outcnt = node->outcnt(); - - for (uint k = 0; k < outcnt; k++) { - Node* out = node->raw_out(k); - - if (out->is_CFG()) { - if (!is_member(_phase->get_loop(out))) { - ctrl_edge_out_cnt++; - } - } else { - Node* ctrl = _phase->get_ctrl(out); - assert(ctrl->is_CFG(), "must be"); - if (!is_member(_phase->get_loop(ctrl))) { - data_edge_out_cnt++; - } - } - } - } - // Add data (x1.5) and control (x1.0) count to estimate iff both are > 0. - if (ctrl_edge_out_cnt > 0 && data_edge_out_cnt > 0) { - estimate += ctrl_edge_out_cnt + data_edge_out_cnt + data_edge_out_cnt / 2; - } - - return estimate; - } - #ifndef PRODUCT //------------------------------dump_head-------------------------------------- // Dump 1 liner for loop header info ! void IdealLoopTree::dump_head() const { ! for (uint i = 0; i < _nest; i++) { tty->print(" "); - } tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx); if (_irreducible) tty->print(" IRREDUCIBLE"); Node* entry = _head->is_Loop() ? _head->as_Loop()->skip_strip_mined(-1)->in(LoopNode::EntryControl) : _head->in(LoopNode::EntryControl); Node* predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); if (predicate != NULL ) { --- 2437,2452 ---- assert(loop->_child != this || (loop->_child->_child == NULL && loop->_child->_next == NULL), "would miss some loops"); if (loop->_child && loop->_child != this) loop->_child->counted_loop(phase); if (loop->_next) loop->_next ->counted_loop(phase); } #ifndef PRODUCT //------------------------------dump_head-------------------------------------- // Dump 1 liner for loop header info ! void IdealLoopTree::dump_head( ) const { ! for (uint i=0; i<_nest; i++) tty->print(" "); tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx); if (_irreducible) tty->print(" IRREDUCIBLE"); Node* entry = _head->is_Loop() ? _head->as_Loop()->skip_strip_mined(-1)->in(LoopNode::EntryControl) : _head->in(LoopNode::EntryControl); Node* predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); if (predicate != NULL ) {
*** 2575,2585 **** tty->cr(); } //------------------------------dump------------------------------------------- // Dump loops by loop tree ! void IdealLoopTree::dump() const { dump_head(); if (_child) _child->dump(); if (_next) _next ->dump(); } --- 2511,2521 ---- tty->cr(); } //------------------------------dump------------------------------------------- // Dump loops by loop tree ! void IdealLoopTree::dump( ) const { dump_head(); if (_child) _child->dump(); if (_next) _next ->dump(); }
*** 2772,2782 **** //============================================================================= //----------------------------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); bool skip_loop_opts = (mode == LoopOptsNone); int old_progress = C->major_progress(); uint orig_worklist_size = _igvn._worklist.size(); --- 2708,2718 ---- //============================================================================= //----------------------------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 == LoopOptsLastRound); bool skip_loop_opts = (mode == LoopOptsNone); int old_progress = C->major_progress(); uint orig_worklist_size = _igvn._worklist.size();
*** 2932,2942 **** NOT_PRODUCT( C->verify_graph_edges(); ) worklist.push( C->top() ); build_loop_late( visited, worklist, nstack ); if (_verify_only) { ! C->restore_major_progress(old_progress); assert(C->unique() == unique, "verification mode made Nodes? ? ?"); assert(_igvn._worklist.size() == orig_worklist_size, "shouldn't push anything"); return; } --- 2868,2880 ---- 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(); assert(C->unique() == unique, "verification mode made Nodes? ? ?"); assert(_igvn._worklist.size() == orig_worklist_size, "shouldn't push anything"); return; }
*** 2968,2986 **** if (_verify_me) { // Nested verify pass? // Check to see if the verify mode is broken assert(C->unique() == unique, "non-optimize mode made Nodes? ? ?"); return; } ! if (VerifyLoopOptimizations) verify(); ! if (TraceLoopOpts && C->has_loops()) { _ltree_root->dump(); } #endif if (skip_loop_opts) { // restore major progress flag ! C->restore_major_progress(old_progress); // Cleanup any modified bits _igvn.optimize(); if (C->log() != NULL) { --- 2906,2926 ---- if (_verify_me) { // Nested verify pass? // Check to see if the verify mode is broken assert(C->unique() == unique, "non-optimize mode made Nodes? ? ?"); return; } ! if(VerifyLoopOptimizations) verify(); ! if(TraceLoopOpts && C->has_loops()) { _ltree_root->dump(); } #endif if (skip_loop_opts) { // restore major progress flag ! for (int i = 0; i < old_progress; i++) { ! C->set_major_progress(); ! } // Cleanup any modified bits _igvn.optimize(); if (C->log() != NULL) {
*** 2996,3023 **** } return; } 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(); if (!is_counted || !lpt->is_innermost()) continue; // check for vectorized loops, any reassociation of invariants was already done ! if (is_counted && lpt->_head->as_CountedLoop()->is_unroll_only()) { ! continue; ! } else { ! AutoNodeBudget node_budget(this); ! lpt->reassociate_invariants(this); ! } // Because RCE opportunities can be masked by split_thru_phi, // look for RCE candidates and inhibit split_thru_phi // on just their loop-phi's for this pass of loop opts if (SplitIfBlocks && do_split_ifs) { - AutoNodeBudget node_budget(this, AutoNodeBudget::NO_BUDGET_CHECK); if (lpt->policy_range_check(this)) { lpt->_rce_candidate = 1; // = true } } } --- 2936,2961 ---- } return; } if (ReassociateInvariants) { + AutoNodeBudget node_budget(this, AutoNodeBudget::NO_BUDGET_CHECK); // 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(); if (!is_counted || !lpt->is_innermost()) continue; // check for vectorized loops, any reassociation of invariants was already done ! if (is_counted && lpt->_head->as_CountedLoop()->is_unroll_only()) continue; ! ! lpt->reassociate_invariants(this); ! // Because RCE opportunities can be masked by split_thru_phi, // look for RCE candidates and inhibit split_thru_phi // on just their loop-phi's for this pass of loop opts if (SplitIfBlocks && do_split_ifs) { if (lpt->policy_range_check(this)) { lpt->_rce_candidate = 1; // = true } } }
*** 3025,3036 **** // 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); NOT_PRODUCT( if( VerifyLoopOptimizations ) verify(); ); } if (!C->major_progress() && do_expensive_nodes && process_expensive_nodes()) { C->set_major_progress(); } --- 2963,2977 ---- // 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 == LoopOptsLastRound ); NOT_PRODUCT( if( VerifyLoopOptimizations ) verify(); ); + if (mode == LoopOptsLastRound) { + C->set_major_progress(); + } } if (!C->major_progress() && do_expensive_nodes && process_expensive_nodes()) { C->set_major_progress(); }
*** 3161,3171 **** assert( fail == 0, "verify loops failed" ); // Verify loop structure is the same _ltree_root->verify_tree(loop_verify._ltree_root, NULL); // Reset major-progress. It was cleared by creating a verify version of // PhaseIdealLoop. ! C->restore_major_progress(old_progress); } //------------------------------verify_compare--------------------------------- // Make sure me and the given PhaseIdealLoop agree on key data structures void PhaseIdealLoop::verify_compare( Node *n, const PhaseIdealLoop *loop_verify, VectorSet &visited ) const { --- 3102,3113 ---- assert( fail == 0, "verify loops failed" ); // Verify loop structure is the same _ltree_root->verify_tree(loop_verify._ltree_root, NULL); // Reset major-progress. It was cleared by creating a verify version of // PhaseIdealLoop. ! for( int i=0; i<old_progress; i++ ) ! C->set_major_progress(); } //------------------------------verify_compare--------------------------------- // Make sure me and the given PhaseIdealLoop agree on key data structures void PhaseIdealLoop::verify_compare( Node *n, const PhaseIdealLoop *loop_verify, VectorSet &visited ) const {
*** 4291,4300 **** --- 4233,4243 ---- case Op_LoadNKlass: case Op_LoadL: case Op_LoadS: case Op_LoadP: case Op_LoadBarrierSlowReg: + case Op_LoadBarrierWeakSlowReg: case Op_LoadN: case Op_LoadRange: case Op_LoadD_unaligned: case Op_LoadL_unaligned: case Op_StrComp: // Does a bunch of load-like effects
< prev index next >