< prev index next >

src/share/vm/opto/loopopts.cpp

Print this page

        

*** 40,59 **** //============================================================================= //------------------------------split_thru_phi--------------------------------- // Split Node 'n' through merge point if there is enough win. Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) { ! if (n->Opcode() == Op_ConvI2L && n->bottom_type() != TypeLong::LONG) { // ConvI2L may have type information on it which is unsafe to push up // so disable this for now return NULL; } // Splitting range check CastIIs through a loop induction Phi can // cause new Phis to be created that are left unrelated to the loop // induction Phi and prevent optimizations (vectorization) ! if (n->Opcode() == Op_CastII && n->as_CastII()->has_range_check() && region->is_CountedLoop() && n->in(1) == region->as_CountedLoop()->phi()) { return NULL; } int wins = 0; --- 40,59 ---- //============================================================================= //------------------------------split_thru_phi--------------------------------- // Split Node 'n' through merge point if there is enough win. Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) { ! if (n->Opcode() == Opcodes::Op_ConvI2L && n->bottom_type() != TypeLong::LONG) { // ConvI2L may have type information on it which is unsafe to push up // so disable this for now return NULL; } // Splitting range check CastIIs through a loop induction Phi can // cause new Phis to be created that are left unrelated to the loop // induction Phi and prevent optimizations (vectorization) ! if (n->Opcode() == Opcodes::Op_CastII && n->as_CastII()->has_range_check() && region->is_CountedLoop() && n->in(1) == region->as_CountedLoop()->phi()) { return NULL; } int wins = 0;
*** 212,232 **** void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff, bool flip, bool exclude_loop_predicate ) { if (VerifyLoopOptimizations && PrintOpto) { tty->print_cr("dominating test"); } // prevdom is the dominating projection of the dominating test. assert( iff->is_If(), "" ); ! assert(iff->Opcode() == Op_If || iff->Opcode() == Op_CountedLoopEnd || iff->Opcode() == Op_RangeCheck, "Check this code when new subtype is added"); ! int pop = prevdom->Opcode(); ! assert( pop == Op_IfFalse || pop == Op_IfTrue, "" ); if (flip) { ! if (pop == Op_IfTrue) ! pop = Op_IfFalse; else ! pop = Op_IfTrue; } // 'con' is set to true or false to kill the dominated test. ! Node *con = _igvn.makecon(pop == Op_IfTrue ? TypeInt::ONE : TypeInt::ZERO); set_ctrl(con, C->root()); // Constant gets a new use // Hack the dominated test _igvn.replace_input_of(iff, 1, con); // If I dont have a reachable TRUE and FALSE path following the IfNode then --- 212,232 ---- void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff, bool flip, bool exclude_loop_predicate ) { if (VerifyLoopOptimizations && PrintOpto) { tty->print_cr("dominating test"); } // prevdom is the dominating projection of the dominating test. assert( iff->is_If(), "" ); ! assert(iff->Opcode() == Opcodes::Op_If || iff->Opcode() == Opcodes::Op_CountedLoopEnd || iff->Opcode() == Opcodes::Op_RangeCheck, "Check this code when new subtype is added"); ! Opcodes pop = prevdom->Opcode(); ! assert( pop == Opcodes::Op_IfFalse || pop == Opcodes::Op_IfTrue, "" ); if (flip) { ! if (pop == Opcodes::Op_IfTrue) ! pop = Opcodes::Op_IfFalse; else ! pop = Opcodes::Op_IfTrue; } // 'con' is set to true or false to kill the dominated test. ! Node *con = _igvn.makecon(pop == Opcodes::Op_IfTrue ? TypeInt::ONE : TypeInt::ZERO); set_ctrl(con, C->root()); // Constant gets a new use // Hack the dominated test _igvn.replace_input_of(iff, 1, con); // If I dont have a reachable TRUE and FALSE path following the IfNode then
*** 236,246 **** if (iff->outcnt() != 2) return; // Make control-dependent data Nodes on the live path (path that will remain // once the dominated IF is removed) become control-dependent on the // dominating projection. ! Node* dp = iff->as_If()->proj_out(pop == Op_IfTrue); // Loop predicates may have depending checks which should not // be skipped. For example, range check predicate has two checks // for lower and upper bounds. if (dp == NULL) --- 236,246 ---- if (iff->outcnt() != 2) return; // Make control-dependent data Nodes on the live path (path that will remain // once the dominated IF is removed) become control-dependent on the // dominating projection. ! Node* dp = iff->as_If()->proj_out(pop == Opcodes::Op_IfTrue); // Loop predicates may have depending checks which should not // be skipped. For example, range check predicate has two checks // for lower and upper bounds. if (dp == NULL)
*** 349,362 **** n2_loop == n_loop && n3_loop == n_loop ) return NULL; // No loop-invariant inputs ! int n_op = n->Opcode(); // Replace expressions like ((V+I) << 2) with (V<<2 + I<<2). ! if( n_op == Op_LShiftI ) { // Scale is loop invariant Node *scale = n->in(2); Node *scale_ctrl = get_ctrl(scale); IdealLoopTree *scale_loop = get_loop(scale_ctrl ); if( n_loop == scale_loop || !scale_loop->is_member( n_loop ) ) --- 349,362 ---- n2_loop == n_loop && n3_loop == n_loop ) return NULL; // No loop-invariant inputs ! Opcodes n_op = n->Opcode(); // Replace expressions like ((V+I) << 2) with (V<<2 + I<<2). ! if( n_op == Opcodes::Op_LShiftI ) { // Scale is loop invariant Node *scale = n->in(2); Node *scale_ctrl = get_ctrl(scale); IdealLoopTree *scale_loop = get_loop(scale_ctrl ); if( n_loop == scale_loop || !scale_loop->is_member( n_loop ) )
*** 370,389 **** IdealLoopTree *add_loop = get_loop(add_ctrl); //assert( n_loop == add_loop, "" ); if( n_loop != add_loop ) return NULL; // happens w/ evil ZKM loops // Convert I-V into I+ (0-V); same for V-I ! if( add->Opcode() == Op_SubI && _igvn.type( add->in(1) ) != TypeInt::ZERO ) { Node *zero = _igvn.intcon(0); set_ctrl(zero, C->root()); Node *neg = new SubINode( _igvn.intcon(0), add->in(2) ); register_new_node( neg, get_ctrl(add->in(2) ) ); add = new AddINode( add->in(1), neg ); register_new_node( add, add_ctrl ); } ! if( add->Opcode() != Op_AddI ) return NULL; // See if one add input is loop invariant Node *add_var = add->in(1); Node *add_var_ctrl = get_ctrl(add_var); IdealLoopTree *add_var_loop = get_loop(add_var_ctrl ); Node *add_invar = add->in(2); --- 370,389 ---- IdealLoopTree *add_loop = get_loop(add_ctrl); //assert( n_loop == add_loop, "" ); if( n_loop != add_loop ) return NULL; // happens w/ evil ZKM loops // Convert I-V into I+ (0-V); same for V-I ! if( add->Opcode() == Opcodes::Op_SubI && _igvn.type( add->in(1) ) != TypeInt::ZERO ) { Node *zero = _igvn.intcon(0); set_ctrl(zero, C->root()); Node *neg = new SubINode( _igvn.intcon(0), add->in(2) ); register_new_node( neg, get_ctrl(add->in(2) ) ); add = new AddINode( add->in(1), neg ); register_new_node( add, add_ctrl ); } ! if( add->Opcode() != Opcodes::Op_AddI ) return NULL; // See if one add input is loop invariant Node *add_var = add->in(1); Node *add_var_ctrl = get_ctrl(add_var); IdealLoopTree *add_var_loop = get_loop(add_var_ctrl ); Node *add_invar = add->in(2);
*** 416,444 **** _igvn.replace_node( n, var_add ); return var_add; } // Replace (I+V) with (V+I) ! if( n_op == Op_AddI || ! n_op == Op_AddL || ! n_op == Op_AddF || ! n_op == Op_AddD || ! n_op == Op_MulI || ! n_op == Op_MulL || ! n_op == Op_MulF || ! n_op == Op_MulD ) { if( n2_loop == n_loop ) { assert( n1_loop != n_loop, "" ); n->swap_edges(1, 2); } } // Replace ((I1 +p V) +p I2) with ((I1 +p I2) +p V), // but not if I2 is a constant. ! if( n_op == Op_AddP ) { if( n2_loop == n_loop && n3_loop != n_loop ) { ! if( n->in(2)->Opcode() == Op_AddP && !n->in(3)->is_Con() ) { Node *n22_ctrl = get_ctrl(n->in(2)->in(2)); Node *n23_ctrl = get_ctrl(n->in(2)->in(3)); IdealLoopTree *n22loop = get_loop( n22_ctrl ); IdealLoopTree *n23_loop = get_loop( n23_ctrl ); if( n22loop != n_loop && n22loop->is_member(n_loop) && --- 416,444 ---- _igvn.replace_node( n, var_add ); return var_add; } // Replace (I+V) with (V+I) ! if( n_op == Opcodes::Op_AddI || ! n_op == Opcodes::Op_AddL || ! n_op == Opcodes::Op_AddF || ! n_op == Opcodes::Op_AddD || ! n_op == Opcodes::Op_MulI || ! n_op == Opcodes::Op_MulL || ! n_op == Opcodes::Op_MulF || ! n_op == Opcodes::Op_MulD ) { if( n2_loop == n_loop ) { assert( n1_loop != n_loop, "" ); n->swap_edges(1, 2); } } // Replace ((I1 +p V) +p I2) with ((I1 +p I2) +p V), // but not if I2 is a constant. ! if( n_op == Opcodes::Op_AddP ) { if( n2_loop == n_loop && n3_loop != n_loop ) { ! if( n->in(2)->Opcode() == Opcodes::Op_AddP && !n->in(3)->is_Con() ) { Node *n22_ctrl = get_ctrl(n->in(2)->in(2)); Node *n23_ctrl = get_ctrl(n->in(2)->in(3)); IdealLoopTree *n22loop = get_loop( n22_ctrl ); IdealLoopTree *n23_loop = get_loop( n23_ctrl ); if( n22loop != n_loop && n22loop->is_member(n_loop) &&
*** 454,464 **** } } // Replace (I1 +p (I2 + V)) with ((I1 +p I2) +p V) if (n2_loop != n_loop && n3_loop == n_loop) { ! if (n->in(3)->Opcode() == Op_AddX) { Node *V = n->in(3)->in(1); Node *I = n->in(3)->in(2); if (is_member(n_loop,get_ctrl(V))) { } else { Node *tmp = V; V = I; I = tmp; --- 454,464 ---- } } // Replace (I1 +p (I2 + V)) with ((I1 +p I2) +p V) if (n2_loop != n_loop && n3_loop == n_loop) { ! if (n->in(3)->Opcode() == Opcodes::Op_AddX) { Node *V = n->in(3)->in(1); Node *I = n->in(3)->in(2); if (is_member(n_loop,get_ctrl(V))) { } else { Node *tmp = V; V = I; I = tmp;
*** 584,598 **** } } } }//for Node* bol = iff->in(1); ! assert(bol->Opcode() == Op_Bool, ""); ! int cmp_op = bol->in(1)->Opcode(); // It is expensive to generate flags from a float compare. // Avoid duplicated float compare. ! if (phis > 1 && (cmp_op == Op_CmpF || cmp_op == Op_CmpD)) return NULL; float infrequent_prob = PROB_UNLIKELY_MAG(3); // Ignore cost and blocks frequency if CMOVE can be moved outside the loop. if (used_inside_loop) { if (cost >= ConditionalMoveLimit) return NULL; // Too much goo --- 584,598 ---- } } } }//for Node* bol = iff->in(1); ! assert(bol->Opcode() == Opcodes::Op_Bool, ""); ! Opcodes cmp_op = bol->in(1)->Opcode(); // It is expensive to generate flags from a float compare. // Avoid duplicated float compare. ! if (phis > 1 && (cmp_op == Opcodes::Op_CmpF || cmp_op == Opcodes::Op_CmpD)) return NULL; float infrequent_prob = PROB_UNLIKELY_MAG(3); // Ignore cost and blocks frequency if CMOVE can be moved outside the loop. if (used_inside_loop) { if (cost >= ConditionalMoveLimit) return NULL; // Too much goo
*** 604,622 **** infrequent_prob = MAX2(infrequent_prob, (float)BlockLayoutMinDiamondPercentage/110.0f); } } // Check for highly predictable branch. No point in CMOV'ing if // we are going to predict accurately all the time. ! if (C->use_cmove() && cmp_op == Op_CmpD) ;//keep going else if (iff->_prob < infrequent_prob || iff->_prob > (1.0f - infrequent_prob)) return NULL; // -------------- // Now replace all Phis with CMOV's Node *cmov_ctrl = iff->in(0); ! uint flip = (lp->Opcode() == Op_IfTrue); while (1) { PhiNode* phi = NULL; for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { Node *out = region->fast_out(i); if (out->is_Phi()) { --- 604,622 ---- infrequent_prob = MAX2(infrequent_prob, (float)BlockLayoutMinDiamondPercentage/110.0f); } } // Check for highly predictable branch. No point in CMOV'ing if // we are going to predict accurately all the time. ! if (C->use_cmove() && cmp_op == Opcodes::Op_CmpD) ;//keep going else if (iff->_prob < infrequent_prob || iff->_prob > (1.0f - infrequent_prob)) return NULL; // -------------- // Now replace all Phis with CMOV's Node *cmov_ctrl = iff->in(0); ! uint flip = (lp->Opcode() == Opcodes::Op_IfTrue); while (1) { PhiNode* phi = NULL; for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { Node *out = region->fast_out(i); if (out->is_Phi()) {
*** 665,675 **** static void enqueue_cfg_uses(Node* m, Unique_Node_List& wq) { for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) { Node* u = m->fast_out(i); if (u->is_CFG()) { ! if (u->Opcode() == Op_NeverBranch) { u = ((NeverBranchNode*)u)->proj_out(0); enqueue_cfg_uses(u, wq); } else { wq.push(u); } --- 665,675 ---- static void enqueue_cfg_uses(Node* m, Unique_Node_List& wq) { for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) { Node* u = m->fast_out(i); if (u->is_CFG()) { ! if (u->Opcode() == Opcodes::Op_NeverBranch) { u = ((NeverBranchNode*)u)->proj_out(0); enqueue_cfg_uses(u, wq); } else { wq.push(u); }
*** 875,899 **** //------------------------------split_if_with_blocks_pre----------------------- // Do the real work in a non-recursive function. Data nodes want to be // cloned in the pre-order so they can feed each other nicely. Node *PhaseIdealLoop::split_if_with_blocks_pre( Node *n ) { // Cloning these guys is unlikely to win ! int n_op = n->Opcode(); ! if( n_op == Op_MergeMem ) return n; if( n->is_Proj() ) return n; // Do not clone-up CmpFXXX variations, as these are always // followed by a CmpI if( n->is_Cmp() ) return n; // Attempt to use a conditional move instead of a phi/branch ! if( ConditionalMoveLimit > 0 && n_op == Op_Region ) { Node *cmov = conditional_move( n ); if( cmov ) return cmov; } if( n->is_CFG() || n->is_LoadStore() ) return n; ! if( n_op == Op_Opaque1 || // Opaque nodes cannot be mod'd ! n_op == Op_Opaque2 ) { if( !C->major_progress() ) // If chance of no more loop opts... _igvn._worklist.push(n); // maybe we'll remove them return n; } --- 875,899 ---- //------------------------------split_if_with_blocks_pre----------------------- // Do the real work in a non-recursive function. Data nodes want to be // cloned in the pre-order so they can feed each other nicely. Node *PhaseIdealLoop::split_if_with_blocks_pre( Node *n ) { // Cloning these guys is unlikely to win ! Opcodes n_op = n->Opcode(); ! if( n_op == Opcodes::Op_MergeMem ) return n; if( n->is_Proj() ) return n; // Do not clone-up CmpFXXX variations, as these are always // followed by a CmpI if( n->is_Cmp() ) return n; // Attempt to use a conditional move instead of a phi/branch ! if( ConditionalMoveLimit > 0 && n_op == Opcodes::Op_Region ) { Node *cmov = conditional_move( n ); if( cmov ) return cmov; } if( n->is_CFG() || n->is_LoadStore() ) return n; ! if( n_op == Opcodes::Op_Opaque1 || // Opaque nodes cannot be mod'd ! n_op == Opcodes::Op_Opaque2 ) { if( !C->major_progress() ) // If chance of no more loop opts... _igvn._worklist.push(n); // maybe we'll remove them return n; }
*** 924,934 **** Node *n_blk = has_local_phi_input( n ); if( !n_blk ) return n; // Do not clone the trip counter through on a CountedLoop // (messes up the canonical shape). ! if( n_blk->is_CountedLoop() && n->Opcode() == Op_AddI ) return n; // Check for having no control input; not pinned. Allow // dominating control. if (n->in(0)) { Node *dom = idom(n_blk); --- 924,934 ---- Node *n_blk = has_local_phi_input( n ); if( !n_blk ) return n; // Do not clone the trip counter through on a CountedLoop // (messes up the canonical shape). ! if( n_blk->is_CountedLoop() && n->Opcode() == Opcodes::Op_AddI ) return n; // Check for having no control input; not pinned. Allow // dominating control. if (n->in(0)) { Node *dom = idom(n_blk);
*** 1003,1013 **** for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { Node* m = n->fast_out(j); if (m->is_FastLock()) return false; #ifdef _LP64 ! if (m->Opcode() == Op_ConvI2L) return false; if (m->is_CastII() && m->isa_CastII()->has_range_check()) { return false; } #endif --- 1003,1013 ---- for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { Node* m = n->fast_out(j); if (m->is_FastLock()) return false; #ifdef _LP64 ! if (m->Opcode() == Opcodes::Op_ConvI2L) return false; if (m->is_CastII() && m->isa_CastII()->has_range_check()) { return false; } #endif
*** 1219,1233 **** return; } // Check for an IF ready to split; one that has its // condition codes input coming from a Phi at the block start. ! int n_op = n->Opcode(); // Check for an IF being dominated by another IF same test ! if (n_op == Op_If || ! n_op == Op_RangeCheck) { Node *bol = n->in(1); uint max = bol->outcnt(); // Check for same test used more than once? if (max > 1 && bol->is_Bool()) { // Search up IDOMs to see if this IF is dominated. --- 1219,1233 ---- return; } // Check for an IF ready to split; one that has its // condition codes input coming from a Phi at the block start. ! Opcodes n_op = n->Opcode(); // Check for an IF being dominated by another IF same test ! if (n_op == Opcodes::Op_If || ! n_op == Opcodes::Op_RangeCheck) { Node *bol = n->in(1); uint max = bol->outcnt(); // Check for same test used more than once? if (max > 1 && bol->is_Bool()) { // Search up IDOMs to see if this IF is dominated.
*** 1266,1276 **** Node* u = n->fast_out(i); if( !has_ctrl(u) ) break; // Found control user IdealLoopTree *u_loop = get_loop(get_ctrl(u)); if( u_loop == n_loop ) break; // Found loop-varying use if( n_loop->is_member( u_loop ) ) break; // Found use in inner loop ! if( u->Opcode() == Op_Opaque1 ) break; // Found loop limit, bugfix for 4677003 } bool did_break = (i < imax); // Did we break out of the previous loop? if (!did_break && n->outcnt() > 1) { // All uses in outer loops! Node *late_load_ctrl = NULL; if (n->is_Load()) { --- 1266,1276 ---- Node* u = n->fast_out(i); if( !has_ctrl(u) ) break; // Found control user IdealLoopTree *u_loop = get_loop(get_ctrl(u)); if( u_loop == n_loop ) break; // Found loop-varying use if( n_loop->is_member( u_loop ) ) break; // Found use in inner loop ! if( u->Opcode() == Opcodes::Op_Opaque1 ) break; // Found loop limit, bugfix for 4677003 } bool did_break = (i < imax); // Did we break out of the previous loop? if (!did_break && n->outcnt() > 1) { // All uses in outer loops! Node *late_load_ctrl = NULL; if (n->is_Load()) {
*** 1353,1363 **** try_move_store_after_loop(n); // Check for Opaque2's who's loop has disappeared - who's input is in the // same loop nest as their output. Remove 'em, they are no longer useful. ! if( n_op == Op_Opaque2 && n->in(1) != NULL && get_loop(get_ctrl(n)) == get_loop(get_ctrl(n->in(1))) ) { _igvn.replace_node( n, n->in(1) ); } } --- 1353,1363 ---- try_move_store_after_loop(n); // Check for Opaque2's who's loop has disappeared - who's input is in the // same loop nest as their output. Remove 'em, they are no longer useful. ! if( n_op == Opcodes::Op_Opaque2 && n->in(1) != NULL && get_loop(get_ctrl(n)) == get_loop(get_ctrl(n->in(1))) ) { _igvn.replace_node( n, n->in(1) ); } }
*** 1768,1778 **** if( use->is_Bool() ) { if( !split_bool_set ) split_bool_set = new Node_List(area); split_bool_set->push(use); } ! if( use->Opcode() == Op_CreateEx ) { if( !split_cex_set ) split_cex_set = new Node_List(area); split_cex_set->push(use); } --- 1768,1778 ---- if( use->is_Bool() ) { if( !split_bool_set ) split_bool_set = new Node_List(area); split_bool_set->push(use); } ! if( use->Opcode() == Opcodes::Op_CreateEx ) { if( !split_cex_set ) split_cex_set = new Node_List(area); split_cex_set->push(use); }
*** 1904,1914 **** if (!iff->is_If() || iff->in(1) == NULL || !iff->in(1)->is_Bool()) { return 0; } BoolNode* bl = iff->in(1)->as_Bool(); Node* cmp = bl->in(1); ! if (!cmp || cmp->Opcode() != Op_CmpI && cmp->Opcode() != Op_CmpU) { return 0; } // Must have an invariant operand if (is_member(get_loop(iff), get_ctrl(cmp->in(2)))) { return 0; --- 1904,1914 ---- if (!iff->is_If() || iff->in(1) == NULL || !iff->in(1)->is_Bool()) { return 0; } BoolNode* bl = iff->in(1)->as_Bool(); Node* cmp = bl->in(1); ! if (!cmp || cmp->Opcode() != Opcodes::Op_CmpI && cmp->Opcode() != Opcodes::Op_CmpU) { return 0; } // Must have an invariant operand if (is_member(get_loop(iff), get_ctrl(cmp->in(2)))) { return 0;
*** 2043,2055 **** register_node(cmp, loop, proj2, ddepth); BoolNode* bol = new BoolNode(cmp, relop); register_node(bol, loop, proj2, ddepth); ! int opcode = iff->Opcode(); ! assert(opcode == Op_If || opcode == Op_RangeCheck, "unexpected opcode"); ! IfNode* new_if = (opcode == Op_If) ? new IfNode(proj2, bol, iff->_prob, iff->_fcnt): new RangeCheckNode(proj2, bol, iff->_prob, iff->_fcnt); register_node(new_if, loop, proj2, ddepth); proj->set_req(0, new_if); // reattach set_idom(proj, new_if, ddepth); --- 2043,2055 ---- register_node(cmp, loop, proj2, ddepth); BoolNode* bol = new BoolNode(cmp, relop); register_node(bol, loop, proj2, ddepth); ! Opcodes opcode = iff->Opcode(); ! assert(opcode == Opcodes::Op_If || opcode == Opcodes::Op_RangeCheck, "unexpected opcode"); ! IfNode* new_if = (opcode == Opcodes::Op_If) ? new IfNode(proj2, bol, iff->_prob, iff->_fcnt): new RangeCheckNode(proj2, bol, iff->_prob, iff->_fcnt); register_node(new_if, loop, proj2, ddepth); proj->set_req(0, new_if); // reattach set_idom(proj, new_if, ddepth);
*** 2157,2167 **** const bool Unsigned = false; BoolNode* bol = if_cmpu->in(1)->as_Bool(); if (bol->_test._test != BoolTest::lt) return NULL; CmpNode* cmpu = bol->in(1)->as_Cmp(); ! if (cmpu->Opcode() != Op_CmpU) return NULL; int stride = stride_of_possible_iv(if_cmpu); if (stride == 0) return NULL; Node* lp_proj = stay_in_loop(if_cmpu, loop); guarantee(lp_proj != NULL, "null loop node"); --- 2157,2167 ---- const bool Unsigned = false; BoolNode* bol = if_cmpu->in(1)->as_Bool(); if (bol->_test._test != BoolTest::lt) return NULL; CmpNode* cmpu = bol->in(1)->as_Cmp(); ! if (cmpu->Opcode() != Opcodes::Op_CmpU) return NULL; int stride = stride_of_possible_iv(if_cmpu); if (stride == 0) return NULL; Node* lp_proj = stay_in_loop(if_cmpu, loop); guarantee(lp_proj != NULL, "null loop node");
*** 2198,2210 **** //------------------------------ remove_cmpi_loop_exit ------------------------------------- // Remove a previously inserted signed compare loop exit. void PhaseIdealLoop::remove_cmpi_loop_exit(IfNode* if_cmp, IdealLoopTree *loop) { Node* lp_proj = stay_in_loop(if_cmp, loop); ! assert(if_cmp->in(1)->in(1)->Opcode() == Op_CmpI && stay_in_loop(lp_proj, loop)->is_If() && ! stay_in_loop(lp_proj, loop)->in(1)->in(1)->Opcode() == Op_CmpU, "inserted cmpi before cmpu"); Node *con = _igvn.makecon(lp_proj->is_IfTrue() ? TypeInt::ONE : TypeInt::ZERO); set_ctrl(con, C->root()); if_cmp->set_req(1, con); } --- 2198,2210 ---- //------------------------------ remove_cmpi_loop_exit ------------------------------------- // Remove a previously inserted signed compare loop exit. void PhaseIdealLoop::remove_cmpi_loop_exit(IfNode* if_cmp, IdealLoopTree *loop) { Node* lp_proj = stay_in_loop(if_cmp, loop); ! assert(if_cmp->in(1)->in(1)->Opcode() == Opcodes::Op_CmpI && stay_in_loop(lp_proj, loop)->is_If() && ! stay_in_loop(lp_proj, loop)->in(1)->in(1)->Opcode() == Opcodes::Op_CmpU, "inserted cmpi before cmpu"); Node *con = _igvn.makecon(lp_proj->is_IfTrue() ? TypeInt::ONE : TypeInt::ZERO); set_ctrl(con, C->root()); if_cmp->set_req(1, con); }
*** 2454,2466 **** // Ensure a use outside of loop is of the right form bool PhaseIdealLoop::is_valid_clone_loop_exit_use( IdealLoopTree *loop, Node* use, uint exit_idx) { Node *use_c = has_ctrl(use) ? get_ctrl(use) : use; return (use->is_Phi() && use_c->is_Region() && use_c->req() == 3 && ! (use_c->in(exit_idx)->Opcode() == Op_IfTrue || ! use_c->in(exit_idx)->Opcode() == Op_IfFalse || ! use_c->in(exit_idx)->Opcode() == Op_JumpProj) && loop->is_member( get_loop( use_c->in(exit_idx)->in(0) ) ) ); } //------------------------------ is_valid_clone_loop_form ------------------------------------- // Ensure that all uses outside of loop are of the right form --- 2454,2466 ---- // Ensure a use outside of loop is of the right form bool PhaseIdealLoop::is_valid_clone_loop_exit_use( IdealLoopTree *loop, Node* use, uint exit_idx) { Node *use_c = has_ctrl(use) ? get_ctrl(use) : use; return (use->is_Phi() && use_c->is_Region() && use_c->req() == 3 && ! (use_c->in(exit_idx)->Opcode() == Opcodes::Op_IfTrue || ! use_c->in(exit_idx)->Opcode() == Opcodes::Op_IfFalse || ! use_c->in(exit_idx)->Opcode() == Opcodes::Op_JumpProj) && loop->is_member( get_loop( use_c->in(exit_idx)->in(0) ) ) ); } //------------------------------ is_valid_clone_loop_form ------------------------------------- // Ensure that all uses outside of loop are of the right form
*** 2709,2724 **** } // Check for complex exit control for(uint ii = 0; ii < loop->_body.size(); ii++ ) { Node *n = loop->_body.at(ii); ! int opc = n->Opcode(); if (n->is_Call() || ! opc == Op_Catch || ! opc == Op_CatchProj || ! opc == Op_Jump || ! opc == Op_JumpProj) { #if !defined(PRODUCT) if (TracePartialPeeling) { tty->print_cr("\nExit control too complex: lp: %d", head->_idx); } #endif --- 2709,2724 ---- } // Check for complex exit control for(uint ii = 0; ii < loop->_body.size(); ii++ ) { Node *n = loop->_body.at(ii); ! Opcodes opc = n->Opcode(); if (n->is_Call() || ! opc == Opcodes::Op_Catch || ! opc == Opcodes::Op_CatchProj || ! opc == Opcodes::Op_Jump || ! opc == Opcodes::Op_JumpProj) { #if !defined(PRODUCT) if (TracePartialPeeling) { tty->print_cr("\nExit control too complex: lp: %d", head->_idx); } #endif
*** 2743,2756 **** // If loop-varying exit-test, check for induction variable if( loop->is_member(get_loop(ctrl)) && loop->is_loop_exit(iff) && is_possible_iv_test(iff)) { Node* cmp = iff->in(1)->in(1); ! if (cmp->Opcode() == Op_CmpI) { peel_if = iff->as_If(); } else { ! assert(cmp->Opcode() == Op_CmpU, "must be CmpI or CmpU"); peel_if_cmpu = iff->as_If(); } } } iff = idom(iff); --- 2743,2756 ---- // If loop-varying exit-test, check for induction variable if( loop->is_member(get_loop(ctrl)) && loop->is_loop_exit(iff) && is_possible_iv_test(iff)) { Node* cmp = iff->in(1)->in(1); ! if (cmp->Opcode() == Opcodes::Op_CmpI) { peel_if = iff->as_If(); } else { ! assert(cmp->Opcode() == Opcodes::Op_CmpU, "must be CmpI or CmpU"); peel_if_cmpu = iff->as_If(); } } } iff = idom(iff);
< prev index next >