src/share/vm/opto/block.cpp

changeset 6490
41b780b43b74
parent 6478
044b28168e20
child 6500
4345c6a92f35
     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  

mercurial