493 switch( bt ) { |
493 switch( bt ) { |
494 case BoolTest::eq: |
494 case BoolTest::eq: |
495 ShouldNotReachHere(); |
495 ShouldNotReachHere(); |
496 case BoolTest::ne: // Ahh, the case we desire |
496 case BoolTest::ne: // Ahh, the case we desire |
497 if (stride_con == 1) |
497 if (stride_con == 1) |
498 trip_count = gvn->transform(new (C, 3) SubINode(limit,init_trip)); |
498 trip_count = gvn->transform(new (C) SubINode(limit,init_trip)); |
499 else if (stride_con == -1) |
499 else if (stride_con == -1) |
500 trip_count = gvn->transform(new (C, 3) SubINode(init_trip,limit)); |
500 trip_count = gvn->transform(new (C) SubINode(init_trip,limit)); |
501 else |
501 else |
502 ShouldNotReachHere(); |
502 ShouldNotReachHere(); |
503 set_subtree_ctrl(trip_count); |
503 set_subtree_ctrl(trip_count); |
504 //_loop.map(trip_count->_idx,loop(limit)); |
504 //_loop.map(trip_count->_idx,loop(limit)); |
505 break; |
505 break; |
506 case BoolTest::le: // Maybe convert to '<' case |
506 case BoolTest::le: // Maybe convert to '<' case |
507 limit = gvn->transform(new (C, 3) AddINode(limit,one_p)); |
507 limit = gvn->transform(new (C) AddINode(limit,one_p)); |
508 set_subtree_ctrl( limit ); |
508 set_subtree_ctrl( limit ); |
509 hook->init_req(4, limit); |
509 hook->init_req(4, limit); |
510 |
510 |
511 bt = BoolTest::lt; |
511 bt = BoolTest::lt; |
512 // Make the new limit be in the same loop nest as the old limit |
512 // Make the new limit be in the same loop nest as the old limit |
513 //_loop.map(limit->_idx,limit_loop); |
513 //_loop.map(limit->_idx,limit_loop); |
514 // Fall into next case |
514 // Fall into next case |
515 case BoolTest::lt: { // Maybe convert to '!=' case |
515 case BoolTest::lt: { // Maybe convert to '!=' case |
516 if (stride_con < 0) // Count down loop rolls through MAXINT |
516 if (stride_con < 0) // Count down loop rolls through MAXINT |
517 ShouldNotReachHere(); |
517 ShouldNotReachHere(); |
518 Node *range = gvn->transform(new (C, 3) SubINode(limit,init_trip)); |
518 Node *range = gvn->transform(new (C) SubINode(limit,init_trip)); |
519 set_subtree_ctrl( range ); |
519 set_subtree_ctrl( range ); |
520 hook->init_req(0, range); |
520 hook->init_req(0, range); |
521 |
521 |
522 Node *bias = gvn->transform(new (C, 3) AddINode(range,stride)); |
522 Node *bias = gvn->transform(new (C) AddINode(range,stride)); |
523 set_subtree_ctrl( bias ); |
523 set_subtree_ctrl( bias ); |
524 hook->init_req(1, bias); |
524 hook->init_req(1, bias); |
525 |
525 |
526 Node *bias1 = gvn->transform(new (C, 3) AddINode(bias,one_m)); |
526 Node *bias1 = gvn->transform(new (C) AddINode(bias,one_m)); |
527 set_subtree_ctrl( bias1 ); |
527 set_subtree_ctrl( bias1 ); |
528 hook->init_req(2, bias1); |
528 hook->init_req(2, bias1); |
529 |
529 |
530 trip_count = gvn->transform(new (C, 3) DivINode(0,bias1,stride)); |
530 trip_count = gvn->transform(new (C) DivINode(0,bias1,stride)); |
531 set_subtree_ctrl( trip_count ); |
531 set_subtree_ctrl( trip_count ); |
532 hook->init_req(3, trip_count); |
532 hook->init_req(3, trip_count); |
533 break; |
533 break; |
534 } |
534 } |
535 |
535 |
536 case BoolTest::ge: // Maybe convert to '>' case |
536 case BoolTest::ge: // Maybe convert to '>' case |
537 limit = gvn->transform(new (C, 3) AddINode(limit,one_m)); |
537 limit = gvn->transform(new (C) AddINode(limit,one_m)); |
538 set_subtree_ctrl( limit ); |
538 set_subtree_ctrl( limit ); |
539 hook->init_req(4 ,limit); |
539 hook->init_req(4 ,limit); |
540 |
540 |
541 bt = BoolTest::gt; |
541 bt = BoolTest::gt; |
542 // Make the new limit be in the same loop nest as the old limit |
542 // Make the new limit be in the same loop nest as the old limit |
543 //_loop.map(limit->_idx,limit_loop); |
543 //_loop.map(limit->_idx,limit_loop); |
544 // Fall into next case |
544 // Fall into next case |
545 case BoolTest::gt: { // Maybe convert to '!=' case |
545 case BoolTest::gt: { // Maybe convert to '!=' case |
546 if (stride_con > 0) // count up loop rolls through MININT |
546 if (stride_con > 0) // count up loop rolls through MININT |
547 ShouldNotReachHere(); |
547 ShouldNotReachHere(); |
548 Node *range = gvn->transform(new (C, 3) SubINode(limit,init_trip)); |
548 Node *range = gvn->transform(new (C) SubINode(limit,init_trip)); |
549 set_subtree_ctrl( range ); |
549 set_subtree_ctrl( range ); |
550 hook->init_req(0, range); |
550 hook->init_req(0, range); |
551 |
551 |
552 Node *bias = gvn->transform(new (C, 3) AddINode(range,stride)); |
552 Node *bias = gvn->transform(new (C) AddINode(range,stride)); |
553 set_subtree_ctrl( bias ); |
553 set_subtree_ctrl( bias ); |
554 hook->init_req(1, bias); |
554 hook->init_req(1, bias); |
555 |
555 |
556 Node *bias1 = gvn->transform(new (C, 3) AddINode(bias,one_p)); |
556 Node *bias1 = gvn->transform(new (C) AddINode(bias,one_p)); |
557 set_subtree_ctrl( bias1 ); |
557 set_subtree_ctrl( bias1 ); |
558 hook->init_req(2, bias1); |
558 hook->init_req(2, bias1); |
559 |
559 |
560 trip_count = gvn->transform(new (C, 3) DivINode(0,bias1,stride)); |
560 trip_count = gvn->transform(new (C) DivINode(0,bias1,stride)); |
561 set_subtree_ctrl( trip_count ); |
561 set_subtree_ctrl( trip_count ); |
562 hook->init_req(3, trip_count); |
562 hook->init_req(3, trip_count); |
563 break; |
563 break; |
564 } |
564 } |
565 } // switch( bt ) |
565 } // switch( bt ) |
566 |
566 |
567 Node *span = gvn->transform(new (C, 3) MulINode(trip_count,stride)); |
567 Node *span = gvn->transform(new (C) MulINode(trip_count,stride)); |
568 set_subtree_ctrl( span ); |
568 set_subtree_ctrl( span ); |
569 hook->init_req(5, span); |
569 hook->init_req(5, span); |
570 |
570 |
571 limit = gvn->transform(new (C, 3) AddINode(span,init_trip)); |
571 limit = gvn->transform(new (C) AddINode(span,init_trip)); |
572 set_subtree_ctrl( limit ); |
572 set_subtree_ctrl( limit ); |
573 |
573 |
574 } // LoopLimitCheck |
574 } // LoopLimitCheck |
575 |
575 |
576 // Check for SafePoint on backedge and remove |
576 // Check for SafePoint on backedge and remove |
615 test->set_req(1,cmp); |
615 test->set_req(1,cmp); |
616 _igvn.register_new_node_with_optimizer(test); |
616 _igvn.register_new_node_with_optimizer(test); |
617 set_ctrl(test, iff->in(0)); |
617 set_ctrl(test, iff->in(0)); |
618 |
618 |
619 // Replace the old IfNode with a new LoopEndNode |
619 // Replace the old IfNode with a new LoopEndNode |
620 Node *lex = _igvn.register_new_node_with_optimizer(new (C, 2) CountedLoopEndNode( iff->in(0), test, cl_prob, iff->as_If()->_fcnt )); |
620 Node *lex = _igvn.register_new_node_with_optimizer(new (C) CountedLoopEndNode( iff->in(0), test, cl_prob, iff->as_If()->_fcnt )); |
621 IfNode *le = lex->as_If(); |
621 IfNode *le = lex->as_If(); |
622 uint dd = dom_depth(iff); |
622 uint dd = dom_depth(iff); |
623 set_idom(le, le->in(0), dd); // Update dominance for loop exit |
623 set_idom(le, le->in(0), dd); // Update dominance for loop exit |
624 set_loop(le, loop); |
624 set_loop(le, loop); |
625 |
625 |
626 // Get the loop-exit control |
626 // Get the loop-exit control |
627 Node *iffalse = iff->as_If()->proj_out(!(iftrue_op == Op_IfTrue)); |
627 Node *iffalse = iff->as_If()->proj_out(!(iftrue_op == Op_IfTrue)); |
628 |
628 |
629 // Need to swap loop-exit and loop-back control? |
629 // Need to swap loop-exit and loop-back control? |
630 if (iftrue_op == Op_IfFalse) { |
630 if (iftrue_op == Op_IfFalse) { |
631 Node *ift2=_igvn.register_new_node_with_optimizer(new (C, 1) IfTrueNode (le)); |
631 Node *ift2=_igvn.register_new_node_with_optimizer(new (C) IfTrueNode (le)); |
632 Node *iff2=_igvn.register_new_node_with_optimizer(new (C, 1) IfFalseNode(le)); |
632 Node *iff2=_igvn.register_new_node_with_optimizer(new (C) IfFalseNode(le)); |
633 |
633 |
634 loop->_tail = back_control = ift2; |
634 loop->_tail = back_control = ift2; |
635 set_loop(ift2, loop); |
635 set_loop(ift2, loop); |
636 set_loop(iff2, get_loop(iffalse)); |
636 set_loop(iff2, get_loop(iffalse)); |
637 |
637 |
653 set_idom(iffalse, le, dd+1); |
653 set_idom(iffalse, le, dd+1); |
654 assert(iff->outcnt() == 0, "should be dead now"); |
654 assert(iff->outcnt() == 0, "should be dead now"); |
655 lazy_replace( iff, le ); // fix 'get_ctrl' |
655 lazy_replace( iff, le ); // fix 'get_ctrl' |
656 |
656 |
657 // Now setup a new CountedLoopNode to replace the existing LoopNode |
657 // Now setup a new CountedLoopNode to replace the existing LoopNode |
658 CountedLoopNode *l = new (C, 3) CountedLoopNode(init_control, back_control); |
658 CountedLoopNode *l = new (C) CountedLoopNode(init_control, back_control); |
659 l->set_unswitch_count(x->as_Loop()->unswitch_count()); // Preserve |
659 l->set_unswitch_count(x->as_Loop()->unswitch_count()); // Preserve |
660 // The following assert is approximately true, and defines the intention |
660 // The following assert is approximately true, and defines the intention |
661 // of can_be_counted_loop. It fails, however, because phase->type |
661 // of can_be_counted_loop. It fails, however, because phase->type |
662 // is not yet initialized for this loop and its parts. |
662 // is not yet initialized for this loop and its parts. |
663 //assert(l->can_be_counted_loop(this), "sanity"); |
663 //assert(l->can_be_counted_loop(this), "sanity"); |
844 } |
844 } |
845 julong range = lim - ini + stride_p; |
845 julong range = lim - ini + stride_p; |
846 if (range <= max) { |
846 if (range <= max) { |
847 // Convert to integer expression if it is not overflow. |
847 // Convert to integer expression if it is not overflow. |
848 Node* stride_m = phase->intcon(stride_con - (stride_con > 0 ? 1 : -1)); |
848 Node* stride_m = phase->intcon(stride_con - (stride_con > 0 ? 1 : -1)); |
849 Node *range = phase->transform(new (phase->C, 3) SubINode(in(Limit), in(Init))); |
849 Node *range = phase->transform(new (phase->C) SubINode(in(Limit), in(Init))); |
850 Node *bias = phase->transform(new (phase->C, 3) AddINode(range, stride_m)); |
850 Node *bias = phase->transform(new (phase->C) AddINode(range, stride_m)); |
851 Node *trip = phase->transform(new (phase->C, 3) DivINode(0, bias, in(Stride))); |
851 Node *trip = phase->transform(new (phase->C) DivINode(0, bias, in(Stride))); |
852 Node *span = phase->transform(new (phase->C, 3) MulINode(trip, in(Stride))); |
852 Node *span = phase->transform(new (phase->C) MulINode(trip, in(Stride))); |
853 return new (phase->C, 3) AddINode(span, in(Init)); // exact limit |
853 return new (phase->C) AddINode(span, in(Init)); // exact limit |
854 } |
854 } |
855 |
855 |
856 if (is_power_of_2(stride_p) || // divisor is 2^n |
856 if (is_power_of_2(stride_p) || // divisor is 2^n |
857 !Matcher::has_match_rule(Op_LoopLimit)) { // or no specialized Mach node? |
857 !Matcher::has_match_rule(Op_LoopLimit)) { // or no specialized Mach node? |
858 // Convert to long expression to avoid integer overflow |
858 // Convert to long expression to avoid integer overflow |
859 // and let igvn optimizer convert this division. |
859 // and let igvn optimizer convert this division. |
860 // |
860 // |
861 Node* init = phase->transform( new (phase->C, 2) ConvI2LNode(in(Init))); |
861 Node* init = phase->transform( new (phase->C) ConvI2LNode(in(Init))); |
862 Node* limit = phase->transform( new (phase->C, 2) ConvI2LNode(in(Limit))); |
862 Node* limit = phase->transform( new (phase->C) ConvI2LNode(in(Limit))); |
863 Node* stride = phase->longcon(stride_con); |
863 Node* stride = phase->longcon(stride_con); |
864 Node* stride_m = phase->longcon(stride_con - (stride_con > 0 ? 1 : -1)); |
864 Node* stride_m = phase->longcon(stride_con - (stride_con > 0 ? 1 : -1)); |
865 |
865 |
866 Node *range = phase->transform(new (phase->C, 3) SubLNode(limit, init)); |
866 Node *range = phase->transform(new (phase->C) SubLNode(limit, init)); |
867 Node *bias = phase->transform(new (phase->C, 3) AddLNode(range, stride_m)); |
867 Node *bias = phase->transform(new (phase->C) AddLNode(range, stride_m)); |
868 Node *span; |
868 Node *span; |
869 if (stride_con > 0 && is_power_of_2(stride_p)) { |
869 if (stride_con > 0 && is_power_of_2(stride_p)) { |
870 // bias >= 0 if stride >0, so if stride is 2^n we can use &(-stride) |
870 // bias >= 0 if stride >0, so if stride is 2^n we can use &(-stride) |
871 // and avoid generating rounding for division. Zero trip guard should |
871 // and avoid generating rounding for division. Zero trip guard should |
872 // guarantee that init < limit but sometimes the guard is missing and |
872 // guarantee that init < limit but sometimes the guard is missing and |
873 // we can get situation when init > limit. Note, for the empty loop |
873 // we can get situation when init > limit. Note, for the empty loop |
874 // optimization zero trip guard is generated explicitly which leaves |
874 // optimization zero trip guard is generated explicitly which leaves |
875 // only RCE predicate where exact limit is used and the predicate |
875 // only RCE predicate where exact limit is used and the predicate |
876 // will simply fail forcing recompilation. |
876 // will simply fail forcing recompilation. |
877 Node* neg_stride = phase->longcon(-stride_con); |
877 Node* neg_stride = phase->longcon(-stride_con); |
878 span = phase->transform(new (phase->C, 3) AndLNode(bias, neg_stride)); |
878 span = phase->transform(new (phase->C) AndLNode(bias, neg_stride)); |
879 } else { |
879 } else { |
880 Node *trip = phase->transform(new (phase->C, 3) DivLNode(0, bias, stride)); |
880 Node *trip = phase->transform(new (phase->C) DivLNode(0, bias, stride)); |
881 span = phase->transform(new (phase->C, 3) MulLNode(trip, stride)); |
881 span = phase->transform(new (phase->C) MulLNode(trip, stride)); |
882 } |
882 } |
883 // Convert back to int |
883 // Convert back to int |
884 Node *span_int = phase->transform(new (phase->C, 2) ConvL2INode(span)); |
884 Node *span_int = phase->transform(new (phase->C) ConvL2INode(span)); |
885 return new (phase->C, 3) AddINode(span_int, in(Init)); // exact limit |
885 return new (phase->C) AddINode(span_int, in(Init)); // exact limit |
886 } |
886 } |
887 |
887 |
888 return NULL; // No progress |
888 return NULL; // No progress |
889 } |
889 } |
890 |
890 |
1669 // variable differs from the trip counter by a loop-invariant |
1669 // variable differs from the trip counter by a loop-invariant |
1670 // amount, the difference between their respective initial values. |
1670 // amount, the difference between their respective initial values. |
1671 // It is scaled by the 'ratio_con'. |
1671 // It is scaled by the 'ratio_con'. |
1672 Node* ratio = _igvn.intcon(ratio_con); |
1672 Node* ratio = _igvn.intcon(ratio_con); |
1673 set_ctrl(ratio, C->root()); |
1673 set_ctrl(ratio, C->root()); |
1674 Node* ratio_init = new (C, 3) MulINode(init, ratio); |
1674 Node* ratio_init = new (C) MulINode(init, ratio); |
1675 _igvn.register_new_node_with_optimizer(ratio_init, init); |
1675 _igvn.register_new_node_with_optimizer(ratio_init, init); |
1676 set_early_ctrl(ratio_init); |
1676 set_early_ctrl(ratio_init); |
1677 Node* diff = new (C, 3) SubINode(init2, ratio_init); |
1677 Node* diff = new (C) SubINode(init2, ratio_init); |
1678 _igvn.register_new_node_with_optimizer(diff, init2); |
1678 _igvn.register_new_node_with_optimizer(diff, init2); |
1679 set_early_ctrl(diff); |
1679 set_early_ctrl(diff); |
1680 Node* ratio_idx = new (C, 3) MulINode(phi, ratio); |
1680 Node* ratio_idx = new (C) MulINode(phi, ratio); |
1681 _igvn.register_new_node_with_optimizer(ratio_idx, phi); |
1681 _igvn.register_new_node_with_optimizer(ratio_idx, phi); |
1682 set_ctrl(ratio_idx, cl); |
1682 set_ctrl(ratio_idx, cl); |
1683 Node* add = new (C, 3) AddINode(ratio_idx, diff); |
1683 Node* add = new (C) AddINode(ratio_idx, diff); |
1684 _igvn.register_new_node_with_optimizer(add); |
1684 _igvn.register_new_node_with_optimizer(add); |
1685 set_ctrl(add, cl); |
1685 set_ctrl(add, cl); |
1686 _igvn.replace_node( phi2, add ); |
1686 _igvn.replace_node( phi2, add ); |
1687 // Sometimes an induction variable is unused |
1687 // Sometimes an induction variable is unused |
1688 if (add->outcnt() == 0) { |
1688 if (add->outcnt() == 0) { |
2694 uint k = 0; // Probably cfg->in(0) |
2694 uint k = 0; // Probably cfg->in(0) |
2695 while( cfg->in(k) != m ) k++; // But check incase cfg is a Region |
2695 while( cfg->in(k) != m ) k++; // But check incase cfg is a Region |
2696 cfg->set_req( k, if_t ); // Now point to NeverBranch |
2696 cfg->set_req( k, if_t ); // Now point to NeverBranch |
2697 |
2697 |
2698 // Now create the never-taken loop exit |
2698 // Now create the never-taken loop exit |
2699 Node *if_f = new (C, 1) CProjNode( iff, 1 ); |
2699 Node *if_f = new (C) CProjNode( iff, 1 ); |
2700 _igvn.register_new_node_with_optimizer(if_f); |
2700 _igvn.register_new_node_with_optimizer(if_f); |
2701 set_loop(if_f, l); |
2701 set_loop(if_f, l); |
2702 // Find frame ptr for Halt. Relies on the optimizer |
2702 // Find frame ptr for Halt. Relies on the optimizer |
2703 // V-N'ing. Easier and quicker than searching through |
2703 // V-N'ing. Easier and quicker than searching through |
2704 // the program structure. |
2704 // the program structure. |
2705 Node *frame = new (C, 1) ParmNode( C->start(), TypeFunc::FramePtr ); |
2705 Node *frame = new (C) ParmNode( C->start(), TypeFunc::FramePtr ); |
2706 _igvn.register_new_node_with_optimizer(frame); |
2706 _igvn.register_new_node_with_optimizer(frame); |
2707 // Halt & Catch Fire |
2707 // Halt & Catch Fire |
2708 Node *halt = new (C, TypeFunc::Parms) HaltNode( if_f, frame ); |
2708 Node *halt = new (C) HaltNode( if_f, frame ); |
2709 _igvn.register_new_node_with_optimizer(halt); |
2709 _igvn.register_new_node_with_optimizer(halt); |
2710 set_loop(halt, l); |
2710 set_loop(halt, l); |
2711 C->root()->add_req(halt); |
2711 C->root()->add_req(halt); |
2712 } |
2712 } |
2713 set_loop(C->root(), _ltree_root); |
2713 set_loop(C->root(), _ltree_root); |