src/share/vm/opto/loopnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/opto/loopnode.cpp	Thu May 15 17:09:30 2014
--- new/src/share/vm/opto/loopnode.cpp	Thu May 15 17:09:30 2014

*** 441,451 **** --- 441,451 ---- // ---- SUCCESS! Found A Trip-Counted Loop! ----- // assert(x->Opcode() == Op_Loop, "regular loops only"); C->print_method(PHASE_BEFORE_CLOOPS, 3); - Node *hook = new (C) Node(6); if (LoopLimitCheck) { // =================================================== // Generate loop limit check to avoid integer overflow
*** 504,518 **** --- 504,518 ---- IfNode* check_iff = limit_check_proj->in(0)->as_If(); Node* cmp_limit; Node* bol; if (stride_con > 0) { - cmp_limit = new (C) CmpINode(limit, _igvn.intcon(max_jint - stride_m)); - bol = new (C) BoolNode(cmp_limit, BoolTest::le); } else { - cmp_limit = new (C) CmpINode(limit, _igvn.intcon(min_jint - stride_m)); - bol = new (C) BoolNode(cmp_limit, BoolTest::ge); } cmp_limit = _igvn.register_new_node_with_optimizer(cmp_limit); bol = _igvn.register_new_node_with_optimizer(bol); set_subtree_ctrl(bol);
*** 545,555 **** --- 545,555 ---- // // i = init; do {} while(i++ < limit); // is converted to // i = init; do {} while(++i < limit+1); // - limit = gvn->transform(new (C) AddINode(limit, stride)); } // Now we need to canonicalize loop condition. if (bt == BoolTest::ne) { assert(stride_con == 1 || stride_con == -1, "simple increment only");
*** 564,574 **** --- 564,574 ---- if (incl_limit) { // The limit check guaranties that 'limit <= (max_jint - stride)' so // we can convert 'i <= limit' to 'i < limit+1' since stride != 0. // Node* one = (stride_con > 0) ? gvn->intcon( 1) : gvn->intcon(-1); - limit = gvn->transform(new (C) AddINode(limit, one)); if (bt == BoolTest::le) bt = BoolTest::lt; else if (bt == BoolTest::ge) bt = BoolTest::gt; else
*** 580,590 **** --- 580,590 ---- // If compare points to incr, we are ok. Otherwise the compare // can directly point to the phi; in this case adjust the compare so that // it points to the incr by adjusting the limit. if (cmp->in(1) == phi || cmp->in(2) == phi) - limit = gvn->transform(new (C) AddINode(limit,stride)); // trip-count for +-tive stride should be: (limit - init_trip + stride - 1)/stride. // Final value for iterator should be: trip_count * stride + init_trip. Node *one_p = gvn->intcon( 1); Node *one_m = gvn->intcon(-1);
*** 593,676 **** --- 593,676 ---- switch( bt ) { case BoolTest::eq: ShouldNotReachHere(); case BoolTest::ne: // Ahh, the case we desire if (stride_con == 1) - trip_count = gvn->transform(new (C) SubINode(limit,init_trip)); else if (stride_con == -1) - trip_count = gvn->transform(new (C) SubINode(init_trip,limit)); else ShouldNotReachHere(); set_subtree_ctrl(trip_count); //_loop.map(trip_count->_idx,loop(limit)); break; case BoolTest::le: // Maybe convert to '<' case - limit = gvn->transform(new (C) AddINode(limit,one_p)); set_subtree_ctrl( limit ); hook->init_req(4, limit); bt = BoolTest::lt; // Make the new limit be in the same loop nest as the old limit //_loop.map(limit->_idx,limit_loop); // Fall into next case case BoolTest::lt: { // Maybe convert to '!=' case if (stride_con < 0) // Count down loop rolls through MAXINT ShouldNotReachHere(); - Node *range = gvn->transform(new (C) SubINode(limit,init_trip)); set_subtree_ctrl( range ); hook->init_req(0, range); - Node *bias = gvn->transform(new (C) AddINode(range,stride)); set_subtree_ctrl( bias ); hook->init_req(1, bias); - Node *bias1 = gvn->transform(new (C) AddINode(bias,one_m)); set_subtree_ctrl( bias1 ); hook->init_req(2, bias1); - trip_count = gvn->transform(new (C) DivINode(0,bias1,stride)); set_subtree_ctrl( trip_count ); hook->init_req(3, trip_count); break; } case BoolTest::ge: // Maybe convert to '>' case - limit = gvn->transform(new (C) AddINode(limit,one_m)); set_subtree_ctrl( limit ); hook->init_req(4 ,limit); bt = BoolTest::gt; // Make the new limit be in the same loop nest as the old limit //_loop.map(limit->_idx,limit_loop); // Fall into next case case BoolTest::gt: { // Maybe convert to '!=' case if (stride_con > 0) // count up loop rolls through MININT ShouldNotReachHere(); - Node *range = gvn->transform(new (C) SubINode(limit,init_trip)); set_subtree_ctrl( range ); hook->init_req(0, range); - Node *bias = gvn->transform(new (C) AddINode(range,stride)); set_subtree_ctrl( bias ); hook->init_req(1, bias); - Node *bias1 = gvn->transform(new (C) AddINode(bias,one_p)); set_subtree_ctrl( bias1 ); hook->init_req(2, bias1); - trip_count = gvn->transform(new (C) DivINode(0,bias1,stride)); set_subtree_ctrl( trip_count ); hook->init_req(3, trip_count); break; } } // switch( bt ) - Node *span = gvn->transform(new (C) MulINode(trip_count,stride)); set_subtree_ctrl( span ); hook->init_req(5, span); - limit = gvn->transform(new (C) AddINode(span,init_trip)); set_subtree_ctrl( limit ); } // LoopLimitCheck // Check for SafePoint on backedge and remove
*** 715,737 **** --- 715,737 ---- test->set_req(1,cmp); _igvn.register_new_node_with_optimizer(test); set_ctrl(test, iff->in(0)); // Replace the old IfNode with a new LoopEndNode - Node *lex = _igvn.register_new_node_with_optimizer(new (C) CountedLoopEndNode( iff->in(0), test, cl_prob, iff->as_If()->_fcnt )); IfNode *le = lex->as_If(); uint dd = dom_depth(iff); set_idom(le, le->in(0), dd); // Update dominance for loop exit set_loop(le, loop); // Get the loop-exit control Node *iffalse = iff->as_If()->proj_out(!(iftrue_op == Op_IfTrue)); // Need to swap loop-exit and loop-back control? if (iftrue_op == Op_IfFalse) { - Node *ift2=_igvn.register_new_node_with_optimizer(new (C) IfTrueNode (le)); - Node *iff2=_igvn.register_new_node_with_optimizer(new (C) IfFalseNode(le)); loop->_tail = back_control = ift2; set_loop(ift2, loop); set_loop(iff2, get_loop(iffalse));
*** 753,763 **** --- 753,763 ---- set_idom(iffalse, le, dd+1); assert(iff->outcnt() == 0, "should be dead now"); lazy_replace( iff, le ); // fix 'get_ctrl' // Now setup a new CountedLoopNode to replace the existing LoopNode - CountedLoopNode *l = new (C) CountedLoopNode(init_control, back_control); l->set_unswitch_count(x->as_Loop()->unswitch_count()); // Preserve // The following assert is approximately true, and defines the intention // of can_be_counted_loop. It fails, however, because phase->type // is not yet initialized for this loop and its parts. //assert(l->can_be_counted_loop(this), "sanity");
*** 827,837 **** --- 827,837 ---- // is counted and the limit was checked for overflow. assert(final_con == (jlong)final_int, "final value should be integer"); limit = _igvn.intcon(final_int); } else { // Create new LoopLimit node to get exact limit (final iv value). - limit = new (C) LoopLimitNode(C, cl->init_trip(), cl->limit(), cl->stride()); register_new_node(limit, cl->in(LoopNode::EntryControl)); } assert(limit != NULL, "sanity"); return limit; }
*** 944,990 **** --- 944,990 ---- } julong range = lim - ini + stride_p; if (range <= max) { // Convert to integer expression if it is not overflow. Node* stride_m = phase->intcon(stride_con - (stride_con > 0 ? 1 : -1)); - Node *range = phase->transform(new (phase->C) SubINode(in(Limit), in(Init))); - Node *bias = phase->transform(new (phase->C) AddINode(range, stride_m)); - Node *trip = phase->transform(new (phase->C) DivINode(0, bias, in(Stride))); - Node *span = phase->transform(new (phase->C) MulINode(trip, in(Stride))); - return new (phase->C) AddINode(span, in(Init)); // exact limit } if (is_power_of_2(stride_p) || // divisor is 2^n !Matcher::has_match_rule(Op_LoopLimit)) { // or no specialized Mach node? // Convert to long expression to avoid integer overflow // and let igvn optimizer convert this division. // - Node* init = phase->transform( new (phase->C) ConvI2LNode(in(Init))); - Node* limit = phase->transform( new (phase->C) ConvI2LNode(in(Limit))); Node* stride = phase->longcon(stride_con); Node* stride_m = phase->longcon(stride_con - (stride_con > 0 ? 1 : -1)); - Node *range = phase->transform(new (phase->C) SubLNode(limit, init)); - Node *bias = phase->transform(new (phase->C) AddLNode(range, stride_m)); Node *span; if (stride_con > 0 && is_power_of_2(stride_p)) { // bias >= 0 if stride >0, so if stride is 2^n we can use &(-stride) // and avoid generating rounding for division. Zero trip guard should // guarantee that init < limit but sometimes the guard is missing and // we can get situation when init > limit. Note, for the empty loop // optimization zero trip guard is generated explicitly which leaves // only RCE predicate where exact limit is used and the predicate // will simply fail forcing recompilation. Node* neg_stride = phase->longcon(-stride_con); - span = phase->transform(new (phase->C) AndLNode(bias, neg_stride)); } else { - Node *trip = phase->transform(new (phase->C) DivLNode(0, bias, stride)); - span = phase->transform(new (phase->C) MulLNode(trip, stride)); } // Convert back to int - Node *span_int = phase->transform(new (phase->C) ConvL2INode(span)); - return new (phase->C) AddINode(span_int, in(Init)); // exact limit } return NULL; // No progress }
*** 1186,1196 **** --- 1186,1196 ---- void IdealLoopTree::split_fall_in( PhaseIdealLoop *phase, int fall_in_cnt ) { PhaseIterGVN &igvn = phase->_igvn; uint i; // Make a new RegionNode to be the landing pad. - Node *landing_pad = new (phase->C) RegionNode( fall_in_cnt+1 ); phase->set_loop(landing_pad,_parent); // Gather all the fall-in control paths into the landing pad uint icnt = fall_in_cnt; uint oreq = _head->req(); for( i = oreq-1; i>0; i-- )
*** 1272,1282 **** --- 1272,1282 ---- uint outer_idx = 1; while( _head->in(outer_idx) != _tail ) outer_idx++; // Make a LoopNode for the outermost loop. Node *ctl = _head->in(LoopNode::EntryControl); - Node *outer = new (phase->C) LoopNode( ctl, _head->in(outer_idx) ); outer = igvn.register_new_node_with_optimizer(outer, _head); phase->set_created_loop_node(); // Outermost loop falls into '_head' loop _head->set_req(LoopNode::EntryControl, outer);
*** 1386,1396 **** --- 1386,1396 ---- // them all except optionally hot_idx. PhaseIterGVN &igvn = phase->_igvn; Node *hot_tail = NULL; // Make a Region for the merge point - Node *r = new (phase->C) RegionNode(1); for( i = 2; i < _head->req(); i++ ) { if( i != hot_idx ) r->add_req( _head->in(i) ); else hot_tail = _head->in(i); }
*** 1405,1415 **** --- 1405,1415 ---- Node *out = _head->fast_out(j); if( out->is_Phi() ) { PhiNode* n = out->as_Phi(); igvn.hash_delete(n); // Delete from hash before hacking edges Node *hot_phi = NULL; - Node *phi = new (phase->C) PhiNode(r, n->type(), n->adr_type()); // Check all inputs for the ones to peel out uint j = 1; for( uint i = 2; i < n->req(); i++ ) { if( i != hot_idx ) phi->set_req( j++, n->in(i) );
*** 1527,1537 **** --- 1527,1537 ---- split_outer_loop( phase ); result = true; } else if (!_head->is_Loop() && !_irreducible) { // Make a new LoopNode to replace the old loop head - Node *l = new (phase->C) LoopNode( _head->in(1), _head->in(2) ); l = igvn.register_new_node_with_optimizer(l, _head); phase->set_created_loop_node(); // Go ahead and replace _head phase->_igvn.replace_node( _head, l ); _head = l;
*** 1769,1788 **** --- 1769,1788 ---- // variable differs from the trip counter by a loop-invariant // amount, the difference between their respective initial values. // It is scaled by the 'ratio_con'. Node* ratio = _igvn.intcon(ratio_con); set_ctrl(ratio, C->root()); - Node* ratio_init = new (C) MulINode(init, ratio); _igvn.register_new_node_with_optimizer(ratio_init, init); set_early_ctrl(ratio_init); - Node* diff = new (C) SubINode(init2, ratio_init); _igvn.register_new_node_with_optimizer(diff, init2); set_early_ctrl(diff); - Node* ratio_idx = new (C) MulINode(phi, ratio); _igvn.register_new_node_with_optimizer(ratio_idx, phi); set_ctrl(ratio_idx, cl); - Node* add = new (C) AddINode(ratio_idx, diff); _igvn.register_new_node_with_optimizer(add); set_ctrl(add, cl); _igvn.replace_node( phi2, add ); // Sometimes an induction variable is unused if (add->outcnt() == 0) {
*** 2886,2899 **** --- 2886,2899 ---- // optimizing an infinite loop? l = _ltree_root; // Oops, found infinite loop if (!_verify_only) { // Insert the NeverBranch between 'm' and it's control user. - NeverBranchNode *iff = new (C) NeverBranchNode( m ); _igvn.register_new_node_with_optimizer(iff); set_loop(iff, l); - Node *if_t = new (C) CProjNode( iff, 0 ); _igvn.register_new_node_with_optimizer(if_t); set_loop(if_t, l); Node* cfg = NULL; // Find the One True Control User of m for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax; j++) {
*** 2905,2924 **** --- 2905,2924 ---- uint k = 0; // Probably cfg->in(0) while( cfg->in(k) != m ) k++; // But check incase cfg is a Region cfg->set_req( k, if_t ); // Now point to NeverBranch // Now create the never-taken loop exit - Node *if_f = new (C) CProjNode( iff, 1 ); _igvn.register_new_node_with_optimizer(if_f); set_loop(if_f, l); // Find frame ptr for Halt. Relies on the optimizer // V-N'ing. Easier and quicker than searching through // the program structure. - Node *frame = new (C) ParmNode( C->start(), TypeFunc::FramePtr ); _igvn.register_new_node_with_optimizer(frame); // Halt & Catch Fire - Node *halt = new (C) HaltNode( if_f, frame ); _igvn.register_new_node_with_optimizer(halt); set_loop(halt, l); C->root()->add_req(halt); } set_loop(C->root(), _ltree_root);

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