1.1 --- a/src/share/vm/opto/block.cpp Tue Nov 26 18:38:19 2013 -0800 1.2 +++ b/src/share/vm/opto/block.cpp Wed Nov 27 16:16:21 2013 -0800 1.3 @@ -530,18 +530,27 @@ 1.4 1.5 // Does this block end in a multiway branch that cannot have the default case 1.6 // flipped for another case? 1.7 -static bool no_flip_branch( Block *b ) { 1.8 +static bool no_flip_branch(Block *b) { 1.9 int branch_idx = b->number_of_nodes() - b->_num_succs-1; 1.10 - if( branch_idx < 1 ) return false; 1.11 - Node *bra = b->get_node(branch_idx); 1.12 - if( bra->is_Catch() ) 1.13 + if (branch_idx < 1) { 1.14 + return false; 1.15 + } 1.16 + Node *branch = b->get_node(branch_idx); 1.17 + if (branch->is_Catch()) { 1.18 return true; 1.19 - if( bra->is_Mach() ) { 1.20 - if( bra->is_MachNullCheck() ) 1.21 + } 1.22 + if (branch->is_Mach()) { 1.23 + if (branch->is_MachNullCheck()) { 1.24 return true; 1.25 - int iop = bra->as_Mach()->ideal_Opcode(); 1.26 - if( iop == Op_FastLock || iop == Op_FastUnlock ) 1.27 + } 1.28 + int iop = branch->as_Mach()->ideal_Opcode(); 1.29 + if (iop == Op_FastLock || iop == Op_FastUnlock) { 1.30 return true; 1.31 + } 1.32 + // Don't flip if branch has an implicit check. 1.33 + if (branch->as_Mach()->is_TrapBasedCheckNode()) { 1.34 + return true; 1.35 + } 1.36 } 1.37 return false; 1.38 } 1.39 @@ -700,6 +709,57 @@ 1.40 } // End of for all blocks 1.41 } 1.42 1.43 +Block *PhaseCFG::fixup_trap_based_check(Node *branch, Block *block, int block_pos, Block *bnext) { 1.44 + // Trap based checks must fall through to the successor with 1.45 + // PROB_ALWAYS. 1.46 + // They should be an If with 2 successors. 1.47 + assert(branch->is_MachIf(), "must be If"); 1.48 + assert(block->_num_succs == 2, "must have 2 successors"); 1.49 + 1.50 + // Get the If node and the projection for the first successor. 1.51 + MachIfNode *iff = block->get_node(block->number_of_nodes()-3)->as_MachIf(); 1.52 + ProjNode *proj0 = block->get_node(block->number_of_nodes()-2)->as_Proj(); 1.53 + ProjNode *proj1 = block->get_node(block->number_of_nodes()-1)->as_Proj(); 1.54 + ProjNode *projt = (proj0->Opcode() == Op_IfTrue) ? proj0 : proj1; 1.55 + ProjNode *projf = (proj0->Opcode() == Op_IfFalse) ? proj0 : proj1; 1.56 + 1.57 + // Assert that proj0 and succs[0] match up. Similarly for proj1 and succs[1]. 1.58 + assert(proj0->raw_out(0) == block->_succs[0]->head(), "Mismatch successor 0"); 1.59 + assert(proj1->raw_out(0) == block->_succs[1]->head(), "Mismatch successor 1"); 1.60 + 1.61 + ProjNode *proj_always; 1.62 + ProjNode *proj_never; 1.63 + // We must negate the branch if the implicit check doesn't follow 1.64 + // the branch's TRUE path. Then, the new TRUE branch target will 1.65 + // be the old FALSE branch target. 1.66 + if (iff->_prob <= 2*PROB_NEVER) { // There are small rounding errors. 1.67 + proj_never = projt; 1.68 + proj_always = projf; 1.69 + } else { 1.70 + // We must negate the branch if the trap doesn't follow the 1.71 + // branch's TRUE path. Then, the new TRUE branch target will 1.72 + // be the old FALSE branch target. 1.73 + proj_never = projf; 1.74 + proj_always = projt; 1.75 + iff->negate(); 1.76 + } 1.77 + assert(iff->_prob <= 2*PROB_NEVER, "Trap based checks are expected to trap never!"); 1.78 + // Map the successors properly 1.79 + block->_succs.map(0, get_block_for_node(proj_never ->raw_out(0))); // The target of the trap. 1.80 + block->_succs.map(1, get_block_for_node(proj_always->raw_out(0))); // The fall through target. 1.81 + 1.82 + // Place the fall through block after this block. 1.83 + Block *bs1 = block->non_connector_successor(1); 1.84 + if (bs1 != bnext && move_to_next(bs1, block_pos)) { 1.85 + bnext = bs1; 1.86 + } 1.87 + // If the fall through block still is not the next block, insert a goto. 1.88 + if (bs1 != bnext) { 1.89 + insert_goto_at(block_pos, 1); 1.90 + } 1.91 + return bnext; 1.92 +} 1.93 + 1.94 // Fix up the final control flow for basic blocks. 1.95 void PhaseCFG::fixup_flow() { 1.96 // Fixup final control flow for the blocks. Remove jump-to-next 1.97 @@ -723,25 +783,39 @@ 1.98 // Check for multi-way branches where I cannot negate the test to 1.99 // exchange the true and false targets. 1.100 if (no_flip_branch(block)) { 1.101 - // Find fall through case - if must fall into its target 1.102 + // Find fall through case - if must fall into its target. 1.103 + // Get the index of the branch's first successor. 1.104 int branch_idx = block->number_of_nodes() - block->_num_succs; 1.105 - for (uint j2 = 0; j2 < block->_num_succs; j2++) { 1.106 - const ProjNode* p = block->get_node(branch_idx + j2)->as_Proj(); 1.107 - if (p->_con == 0) { 1.108 - // successor j2 is fall through case 1.109 - if (block->non_connector_successor(j2) != bnext) { 1.110 - // but it is not the next block => insert a goto 1.111 - insert_goto_at(i, j2); 1.112 + 1.113 + // The branch is 1 before the branch's first successor. 1.114 + Node *branch = block->get_node(branch_idx-1); 1.115 + 1.116 + // Handle no-flip branches which have implicit checks and which require 1.117 + // special block ordering and individual semantics of the 'fall through 1.118 + // case'. 1.119 + if ((TrapBasedNullChecks || TrapBasedRangeChecks) && 1.120 + branch->is_Mach() && branch->as_Mach()->is_TrapBasedCheckNode()) { 1.121 + bnext = fixup_trap_based_check(branch, block, i, bnext); 1.122 + } else { 1.123 + // Else, default handling for no-flip branches 1.124 + for (uint j2 = 0; j2 < block->_num_succs; j2++) { 1.125 + const ProjNode* p = block->get_node(branch_idx + j2)->as_Proj(); 1.126 + if (p->_con == 0) { 1.127 + // successor j2 is fall through case 1.128 + if (block->non_connector_successor(j2) != bnext) { 1.129 + // but it is not the next block => insert a goto 1.130 + insert_goto_at(i, j2); 1.131 + } 1.132 + // Put taken branch in slot 0 1.133 + if (j2 == 0 && block->_num_succs == 2) { 1.134 + // Flip targets in succs map 1.135 + Block *tbs0 = block->_succs[0]; 1.136 + Block *tbs1 = block->_succs[1]; 1.137 + block->_succs.map(0, tbs1); 1.138 + block->_succs.map(1, tbs0); 1.139 + } 1.140 + break; 1.141 } 1.142 - // Put taken branch in slot 0 1.143 - if (j2 == 0 && block->_num_succs == 2) { 1.144 - // Flip targets in succs map 1.145 - Block *tbs0 = block->_succs[0]; 1.146 - Block *tbs1 = block->_succs[1]; 1.147 - block->_succs.map(0, tbs1); 1.148 - block->_succs.map(1, tbs0); 1.149 - } 1.150 - break; 1.151 } 1.152 } 1.153