627 // max(scale*i + offset) = scale*(limit-stride) + offset |
628 // max(scale*i + offset) = scale*(limit-stride) + offset |
628 // (2) stride*scale < 0 |
629 // (2) stride*scale < 0 |
629 // max(scale*i + offset) = scale*init + offset |
630 // max(scale*i + offset) = scale*init + offset |
630 BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl, |
631 BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl, |
631 int scale, Node* offset, |
632 int scale, Node* offset, |
632 Node* init, Node* limit, Node* stride, |
633 Node* init, Node* limit, jint stride, |
633 Node* range, bool upper) { |
634 Node* range, bool upper, bool &overflow) { |
|
635 jint con_limit = limit->is_Con() ? limit->get_int() : 0; |
|
636 jint con_init = init->is_Con() ? init->get_int() : 0; |
|
637 jint con_offset = offset->is_Con() ? offset->get_int() : 0; |
|
638 |
634 stringStream* predString = NULL; |
639 stringStream* predString = NULL; |
635 if (TraceLoopPredicate) { |
640 if (TraceLoopPredicate) { |
636 predString = new stringStream(); |
641 predString = new stringStream(); |
637 predString->print("rc_predicate "); |
642 predString->print("rc_predicate "); |
638 } |
643 } |
639 |
644 |
640 Node* max_idx_expr = init; |
645 overflow = false; |
641 int stride_con = stride->get_int(); |
646 Node* max_idx_expr = NULL; |
642 if ((stride_con > 0) == (scale > 0) == upper) { |
647 const TypeInt* idx_type = TypeInt::INT; |
643 // Limit is not exact. |
648 if ((stride > 0) == (scale > 0) == upper) { |
644 // Calculate exact limit here. |
649 if (TraceLoopPredicate) { |
645 // Note, counted loop's test is '<' or '>'. |
650 if (limit->is_Con()) { |
646 limit = exact_limit(loop); |
651 predString->print("(%d ", con_limit); |
647 max_idx_expr = new SubINode(limit, stride); |
652 } else { |
|
653 predString->print("(limit "); |
|
654 } |
|
655 predString->print("- %d) ", stride); |
|
656 } |
|
657 // Check if (limit - stride) may overflow |
|
658 const TypeInt* limit_type = _igvn.type(limit)->isa_int(); |
|
659 jint limit_lo = limit_type->_lo; |
|
660 jint limit_hi = limit_type->_hi; |
|
661 if ((stride > 0 && (java_subtract(limit_lo, stride) < limit_lo)) || |
|
662 (stride < 0 && (java_subtract(limit_hi, stride) > limit_hi))) { |
|
663 // No overflow possible |
|
664 ConINode* con_stride = _igvn.intcon(stride); |
|
665 set_ctrl(con_stride, C->root()); |
|
666 max_idx_expr = new SubINode(limit, con_stride); |
|
667 idx_type = TypeInt::make(limit_lo - stride, limit_hi - stride, limit_type->_widen); |
|
668 } else { |
|
669 // May overflow |
|
670 overflow = true; |
|
671 limit = new ConvI2LNode(limit); |
|
672 register_new_node(limit, ctrl); |
|
673 ConLNode* con_stride = _igvn.longcon(stride); |
|
674 set_ctrl(con_stride, C->root()); |
|
675 max_idx_expr = new SubLNode(limit, con_stride); |
|
676 } |
648 register_new_node(max_idx_expr, ctrl); |
677 register_new_node(max_idx_expr, ctrl); |
649 if (TraceLoopPredicate) predString->print("(limit - stride) "); |
|
650 } else { |
678 } else { |
651 if (TraceLoopPredicate) predString->print("init "); |
679 if (TraceLoopPredicate) { |
|
680 if (init->is_Con()) { |
|
681 predString->print("%d ", con_init); |
|
682 } else { |
|
683 predString->print("init "); |
|
684 } |
|
685 } |
|
686 idx_type = _igvn.type(init)->isa_int(); |
|
687 max_idx_expr = init; |
652 } |
688 } |
653 |
689 |
654 if (scale != 1) { |
690 if (scale != 1) { |
655 ConNode* con_scale = _igvn.intcon(scale); |
691 ConNode* con_scale = _igvn.intcon(scale); |
656 set_ctrl(con_scale, C->root()); |
692 set_ctrl(con_scale, C->root()); |
657 max_idx_expr = new MulINode(max_idx_expr, con_scale); |
693 if (TraceLoopPredicate) { |
|
694 predString->print("* %d ", scale); |
|
695 } |
|
696 // Check if (scale * max_idx_expr) may overflow |
|
697 const TypeInt* scale_type = TypeInt::make(scale); |
|
698 MulINode* mul = new MulINode(max_idx_expr, con_scale); |
|
699 idx_type = (TypeInt*)mul->mul_ring(idx_type, scale_type); |
|
700 if (overflow || TypeInt::INT->higher_equal(idx_type)) { |
|
701 // May overflow |
|
702 mul->destruct(); |
|
703 if (!overflow) { |
|
704 max_idx_expr = new ConvI2LNode(max_idx_expr); |
|
705 register_new_node(max_idx_expr, ctrl); |
|
706 } |
|
707 overflow = true; |
|
708 con_scale = _igvn.longcon(scale); |
|
709 set_ctrl(con_scale, C->root()); |
|
710 max_idx_expr = new MulLNode(max_idx_expr, con_scale); |
|
711 } else { |
|
712 // No overflow possible |
|
713 max_idx_expr = mul; |
|
714 } |
658 register_new_node(max_idx_expr, ctrl); |
715 register_new_node(max_idx_expr, ctrl); |
659 if (TraceLoopPredicate) predString->print("* %d ", scale); |
716 } |
660 } |
717 |
661 |
718 if (offset && (!offset->is_Con() || con_offset != 0)){ |
662 if (offset && (!offset->is_Con() || offset->get_int() != 0)){ |
|
663 max_idx_expr = new AddINode(max_idx_expr, offset); |
|
664 register_new_node(max_idx_expr, ctrl); |
|
665 if (TraceLoopPredicate) { |
719 if (TraceLoopPredicate) { |
666 if (offset->is_Con()) { |
720 if (offset->is_Con()) { |
667 predString->print("+ %d ", offset->get_int()); |
721 predString->print("+ %d ", con_offset); |
668 } else { |
722 } else { |
669 predString->print("+ offset "); |
723 predString->print("+ offset"); |
670 } |
724 } |
671 } |
725 } |
672 } |
726 // Check if (max_idx_expr + offset) may overflow |
673 |
727 const TypeInt* offset_type = _igvn.type(offset)->isa_int(); |
674 CmpUNode* cmp = new CmpUNode(max_idx_expr, range); |
728 jint lo = java_add(idx_type->_lo, offset_type->_lo); |
|
729 jint hi = java_add(idx_type->_hi, offset_type->_hi); |
|
730 if (overflow || (lo > hi) || |
|
731 ((idx_type->_lo & offset_type->_lo) < 0 && lo >= 0) || |
|
732 ((~(idx_type->_hi | offset_type->_hi)) < 0 && hi < 0)) { |
|
733 // May overflow |
|
734 if (!overflow) { |
|
735 max_idx_expr = new ConvI2LNode(max_idx_expr); |
|
736 register_new_node(max_idx_expr, ctrl); |
|
737 } |
|
738 overflow = true; |
|
739 offset = new ConvI2LNode(offset); |
|
740 register_new_node(offset, ctrl); |
|
741 max_idx_expr = new AddLNode(max_idx_expr, offset); |
|
742 } else { |
|
743 // No overflow possible |
|
744 max_idx_expr = new AddINode(max_idx_expr, offset); |
|
745 } |
|
746 register_new_node(max_idx_expr, ctrl); |
|
747 } |
|
748 |
|
749 CmpNode* cmp = NULL; |
|
750 if (overflow) { |
|
751 // Integer expressions may overflow, do long comparison |
|
752 range = new ConvI2LNode(range); |
|
753 register_new_node(range, ctrl); |
|
754 if (!Matcher::has_match_rule(Op_CmpUL)) { |
|
755 // We don't support unsigned long comparisons. Set 'max_idx_expr' |
|
756 // to max_julong if < 0 to make the signed comparison fail. |
|
757 ConINode* sign_pos = _igvn.intcon(BitsPerLong - 1); |
|
758 set_ctrl(sign_pos, C->root()); |
|
759 Node* sign_bit_mask = new RShiftLNode(max_idx_expr, sign_pos); |
|
760 register_new_node(sign_bit_mask, ctrl); |
|
761 // OR with sign bit to set all bits to 1 if negative (otherwise no change) |
|
762 max_idx_expr = new OrLNode(max_idx_expr, sign_bit_mask); |
|
763 register_new_node(max_idx_expr, ctrl); |
|
764 // AND with 0x7ff... to unset the sign bit |
|
765 ConLNode* remove_sign_mask = _igvn.longcon(max_jlong); |
|
766 set_ctrl(remove_sign_mask, C->root()); |
|
767 max_idx_expr = new AndLNode(max_idx_expr, remove_sign_mask); |
|
768 register_new_node(max_idx_expr, ctrl); |
|
769 |
|
770 cmp = new CmpLNode(max_idx_expr, range); |
|
771 } else { |
|
772 cmp = new CmpULNode(max_idx_expr, range); |
|
773 } |
|
774 } else { |
|
775 cmp = new CmpUNode(max_idx_expr, range); |
|
776 } |
675 register_new_node(cmp, ctrl); |
777 register_new_node(cmp, ctrl); |
676 BoolNode* bol = new BoolNode(cmp, BoolTest::lt); |
778 BoolNode* bol = new BoolNode(cmp, BoolTest::lt); |
677 register_new_node(bol, ctrl); |
779 register_new_node(bol, ctrl); |
678 |
780 |
679 if (TraceLoopPredicate) { |
781 if (TraceLoopPredicate) { |
816 Node* offset = zero; |
918 Node* offset = zero; |
817 bool ok = is_scaled_iv_plus_offset(idx, cl->phi(), &scale, &offset); |
919 bool ok = is_scaled_iv_plus_offset(idx, cl->phi(), &scale, &offset); |
818 assert(ok, "must be index expression"); |
920 assert(ok, "must be index expression"); |
819 |
921 |
820 Node* init = cl->init_trip(); |
922 Node* init = cl->init_trip(); |
821 Node* limit = cl->limit(); |
923 // Limit is not exact. |
822 Node* stride = cl->stride(); |
924 // Calculate exact limit here. |
|
925 // Note, counted loop's test is '<' or '>'. |
|
926 Node* limit = exact_limit(loop); |
|
927 int stride = cl->stride()->get_int(); |
823 |
928 |
824 // Build if's for the upper and lower bound tests. The |
929 // Build if's for the upper and lower bound tests. The |
825 // lower_bound test will dominate the upper bound test and all |
930 // lower_bound test will dominate the upper bound test and all |
826 // cloned or created nodes will use the lower bound test as |
931 // cloned or created nodes will use the lower bound test as |
827 // their declared control. |
932 // their declared control. |
828 ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, iff->Opcode()); |
|
829 ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, iff->Opcode()); |
|
830 assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate"); |
|
831 Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0); |
|
832 |
933 |
833 // Perform cloning to keep Invariance state correct since the |
934 // Perform cloning to keep Invariance state correct since the |
834 // late schedule will place invariant things in the loop. |
935 // late schedule will place invariant things in the loop. |
|
936 Node *ctrl = predicate_proj->in(0)->as_If()->in(0); |
835 rng = invar.clone(rng, ctrl); |
937 rng = invar.clone(rng, ctrl); |
836 if (offset && offset != zero) { |
938 if (offset && offset != zero) { |
837 assert(invar.is_invariant(offset), "offset must be loop invariant"); |
939 assert(invar.is_invariant(offset), "offset must be loop invariant"); |
838 offset = invar.clone(offset, ctrl); |
940 offset = invar.clone(offset, ctrl); |
839 } |
941 } |
|
942 // If predicate expressions may overflow in the integer range, longs are used. |
|
943 bool overflow = false; |
840 |
944 |
841 // Test the lower bound |
945 // Test the lower bound |
842 BoolNode* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false); |
946 BoolNode* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false, overflow); |
843 // Negate test if necessary |
947 // Negate test if necessary |
844 bool negated = false; |
948 bool negated = false; |
845 if (proj->_con != predicate_proj->_con) { |
949 if (proj->_con != predicate_proj->_con) { |
846 lower_bound_bol = new BoolNode(lower_bound_bol->in(1), lower_bound_bol->_test.negate()); |
950 lower_bound_bol = new BoolNode(lower_bound_bol->in(1), lower_bound_bol->_test.negate()); |
847 register_new_node(lower_bound_bol, ctrl); |
951 register_new_node(lower_bound_bol, ctrl); |
848 negated = true; |
952 negated = true; |
849 } |
953 } |
|
954 ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, overflow ? Op_If : iff->Opcode()); |
850 IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If(); |
955 IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If(); |
851 _igvn.hash_delete(lower_bound_iff); |
956 _igvn.hash_delete(lower_bound_iff); |
852 lower_bound_iff->set_req(1, lower_bound_bol); |
957 lower_bound_iff->set_req(1, lower_bound_bol); |
853 if (TraceLoopPredicate) tty->print_cr("lower bound check if: %s %d ", negated ? " negated" : "", lower_bound_iff->_idx); |
958 if (TraceLoopPredicate) tty->print_cr("lower bound check if: %s %d ", negated ? " negated" : "", lower_bound_iff->_idx); |
854 |
959 |
855 // Test the upper bound |
960 // Test the upper bound |
856 BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true); |
961 BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true, overflow); |
857 negated = false; |
962 negated = false; |
858 if (proj->_con != predicate_proj->_con) { |
963 if (proj->_con != predicate_proj->_con) { |
859 upper_bound_bol = new BoolNode(upper_bound_bol->in(1), upper_bound_bol->_test.negate()); |
964 upper_bound_bol = new BoolNode(upper_bound_bol->in(1), upper_bound_bol->_test.negate()); |
860 register_new_node(upper_bound_bol, ctrl); |
965 register_new_node(upper_bound_bol, ctrl); |
861 negated = true; |
966 negated = true; |
862 } |
967 } |
|
968 ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, overflow ? Op_If : iff->Opcode()); |
|
969 assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate"); |
863 IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If(); |
970 IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If(); |
864 _igvn.hash_delete(upper_bound_iff); |
971 _igvn.hash_delete(upper_bound_iff); |
865 upper_bound_iff->set_req(1, upper_bound_bol); |
972 upper_bound_iff->set_req(1, upper_bound_bol); |
866 if (TraceLoopPredicate) tty->print_cr("upper bound check if: %s %d ", negated ? " negated" : "", lower_bound_iff->_idx); |
973 if (TraceLoopPredicate) tty->print_cr("upper bound check if: %s %d ", negated ? " negated" : "", lower_bound_iff->_idx); |
867 |
974 |