< prev index next >

src/hotspot/share/opto/loopnode.cpp

Print this page

        

*** 322,331 **** --- 322,356 ---- set_idom(outer_l, init_control, dom_depth(init_control)+1); return outer_ilt; } + void PhaseIdealLoop::insert_loop_limit_check(ProjNode* limit_check_proj, Node* cmp_limit, Node* bol) { + Node* new_predicate_proj = create_new_if_for_predicate(limit_check_proj, NULL, + Deoptimization::Reason_loop_limit_check, + Op_If); + Node* iff = new_predicate_proj->in(0); + assert(iff->Opcode() == Op_If, "bad graph shape"); + Node* conv = iff->in(1); + assert(conv->Opcode() == Op_Conv2B, "bad graph shape"); + Node* opaq = conv->in(1); + assert(opaq->Opcode() == Op_Opaque1, "bad graph shape"); + cmp_limit = _igvn.register_new_node_with_optimizer(cmp_limit); + bol = _igvn.register_new_node_with_optimizer(bol); + set_subtree_ctrl(bol); + _igvn.replace_input_of(iff, 1, bol); + + #ifndef PRODUCT + // report that the loop predication has been actually performed + // for this loop + if (TraceLoopLimitCheck) { + tty->print_cr("Counted Loop Limit Check generated:"); + debug_only( bol->dump(2); ) + } + #endif + } + //------------------------------is_counted_loop-------------------------------- bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*& loop) { PhaseGVN *gvn = &_igvn; // Counted loop head must be a good RegionNode with only 3 not NULL
*** 538,548 **** jlong init_p = (jlong)init_t->_hi + stride_con; if (init_p < (jlong)min_jint || init_p < (jlong)limit_t->_lo) return false; // cyclic loop or this loop trips only once } ! if (phi_incr != NULL) { // check if there is a possiblity of IV overflowing after the first increment if (stride_con > 0) { if (init_t->_hi > max_jint - stride_con) { return false; } --- 563,573 ---- jlong init_p = (jlong)init_t->_hi + stride_con; if (init_p < (jlong)min_jint || init_p < (jlong)limit_t->_lo) return false; // cyclic loop or this loop trips only once } ! if (phi_incr != NULL && bt != BoolTest::ne) { // check if there is a possiblity of IV overflowing after the first increment if (stride_con > 0) { if (init_t->_hi > max_jint - stride_con) { return false; }
*** 629,660 **** bol = new BoolNode(cmp_limit, BoolTest::le); } else { cmp_limit = new CmpINode(limit, _igvn.intcon(min_jint - stride_m)); bol = new 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); ! // Replace condition in original predicate but preserve Opaque node ! // so that previous predicates could be found. ! assert(check_iff->in(1)->Opcode() == Op_Conv2B && ! check_iff->in(1)->in(1)->Opcode() == Op_Opaque1, ""); ! Node* opq = check_iff->in(1)->in(1); ! _igvn.replace_input_of(opq, 1, bol); ! // Update ctrl. ! set_ctrl(opq, check_iff->in(0)); ! set_ctrl(check_iff->in(1), check_iff->in(0)); ! #ifndef PRODUCT ! // report that the loop predication has been actually performed ! // for this loop if (TraceLoopLimitCheck) { ! tty->print_cr("Counted Loop Limit Check generated:"); ! debug_only( bol->dump(2); ) } #endif } if (phi_incr != NULL) { // If compare points directly to the phi we need to adjust // the compare so that it points to the incr. Limit have --- 654,717 ---- bol = new BoolNode(cmp_limit, BoolTest::le); } else { cmp_limit = new CmpINode(limit, _igvn.intcon(min_jint - stride_m)); bol = new BoolNode(cmp_limit, BoolTest::ge); } ! insert_loop_limit_check(limit_check_proj, cmp_limit, bol); ! } ! // Now we need to canonicalize loop condition. ! if (bt == BoolTest::ne) { ! assert(stride_con == 1 || stride_con == -1, "simple increment only"); ! if (stride_con > 0 && init_t->_hi < limit_t->_lo) { ! // 'ne' can be replaced with 'lt' only when init < limit. ! bt = BoolTest::lt; ! } else if (stride_con < 0 && init_t->_lo > limit_t->_hi) { ! // 'ne' can be replaced with 'gt' only when init > limit. ! bt = BoolTest::gt; ! } else { ! ProjNode *limit_check_proj = find_predicate_insertion_point(init_control, Deoptimization::Reason_loop_limit_check); ! if (!limit_check_proj) { ! // The limit check predicate is not generated if this method trapped here before. ! #ifdef ASSERT if (TraceLoopLimitCheck) { ! tty->print("missing loop limit check:"); ! loop->dump_head(); ! x->dump(1); } #endif + return false; + } + IfNode* check_iff = limit_check_proj->in(0)->as_If(); + + if (!is_dominator(get_ctrl(limit), check_iff->in(0)) || + !is_dominator(get_ctrl(init_trip), check_iff->in(0))) { + return false; + } + + Node* cmp_limit; + Node* bol; + + if (stride_con > 0) { + cmp_limit = new CmpINode(init_trip, limit); + bol = new BoolNode(cmp_limit, BoolTest::lt); + } else { + cmp_limit = new CmpINode(init_trip, limit); + bol = new BoolNode(cmp_limit, BoolTest::gt); + } + + insert_loop_limit_check(limit_check_proj, cmp_limit, bol); + + if (stride_con > 0) { + // 'ne' can be replaced with 'lt' only when init < limit. + bt = BoolTest::lt; + } else if (stride_con < 0) { + // 'ne' can be replaced with 'gt' only when init > limit. + bt = BoolTest::gt; + } + } } if (phi_incr != NULL) { // If compare points directly to the phi we need to adjust // the compare so that it points to the incr. Limit have
*** 666,686 **** // i = init; do {} while(++i < limit+1); // limit = gvn->transform(new AddINode(limit, stride)); } - // Now we need to canonicalize loop condition. - if (bt == BoolTest::ne) { - assert(stride_con == 1 || stride_con == -1, "simple increment only"); - // 'ne' can be replaced with 'lt' only when init < limit. - if (stride_con > 0 && init_t->_hi < limit_t->_lo) - bt = BoolTest::lt; - // 'ne' can be replaced with 'gt' only when init > limit. - if (stride_con < 0 && init_t->_lo > limit_t->_hi) - bt = BoolTest::gt; - } - 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); --- 723,732 ----
*** 2402,2412 **** 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 ) { tty->print(" limit_check"); ! entry = entry->in(0)->in(0); } if (UseLoopPredicate) { entry = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); if (entry != NULL) { tty->print(" predicated"); --- 2448,2458 ---- 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 ) { tty->print(" limit_check"); ! entry = PhaseIdealLoop::skip_loop_predicates(entry); } if (UseLoopPredicate) { entry = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); if (entry != NULL) { tty->print(" predicated");
< prev index next >