comparison src/share/vm/opto/block.cpp @ 14440:41b780b43b74

8029015: PPC64 (part 216): opto: trap based null and range checks Summary: On PPC64 use tdi instruction that does a compare and raises SIGTRAP for NULL and range checks. Reviewed-by: kvn
author goetz
date Wed, 27 Nov 2013 16:16:21 -0800
parents 044b28168e20
children c3efa8868779
comparison
equal deleted inserted replaced
14439:50fdb38839eb 14440:41b780b43b74
528 add_block_at(block_no + 1, block); 528 add_block_at(block_no + 1, block);
529 } 529 }
530 530
531 // Does this block end in a multiway branch that cannot have the default case 531 // Does this block end in a multiway branch that cannot have the default case
532 // flipped for another case? 532 // flipped for another case?
533 static bool no_flip_branch( Block *b ) { 533 static bool no_flip_branch(Block *b) {
534 int branch_idx = b->number_of_nodes() - b->_num_succs-1; 534 int branch_idx = b->number_of_nodes() - b->_num_succs-1;
535 if( branch_idx < 1 ) return false; 535 if (branch_idx < 1) {
536 Node *bra = b->get_node(branch_idx); 536 return false;
537 if( bra->is_Catch() ) 537 }
538 Node *branch = b->get_node(branch_idx);
539 if (branch->is_Catch()) {
538 return true; 540 return true;
539 if( bra->is_Mach() ) { 541 }
540 if( bra->is_MachNullCheck() ) 542 if (branch->is_Mach()) {
543 if (branch->is_MachNullCheck()) {
541 return true; 544 return true;
542 int iop = bra->as_Mach()->ideal_Opcode(); 545 }
543 if( iop == Op_FastLock || iop == Op_FastUnlock ) 546 int iop = branch->as_Mach()->ideal_Opcode();
547 if (iop == Op_FastLock || iop == Op_FastUnlock) {
544 return true; 548 return true;
549 }
550 // Don't flip if branch has an implicit check.
551 if (branch->as_Mach()->is_TrapBasedCheckNode()) {
552 return true;
553 }
545 } 554 }
546 return false; 555 return false;
547 } 556 }
548 557
549 // Check for NeverBranch at block end. This needs to become a GOTO to the 558 // Check for NeverBranch at block end. This needs to become a GOTO to the
698 i--; 707 i--;
699 } 708 }
700 } // End of for all blocks 709 } // End of for all blocks
701 } 710 }
702 711
712 Block *PhaseCFG::fixup_trap_based_check(Node *branch, Block *block, int block_pos, Block *bnext) {
713 // Trap based checks must fall through to the successor with
714 // PROB_ALWAYS.
715 // They should be an If with 2 successors.
716 assert(branch->is_MachIf(), "must be If");
717 assert(block->_num_succs == 2, "must have 2 successors");
718
719 // Get the If node and the projection for the first successor.
720 MachIfNode *iff = block->get_node(block->number_of_nodes()-3)->as_MachIf();
721 ProjNode *proj0 = block->get_node(block->number_of_nodes()-2)->as_Proj();
722 ProjNode *proj1 = block->get_node(block->number_of_nodes()-1)->as_Proj();
723 ProjNode *projt = (proj0->Opcode() == Op_IfTrue) ? proj0 : proj1;
724 ProjNode *projf = (proj0->Opcode() == Op_IfFalse) ? proj0 : proj1;
725
726 // Assert that proj0 and succs[0] match up. Similarly for proj1 and succs[1].
727 assert(proj0->raw_out(0) == block->_succs[0]->head(), "Mismatch successor 0");
728 assert(proj1->raw_out(0) == block->_succs[1]->head(), "Mismatch successor 1");
729
730 ProjNode *proj_always;
731 ProjNode *proj_never;
732 // We must negate the branch if the implicit check doesn't follow
733 // the branch's TRUE path. Then, the new TRUE branch target will
734 // be the old FALSE branch target.
735 if (iff->_prob <= 2*PROB_NEVER) { // There are small rounding errors.
736 proj_never = projt;
737 proj_always = projf;
738 } else {
739 // We must negate the branch if the trap doesn't follow the
740 // branch's TRUE path. Then, the new TRUE branch target will
741 // be the old FALSE branch target.
742 proj_never = projf;
743 proj_always = projt;
744 iff->negate();
745 }
746 assert(iff->_prob <= 2*PROB_NEVER, "Trap based checks are expected to trap never!");
747 // Map the successors properly
748 block->_succs.map(0, get_block_for_node(proj_never ->raw_out(0))); // The target of the trap.
749 block->_succs.map(1, get_block_for_node(proj_always->raw_out(0))); // The fall through target.
750
751 // Place the fall through block after this block.
752 Block *bs1 = block->non_connector_successor(1);
753 if (bs1 != bnext && move_to_next(bs1, block_pos)) {
754 bnext = bs1;
755 }
756 // If the fall through block still is not the next block, insert a goto.
757 if (bs1 != bnext) {
758 insert_goto_at(block_pos, 1);
759 }
760 return bnext;
761 }
762
703 // Fix up the final control flow for basic blocks. 763 // Fix up the final control flow for basic blocks.
704 void PhaseCFG::fixup_flow() { 764 void PhaseCFG::fixup_flow() {
705 // Fixup final control flow for the blocks. Remove jump-to-next 765 // Fixup final control flow for the blocks. Remove jump-to-next
706 // block. If neither arm of an IF follows the conditional branch, we 766 // block. If neither arm of an IF follows the conditional branch, we
707 // have to add a second jump after the conditional. We place the 767 // have to add a second jump after the conditional. We place the
721 Block* bs0 = block->non_connector_successor(0); 781 Block* bs0 = block->non_connector_successor(0);
722 782
723 // Check for multi-way branches where I cannot negate the test to 783 // Check for multi-way branches where I cannot negate the test to
724 // exchange the true and false targets. 784 // exchange the true and false targets.
725 if (no_flip_branch(block)) { 785 if (no_flip_branch(block)) {
726 // Find fall through case - if must fall into its target 786 // Find fall through case - if must fall into its target.
787 // Get the index of the branch's first successor.
727 int branch_idx = block->number_of_nodes() - block->_num_succs; 788 int branch_idx = block->number_of_nodes() - block->_num_succs;
728 for (uint j2 = 0; j2 < block->_num_succs; j2++) { 789
729 const ProjNode* p = block->get_node(branch_idx + j2)->as_Proj(); 790 // The branch is 1 before the branch's first successor.
730 if (p->_con == 0) { 791 Node *branch = block->get_node(branch_idx-1);
731 // successor j2 is fall through case 792
732 if (block->non_connector_successor(j2) != bnext) { 793 // Handle no-flip branches which have implicit checks and which require
733 // but it is not the next block => insert a goto 794 // special block ordering and individual semantics of the 'fall through
734 insert_goto_at(i, j2); 795 // case'.
796 if ((TrapBasedNullChecks || TrapBasedRangeChecks) &&
797 branch->is_Mach() && branch->as_Mach()->is_TrapBasedCheckNode()) {
798 bnext = fixup_trap_based_check(branch, block, i, bnext);
799 } else {
800 // Else, default handling for no-flip branches
801 for (uint j2 = 0; j2 < block->_num_succs; j2++) {
802 const ProjNode* p = block->get_node(branch_idx + j2)->as_Proj();
803 if (p->_con == 0) {
804 // successor j2 is fall through case
805 if (block->non_connector_successor(j2) != bnext) {
806 // but it is not the next block => insert a goto
807 insert_goto_at(i, j2);
808 }
809 // Put taken branch in slot 0
810 if (j2 == 0 && block->_num_succs == 2) {
811 // Flip targets in succs map
812 Block *tbs0 = block->_succs[0];
813 Block *tbs1 = block->_succs[1];
814 block->_succs.map(0, tbs1);
815 block->_succs.map(1, tbs0);
816 }
817 break;
735 } 818 }
736 // Put taken branch in slot 0
737 if (j2 == 0 && block->_num_succs == 2) {
738 // Flip targets in succs map
739 Block *tbs0 = block->_succs[0];
740 Block *tbs1 = block->_succs[1];
741 block->_succs.map(0, tbs1);
742 block->_succs.map(1, tbs0);
743 }
744 break;
745 } 819 }
746 } 820 }
747 821
748 // Remove all CatchProjs 822 // Remove all CatchProjs
749 for (uint j = 0; j < block->_num_succs; j++) { 823 for (uint j = 0; j < block->_num_succs; j++) {