src/share/vm/opto/gcm.cpp

changeset 5539
adb9a7d94cb5
parent 5509
d1034bd8cefc
child 5635
650868c062a9
child 6462
e2722a66aba7
     1.1 --- a/src/share/vm/opto/gcm.cpp	Thu Aug 15 11:59:19 2013 -0700
     1.2 +++ b/src/share/vm/opto/gcm.cpp	Fri Aug 16 10:23:55 2013 +0200
     1.3 @@ -121,27 +121,30 @@
     1.4  
     1.5  //------------------------------schedule_pinned_nodes--------------------------
     1.6  // Set the basic block for Nodes pinned into blocks
     1.7 -void PhaseCFG::schedule_pinned_nodes( VectorSet &visited ) {
     1.8 +void PhaseCFG::schedule_pinned_nodes(VectorSet &visited) {
     1.9    // Allocate node stack of size C->unique()+8 to avoid frequent realloc
    1.10 -  GrowableArray <Node *> spstack(C->unique()+8);
    1.11 +  GrowableArray <Node *> spstack(C->unique() + 8);
    1.12    spstack.push(_root);
    1.13 -  while ( spstack.is_nonempty() ) {
    1.14 -    Node *n = spstack.pop();
    1.15 -    if( !visited.test_set(n->_idx) ) { // Test node and flag it as visited
    1.16 -      if( n->pinned() && !has_block(n)) {  // Pinned?  Nail it down!
    1.17 -        assert( n->in(0), "pinned Node must have Control" );
    1.18 +  while (spstack.is_nonempty()) {
    1.19 +    Node* node = spstack.pop();
    1.20 +    if (!visited.test_set(node->_idx)) { // Test node and flag it as visited
    1.21 +      if (node->pinned() && !has_block(node)) {  // Pinned?  Nail it down!
    1.22 +        assert(node->in(0), "pinned Node must have Control");
    1.23          // Before setting block replace block_proj control edge
    1.24 -        replace_block_proj_ctrl(n);
    1.25 -        Node *input = n->in(0);
    1.26 +        replace_block_proj_ctrl(node);
    1.27 +        Node* input = node->in(0);
    1.28          while (!input->is_block_start()) {
    1.29            input = input->in(0);
    1.30          }
    1.31 -        Block *b = get_block_for_node(input); // Basic block of controlling input
    1.32 -        schedule_node_into_block(n, b);
    1.33 +        Block* block = get_block_for_node(input); // Basic block of controlling input
    1.34 +        schedule_node_into_block(node, block);
    1.35        }
    1.36 -      for( int i = n->req() - 1; i >= 0; --i ) {  // For all inputs
    1.37 -        if( n->in(i) != NULL )
    1.38 -          spstack.push(n->in(i));
    1.39 +
    1.40 +      // process all inputs that are non NULL
    1.41 +      for (int i = node->req() - 1; i >= 0; --i) {
    1.42 +        if (node->in(i) != NULL) {
    1.43 +          spstack.push(node->in(i));
    1.44 +        }
    1.45        }
    1.46      }
    1.47    }
    1.48 @@ -205,32 +208,29 @@
    1.49  // which all their inputs occur.
    1.50  bool PhaseCFG::schedule_early(VectorSet &visited, Node_List &roots) {
    1.51    // Allocate stack with enough space to avoid frequent realloc
    1.52 -  Node_Stack nstack(roots.Size() + 8); // (unique >> 1) + 24 from Java2D stats
    1.53 -  // roots.push(_root); _root will be processed among C->top() inputs
    1.54 +  Node_Stack nstack(roots.Size() + 8);
    1.55 +  // _root will be processed among C->top() inputs
    1.56    roots.push(C->top());
    1.57    visited.set(C->top()->_idx);
    1.58  
    1.59    while (roots.size() != 0) {
    1.60      // Use local variables nstack_top_n & nstack_top_i to cache values
    1.61      // on stack's top.
    1.62 -    Node *nstack_top_n = roots.pop();
    1.63 -    uint  nstack_top_i = 0;
    1.64 -//while_nstack_nonempty:
    1.65 +    Node* parent_node = roots.pop();
    1.66 +    uint  input_index = 0;
    1.67 +
    1.68      while (true) {
    1.69 -      // Get parent node and next input's index from stack's top.
    1.70 -      Node *n = nstack_top_n;
    1.71 -      uint  i = nstack_top_i;
    1.72 -
    1.73 -      if (i == 0) {
    1.74 +      if (input_index == 0) {
    1.75          // Fixup some control.  Constants without control get attached
    1.76          // to root and nodes that use is_block_proj() nodes should be attached
    1.77          // to the region that starts their block.
    1.78 -        const Node *in0 = n->in(0);
    1.79 -        if (in0 != NULL) {              // Control-dependent?
    1.80 -          replace_block_proj_ctrl(n);
    1.81 -        } else {               // n->in(0) == NULL
    1.82 -          if (n->req() == 1) { // This guy is a constant with NO inputs?
    1.83 -            n->set_req(0, _root);
    1.84 +        const Node* control_input = parent_node->in(0);
    1.85 +        if (control_input != NULL) {
    1.86 +          replace_block_proj_ctrl(parent_node);
    1.87 +        } else {
    1.88 +          // Is a constant with NO inputs?
    1.89 +          if (parent_node->req() == 1) {
    1.90 +            parent_node->set_req(0, _root);
    1.91            }
    1.92          }
    1.93        }
    1.94 @@ -239,37 +239,47 @@
    1.95        // input is already in a block we quit following inputs (to avoid
    1.96        // cycles). Instead we put that Node on a worklist to be handled
    1.97        // later (since IT'S inputs may not have a block yet).
    1.98 -      bool done = true;              // Assume all n's inputs will be processed
    1.99 -      while (i < n->len()) {         // For all inputs
   1.100 -        Node *in = n->in(i);         // Get input
   1.101 -        ++i;
   1.102 -        if (in == NULL) continue;    // Ignore NULL, missing inputs
   1.103 +
   1.104 +      // Assume all n's inputs will be processed
   1.105 +      bool done = true;
   1.106 +
   1.107 +      while (input_index < parent_node->len()) {
   1.108 +        Node* in = parent_node->in(input_index++);
   1.109 +        if (in == NULL) {
   1.110 +          continue;
   1.111 +        }
   1.112 +
   1.113          int is_visited = visited.test_set(in->_idx);
   1.114 -        if (!has_block(in)) { // Missing block selection?
   1.115 +        if (!has_block(in)) {
   1.116            if (is_visited) {
   1.117 -            // assert( !visited.test(in->_idx), "did not schedule early" );
   1.118              return false;
   1.119            }
   1.120 -          nstack.push(n, i);         // Save parent node and next input's index.
   1.121 -          nstack_top_n = in;         // Process current input now.
   1.122 -          nstack_top_i = 0;
   1.123 -          done = false;              // Not all n's inputs processed.
   1.124 -          break; // continue while_nstack_nonempty;
   1.125 -        } else if (!is_visited) {    // Input not yet visited?
   1.126 -          roots.push(in);            // Visit this guy later, using worklist
   1.127 +          // Save parent node and next input's index.
   1.128 +          nstack.push(parent_node, input_index);
   1.129 +          // Process current input now.
   1.130 +          parent_node = in;
   1.131 +          input_index = 0;
   1.132 +          // Not all n's inputs processed.
   1.133 +          done = false;
   1.134 +          break;
   1.135 +        } else if (!is_visited) {
   1.136 +          // Visit this guy later, using worklist
   1.137 +          roots.push(in);
   1.138          }
   1.139        }
   1.140 +
   1.141        if (done) {
   1.142          // All of n's inputs have been processed, complete post-processing.
   1.143  
   1.144          // Some instructions are pinned into a block.  These include Region,
   1.145          // Phi, Start, Return, and other control-dependent instructions and
   1.146          // any projections which depend on them.
   1.147 -        if (!n->pinned()) {
   1.148 +        if (!parent_node->pinned()) {
   1.149            // Set earliest legal block.
   1.150 -          map_node_to_block(n, find_deepest_input(n, this));
   1.151 +          Block* earliest_block = find_deepest_input(parent_node, this);
   1.152 +          map_node_to_block(parent_node, earliest_block);
   1.153          } else {
   1.154 -          assert(get_block_for_node(n) == get_block_for_node(n->in(0)), "Pinned Node should be at the same block as its control edge");
   1.155 +          assert(get_block_for_node(parent_node) == get_block_for_node(parent_node->in(0)), "Pinned Node should be at the same block as its control edge");
   1.156          }
   1.157  
   1.158          if (nstack.is_empty()) {
   1.159 @@ -278,12 +288,12 @@
   1.160            break;
   1.161          }
   1.162          // Get saved parent node and next input's index.
   1.163 -        nstack_top_n = nstack.node();
   1.164 -        nstack_top_i = nstack.index();
   1.165 +        parent_node = nstack.node();
   1.166 +        input_index = nstack.index();
   1.167          nstack.pop();
   1.168 -      } //    if (done)
   1.169 -    }   // while (true)
   1.170 -  }     // while (roots.size() != 0)
   1.171 +      }
   1.172 +    }
   1.173 +  }
   1.174    return true;
   1.175  }
   1.176  
   1.177 @@ -847,7 +857,7 @@
   1.178  
   1.179  //------------------------------ComputeLatenciesBackwards----------------------
   1.180  // Compute the latency of all the instructions.
   1.181 -void PhaseCFG::ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack) {
   1.182 +void PhaseCFG::compute_latencies_backwards(VectorSet &visited, Node_List &stack) {
   1.183  #ifndef PRODUCT
   1.184    if (trace_opto_pipelining())
   1.185      tty->print("\n#---- ComputeLatenciesBackwards ----\n");
   1.186 @@ -870,31 +880,34 @@
   1.187    // Set the latency for this instruction
   1.188  #ifndef PRODUCT
   1.189    if (trace_opto_pipelining()) {
   1.190 -    tty->print("# latency_to_inputs: node_latency[%d] = %d for node",
   1.191 -               n->_idx, _node_latency->at_grow(n->_idx));
   1.192 +    tty->print("# latency_to_inputs: node_latency[%d] = %d for node", n->_idx, get_latency_for_node(n));
   1.193      dump();
   1.194    }
   1.195  #endif
   1.196  
   1.197 -  if (n->is_Proj())
   1.198 +  if (n->is_Proj()) {
   1.199      n = n->in(0);
   1.200 +  }
   1.201  
   1.202 -  if (n->is_Root())
   1.203 +  if (n->is_Root()) {
   1.204      return;
   1.205 +  }
   1.206  
   1.207    uint nlen = n->len();
   1.208 -  uint use_latency = _node_latency->at_grow(n->_idx);
   1.209 +  uint use_latency = get_latency_for_node(n);
   1.210    uint use_pre_order = get_block_for_node(n)->_pre_order;
   1.211  
   1.212 -  for ( uint j=0; j<nlen; j++ ) {
   1.213 +  for (uint j = 0; j < nlen; j++) {
   1.214      Node *def = n->in(j);
   1.215  
   1.216 -    if (!def || def == n)
   1.217 +    if (!def || def == n) {
   1.218        continue;
   1.219 +    }
   1.220  
   1.221      // Walk backwards thru projections
   1.222 -    if (def->is_Proj())
   1.223 +    if (def->is_Proj()) {
   1.224        def = def->in(0);
   1.225 +    }
   1.226  
   1.227  #ifndef PRODUCT
   1.228      if (trace_opto_pipelining()) {
   1.229 @@ -907,22 +920,20 @@
   1.230      Block *def_block = get_block_for_node(def);
   1.231      uint def_pre_order = def_block ? def_block->_pre_order : 0;
   1.232  
   1.233 -    if ( (use_pre_order <  def_pre_order) ||
   1.234 -         (use_pre_order == def_pre_order && n->is_Phi()) )
   1.235 +    if ((use_pre_order <  def_pre_order) || (use_pre_order == def_pre_order && n->is_Phi())) {
   1.236        continue;
   1.237 +    }
   1.238  
   1.239      uint delta_latency = n->latency(j);
   1.240      uint current_latency = delta_latency + use_latency;
   1.241  
   1.242 -    if (_node_latency->at_grow(def->_idx) < current_latency) {
   1.243 -      _node_latency->at_put_grow(def->_idx, current_latency);
   1.244 +    if (get_latency_for_node(def) < current_latency) {
   1.245 +      set_latency_for_node(def, current_latency);
   1.246      }
   1.247  
   1.248  #ifndef PRODUCT
   1.249      if (trace_opto_pipelining()) {
   1.250 -      tty->print_cr("#      %d + edge_latency(%d) == %d -> %d, node_latency[%d] = %d",
   1.251 -                    use_latency, j, delta_latency, current_latency, def->_idx,
   1.252 -                    _node_latency->at_grow(def->_idx));
   1.253 +      tty->print_cr("#      %d + edge_latency(%d) == %d -> %d, node_latency[%d] = %d", use_latency, j, delta_latency, current_latency, def->_idx, get_latency_for_node(def));
   1.254      }
   1.255  #endif
   1.256    }
   1.257 @@ -957,7 +968,7 @@
   1.258        return 0;
   1.259  
   1.260      uint nlen = use->len();
   1.261 -    uint nl = _node_latency->at_grow(use->_idx);
   1.262 +    uint nl = get_latency_for_node(use);
   1.263  
   1.264      for ( uint j=0; j<nlen; j++ ) {
   1.265        if (use->in(j) == n) {
   1.266 @@ -992,8 +1003,7 @@
   1.267    // Set the latency for this instruction
   1.268  #ifndef PRODUCT
   1.269    if (trace_opto_pipelining()) {
   1.270 -    tty->print("# latency_from_outputs: node_latency[%d] = %d for node",
   1.271 -               n->_idx, _node_latency->at_grow(n->_idx));
   1.272 +    tty->print("# latency_from_outputs: node_latency[%d] = %d for node", n->_idx, get_latency_for_node(n));
   1.273      dump();
   1.274    }
   1.275  #endif
   1.276 @@ -1006,7 +1016,7 @@
   1.277      if (latency < l) latency = l;
   1.278    }
   1.279  
   1.280 -  _node_latency->at_put_grow(n->_idx, latency);
   1.281 +  set_latency_for_node(n, latency);
   1.282  }
   1.283  
   1.284  //------------------------------hoist_to_cheaper_block-------------------------
   1.285 @@ -1016,9 +1026,9 @@
   1.286    const double delta = 1+PROB_UNLIKELY_MAG(4);
   1.287    Block* least       = LCA;
   1.288    double least_freq  = least->_freq;
   1.289 -  uint target        = _node_latency->at_grow(self->_idx);
   1.290 -  uint start_latency = _node_latency->at_grow(LCA->_nodes[0]->_idx);
   1.291 -  uint end_latency   = _node_latency->at_grow(LCA->_nodes[LCA->end_idx()]->_idx);
   1.292 +  uint target        = get_latency_for_node(self);
   1.293 +  uint start_latency = get_latency_for_node(LCA->_nodes[0]);
   1.294 +  uint end_latency   = get_latency_for_node(LCA->_nodes[LCA->end_idx()]);
   1.295    bool in_latency    = (target <= start_latency);
   1.296    const Block* root_block = get_block_for_node(_root);
   1.297  
   1.298 @@ -1035,8 +1045,7 @@
   1.299  
   1.300  #ifndef PRODUCT
   1.301    if (trace_opto_pipelining()) {
   1.302 -    tty->print("# Find cheaper block for latency %d: ",
   1.303 -      _node_latency->at_grow(self->_idx));
   1.304 +    tty->print("# Find cheaper block for latency %d: ", get_latency_for_node(self));
   1.305      self->dump();
   1.306      tty->print_cr("#   B%d: start latency for [%4d]=%d, end latency for [%4d]=%d, freq=%g",
   1.307        LCA->_pre_order,
   1.308 @@ -1065,9 +1074,9 @@
   1.309      if (mach && LCA == root_block)
   1.310        break;
   1.311  
   1.312 -    uint start_lat = _node_latency->at_grow(LCA->_nodes[0]->_idx);
   1.313 +    uint start_lat = get_latency_for_node(LCA->_nodes[0]);
   1.314      uint end_idx   = LCA->end_idx();
   1.315 -    uint end_lat   = _node_latency->at_grow(LCA->_nodes[end_idx]->_idx);
   1.316 +    uint end_lat   = get_latency_for_node(LCA->_nodes[end_idx]);
   1.317      double LCA_freq = LCA->_freq;
   1.318  #ifndef PRODUCT
   1.319      if (trace_opto_pipelining()) {
   1.320 @@ -1109,7 +1118,7 @@
   1.321        tty->print_cr("#  Change latency for [%4d] from %d to %d", self->_idx, target, end_latency);
   1.322      }
   1.323  #endif
   1.324 -    _node_latency->at_put_grow(self->_idx, end_latency);
   1.325 +    set_latency_for_node(self, end_latency);
   1.326      partial_latency_of_defs(self);
   1.327    }
   1.328  
   1.329 @@ -1255,7 +1264,7 @@
   1.330  } // end ScheduleLate
   1.331  
   1.332  //------------------------------GlobalCodeMotion-------------------------------
   1.333 -void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_list ) {
   1.334 +void PhaseCFG::global_code_motion() {
   1.335    ResourceMark rm;
   1.336  
   1.337  #ifndef PRODUCT
   1.338 @@ -1265,21 +1274,22 @@
   1.339  #endif
   1.340  
   1.341    // Initialize the node to block mapping for things on the proj_list
   1.342 -  for (uint i = 0; i < proj_list.size(); i++) {
   1.343 -    unmap_node_from_block(proj_list[i]);
   1.344 +  for (uint i = 0; i < _matcher.number_of_projections(); i++) {
   1.345 +    unmap_node_from_block(_matcher.get_projection(i));
   1.346    }
   1.347  
   1.348    // Set the basic block for Nodes pinned into blocks
   1.349 -  Arena *a = Thread::current()->resource_area();
   1.350 -  VectorSet visited(a);
   1.351 -  schedule_pinned_nodes( visited );
   1.352 +  Arena* arena = Thread::current()->resource_area();
   1.353 +  VectorSet visited(arena);
   1.354 +  schedule_pinned_nodes(visited);
   1.355  
   1.356    // Find the earliest Block any instruction can be placed in.  Some
   1.357    // instructions are pinned into Blocks.  Unpinned instructions can
   1.358    // appear in last block in which all their inputs occur.
   1.359    visited.Clear();
   1.360 -  Node_List stack(a);
   1.361 -  stack.map( (unique >> 1) + 16, NULL); // Pre-grow the list
   1.362 +  Node_List stack(arena);
   1.363 +  // Pre-grow the list
   1.364 +  stack.map((C->unique() >> 1) + 16, NULL);
   1.365    if (!schedule_early(visited, stack)) {
   1.366      // Bailout without retry
   1.367      C->record_method_not_compilable("early schedule failed");
   1.368 @@ -1287,29 +1297,25 @@
   1.369    }
   1.370  
   1.371    // Build Def-Use edges.
   1.372 -  proj_list.push(_root);        // Add real root as another root
   1.373 -  proj_list.pop();
   1.374 -
   1.375    // Compute the latency information (via backwards walk) for all the
   1.376    // instructions in the graph
   1.377    _node_latency = new GrowableArray<uint>(); // resource_area allocation
   1.378  
   1.379 -  if( C->do_scheduling() )
   1.380 -    ComputeLatenciesBackwards(visited, stack);
   1.381 +  if (C->do_scheduling()) {
   1.382 +    compute_latencies_backwards(visited, stack);
   1.383 +  }
   1.384  
   1.385    // Now schedule all codes as LATE as possible.  This is the LCA in the
   1.386    // dominator tree of all USES of a value.  Pick the block with the least
   1.387    // loop nesting depth that is lowest in the dominator tree.
   1.388    // ( visited.Clear() called in schedule_late()->Node_Backward_Iterator() )
   1.389    schedule_late(visited, stack);
   1.390 -  if( C->failing() ) {
   1.391 +  if (C->failing()) {
   1.392      // schedule_late fails only when graph is incorrect.
   1.393      assert(!VerifyGraphEdges, "verification should have failed");
   1.394      return;
   1.395    }
   1.396  
   1.397 -  unique = C->unique();
   1.398 -
   1.399  #ifndef PRODUCT
   1.400    if (trace_opto_pipelining()) {
   1.401      tty->print("\n---- Detect implicit null checks ----\n");
   1.402 @@ -1332,10 +1338,11 @@
   1.403      // By reversing the loop direction we get a very minor gain on mpegaudio.
   1.404      // Feel free to revert to a forward loop for clarity.
   1.405      // for( int i=0; i < (int)matcher._null_check_tests.size(); i+=2 ) {
   1.406 -    for( int i= matcher._null_check_tests.size()-2; i>=0; i-=2 ) {
   1.407 -      Node *proj = matcher._null_check_tests[i  ];
   1.408 -      Node *val  = matcher._null_check_tests[i+1];
   1.409 -      get_block_for_node(proj)->implicit_null_check(this, proj, val, allowed_reasons);
   1.410 +    for (int i = _matcher._null_check_tests.size() - 2; i >= 0; i -= 2) {
   1.411 +      Node* proj = _matcher._null_check_tests[i];
   1.412 +      Node* val  = _matcher._null_check_tests[i + 1];
   1.413 +      Block* block = get_block_for_node(proj);
   1.414 +      block->implicit_null_check(this, proj, val, allowed_reasons);
   1.415        // The implicit_null_check will only perform the transformation
   1.416        // if the null branch is truly uncommon, *and* it leads to an
   1.417        // uncommon trap.  Combined with the too_many_traps guards
   1.418 @@ -1352,11 +1359,11 @@
   1.419  
   1.420    // Schedule locally.  Right now a simple topological sort.
   1.421    // Later, do a real latency aware scheduler.
   1.422 -  uint max_idx = C->unique();
   1.423 -  GrowableArray<int> ready_cnt(max_idx, max_idx, -1);
   1.424 +  GrowableArray<int> ready_cnt(C->unique(), C->unique(), -1);
   1.425    visited.Clear();
   1.426 -  for (uint i = 0; i < _num_blocks; i++) {
   1.427 -    if (!_blocks[i]->schedule_local(this, matcher, ready_cnt, visited)) {
   1.428 +  for (uint i = 0; i < number_of_blocks(); i++) {
   1.429 +    Block* block = get_block(i);
   1.430 +    if (!block->schedule_local(this, _matcher, ready_cnt, visited)) {
   1.431        if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
   1.432          C->record_method_not_compilable("local schedule failed");
   1.433        }
   1.434 @@ -1366,15 +1373,17 @@
   1.435  
   1.436    // If we inserted any instructions between a Call and his CatchNode,
   1.437    // clone the instructions on all paths below the Catch.
   1.438 -  for (uint i = 0; i < _num_blocks; i++) {
   1.439 -    _blocks[i]->call_catch_cleanup(this, C);
   1.440 +  for (uint i = 0; i < number_of_blocks(); i++) {
   1.441 +    Block* block = get_block(i);
   1.442 +    block->call_catch_cleanup(this, C);
   1.443    }
   1.444  
   1.445  #ifndef PRODUCT
   1.446    if (trace_opto_pipelining()) {
   1.447      tty->print("\n---- After GlobalCodeMotion ----\n");
   1.448 -    for (uint i = 0; i < _num_blocks; i++) {
   1.449 -      _blocks[i]->dump();
   1.450 +    for (uint i = 0; i < number_of_blocks(); i++) {
   1.451 +      Block* block = get_block(i);
   1.452 +      block->dump();
   1.453      }
   1.454    }
   1.455  #endif
   1.456 @@ -1382,10 +1391,29 @@
   1.457    _node_latency = (GrowableArray<uint> *)0xdeadbeef;
   1.458  }
   1.459  
   1.460 +bool PhaseCFG::do_global_code_motion() {
   1.461 +
   1.462 +  build_dominator_tree();
   1.463 +  if (C->failing()) {
   1.464 +    return false;
   1.465 +  }
   1.466 +
   1.467 +  NOT_PRODUCT( C->verify_graph_edges(); )
   1.468 +
   1.469 +  estimate_block_frequency();
   1.470 +
   1.471 +  global_code_motion();
   1.472 +
   1.473 +  if (C->failing()) {
   1.474 +    return false;
   1.475 +  }
   1.476 +
   1.477 +  return true;
   1.478 +}
   1.479  
   1.480  //------------------------------Estimate_Block_Frequency-----------------------
   1.481  // Estimate block frequencies based on IfNode probabilities.
   1.482 -void PhaseCFG::Estimate_Block_Frequency() {
   1.483 +void PhaseCFG::estimate_block_frequency() {
   1.484  
   1.485    // Force conditional branches leading to uncommon traps to be unlikely,
   1.486    // not because we get to the uncommon_trap with less relative frequency,
   1.487 @@ -1393,7 +1421,7 @@
   1.488    // there once.
   1.489    if (C->do_freq_based_layout()) {
   1.490      Block_List worklist;
   1.491 -    Block* root_blk = _blocks[0];
   1.492 +    Block* root_blk = get_block(0);
   1.493      for (uint i = 1; i < root_blk->num_preds(); i++) {
   1.494        Block *pb = get_block_for_node(root_blk->pred(i));
   1.495        if (pb->has_uncommon_code()) {
   1.496 @@ -1402,7 +1430,9 @@
   1.497      }
   1.498      while (worklist.size() > 0) {
   1.499        Block* uct = worklist.pop();
   1.500 -      if (uct == _broot) continue;
   1.501 +      if (uct == get_root_block()) {
   1.502 +        continue;
   1.503 +      }
   1.504        for (uint i = 1; i < uct->num_preds(); i++) {
   1.505          Block *pb = get_block_for_node(uct->pred(i));
   1.506          if (pb->_num_succs == 1) {
   1.507 @@ -1426,12 +1456,12 @@
   1.508    _root_loop->scale_freq();
   1.509  
   1.510    // Save outmost loop frequency for LRG frequency threshold
   1.511 -  _outer_loop_freq = _root_loop->outer_loop_freq();
   1.512 +  _outer_loop_frequency = _root_loop->outer_loop_freq();
   1.513  
   1.514    // force paths ending at uncommon traps to be infrequent
   1.515    if (!C->do_freq_based_layout()) {
   1.516      Block_List worklist;
   1.517 -    Block* root_blk = _blocks[0];
   1.518 +    Block* root_blk = get_block(0);
   1.519      for (uint i = 1; i < root_blk->num_preds(); i++) {
   1.520        Block *pb = get_block_for_node(root_blk->pred(i));
   1.521        if (pb->has_uncommon_code()) {
   1.522 @@ -1451,8 +1481,8 @@
   1.523    }
   1.524  
   1.525  #ifdef ASSERT
   1.526 -  for (uint i = 0; i < _num_blocks; i++ ) {
   1.527 -    Block *b = _blocks[i];
   1.528 +  for (uint i = 0; i < number_of_blocks(); i++) {
   1.529 +    Block* b = get_block(i);
   1.530      assert(b->_freq >= MIN_BLOCK_FREQUENCY, "Register Allocator requires meaningful block frequency");
   1.531    }
   1.532  #endif
   1.533 @@ -1476,16 +1506,16 @@
   1.534  CFGLoop* PhaseCFG::create_loop_tree() {
   1.535  
   1.536  #ifdef ASSERT
   1.537 -  assert( _blocks[0] == _broot, "" );
   1.538 -  for (uint i = 0; i < _num_blocks; i++ ) {
   1.539 -    Block *b = _blocks[i];
   1.540 +  assert(get_block(0) == get_root_block(), "first block should be root block");
   1.541 +  for (uint i = 0; i < number_of_blocks(); i++) {
   1.542 +    Block* block = get_block(i);
   1.543      // Check that _loop field are clear...we could clear them if not.
   1.544 -    assert(b->_loop == NULL, "clear _loop expected");
   1.545 +    assert(block->_loop == NULL, "clear _loop expected");
   1.546      // Sanity check that the RPO numbering is reflected in the _blocks array.
   1.547      // It doesn't have to be for the loop tree to be built, but if it is not,
   1.548      // then the blocks have been reordered since dom graph building...which
   1.549      // may question the RPO numbering
   1.550 -    assert(b->_rpo == i, "unexpected reverse post order number");
   1.551 +    assert(block->_rpo == i, "unexpected reverse post order number");
   1.552    }
   1.553  #endif
   1.554  
   1.555 @@ -1495,11 +1525,11 @@
   1.556    Block_List worklist;
   1.557  
   1.558    // Assign blocks to loops
   1.559 -  for(uint i = _num_blocks - 1; i > 0; i-- ) { // skip Root block
   1.560 -    Block *b = _blocks[i];
   1.561 +  for(uint i = number_of_blocks() - 1; i > 0; i-- ) { // skip Root block
   1.562 +    Block* block = get_block(i);
   1.563  
   1.564 -    if (b->head()->is_Loop()) {
   1.565 -      Block* loop_head = b;
   1.566 +    if (block->head()->is_Loop()) {
   1.567 +      Block* loop_head = block;
   1.568        assert(loop_head->num_preds() - 1 == 2, "loop must have 2 predecessors");
   1.569        Node* tail_n = loop_head->pred(LoopNode::LoopBackControl);
   1.570        Block* tail = get_block_for_node(tail_n);
   1.571 @@ -1533,23 +1563,23 @@
   1.572  
   1.573    // Create a member list for each loop consisting
   1.574    // of both blocks and (immediate child) loops.
   1.575 -  for (uint i = 0; i < _num_blocks; i++) {
   1.576 -    Block *b = _blocks[i];
   1.577 -    CFGLoop* lp = b->_loop;
   1.578 +  for (uint i = 0; i < number_of_blocks(); i++) {
   1.579 +    Block* block = get_block(i);
   1.580 +    CFGLoop* lp = block->_loop;
   1.581      if (lp == NULL) {
   1.582        // Not assigned to a loop. Add it to the method's pseudo loop.
   1.583 -      b->_loop = root_loop;
   1.584 +      block->_loop = root_loop;
   1.585        lp = root_loop;
   1.586      }
   1.587 -    if (lp == root_loop || b != lp->head()) { // loop heads are already members
   1.588 -      lp->add_member(b);
   1.589 +    if (lp == root_loop || block != lp->head()) { // loop heads are already members
   1.590 +      lp->add_member(block);
   1.591      }
   1.592      if (lp != root_loop) {
   1.593        if (lp->parent() == NULL) {
   1.594          // Not a nested loop. Make it a child of the method's pseudo loop.
   1.595          root_loop->add_nested_loop(lp);
   1.596        }
   1.597 -      if (b == lp->head()) {
   1.598 +      if (block == lp->head()) {
   1.599          // Add nested loop to member list of parent loop.
   1.600          lp->parent()->add_member(lp);
   1.601        }

mercurial