541 |
541 |
542 // Give up the search at true merges |
542 // Give up the search at true merges |
543 return NULL; // Dead loop? Or hit root? |
543 return NULL; // Dead loop? Or hit root? |
544 } |
544 } |
545 |
545 |
|
546 |
|
547 //------------------------------filtered_int_type-------------------------------- |
|
548 // Return a possibly more restrictive type for val based on condition control flow for an if |
|
549 const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node *val, Node* if_proj) { |
|
550 assert(if_proj && |
|
551 (if_proj->Opcode() == Op_IfTrue || if_proj->Opcode() == Op_IfFalse), "expecting an if projection"); |
|
552 if (if_proj->in(0) && if_proj->in(0)->is_If()) { |
|
553 IfNode* iff = if_proj->in(0)->as_If(); |
|
554 if (iff->in(1) && iff->in(1)->is_Bool()) { |
|
555 BoolNode* bol = iff->in(1)->as_Bool(); |
|
556 if (bol->in(1) && bol->in(1)->is_Cmp()) { |
|
557 const CmpNode* cmp = bol->in(1)->as_Cmp(); |
|
558 if (cmp->in(1) == val) { |
|
559 const TypeInt* cmp2_t = gvn->type(cmp->in(2))->isa_int(); |
|
560 if (cmp2_t != NULL) { |
|
561 jint lo = cmp2_t->_lo; |
|
562 jint hi = cmp2_t->_hi; |
|
563 BoolTest::mask msk = if_proj->Opcode() == Op_IfTrue ? bol->_test._test : bol->_test.negate(); |
|
564 switch (msk) { |
|
565 case BoolTest::ne: |
|
566 // Can't refine type |
|
567 return NULL; |
|
568 case BoolTest::eq: |
|
569 return cmp2_t; |
|
570 case BoolTest::lt: |
|
571 lo = TypeInt::INT->_lo; |
|
572 if (hi - 1 < hi) { |
|
573 hi = hi - 1; |
|
574 } |
|
575 break; |
|
576 case BoolTest::le: |
|
577 lo = TypeInt::INT->_lo; |
|
578 break; |
|
579 case BoolTest::gt: |
|
580 if (lo + 1 > lo) { |
|
581 lo = lo + 1; |
|
582 } |
|
583 hi = TypeInt::INT->_hi; |
|
584 break; |
|
585 case BoolTest::ge: |
|
586 // lo unchanged |
|
587 hi = TypeInt::INT->_hi; |
|
588 break; |
|
589 } |
|
590 const TypeInt* rtn_t = TypeInt::make(lo, hi, cmp2_t->_widen); |
|
591 return rtn_t; |
|
592 } |
|
593 } |
|
594 } |
|
595 } |
|
596 } |
|
597 return NULL; |
|
598 } |
|
599 |
|
600 //------------------------------fold_compares---------------------------- |
|
601 // See if a pair of CmpIs can be converted into a CmpU. In some cases |
|
602 // the direction of this if is determined by the preciding if so it |
|
603 // can be eliminate entirely. Given an if testing (CmpI n c) check |
|
604 // for an immediately control dependent if that is testing (CmpI n c2) |
|
605 // and has one projection leading to this if and the other projection |
|
606 // leading to a region that merges one of this ifs control |
|
607 // projections. |
|
608 // |
|
609 // If |
|
610 // / | |
|
611 // / | |
|
612 // / | |
|
613 // If | |
|
614 // /\ | |
|
615 // / \ | |
|
616 // / \ | |
|
617 // / Region |
|
618 // |
|
619 Node* IfNode::fold_compares(PhaseGVN* phase) { |
|
620 if (!EliminateAutoBox || Opcode() != Op_If) return NULL; |
|
621 |
|
622 Node* this_cmp = in(1)->in(1); |
|
623 if (this_cmp != NULL && this_cmp->Opcode() == Op_CmpI && |
|
624 this_cmp->in(2)->is_Con() && this_cmp->in(2) != phase->C->top()) { |
|
625 Node* ctrl = in(0); |
|
626 BoolNode* this_bool = in(1)->as_Bool(); |
|
627 Node* n = this_cmp->in(1); |
|
628 int hi = this_cmp->in(2)->get_int(); |
|
629 if (ctrl != NULL && ctrl->is_Proj() && ctrl->outcnt() == 1 && |
|
630 ctrl->in(0)->is_If() && |
|
631 ctrl->in(0)->outcnt() == 2 && |
|
632 ctrl->in(0)->in(1)->is_Bool() && |
|
633 ctrl->in(0)->in(1)->in(1)->Opcode() == Op_CmpI && |
|
634 ctrl->in(0)->in(1)->in(1)->in(2)->is_Con() && |
|
635 ctrl->in(0)->in(1)->in(1)->in(1) == n) { |
|
636 IfNode* dom_iff = ctrl->in(0)->as_If(); |
|
637 Node* otherproj = dom_iff->proj_out(!ctrl->as_Proj()->_con); |
|
638 if (otherproj->outcnt() == 1 && otherproj->unique_out()->is_Region() && |
|
639 this_bool->_test._test != BoolTest::ne && this_bool->_test._test != BoolTest::eq) { |
|
640 // Identify which proj goes to the region and which continues on |
|
641 RegionNode* region = otherproj->unique_out()->as_Region(); |
|
642 Node* success = NULL; |
|
643 Node* fail = NULL; |
|
644 for (int i = 0; i < 2; i++) { |
|
645 Node* proj = proj_out(i); |
|
646 if (success == NULL && proj->outcnt() == 1 && proj->unique_out() == region) { |
|
647 success = proj; |
|
648 } else if (fail == NULL) { |
|
649 fail = proj; |
|
650 } else { |
|
651 success = fail = NULL; |
|
652 } |
|
653 } |
|
654 if (success != NULL && fail != NULL && !region->has_phi()) { |
|
655 int lo = dom_iff->in(1)->in(1)->in(2)->get_int(); |
|
656 BoolNode* dom_bool = dom_iff->in(1)->as_Bool(); |
|
657 Node* dom_cmp = dom_bool->in(1); |
|
658 const TypeInt* failtype = filtered_int_type(phase, n, ctrl); |
|
659 if (failtype != NULL) { |
|
660 const TypeInt* type2 = filtered_int_type(phase, n, fail); |
|
661 if (type2 != NULL) { |
|
662 failtype = failtype->join(type2)->is_int(); |
|
663 } else { |
|
664 failtype = NULL; |
|
665 } |
|
666 } |
|
667 |
|
668 if (failtype != NULL && |
|
669 dom_bool->_test._test != BoolTest::ne && dom_bool->_test._test != BoolTest::eq) { |
|
670 int bound = failtype->_hi - failtype->_lo + 1; |
|
671 if (failtype->_hi != max_jint && failtype->_lo != min_jint && bound > 1) { |
|
672 // Merge the two compares into a single unsigned compare by building (CmpU (n - lo) hi) |
|
673 BoolTest::mask cond = fail->as_Proj()->_con ? BoolTest::lt : BoolTest::ge; |
|
674 Node* adjusted = phase->transform(new (phase->C, 3) SubINode(n, phase->intcon(failtype->_lo))); |
|
675 Node* newcmp = phase->transform(new (phase->C, 3) CmpUNode(adjusted, phase->intcon(bound))); |
|
676 Node* newbool = phase->transform(new (phase->C, 2) BoolNode(newcmp, cond)); |
|
677 phase->hash_delete(dom_iff); |
|
678 dom_iff->set_req(1, phase->intcon(ctrl->as_Proj()->_con)); |
|
679 phase->is_IterGVN()->_worklist.push(dom_iff); |
|
680 phase->hash_delete(this); |
|
681 set_req(1, newbool); |
|
682 return this; |
|
683 } |
|
684 if (failtype->_lo > failtype->_hi) { |
|
685 // previous if determines the result of this if so |
|
686 // replace Bool with constant |
|
687 phase->hash_delete(this); |
|
688 set_req(1, phase->intcon(success->as_Proj()->_con)); |
|
689 return this; |
|
690 } |
|
691 } |
|
692 } |
|
693 } |
|
694 } |
|
695 } |
|
696 return NULL; |
|
697 } |
|
698 |
546 //------------------------------remove_useless_bool---------------------------- |
699 //------------------------------remove_useless_bool---------------------------- |
547 // Check for people making a useless boolean: things like |
700 // Check for people making a useless boolean: things like |
548 // if( (x < y ? true : false) ) { ... } |
701 // if( (x < y ? true : false) ) { ... } |
549 // Replace with if( x < y ) { ... } |
702 // Replace with if( x < y ) { ... } |
550 static Node *remove_useless_bool(IfNode *iff, PhaseGVN *phase) { |
703 static Node *remove_useless_bool(IfNode *iff, PhaseGVN *phase) { |