622 return false;
623 }
624
625 static bool is_safepoint(BlockEnd* x, BlockBegin* sux) {
626 // An Instruction with multiple successors, x, is replaced by a Goto
627 // to a single successor, sux. Is a safepoint check needed = was the
628 // instruction being replaced a safepoint and the single remaining
629 // successor a back branch?
630 return x->is_safepoint() && (sux->bci() < x->state_before()->bci());
631 }
632
633 void Canonicalizer::do_If(If* x) {
634 // move const to right
635 if (x->x()->type()->is_constant()) x->swap_operands();
636 // simplify
637 const Value l = x->x(); ValueType* lt = l->type();
638 const Value r = x->y(); ValueType* rt = r->type();
639
640 if (l == r && !lt->is_float_kind()) {
641 // pattern: If (a cond a) => simplify to Goto
642 BlockBegin* sux;
643 switch (x->cond()) {
644 case If::eql: sux = x->sux_for(true); break;
645 case If::neq: sux = x->sux_for(false); break;
646 case If::lss: sux = x->sux_for(false); break;
647 case If::leq: sux = x->sux_for(true); break;
648 case If::gtr: sux = x->sux_for(false); break;
649 case If::geq: sux = x->sux_for(true); break;
650 }
651 // If is a safepoint then the debug information should come from the state_before of the If.
652 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
653 return;
654 }
655
656 if (lt->is_constant() && rt->is_constant()) {
657 if (x->x()->as_Constant() != NULL) {
658 // pattern: If (lc cond rc) => simplify to: Goto
659 BlockBegin* sux = x->x()->as_Constant()->compare(x->cond(), x->y(),
660 x->sux_for(true),
661 x->sux_for(false));
662 if (sux != NULL) {
663 // If is a safepoint then the debug information should come from the state_before of the If.
664 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
665 }
666 }
667 } else if (rt->as_IntConstant() != NULL) {
668 // pattern: If (l cond rc) => investigate further
669 const jint rc = rt->as_IntConstant()->value();
670 if (l->as_CompareOp() != NULL) {
671 // pattern: If ((a cmp b) cond rc) => simplify to: If (x cond y) or: Goto
672 CompareOp* cmp = l->as_CompareOp();
673 bool unordered_is_less = cmp->op() == Bytecodes::_fcmpl || cmp->op() == Bytecodes::_dcmpl;
674 BlockBegin* lss_sux = x->sux_for(is_true(-1, x->cond(), rc)); // successor for a < b
675 BlockBegin* eql_sux = x->sux_for(is_true( 0, x->cond(), rc)); // successor for a = b
676 BlockBegin* gtr_sux = x->sux_for(is_true(+1, x->cond(), rc)); // successor for a > b
677 BlockBegin* nan_sux = unordered_is_less ? lss_sux : gtr_sux ; // successor for unordered
678 // Note: At this point all successors (lss_sux, eql_sux, gtr_sux, nan_sux) are
679 // equal to x->tsux() or x->fsux(). Furthermore, nan_sux equals either
680 // lss_sux or gtr_sux.
681 if (lss_sux == eql_sux && eql_sux == gtr_sux) {
682 // all successors identical => simplify to: Goto
683 set_canonical(new Goto(lss_sux, x->state_before(), x->is_safepoint()));
684 } else {
685 // two successors differ and two successors are the same => simplify to: If (x cmp y)
686 // determine new condition & successors
687 If::Condition cond;
688 BlockBegin* tsux = NULL;
689 BlockBegin* fsux = NULL;
690 if (lss_sux == eql_sux) { cond = If::leq; tsux = lss_sux; fsux = gtr_sux; }
691 else if (lss_sux == gtr_sux) { cond = If::neq; tsux = lss_sux; fsux = eql_sux; }
692 else if (eql_sux == gtr_sux) { cond = If::geq; tsux = eql_sux; fsux = lss_sux; }
693 else { ShouldNotReachHere(); }
694 If* canon = new If(cmp->x(), cond, nan_sux == tsux, cmp->y(), tsux, fsux, cmp->state_before(), x->is_safepoint());
695 if (cmp->x() == cmp->y()) {
696 do_If(canon);
697 } else {
698 if (compilation()->profile_branches()) {
699 // TODO: If profiling, leave floating point comparisons unoptimized.
700 // We currently do not support profiling of the unordered case.
701 switch(cmp->op()) {
702 case Bytecodes::_fcmpl: case Bytecodes::_fcmpg:
703 case Bytecodes::_dcmpl: case Bytecodes::_dcmpg:
704 set_canonical(x);
705 return;
706 }
707 }
|
622 return false;
623 }
624
625 static bool is_safepoint(BlockEnd* x, BlockBegin* sux) {
626 // An Instruction with multiple successors, x, is replaced by a Goto
627 // to a single successor, sux. Is a safepoint check needed = was the
628 // instruction being replaced a safepoint and the single remaining
629 // successor a back branch?
630 return x->is_safepoint() && (sux->bci() < x->state_before()->bci());
631 }
632
633 void Canonicalizer::do_If(If* x) {
634 // move const to right
635 if (x->x()->type()->is_constant()) x->swap_operands();
636 // simplify
637 const Value l = x->x(); ValueType* lt = l->type();
638 const Value r = x->y(); ValueType* rt = r->type();
639
640 if (l == r && !lt->is_float_kind()) {
641 // pattern: If (a cond a) => simplify to Goto
642 BlockBegin* sux = NULL;
643 switch (x->cond()) {
644 case If::eql: sux = x->sux_for(true); break;
645 case If::neq: sux = x->sux_for(false); break;
646 case If::lss: sux = x->sux_for(false); break;
647 case If::leq: sux = x->sux_for(true); break;
648 case If::gtr: sux = x->sux_for(false); break;
649 case If::geq: sux = x->sux_for(true); break;
650 default: ShouldNotReachHere();
651 }
652 // If is a safepoint then the debug information should come from the state_before of the If.
653 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
654 return;
655 }
656
657 if (lt->is_constant() && rt->is_constant()) {
658 if (x->x()->as_Constant() != NULL) {
659 // pattern: If (lc cond rc) => simplify to: Goto
660 BlockBegin* sux = x->x()->as_Constant()->compare(x->cond(), x->y(),
661 x->sux_for(true),
662 x->sux_for(false));
663 if (sux != NULL) {
664 // If is a safepoint then the debug information should come from the state_before of the If.
665 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
666 }
667 }
668 } else if (rt->as_IntConstant() != NULL) {
669 // pattern: If (l cond rc) => investigate further
670 const jint rc = rt->as_IntConstant()->value();
671 if (l->as_CompareOp() != NULL) {
672 // pattern: If ((a cmp b) cond rc) => simplify to: If (x cond y) or: Goto
673 CompareOp* cmp = l->as_CompareOp();
674 bool unordered_is_less = cmp->op() == Bytecodes::_fcmpl || cmp->op() == Bytecodes::_dcmpl;
675 BlockBegin* lss_sux = x->sux_for(is_true(-1, x->cond(), rc)); // successor for a < b
676 BlockBegin* eql_sux = x->sux_for(is_true( 0, x->cond(), rc)); // successor for a = b
677 BlockBegin* gtr_sux = x->sux_for(is_true(+1, x->cond(), rc)); // successor for a > b
678 BlockBegin* nan_sux = unordered_is_less ? lss_sux : gtr_sux ; // successor for unordered
679 // Note: At this point all successors (lss_sux, eql_sux, gtr_sux, nan_sux) are
680 // equal to x->tsux() or x->fsux(). Furthermore, nan_sux equals either
681 // lss_sux or gtr_sux.
682 if (lss_sux == eql_sux && eql_sux == gtr_sux) {
683 // all successors identical => simplify to: Goto
684 set_canonical(new Goto(lss_sux, x->state_before(), x->is_safepoint()));
685 } else {
686 // two successors differ and two successors are the same => simplify to: If (x cmp y)
687 // determine new condition & successors
688 If::Condition cond = If::eql;
689 BlockBegin* tsux = NULL;
690 BlockBegin* fsux = NULL;
691 if (lss_sux == eql_sux) { cond = If::leq; tsux = lss_sux; fsux = gtr_sux; }
692 else if (lss_sux == gtr_sux) { cond = If::neq; tsux = lss_sux; fsux = eql_sux; }
693 else if (eql_sux == gtr_sux) { cond = If::geq; tsux = eql_sux; fsux = lss_sux; }
694 else { ShouldNotReachHere(); }
695 If* canon = new If(cmp->x(), cond, nan_sux == tsux, cmp->y(), tsux, fsux, cmp->state_before(), x->is_safepoint());
696 if (cmp->x() == cmp->y()) {
697 do_If(canon);
698 } else {
699 if (compilation()->profile_branches()) {
700 // TODO: If profiling, leave floating point comparisons unoptimized.
701 // We currently do not support profiling of the unordered case.
702 switch(cmp->op()) {
703 case Bytecodes::_fcmpl: case Bytecodes::_fcmpg:
704 case Bytecodes::_dcmpl: case Bytecodes::_dcmpg:
705 set_canonical(x);
706 return;
707 }
708 }
|