/*
 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "precompiled.hpp"
#include "libadt/vectset.hpp"
#include "memory/allocation.inline.hpp"
#include "opto/block.hpp"
#include "opto/cfgnode.hpp"
#include "opto/chaitin.hpp"
#include "opto/loopnode.hpp"
#include "opto/machnode.hpp"
#include "opto/matcher.hpp"
#include "opto/opcodes.hpp"
#include "opto/rootnode.hpp"
#include "utilities/copy.hpp"

void Block_Array::grow( uint i ) {
  assert(i >= Max(), "must be an overflow");
  debug_only(_limit = i+1);
  if( i < _size )  return;
  if( !_size ) {
    _size = 1;
    _blocks = (Block**)_arena->Amalloc( _size * sizeof(Block*) );
    _blocks[0] = NULL;
  }
  uint old = _size;
  while( i >= _size ) _size <<= 1;      // Double to fit
  _blocks = (Block**)_arena->Arealloc( _blocks, old*sizeof(Block*),_size*sizeof(Block*));
  Copy::zero_to_bytes( &_blocks[old], (_size-old)*sizeof(Block*) );
}

void Block_List::remove(uint i) {
  assert(i < _cnt, "index out of bounds");
  Copy::conjoint_words_to_lower((HeapWord*)&_blocks[i+1], (HeapWord*)&_blocks[i], ((_cnt-i-1)*sizeof(Block*)));
  pop(); // shrink list by one block
}

void Block_List::insert(uint i, Block *b) {
  push(b); // grow list by one block
  Copy::conjoint_words_to_higher((HeapWord*)&_blocks[i], (HeapWord*)&_blocks[i+1], ((_cnt-i-1)*sizeof(Block*)));
  _blocks[i] = b;
}

#ifndef PRODUCT
void Block_List::print() {
  for (uint i=0; i < size(); i++) {
    tty->print("B%d ", _blocks[i]->_pre_order);
  }
  tty->print("size = %d\n", size());
}
#endif

uint Block::code_alignment() {
  // Check for Root block
  if (_pre_order == 0) return CodeEntryAlignment;
  // Check for Start block
  if (_pre_order == 1) return InteriorEntryAlignment;
  // Check for loop alignment
  if (has_loop_alignment()) return loop_alignment();

  return relocInfo::addr_unit(); // no particular alignment
}

uint Block::compute_loop_alignment() {
  Node *h = head();
  int unit_sz = relocInfo::addr_unit();
  if (h->is_Loop() && h->as_Loop()->is_inner_loop())  {
    // Pre- and post-loops have low trip count so do not bother with
    // NOPs for align loop head.  The constants are hidden from tuning
    // but only because my "divide by 4" heuristic surely gets nearly
    // all possible gain (a "do not align at all" heuristic has a
    // chance of getting a really tiny gain).
    if (h->is_CountedLoop() && (h->as_CountedLoop()->is_pre_loop() ||
                                h->as_CountedLoop()->is_post_loop())) {
      return (OptoLoopAlignment > 4*unit_sz) ? (OptoLoopAlignment>>2) : unit_sz;
    }
    // Loops with low backedge frequency should not be aligned.
    Node *n = h->in(LoopNode::LoopBackControl)->in(0);
    if (n->is_MachIf() && n->as_MachIf()->_prob < 0.01) {
      return unit_sz; // Loop does not loop, more often than not!
    }
    return OptoLoopAlignment; // Otherwise align loop head
  }

  return unit_sz; // no particular alignment
}

// Compute the size of first 'inst_cnt' instructions in this block.
// Return the number of instructions left to compute if the block has
// less then 'inst_cnt' instructions. Stop, and return 0 if sum_size
// exceeds OptoLoopAlignment.
uint Block::compute_first_inst_size(uint& sum_size, uint inst_cnt,
                                    PhaseRegAlloc* ra) {
  uint last_inst = number_of_nodes();
  for( uint j = 0; j < last_inst && inst_cnt > 0; j++ ) {
    uint inst_size = get_node(j)->size(ra);
    if( inst_size > 0 ) {
      inst_cnt--;
      uint sz = sum_size + inst_size;
      if( sz <= (uint)OptoLoopAlignment ) {
        // Compute size of instructions which fit into fetch buffer only
        // since all inst_cnt instructions will not fit even if we align them.
        sum_size = sz;
      } else {
        return 0;
      }
    }
  }
  return inst_cnt;
}

uint Block::find_node( const Node *n ) const {
  for( uint i = 0; i < number_of_nodes(); i++ ) {
    if( get_node(i) == n )
      return i;
  }
  ShouldNotReachHere();
  return 0;
}

// Find and remove n from block list
void Block::find_remove( const Node *n ) {
  remove_node(find_node(n));
}

bool Block::contains(const Node *n) const {
  return _nodes.contains(n);
}

// Return empty status of a block.  Empty blocks contain only the head, other
// ideal nodes, and an optional trailing goto.
int Block::is_Empty() const {

  // Root or start block is not considered empty
  if (head()->is_Root() || head()->is_Start()) {
    return not_empty;
  }

  int success_result = completely_empty;
  int end_idx = number_of_nodes() - 1;

  // Check for ending goto
  if ((end_idx > 0) && (get_node(end_idx)->is_MachGoto())) {
    success_result = empty_with_goto;
    end_idx--;
  }

  // Unreachable blocks are considered empty
  if (num_preds() <= 1) {
    return success_result;
  }

  // Ideal nodes are allowable in empty blocks: skip them  Only MachNodes
  // turn directly into code, because only MachNodes have non-trivial
  // emit() functions.
  while ((end_idx > 0) && !get_node(end_idx)->is_Mach()) {
    end_idx--;
  }

  // No room for any interesting instructions?
  if (end_idx == 0) {
    return success_result;
  }

  return not_empty;
}

// Return true if the block's code implies that it is likely to be
// executed infrequently.  Check to see if the block ends in a Halt or
// a low probability call.
bool Block::has_uncommon_code() const {
  Node* en = end();

  if (en->is_MachGoto())
    en = en->in(0);
  if (en->is_Catch())
    en = en->in(0);
  if (en->is_MachProj() && en->in(0)->is_MachCall()) {
    MachCallNode* call = en->in(0)->as_MachCall();
    if (call->cnt() != COUNT_UNKNOWN && call->cnt() <= PROB_UNLIKELY_MAG(4)) {
      // This is true for slow-path stubs like new_{instance,array},
      // slow_arraycopy, complete_monitor_locking, uncommon_trap.
      // The magic number corresponds to the probability of an uncommon_trap,
      // even though it is a count not a probability.
      return true;
    }
  }

  int op = en->is_Mach() ? en->as_Mach()->ideal_Opcode() : en->Opcode();
  return op == Op_Halt;
}

// True if block is low enough frequency or guarded by a test which
// mostly does not go here.
bool PhaseCFG::is_uncommon(const Block* block) {
  // Initial blocks must never be moved, so are never uncommon.
  if (block->head()->is_Root() || block->head()->is_Start())  return false;

  // Check for way-low freq
  if(block->_freq < BLOCK_FREQUENCY(0.00001f) ) return true;

  // Look for code shape indicating uncommon_trap or slow path
  if (block->has_uncommon_code()) return true;

  const float epsilon = 0.05f;
  const float guard_factor = PROB_UNLIKELY_MAG(4) / (1.f - epsilon);
  uint uncommon_preds = 0;
  uint freq_preds = 0;
  uint uncommon_for_freq_preds = 0;

  for( uint i=1; i< block->num_preds(); i++ ) {
    Block* guard = get_block_for_node(block->pred(i));
    // Check to see if this block follows its guard 1 time out of 10000
    // or less.
    //
    // See list of magnitude-4 unlikely probabilities in cfgnode.hpp which
    // we intend to be "uncommon", such as slow-path TLE allocation,
    // predicted call failure, and uncommon trap triggers.
    //
    // Use an epsilon value of 5% to allow for variability in frequency
    // predictions and floating point calculations. The net effect is
    // that guard_factor is set to 9500.
    //
    // Ignore low-frequency blocks.
    // The next check is (guard->_freq < 1.e-5 * 9500.).
    if(guard->_freq*BLOCK_FREQUENCY(guard_factor) < BLOCK_FREQUENCY(0.00001f)) {
      uncommon_preds++;
    } else {
      freq_preds++;
      if(block->_freq < guard->_freq * guard_factor ) {
        uncommon_for_freq_preds++;
      }
    }
  }
  if( block->num_preds() > 1 &&
      // The block is uncommon if all preds are uncommon or
      (uncommon_preds == (block->num_preds()-1) ||
      // it is uncommon for all frequent preds.
       uncommon_for_freq_preds == freq_preds) ) {
    return true;
  }
  return false;
}

#ifndef PRODUCT
void Block::dump_bidx(const Block* orig, outputStream* st) const {
  if (_pre_order) st->print("B%d",_pre_order);
  else st->print("N%d", head()->_idx);

  if (Verbose && orig != this) {
    // Dump the original block's idx
    st->print(" (");
    orig->dump_bidx(orig, st);
    st->print(")");
  }
}

void Block::dump_pred(const PhaseCFG* cfg, Block* orig, outputStream* st) const {
  if (is_connector()) {
    for (uint i=1; i<num_preds(); i++) {
      Block *p = cfg->get_block_for_node(pred(i));
      p->dump_pred(cfg, orig, st);
    }
  } else {
    dump_bidx(orig, st);
    st->print(" ");
  }
}

void Block::dump_head(const PhaseCFG* cfg, outputStream* st) const {
  // Print the basic block
  dump_bidx(this, st);
  st->print(": #\t");

  // Print the incoming CFG edges and the outgoing CFG edges
  for( uint i=0; i<_num_succs; i++ ) {
    non_connector_successor(i)->dump_bidx(_succs[i], st);
    st->print(" ");
  }
  st->print("<- ");
  if( head()->is_block_start() ) {
    for (uint i=1; i<num_preds(); i++) {
      Node *s = pred(i);
      if (cfg != NULL) {
        Block *p = cfg->get_block_for_node(s);
        p->dump_pred(cfg, p, st);
      } else {
        while (!s->is_block_start())
          s = s->in(0);
        st->print("N%d ", s->_idx );
      }
    }
  } else {
    st->print("BLOCK HEAD IS JUNK  ");
  }

  // Print loop, if any
  const Block *bhead = this;    // Head of self-loop
  Node *bh = bhead->head();

  if ((cfg != NULL) && bh->is_Loop() && !head()->is_Root()) {
    LoopNode *loop = bh->as_Loop();
    const Block *bx = cfg->get_block_for_node(loop->in(LoopNode::LoopBackControl));
    while (bx->is_connector()) {
      bx = cfg->get_block_for_node(bx->pred(1));
    }
    st->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order);
    // Dump any loop-specific bits, especially for CountedLoops.
    loop->dump_spec(st);
  } else if (has_loop_alignment()) {
    st->print(" top-of-loop");
  }
  st->print(" Freq: %g",_freq);
  if( Verbose || WizardMode ) {
    st->print(" IDom: %d/#%d", _idom ? _idom->_pre_order : 0, _dom_depth);
    st->print(" RegPressure: %d",_reg_pressure);
    st->print(" IHRP Index: %d",_ihrp_index);
    st->print(" FRegPressure: %d",_freg_pressure);
    st->print(" FHRP Index: %d",_fhrp_index);
  }
  st->cr();
}

void Block::dump() const {
  dump(NULL);
}

void Block::dump(const PhaseCFG* cfg) const {
  dump_head(cfg);
  for (uint i=0; i< number_of_nodes(); i++) {
    get_node(i)->dump();
  }
  tty->print("\n");
}
#endif

PhaseCFG::PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher)
: Phase(CFG)
, _block_arena(arena)
, _root(root)
, _matcher(matcher)
, _node_to_block_mapping(arena)
, _node_latency(NULL)
#ifndef PRODUCT
, _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining"))
#endif
#ifdef ASSERT
, _raw_oops(arena)
#endif
{
  ResourceMark rm;
  // I'll need a few machine-specific GotoNodes.  Make an Ideal GotoNode,
  // then Match it into a machine-specific Node.  Then clone the machine
  // Node on demand.
  Node *x = new (C) GotoNode(NULL);
  x->init_req(0, x);
  _goto = matcher.match_tree(x);
  assert(_goto != NULL, "");
  _goto->set_req(0,_goto);

  // Build the CFG in Reverse Post Order
  _number_of_blocks = build_cfg();
  _root_block = get_block_for_node(_root);
}

// Build a proper looking CFG.  Make every block begin with either a StartNode
// or a RegionNode.  Make every block end with either a Goto, If or Return.
// The RootNode both starts and ends it's own block.  Do this with a recursive
// backwards walk over the control edges.
uint PhaseCFG::build_cfg() {
  Arena *a = Thread::current()->resource_area();
  VectorSet visited(a);

  // Allocate stack with enough space to avoid frequent realloc
  Node_Stack nstack(a, C->live_nodes() >> 1);
  nstack.push(_root, 0);
  uint sum = 0;                 // Counter for blocks

  while (nstack.is_nonempty()) {
    // node and in's index from stack's top
    // 'np' is _root (see above) or RegionNode, StartNode: we push on stack
    // only nodes which point to the start of basic block (see below).
    Node *np = nstack.node();
    // idx > 0, except for the first node (_root) pushed on stack
    // at the beginning when idx == 0.
    // We will use the condition (idx == 0) later to end the build.
    uint idx = nstack.index();
    Node *proj = np->in(idx);
    const Node *x = proj->is_block_proj();
    // Does the block end with a proper block-ending Node?  One of Return,
    // If or Goto? (This check should be done for visited nodes also).
    if (x == NULL) {                    // Does not end right...
      Node *g = _goto->clone(); // Force it to end in a Goto
      g->set_req(0, proj);
      np->set_req(idx, g);
      x = proj = g;
    }
    if (!visited.test_set(x->_idx)) { // Visit this block once
      // Skip any control-pinned middle'in stuff
      Node *p = proj;
      do {
        proj = p;                   // Update pointer to last Control
        p = p->in(0);               // Move control forward
      } while( !p->is_block_proj() &&
               !p->is_block_start() );
      // Make the block begin with one of Region or StartNode.
      if( !p->is_block_start() ) {
        RegionNode *r = new (C) RegionNode( 2 );
        r->init_req(1, p);         // Insert RegionNode in the way
        proj->set_req(0, r);        // Insert RegionNode in the way
        p = r;
      }
      // 'p' now points to the start of this basic block

      // Put self in array of basic blocks
      Block *bb = new (_block_arena) Block(_block_arena, p);
      map_node_to_block(p, bb);
      map_node_to_block(x, bb);
      if( x != p ) {                // Only for root is x == p
        bb->push_node((Node*)x);
      }
      // Now handle predecessors
      ++sum;                        // Count 1 for self block
      uint cnt = bb->num_preds();
      for (int i = (cnt - 1); i > 0; i-- ) { // For all predecessors
        Node *prevproj = p->in(i);  // Get prior input
        assert( !prevproj->is_Con(), "dead input not removed" );
        // Check to see if p->in(i) is a "control-dependent" CFG edge -
        // i.e., it splits at the source (via an IF or SWITCH) and merges
        // at the destination (via a many-input Region).
        // This breaks critical edges.  The RegionNode to start the block
        // will be added when <p,i> is pulled off the node stack
        if ( cnt > 2 ) {             // Merging many things?
          assert( prevproj== bb->pred(i),"");
          if(prevproj->is_block_proj() != prevproj) { // Control-dependent edge?
            // Force a block on the control-dependent edge
            Node *g = _goto->clone();       // Force it to end in a Goto
            g->set_req(0,prevproj);
            p->set_req(i,g);
          }
        }
        nstack.push(p, i);  // 'p' is RegionNode or StartNode
      }
    } else { // Post-processing visited nodes
      nstack.pop();                 // remove node from stack
      // Check if it the fist node pushed on stack at the beginning.
      if (idx == 0) break;          // end of the build
      // Find predecessor basic block
      Block *pb = get_block_for_node(x);
      // Insert into nodes array, if not already there
      if (!has_block(proj)) {
        assert( x != proj, "" );
        // Map basic block of projection
        map_node_to_block(proj, pb);
        pb->push_node(proj);
      }
      // Insert self as a child of my predecessor block
      pb->_succs.map(pb->_num_succs++, get_block_for_node(np));
      assert( pb->get_node(pb->number_of_nodes() - pb->_num_succs)->is_block_proj(),
              "too many control users, not a CFG?" );
    }
  }
  // Return number of basic blocks for all children and self
  return sum;
}

// Inserts a goto & corresponding basic block between
// block[block_no] and its succ_no'th successor block
void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) {
  // get block with block_no
  assert(block_no < number_of_blocks(), "illegal block number");
  Block* in  = get_block(block_no);
  // get successor block succ_no
  assert(succ_no < in->_num_succs, "illegal successor number");
  Block* out = in->_succs[succ_no];
  // Compute frequency of the new block. Do this before inserting
  // new block in case succ_prob() needs to infer the probability from
  // surrounding blocks.
  float freq = in->_freq * in->succ_prob(succ_no);
  // get ProjNode corresponding to the succ_no'th successor of the in block
  ProjNode* proj = in->get_node(in->number_of_nodes() - in->_num_succs + succ_no)->as_Proj();
  // create region for basic block
  RegionNode* region = new (C) RegionNode(2);
  region->init_req(1, proj);
  // setup corresponding basic block
  Block* block = new (_block_arena) Block(_block_arena, region);
  map_node_to_block(region, block);
  C->regalloc()->set_bad(region->_idx);
  // add a goto node
  Node* gto = _goto->clone(); // get a new goto node
  gto->set_req(0, region);
  // add it to the basic block
  block->push_node(gto);
  map_node_to_block(gto, block);
  C->regalloc()->set_bad(gto->_idx);
  // hook up successor block
  block->_succs.map(block->_num_succs++, out);
  // remap successor's predecessors if necessary
  for (uint i = 1; i < out->num_preds(); i++) {
    if (out->pred(i) == proj) out->head()->set_req(i, gto);
  }
  // remap predecessor's successor to new block
  in->_succs.map(succ_no, block);
  // Set the frequency of the new block
  block->_freq = freq;
  // add new basic block to basic block list
  add_block_at(block_no + 1, block);
}

// Does this block end in a multiway branch that cannot have the default case
// flipped for another case?
static bool no_flip_branch(Block *b) {
  int branch_idx = b->number_of_nodes() - b->_num_succs-1;
  if (branch_idx < 1) {
    return false;
  }
  Node *branch = b->get_node(branch_idx);
  if (branch->is_Catch()) {
    return true;
  }
  if (branch->is_Mach()) {
    if (branch->is_MachNullCheck()) {
      return true;
    }
    int iop = branch->as_Mach()->ideal_Opcode();
    if (iop == Op_FastLock || iop == Op_FastUnlock) {
      return true;
    }
    // Don't flip if branch has an implicit check.
    if (branch->as_Mach()->is_TrapBasedCheckNode()) {
      return true;
    }
  }
  return false;
}

// Check for NeverBranch at block end.  This needs to become a GOTO to the
// true target.  NeverBranch are treated as a conditional branch that always
// goes the same direction for most of the optimizer and are used to give a
// fake exit path to infinite loops.  At this late stage they need to turn
// into Goto's so that when you enter the infinite loop you indeed hang.
void PhaseCFG::convert_NeverBranch_to_Goto(Block *b) {
  // Find true target
  int end_idx = b->end_idx();
  int idx = b->get_node(end_idx+1)->as_Proj()->_con;
  Block *succ = b->_succs[idx];
  Node* gto = _goto->clone(); // get a new goto node
  gto->set_req(0, b->head());
  Node *bp = b->get_node(end_idx);
  b->map_node(gto, end_idx); // Slam over NeverBranch
  map_node_to_block(gto, b);
  C->regalloc()->set_bad(gto->_idx);
  b->pop_node();              // Yank projections
  b->pop_node();              // Yank projections
  b->_succs.map(0,succ);        // Map only successor
  b->_num_succs = 1;
  // remap successor's predecessors if necessary
  uint j;
  for( j = 1; j < succ->num_preds(); j++)
    if( succ->pred(j)->in(0) == bp )
      succ->head()->set_req(j, gto);
  // Kill alternate exit path
  Block *dead = b->_succs[1-idx];
  for( j = 1; j < dead->num_preds(); j++)
    if( dead->pred(j)->in(0) == bp )
      break;
  // Scan through block, yanking dead path from
  // all regions and phis.
  dead->head()->del_req(j);
  for( int k = 1; dead->get_node(k)->is_Phi(); k++ )
    dead->get_node(k)->del_req(j);
}

// Helper function to move block bx to the slot following b_index. Return
// true if the move is successful, otherwise false
bool PhaseCFG::move_to_next(Block* bx, uint b_index) {
  if (bx == NULL) return false;

  // Return false if bx is already scheduled.
  uint bx_index = bx->_pre_order;
  if ((bx_index <= b_index) && (get_block(bx_index) == bx)) {
    return false;
  }

  // Find the current index of block bx on the block list
  bx_index = b_index + 1;
  while (bx_index < number_of_blocks() && get_block(bx_index) != bx) {
    bx_index++;
  }
  assert(get_block(bx_index) == bx, "block not found");

  // If the previous block conditionally falls into bx, return false,
  // because moving bx will create an extra jump.
  for(uint k = 1; k < bx->num_preds(); k++ ) {
    Block* pred = get_block_for_node(bx->pred(k));
    if (pred == get_block(bx_index - 1)) {
      if (pred->_num_succs != 1) {
        return false;
      }
    }
  }

  // Reinsert bx just past block 'b'
  _blocks.remove(bx_index);
  _blocks.insert(b_index + 1, bx);
  return true;
}

// Move empty and uncommon blocks to the end.
void PhaseCFG::move_to_end(Block *b, uint i) {
  int e = b->is_Empty();
  if (e != Block::not_empty) {
    if (e == Block::empty_with_goto) {
      // Remove the goto, but leave the block.
      b->pop_node();
    }
    // Mark this block as a connector block, which will cause it to be
    // ignored in certain functions such as non_connector_successor().
    b->set_connector();
  }
  // Move the empty block to the end, and don't recheck.
  _blocks.remove(i);
  _blocks.push(b);
}

// Set loop alignment for every block
void PhaseCFG::set_loop_alignment() {
  uint last = number_of_blocks();
  assert(get_block(0) == get_root_block(), "");

  for (uint i = 1; i < last; i++) {
    Block* block = get_block(i);
    if (block->head()->is_Loop()) {
      block->set_loop_alignment(block);
    }
  }
}

// Make empty basic blocks to be "connector" blocks, Move uncommon blocks
// to the end.
void PhaseCFG::remove_empty_blocks() {
  // Move uncommon blocks to the end
  uint last = number_of_blocks();
  assert(get_block(0) == get_root_block(), "");

  for (uint i = 1; i < last; i++) {
    Block* block = get_block(i);
    if (block->is_connector()) {
      break;
    }

    // Check for NeverBranch at block end.  This needs to become a GOTO to the
    // true target.  NeverBranch are treated as a conditional branch that
    // always goes the same direction for most of the optimizer and are used
    // to give a fake exit path to infinite loops.  At this late stage they
    // need to turn into Goto's so that when you enter the infinite loop you
    // indeed hang.
    if (block->get_node(block->end_idx())->Opcode() == Op_NeverBranch) {
      convert_NeverBranch_to_Goto(block);
    }

    // Look for uncommon blocks and move to end.
    if (!C->do_freq_based_layout()) {
      if (is_uncommon(block)) {
        move_to_end(block, i);
        last--;                   // No longer check for being uncommon!
        if (no_flip_branch(block)) { // Fall-thru case must follow?
          // Find the fall-thru block
          block = get_block(i);
          move_to_end(block, i);
          last--;
        }
        // backup block counter post-increment
        i--;
      }
    }
  }

  // Move empty blocks to the end
  last = number_of_blocks();
  for (uint i = 1; i < last; i++) {
    Block* block = get_block(i);
    if (block->is_Empty() != Block::not_empty) {
      move_to_end(block, i);
      last--;
      i--;
    }
  } // End of for all blocks
}

Block *PhaseCFG::fixup_trap_based_check(Node *branch, Block *block, int block_pos, Block *bnext) {
  // Trap based checks must fall through to the successor with
  // PROB_ALWAYS.
  // They should be an If with 2 successors.
  assert(branch->is_MachIf(),   "must be If");
  assert(block->_num_succs == 2, "must have 2 successors");

  // Get the If node and the projection for the first successor.
  MachIfNode *iff   = block->get_node(block->number_of_nodes()-3)->as_MachIf();
  ProjNode   *proj0 = block->get_node(block->number_of_nodes()-2)->as_Proj();
  ProjNode   *proj1 = block->get_node(block->number_of_nodes()-1)->as_Proj();
  ProjNode   *projt = (proj0->Opcode() == Op_IfTrue)  ? proj0 : proj1;
  ProjNode   *projf = (proj0->Opcode() == Op_IfFalse) ? proj0 : proj1;

  // Assert that proj0 and succs[0] match up. Similarly for proj1 and succs[1].
  assert(proj0->raw_out(0) == block->_succs[0]->head(), "Mismatch successor 0");
  assert(proj1->raw_out(0) == block->_succs[1]->head(), "Mismatch successor 1");

  ProjNode *proj_always;
  ProjNode *proj_never;
  // We must negate the branch if the implicit check doesn't follow
  // the branch's TRUE path. Then, the new TRUE branch target will
  // be the old FALSE branch target.
  if (iff->_prob <= 2*PROB_NEVER) {   // There are small rounding errors.
    proj_never  = projt;
    proj_always = projf;
  } else {
    // We must negate the branch if the trap doesn't follow the
    // branch's TRUE path. Then, the new TRUE branch target will
    // be the old FALSE branch target.
    proj_never  = projf;
    proj_always = projt;
    iff->negate();
  }
  assert(iff->_prob <= 2*PROB_NEVER, "Trap based checks are expected to trap never!");
  // Map the successors properly
  block->_succs.map(0, get_block_for_node(proj_never ->raw_out(0)));   // The target of the trap.
  block->_succs.map(1, get_block_for_node(proj_always->raw_out(0)));   // The fall through target.

  if (block->get_node(block->number_of_nodes() - block->_num_succs + 1) != proj_always) {
    block->map_node(proj_never,  block->number_of_nodes() - block->_num_succs + 0);
    block->map_node(proj_always, block->number_of_nodes() - block->_num_succs + 1);
  }

  // Place the fall through block after this block.
  Block *bs1 = block->non_connector_successor(1);
  if (bs1 != bnext && move_to_next(bs1, block_pos)) {
    bnext = bs1;
  }
  // If the fall through block still is not the next block, insert a goto.
  if (bs1 != bnext) {
    insert_goto_at(block_pos, 1);
  }
  return bnext;
}

// Fix up the final control flow for basic blocks.
void PhaseCFG::fixup_flow() {
  // Fixup final control flow for the blocks.  Remove jump-to-next
  // block. If neither arm of an IF follows the conditional branch, we
  // have to add a second jump after the conditional.  We place the
  // TRUE branch target in succs[0] for both GOTOs and IFs.
  for (uint i = 0; i < number_of_blocks(); i++) {
    Block* block = get_block(i);
    block->_pre_order = i;          // turn pre-order into block-index

    // Connector blocks need no further processing.
    if (block->is_connector()) {
      assert((i+1) == number_of_blocks() || get_block(i + 1)->is_connector(), "All connector blocks should sink to the end");
      continue;
    }
    assert(block->is_Empty() != Block::completely_empty, "Empty blocks should be connectors");

    Block* bnext = (i < number_of_blocks() - 1) ? get_block(i + 1) : NULL;
    Block* bs0 = block->non_connector_successor(0);

    // Check for multi-way branches where I cannot negate the test to
    // exchange the true and false targets.
    if (no_flip_branch(block)) {
      // Find fall through case - if must fall into its target.
      // Get the index of the branch's first successor.
      int branch_idx = block->number_of_nodes() - block->_num_succs;

      // The branch is 1 before the branch's first successor.
      Node *branch = block->get_node(branch_idx-1);

      // Handle no-flip branches which have implicit checks and which require
      // special block ordering and individual semantics of the 'fall through
      // case'.
      if ((TrapBasedNullChecks || TrapBasedRangeChecks) &&
          branch->is_Mach() && branch->as_Mach()->is_TrapBasedCheckNode()) {
        bnext = fixup_trap_based_check(branch, block, i, bnext);
      } else {
        // Else, default handling for no-flip branches
        for (uint j2 = 0; j2 < block->_num_succs; j2++) {
          const ProjNode* p = block->get_node(branch_idx + j2)->as_Proj();
          if (p->_con == 0) {
            // successor j2 is fall through case
            if (block->non_connector_successor(j2) != bnext) {
              // but it is not the next block => insert a goto
              insert_goto_at(i, j2);
            }
            // Put taken branch in slot 0
            if (j2 == 0 && block->_num_succs == 2) {
              // Flip targets in succs map
              Block *tbs0 = block->_succs[0];
              Block *tbs1 = block->_succs[1];
              block->_succs.map(0, tbs1);
              block->_succs.map(1, tbs0);
            }
            break;
          }
        }
      }

      // Remove all CatchProjs
      for (uint j = 0; j < block->_num_succs; j++) {
        block->pop_node();
      }

    } else if (block->_num_succs == 1) {
      // Block ends in a Goto?
      if (bnext == bs0) {
        // We fall into next block; remove the Goto
        block->pop_node();
      }

    } else if(block->_num_succs == 2) { // Block ends in a If?
      // Get opcode of 1st projection (matches _succs[0])
      // Note: Since this basic block has 2 exits, the last 2 nodes must
      //       be projections (in any order), the 3rd last node must be
      //       the IfNode (we have excluded other 2-way exits such as
      //       CatchNodes already).
      MachNode* iff   = block->get_node(block->number_of_nodes() - 3)->as_Mach();
      ProjNode* proj0 = block->get_node(block->number_of_nodes() - 2)->as_Proj();
      ProjNode* proj1 = block->get_node(block->number_of_nodes() - 1)->as_Proj();

      // Assert that proj0 and succs[0] match up. Similarly for proj1 and succs[1].
      assert(proj0->raw_out(0) == block->_succs[0]->head(), "Mismatch successor 0");
      assert(proj1->raw_out(0) == block->_succs[1]->head(), "Mismatch successor 1");

      Block* bs1 = block->non_connector_successor(1);

      // Check for neither successor block following the current
      // block ending in a conditional. If so, move one of the
      // successors after the current one, provided that the
      // successor was previously unscheduled, but moveable
      // (i.e., all paths to it involve a branch).
      if (!C->do_freq_based_layout() && bnext != bs0 && bnext != bs1) {
        // Choose the more common successor based on the probability
        // of the conditional branch.
        Block* bx = bs0;
        Block* by = bs1;

        // _prob is the probability of taking the true path. Make
        // p the probability of taking successor #1.
        float p = iff->as_MachIf()->_prob;
        if (proj0->Opcode() == Op_IfTrue) {
          p = 1.0 - p;
        }

        // Prefer successor #1 if p > 0.5
        if (p > PROB_FAIR) {
          bx = bs1;
          by = bs0;
        }

        // Attempt the more common successor first
        if (move_to_next(bx, i)) {
          bnext = bx;
        } else if (move_to_next(by, i)) {
          bnext = by;
        }
      }

      // Check for conditional branching the wrong way.  Negate
      // conditional, if needed, so it falls into the following block
      // and branches to the not-following block.

      // Check for the next block being in succs[0].  We are going to branch
      // to succs[0], so we want the fall-thru case as the next block in
      // succs[1].
      if (bnext == bs0) {
        // Fall-thru case in succs[0], so flip targets in succs map
        Block* tbs0 = block->_succs[0];
        Block* tbs1 = block->_succs[1];
        block->_succs.map(0, tbs1);
        block->_succs.map(1, tbs0);
        // Flip projection for each target
        ProjNode* tmp = proj0;
        proj0 = proj1;
        proj1 = tmp;

      } else if(bnext != bs1) {
        // Need a double-branch
        // The existing conditional branch need not change.
        // Add a unconditional branch to the false target.
        // Alas, it must appear in its own block and adding a
        // block this late in the game is complicated.  Sigh.
        insert_goto_at(i, 1);
      }

      // Make sure we TRUE branch to the target
      if (proj0->Opcode() == Op_IfFalse) {
        iff->as_MachIf()->negate();
      }

      block->pop_node();          // Remove IfFalse & IfTrue projections
      block->pop_node();

    } else {
      // Multi-exit block, e.g. a switch statement
      // But we don't need to do anything here
    }
  } // End of for all blocks
}


// postalloc_expand: Expand nodes after register allocation.
//
// postalloc_expand has to be called after register allocation, just
// before output (i.e. scheduling). It only gets called if
// Matcher::require_postalloc_expand is true.
//
// Background:
//
// Nodes that are expandend (one compound node requiring several
// assembler instructions to be implemented split into two or more
// non-compound nodes) after register allocation are not as nice as
// the ones expanded before register allocation - they don't
// participate in optimizations as global code motion. But after
// register allocation we can expand nodes that use registers which
// are not spillable or registers that are not allocated, because the
// old compound node is simply replaced (in its location in the basic
// block) by a new subgraph which does not contain compound nodes any
// more. The scheduler called during output can later on process these
// non-compound nodes.
//
// Implementation:
//
// Nodes requiring postalloc expand are specified in the ad file by using
// a postalloc_expand statement instead of ins_encode. A postalloc_expand
// contains a single call to an encoding, as does an ins_encode
// statement. Instead of an emit() function a postalloc_expand() function
// is generated that doesn't emit assembler but creates a new
// subgraph. The code below calls this postalloc_expand function for each
// node with the appropriate attribute. This function returns the new
// nodes generated in an array passed in the call. The old node,
// potential MachTemps before and potential Projs after it then get
// disconnected and replaced by the new nodes. The instruction
// generating the result has to be the last one in the array. In
// general it is assumed that Projs after the node expanded are
// kills. These kills are not required any more after expanding as
// there are now explicitly visible def-use chains and the Projs are
// removed. This does not hold for calls: They do not only have
// kill-Projs but also Projs defining values. Therefore Projs after
// the node expanded are removed for all but for calls. If a node is
// to be reused, it must be added to the nodes list returned, and it
// will be added again.
//
// Implementing the postalloc_expand function for a node in an enc_class
// is rather tedious. It requires knowledge about many node details, as
// the nodes and the subgraph must be hand crafted. To simplify this,
// adlc generates some utility variables into the postalloc_expand function,
// e.g., holding the operands as specified by the postalloc_expand encoding
// specification, e.g.:
//  * unsigned idx_<par_name>  holding the index of the node in the ins
//  * Node *n_<par_name>       holding the node loaded from the ins
//  * MachOpnd *op_<par_name>  holding the corresponding operand
//
// The ordering of operands can not be determined by looking at a
// rule. Especially if a match rule matches several different trees,
// several nodes are generated from one instruct specification with
// different operand orderings. In this case the adlc generated
// variables are the only way to access the ins and operands
// deterministically.
//
// If assigning a register to a node that contains an oop, don't
// forget to call ra_->set_oop() for the node.
void PhaseCFG::postalloc_expand(PhaseRegAlloc* _ra) {
  GrowableArray <Node *> new_nodes(32); // Array with new nodes filled by postalloc_expand function of node.
  GrowableArray <Node *> remove(32);
  GrowableArray <Node *> succs(32);
  unsigned int max_idx = C->unique();   // Remember to distinguish new from old nodes.
  DEBUG_ONLY(bool foundNode = false);

  // for all blocks
  for (uint i = 0; i < number_of_blocks(); i++) {
    Block *b = _blocks[i];
    // For all instructions in the current block.
    for (uint j = 0; j < b->number_of_nodes(); j++) {
      Node *n = b->get_node(j);
      if (n->is_Mach() && n->as_Mach()->requires_postalloc_expand()) {
#ifdef ASSERT
        if (TracePostallocExpand) {
          if (!foundNode) {
            foundNode = true;
            tty->print("POSTALLOC EXPANDING %d %s\n", C->compile_id(),
                       C->method() ? C->method()->name()->as_utf8() : C->stub_name());
          }
          tty->print("  postalloc expanding "); n->dump();
          if (Verbose) {
            tty->print("    with ins:\n");
            for (uint k = 0; k < n->len(); ++k) {
              if (n->in(k)) { tty->print("        "); n->in(k)->dump(); }
            }
          }
        }
#endif
        new_nodes.clear();
        // Collect nodes that have to be removed from the block later on.
        uint req = n->req();
        remove.clear();
        for (uint k = 0; k < req; ++k) {
          if (n->in(k) && n->in(k)->is_MachTemp()) {
            remove.push(n->in(k)); // MachTemps which are inputs to the old node have to be removed.
            n->in(k)->del_req(0);
            j--;
          }
        }

        // Check whether we can allocate enough nodes. We set a fix limit for
        // the size of postalloc expands with this.
        uint unique_limit = C->unique() + 40;
        if (unique_limit >= _ra->node_regs_max_index()) {
          Compile::current()->record_failure("out of nodes in postalloc expand");
          return;
        }

        // Emit (i.e. generate new nodes).
        n->as_Mach()->postalloc_expand(&new_nodes, _ra);

        assert(C->unique() < unique_limit, "You allocated too many nodes in your postalloc expand.");

        // Disconnect the inputs of the old node.
        //
        // We reuse MachSpillCopy nodes. If we need to expand them, there
        // are many, so reusing pays off. If reused, the node already
        // has the new ins. n must be the last node on new_nodes list.
        if (!n->is_MachSpillCopy()) {
          for (int k = req - 1; k >= 0; --k) {
            n->del_req(k);
          }
        }

#ifdef ASSERT
        // Check that all nodes have proper operands.
        for (int k = 0; k < new_nodes.length(); ++k) {
          if (new_nodes.at(k)->_idx < max_idx || !new_nodes.at(k)->is_Mach()) continue; // old node, Proj ...
          MachNode *m = new_nodes.at(k)->as_Mach();
          for (unsigned int l = 0; l < m->num_opnds(); ++l) {
            if (MachOper::notAnOper(m->_opnds[l])) {
              outputStream *os = tty;
              os->print("Node %s ", m->Name());
              os->print("has invalid opnd %d: %p\n", l, m->_opnds[l]);
              assert(0, "Invalid operands, see inline trace in hs_err_pid file.");
            }
          }
        }
#endif

        // Collect succs of old node in remove (for projections) and in succs (for
        // all other nodes) do _not_ collect projections in remove (but in succs)
        // in case the node is a call. We need the projections for calls as they are
        // associated with registes (i.e. they are defs).
        succs.clear();
        for (DUIterator k = n->outs(); n->has_out(k); k++) {
          if (n->out(k)->is_Proj() && !n->is_MachCall() && !n->is_MachBranch()) {
            remove.push(n->out(k));
          } else {
            succs.push(n->out(k));
          }
        }
        // Replace old node n as input of its succs by last of the new nodes.
        for (int k = 0; k < succs.length(); ++k) {
          Node *succ = succs.at(k);
          for (uint l = 0; l < succ->req(); ++l) {
            if (succ->in(l) == n) {
              succ->set_req(l, new_nodes.at(new_nodes.length() - 1));
            }
          }
          for (uint l = succ->req(); l < succ->len(); ++l) {
            if (succ->in(l) == n) {
              succ->set_prec(l, new_nodes.at(new_nodes.length() - 1));
            }
          }
        }

        // Index of old node in block.
        uint index = b->find_node(n);
        // Insert new nodes into block and map them in nodes->blocks array
        // and remember last node in n2.
        Node *n2 = NULL;
        for (int k = 0; k < new_nodes.length(); ++k) {
          n2 = new_nodes.at(k);
          b->insert_node(n2, ++index);
          map_node_to_block(n2, b);
        }

        // Add old node n to remove and remove them all from block.
        remove.push(n);
        j--;
#ifdef ASSERT
        if (TracePostallocExpand && Verbose) {
          tty->print("    removing:\n");
          for (int k = 0; k < remove.length(); ++k) {
            tty->print("        "); remove.at(k)->dump();
          }
          tty->print("    inserting:\n");
          for (int k = 0; k < new_nodes.length(); ++k) {
            tty->print("        "); new_nodes.at(k)->dump();
          }
        }
#endif
        for (int k = 0; k < remove.length(); ++k) {
          if (b->contains(remove.at(k))) {
            b->find_remove(remove.at(k));
          } else {
            assert(remove.at(k)->is_Proj() && (remove.at(k)->in(0)->is_MachBranch()), "");
          }
        }
        // If anything has been inserted (n2 != NULL), continue after last node inserted.
        // This does not always work. Some postalloc expands don't insert any nodes, if they
        // do optimizations (e.g., max(x,x)). In this case we decrement j accordingly.
        j = n2 ? b->find_node(n2) : j;
      }
    }
  }

#ifdef ASSERT
  if (foundNode) {
    tty->print("FINISHED %d %s\n", C->compile_id(),
               C->method() ? C->method()->name()->as_utf8() : C->stub_name());
    tty->flush();
  }
#endif
}


//------------------------------dump-------------------------------------------
#ifndef PRODUCT
void PhaseCFG::_dump_cfg( const Node *end, VectorSet &visited  ) const {
  const Node *x = end->is_block_proj();
  assert( x, "not a CFG" );

  // Do not visit this block again
  if( visited.test_set(x->_idx) ) return;

  // Skip through this block
  const Node *p = x;
  do {
    p = p->in(0);               // Move control forward
    assert( !p->is_block_proj() || p->is_Root(), "not a CFG" );
  } while( !p->is_block_start() );

  // Recursively visit
  for (uint i = 1; i < p->req(); i++) {
    _dump_cfg(p->in(i), visited);
  }

  // Dump the block
  get_block_for_node(p)->dump(this);
}

void PhaseCFG::dump( ) const {
  tty->print("\n--- CFG --- %d BBs\n", number_of_blocks());
  if (_blocks.size()) {        // Did we do basic-block layout?
    for (uint i = 0; i < number_of_blocks(); i++) {
      const Block* block = get_block(i);
      block->dump(this);
    }
  } else {                      // Else do it with a DFS
    VectorSet visited(_block_arena);
    _dump_cfg(_root,visited);
  }
}

void PhaseCFG::dump_headers() {
  for (uint i = 0; i < number_of_blocks(); i++) {
    Block* block = get_block(i);
    if (block != NULL) {
      block->dump_head(this);
    }
  }
}

void PhaseCFG::verify() const {
#ifdef ASSERT
  // Verify sane CFG
  for (uint i = 0; i < number_of_blocks(); i++) {
    Block* block = get_block(i);
    uint cnt = block->number_of_nodes();
    uint j;
    for (j = 0; j < cnt; j++)  {
      Node *n = block->get_node(j);
      assert(get_block_for_node(n) == block, "");
      if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) {
        assert(j == 1 || block->get_node(j-1)->is_Phi(), "CreateEx must be first instruction in block");
      }
      for (uint k = 0; k < n->req(); k++) {
        Node *def = n->in(k);
        if (def && def != n) {
          assert(get_block_for_node(def) || def->is_Con(), "must have block; constants for debug info ok");
          // Verify that instructions in the block is in correct order.
          // Uses must follow their definition if they are at the same block.
          // Mostly done to check that MachSpillCopy nodes are placed correctly
          // when CreateEx node is moved in build_ifg_physical().
          if (get_block_for_node(def) == block && !(block->head()->is_Loop() && n->is_Phi()) &&
              // See (+++) comment in reg_split.cpp
              !(n->jvms() != NULL && n->jvms()->is_monitor_use(k))) {
            bool is_loop = false;
            if (n->is_Phi()) {
              for (uint l = 1; l < def->req(); l++) {
                if (n == def->in(l)) {
                  is_loop = true;
                  break; // Some kind of loop
                }
              }
            }
            assert(is_loop || block->find_node(def) < j, "uses must follow definitions");
          }
        }
      }
    }

    j = block->end_idx();
    Node* bp = (Node*)block->get_node(block->number_of_nodes() - 1)->is_block_proj();
    assert(bp, "last instruction must be a block proj");
    assert(bp == block->get_node(j), "wrong number of successors for this block");
    if (bp->is_Catch()) {
      while (block->get_node(--j)->is_MachProj()) {
        ;
      }
      assert(block->get_node(j)->is_MachCall(), "CatchProj must follow call");
    } else if (bp->is_Mach() && bp->as_Mach()->ideal_Opcode() == Op_If) {
      assert(block->_num_succs == 2, "Conditional branch must have two targets");
    }
  }
#endif
}
#endif

UnionFind::UnionFind( uint max ) : _cnt(max), _max(max), _indices(NEW_RESOURCE_ARRAY(uint,max)) {
  Copy::zero_to_bytes( _indices, sizeof(uint)*max );
}

void UnionFind::extend( uint from_idx, uint to_idx ) {
  _nesting.check();
  if( from_idx >= _max ) {
    uint size = 16;
    while( size <= from_idx ) size <<=1;
    _indices = REALLOC_RESOURCE_ARRAY( uint, _indices, _max, size );
    _max = size;
  }
  while( _cnt <= from_idx ) _indices[_cnt++] = 0;
  _indices[from_idx] = to_idx;
}

void UnionFind::reset( uint max ) {
  assert( max <= max_uint, "Must fit within uint" );
  // Force the Union-Find mapping to be at least this large
  extend(max,0);
  // Initialize to be the ID mapping.
  for( uint i=0; i<max; i++ ) map(i,i);
}

// Straight out of Tarjan's union-find algorithm
uint UnionFind::Find_compress( uint idx ) {
  uint cur  = idx;
  uint next = lookup(cur);
  while( next != cur ) {        // Scan chain of equivalences
    assert( next < cur, "always union smaller" );
    cur = next;                 // until find a fixed-point
    next = lookup(cur);
  }
  // Core of union-find algorithm: update chain of
  // equivalences to be equal to the root.
  while( idx != next ) {
    uint tmp = lookup(idx);
    map(idx, next);
    idx = tmp;
  }
  return idx;
}

// Like Find above, but no path compress, so bad asymptotic behavior
uint UnionFind::Find_const( uint idx ) const {
  if( idx == 0 ) return idx;    // Ignore the zero idx
  // Off the end?  This can happen during debugging dumps
  // when data structures have not finished being updated.
  if( idx >= _max ) return idx;
  uint next = lookup(idx);
  while( next != idx ) {        // Scan chain of equivalences
    idx = next;                 // until find a fixed-point
    next = lookup(idx);
  }
  return next;
}

// union 2 sets together.
void UnionFind::Union( uint idx1, uint idx2 ) {
  uint src = Find(idx1);
  uint dst = Find(idx2);
  assert( src, "" );
  assert( dst, "" );
  assert( src < _max, "oob" );
  assert( dst < _max, "oob" );
  assert( src < dst, "always union smaller" );
  map(dst,src);
}

#ifndef PRODUCT
void Trace::dump( ) const {
  tty->print_cr("Trace (freq %f)", first_block()->_freq);
  for (Block *b = first_block(); b != NULL; b = next(b)) {
    tty->print("  B%d", b->_pre_order);
    if (b->head()->is_Loop()) {
      tty->print(" (L%d)", b->compute_loop_alignment());
    }
    if (b->has_loop_alignment()) {
      tty->print(" (T%d)", b->code_alignment());
    }
  }
  tty->cr();
}

void CFGEdge::dump( ) const {
  tty->print(" B%d  -->  B%d  Freq: %f  out:%3d%%  in:%3d%%  State: ",
             from()->_pre_order, to()->_pre_order, freq(), _from_pct, _to_pct);
  switch(state()) {
  case connected:
    tty->print("connected");
    break;
  case open:
    tty->print("open");
    break;
  case interior:
    tty->print("interior");
    break;
  }
  if (infrequent()) {
    tty->print("  infrequent");
  }
  tty->cr();
}
#endif

// Comparison function for edges
static int edge_order(CFGEdge **e0, CFGEdge **e1) {
  float freq0 = (*e0)->freq();
  float freq1 = (*e1)->freq();
  if (freq0 != freq1) {
    return freq0 > freq1 ? -1 : 1;
  }

  int dist0 = (*e0)->to()->_rpo - (*e0)->from()->_rpo;
  int dist1 = (*e1)->to()->_rpo - (*e1)->from()->_rpo;

  return dist1 - dist0;
}

// Comparison function for edges
extern "C" int trace_frequency_order(const void *p0, const void *p1) {
  Trace *tr0 = *(Trace **) p0;
  Trace *tr1 = *(Trace **) p1;
  Block *b0 = tr0->first_block();
  Block *b1 = tr1->first_block();

  // The trace of connector blocks goes at the end;
  // we only expect one such trace
  if (b0->is_connector() != b1->is_connector()) {
    return b1->is_connector() ? -1 : 1;
  }

  // Pull more frequently executed blocks to the beginning
  float freq0 = b0->_freq;
  float freq1 = b1->_freq;
  if (freq0 != freq1) {
    return freq0 > freq1 ? -1 : 1;
  }

  int diff = tr0->first_block()->_rpo - tr1->first_block()->_rpo;

  return diff;
}

// Find edges of interest, i.e, those which can fall through. Presumes that
// edges which don't fall through are of low frequency and can be generally
// ignored.  Initialize the list of traces.
void PhaseBlockLayout::find_edges() {
  // Walk the blocks, creating edges and Traces
  uint i;
  Trace *tr = NULL;
  for (i = 0; i < _cfg.number_of_blocks(); i++) {
    Block* b = _cfg.get_block(i);
    tr = new Trace(b, next, prev);
    traces[tr->id()] = tr;

    // All connector blocks should be at the end of the list
    if (b->is_connector()) break;

    // If this block and the next one have a one-to-one successor
    // predecessor relationship, simply append the next block
    int nfallthru = b->num_fall_throughs();
    while (nfallthru == 1 &&
           b->succ_fall_through(0)) {
      Block *n = b->_succs[0];

      // Skip over single-entry connector blocks, we don't want to
      // add them to the trace.
      while (n->is_connector() && n->num_preds() == 1) {
        n = n->_succs[0];
      }

      // We see a merge point, so stop search for the next block
      if (n->num_preds() != 1) break;

      i++;
      assert(n = _cfg.get_block(i), "expecting next block");
      tr->append(n);
      uf->map(n->_pre_order, tr->id());
      traces[n->_pre_order] = NULL;
      nfallthru = b->num_fall_throughs();
      b = n;
    }

    if (nfallthru > 0) {
      // Create a CFGEdge for each outgoing
      // edge that could be a fall-through.
      for (uint j = 0; j < b->_num_succs; j++ ) {
        if (b->succ_fall_through(j)) {
          Block *target = b->non_connector_successor(j);
          float freq = b->_freq * b->succ_prob(j);
          int from_pct = (int) ((100 * freq) / b->_freq);
          int to_pct = (int) ((100 * freq) / target->_freq);
          edges->append(new CFGEdge(b, target, freq, from_pct, to_pct));
        }
      }
    }
  }

  // Group connector blocks into one trace
  for (i++; i < _cfg.number_of_blocks(); i++) {
    Block *b = _cfg.get_block(i);
    assert(b->is_connector(), "connector blocks at the end");
    tr->append(b);
    uf->map(b->_pre_order, tr->id());
    traces[b->_pre_order] = NULL;
  }
}

// Union two traces together in uf, and null out the trace in the list
void PhaseBlockLayout::union_traces(Trace* updated_trace, Trace* old_trace) {
  uint old_id = old_trace->id();
  uint updated_id = updated_trace->id();

  uint lo_id = updated_id;
  uint hi_id = old_id;

  // If from is greater than to, swap values to meet
  // UnionFind guarantee.
  if (updated_id > old_id) {
    lo_id = old_id;
    hi_id = updated_id;

    // Fix up the trace ids
    traces[lo_id] = traces[updated_id];
    updated_trace->set_id(lo_id);
  }

  // Union the lower with the higher and remove the pointer
  // to the higher.
  uf->Union(lo_id, hi_id);
  traces[hi_id] = NULL;
}

// Append traces together via the most frequently executed edges
void PhaseBlockLayout::grow_traces() {
  // Order the edges, and drive the growth of Traces via the most
  // frequently executed edges.
  edges->sort(edge_order);
  for (int i = 0; i < edges->length(); i++) {
    CFGEdge *e = edges->at(i);

    if (e->state() != CFGEdge::open) continue;

    Block *src_block = e->from();
    Block *targ_block = e->to();

    // Don't grow traces along backedges?
    if (!BlockLayoutRotateLoops) {
      if (targ_block->_rpo <= src_block->_rpo) {
        targ_block->set_loop_alignment(targ_block);
        continue;
      }
    }

    Trace *src_trace = trace(src_block);
    Trace *targ_trace = trace(targ_block);

    // If the edge in question can join two traces at their ends,
    // append one trace to the other.
   if (src_trace->last_block() == src_block) {
      if (src_trace == targ_trace) {
        e->set_state(CFGEdge::interior);
        if (targ_trace->backedge(e)) {
          // Reset i to catch any newly eligible edge
          // (Or we could remember the first "open" edge, and reset there)
          i = 0;
        }
      } else if (targ_trace->first_block() == targ_block) {
        e->set_state(CFGEdge::connected);
        src_trace->append(targ_trace);
        union_traces(src_trace, targ_trace);
      }
    }
  }
}

// Embed one trace into another, if the fork or join points are sufficiently
// balanced.
void PhaseBlockLayout::merge_traces(bool fall_thru_only) {
  // Walk the edge list a another time, looking at unprocessed edges.
  // Fold in diamonds
  for (int i = 0; i < edges->length(); i++) {
    CFGEdge *e = edges->at(i);

    if (e->state() != CFGEdge::open) continue;
    if (fall_thru_only) {
      if (e->infrequent()) continue;
    }

    Block *src_block = e->from();
    Trace *src_trace = trace(src_block);
    bool src_at_tail = src_trace->last_block() == src_block;

    Block *targ_block  = e->to();
    Trace *targ_trace  = trace(targ_block);
    bool targ_at_start = targ_trace->first_block() == targ_block;

    if (src_trace == targ_trace) {
      // This may be a loop, but we can't do much about it.
      e->set_state(CFGEdge::interior);
      continue;
    }

    if (fall_thru_only) {
      // If the edge links the middle of two traces, we can't do anything.
      // Mark the edge and continue.
      if (!src_at_tail & !targ_at_start) {
        continue;
      }

      // Don't grow traces along backedges?
      if (!BlockLayoutRotateLoops && (targ_block->_rpo <= src_block->_rpo)) {
          continue;
      }

      // If both ends of the edge are available, why didn't we handle it earlier?
      assert(src_at_tail ^ targ_at_start, "Should have caught this edge earlier.");

      if (targ_at_start) {
        // Insert the "targ" trace in the "src" trace if the insertion point
        // is a two way branch.
        // Better profitability check possible, but may not be worth it.
        // Someday, see if the this "fork" has an associated "join";
        // then make a policy on merging this trace at the fork or join.
        // For example, other things being equal, it may be better to place this
        // trace at the join point if the "src" trace ends in a two-way, but
        // the insertion point is one-way.
        assert(src_block->num_fall_throughs() == 2, "unexpected diamond");
        e->set_state(CFGEdge::connected);
        src_trace->insert_after(src_block, targ_trace);
        union_traces(src_trace, targ_trace);
      } else if (src_at_tail) {
        if (src_trace != trace(_cfg.get_root_block())) {
          e->set_state(CFGEdge::connected);
          targ_trace->insert_before(targ_block, src_trace);
          union_traces(targ_trace, src_trace);
        }
      }
    } else if (e->state() == CFGEdge::open) {
      // Append traces, even without a fall-thru connection.
      // But leave root entry at the beginning of the block list.
      if (targ_trace != trace(_cfg.get_root_block())) {
        e->set_state(CFGEdge::connected);
        src_trace->append(targ_trace);
        union_traces(src_trace, targ_trace);
      }
    }
  }
}

// Order the sequence of the traces in some desirable way, and fixup the
// jumps at the end of each block.
void PhaseBlockLayout::reorder_traces(int count) {
  ResourceArea *area = Thread::current()->resource_area();
  Trace ** new_traces = NEW_ARENA_ARRAY(area, Trace *, count);
  Block_List worklist;
  int new_count = 0;

  // Compact the traces.
  for (int i = 0; i < count; i++) {
    Trace *tr = traces[i];
    if (tr != NULL) {
      new_traces[new_count++] = tr;
    }
  }

  // The entry block should be first on the new trace list.
  Trace *tr = trace(_cfg.get_root_block());
  assert(tr == new_traces[0], "entry trace misplaced");

  // Sort the new trace list by frequency
  qsort(new_traces + 1, new_count - 1, sizeof(new_traces[0]), trace_frequency_order);

  // Patch up the successor blocks
  _cfg.clear_blocks();
  for (int i = 0; i < new_count; i++) {
    Trace *tr = new_traces[i];
    if (tr != NULL) {
      tr->fixup_blocks(_cfg);
    }
  }
}

// Order basic blocks based on frequency
PhaseBlockLayout::PhaseBlockLayout(PhaseCFG &cfg)
: Phase(BlockLayout)
, _cfg(cfg) {
  ResourceMark rm;
  ResourceArea *area = Thread::current()->resource_area();

  // List of traces
  int size = _cfg.number_of_blocks() + 1;
  traces = NEW_ARENA_ARRAY(area, Trace *, size);
  memset(traces, 0, size*sizeof(Trace*));
  next = NEW_ARENA_ARRAY(area, Block *, size);
  memset(next,   0, size*sizeof(Block *));
  prev = NEW_ARENA_ARRAY(area, Block *, size);
  memset(prev  , 0, size*sizeof(Block *));

  // List of edges
  edges = new GrowableArray<CFGEdge*>;

  // Mapping block index --> block_trace
  uf = new UnionFind(size);
  uf->reset(size);

  // Find edges and create traces.
  find_edges();

  // Grow traces at their ends via most frequent edges.
  grow_traces();

  // Merge one trace into another, but only at fall-through points.
  // This may make diamonds and other related shapes in a trace.
  merge_traces(true);

  // Run merge again, allowing two traces to be catenated, even if
  // one does not fall through into the other. This appends loosely
  // related traces to be near each other.
  merge_traces(false);

  // Re-order all the remaining traces by frequency
  reorder_traces(size);

  assert(_cfg.number_of_blocks() >= (uint) (size - 1), "number of blocks can not shrink");
}


// Edge e completes a loop in a trace. If the target block is head of the
// loop, rotate the loop block so that the loop ends in a conditional branch.
bool Trace::backedge(CFGEdge *e) {
  bool loop_rotated = false;
  Block *src_block  = e->from();
  Block *targ_block    = e->to();

  assert(last_block() == src_block, "loop discovery at back branch");
  if (first_block() == targ_block) {
    if (BlockLayoutRotateLoops && last_block()->num_fall_throughs() < 2) {
      // Find the last block in the trace that has a conditional
      // branch.
      Block *b;
      for (b = last_block(); b != NULL; b = prev(b)) {
        if (b->num_fall_throughs() == 2) {
          break;
        }
      }

      if (b != last_block() && b != NULL) {
        loop_rotated = true;

        // Rotate the loop by doing two-part linked-list surgery.
        append(first_block());
        break_loop_after(b);
      }
    }

    // Backbranch to the top of a trace
    // Scroll forward through the trace from the targ_block. If we find
    // a loop head before another loop top, use the the loop head alignment.
    for (Block *b = targ_block; b != NULL; b = next(b)) {
      if (b->has_loop_alignment()) {
        break;
      }
      if (b->head()->is_Loop()) {
        targ_block = b;
        break;
      }
    }

    first_block()->set_loop_alignment(targ_block);

  } else {
    // Backbranch into the middle of a trace
    targ_block->set_loop_alignment(targ_block);
  }

  return loop_rotated;
}

// push blocks onto the CFG list
// ensure that blocks have the correct two-way branch sense
void Trace::fixup_blocks(PhaseCFG &cfg) {
  Block *last = last_block();
  for (Block *b = first_block(); b != NULL; b = next(b)) {
    cfg.add_block(b);
    if (!b->is_connector()) {
      int nfallthru = b->num_fall_throughs();
      if (b != last) {
        if (nfallthru == 2) {
          // Ensure that the sense of the branch is correct
          Block *bnext = next(b);
          Block *bs0 = b->non_connector_successor(0);

          MachNode *iff = b->get_node(b->number_of_nodes() - 3)->as_Mach();
          ProjNode *proj0 = b->get_node(b->number_of_nodes() - 2)->as_Proj();
          ProjNode *proj1 = b->get_node(b->number_of_nodes() - 1)->as_Proj();

          if (bnext == bs0) {
            // Fall-thru case in succs[0], should be in succs[1]

            // Flip targets in _succs map
            Block *tbs0 = b->_succs[0];
            Block *tbs1 = b->_succs[1];
            b->_succs.map( 0, tbs1 );
            b->_succs.map( 1, tbs0 );

            // Flip projections to match targets
            b->map_node(proj1, b->number_of_nodes() - 2);
            b->map_node(proj0, b->number_of_nodes() - 1);
          }
        }
      }
    }
  }
}
