Example #1
0
void do_DFS (struct node *tree) 
// Perform a depth-first traversal of the given suffix tree
// and store the string depths of the nodes in the order visited.
{
	struct node *curr;
	if (tree) {
		curr = tree -> leftchild;
		while (curr) {
			do_DFS (curr);
			curr = curr -> rightsib;
		}
		if (tree -> sfxnum == -1) {
			++numints;
		} else {
			++numleaves;
		}
	}
}
Example #2
0
// Compute the dominator tree of the CFG.  The CFG must already have been
// constructed.  This is the Lengauer & Tarjan O(E-alpha(E,V)) algorithm.
void PhaseCFG::build_dominator_tree() {
  // Pre-grow the blocks array, prior to the ResourceMark kicking in
  _blocks.map(number_of_blocks(), 0);

  ResourceMark rm;
  // Setup mappings from my Graph to Tarjan's stuff and back
  // Note: Tarjan uses 1-based arrays
  Tarjan* tarjan = NEW_RESOURCE_ARRAY(Tarjan, number_of_blocks() + 1);

  // Tarjan's algorithm, almost verbatim:
  // Step 1:
  uint dfsnum = do_DFS(tarjan, number_of_blocks());
  if (dfsnum - 1 != number_of_blocks()) { // Check for unreachable loops!
    // If the returned dfsnum does not match the number of blocks, then we
    // must have some unreachable loops.  These can be made at any time by
    // IterGVN.  They are cleaned up by CCP or the loop opts, but the last
    // IterGVN can always make more that are not cleaned up.  Highly unlikely
    // except in ZKM.jar, where endless irreducible loops cause the loop opts
    // to not get run.
    //
    // Having found unreachable loops, we have made a bad RPO _block layout.
    // We can re-run the above DFS pass with the correct number of blocks,
    // and hack the Tarjan algorithm below to be robust in the presence of
    // such dead loops (as was done for the NTarjan code farther below).
    // Since this situation is so unlikely, instead I've decided to bail out.
    // CNC 7/24/2001
    C->record_method_not_compilable("unreachable loop");
    return;
  }
  _blocks._cnt = number_of_blocks();

  // Tarjan is using 1-based arrays, so these are some initialize flags
  tarjan[0]._size = tarjan[0]._semi = 0;
  tarjan[0]._label = &tarjan[0];

  for (uint i = number_of_blocks(); i >= 2; i--) { // For all vertices in DFS order
    Tarjan *w = &tarjan[i];     // Get vertex from DFS

    // Step 2:
    Node *whead = w->_block->head();
    for (uint j = 1; j < whead->req(); j++) {
      Block* b = get_block_for_node(whead->in(j));
      Tarjan *vx = &tarjan[b->_pre_order];
      Tarjan *u = vx->EVAL();
      if( u->_semi < w->_semi )
        w->_semi = u->_semi;
    }

    // w is added to a bucket here, and only here.
    // Thus w is in at most one bucket and the sum of all bucket sizes is O(n).
    // Thus bucket can be a linked list.
    // Thus we do not need a small integer name for each Block.
    w->_bucket = tarjan[w->_semi]._bucket;
    tarjan[w->_semi]._bucket = w;

    w->_parent->LINK( w, &tarjan[0] );

    // Step 3:
    for( Tarjan *vx = w->_parent->_bucket; vx; vx = vx->_bucket ) {
      Tarjan *u = vx->EVAL();
      vx->_dom = (u->_semi < vx->_semi) ? u : w->_parent;
    }
  }

  // Step 4:
  for (uint i = 2; i <= number_of_blocks(); i++) {
    Tarjan *w = &tarjan[i];
    if( w->_dom != &tarjan[w->_semi] )
      w->_dom = w->_dom->_dom;
    w->_dom_next = w->_dom_child = NULL;  // Initialize for building tree later
  }
  // No immediate dominator for the root
  Tarjan *w = &tarjan[get_root_block()->_pre_order];
  w->_dom = NULL;
  w->_dom_next = w->_dom_child = NULL;  // Initialize for building tree later

  // Convert the dominator tree array into my kind of graph
  for(uint i = 1; i <= number_of_blocks(); i++){ // For all Tarjan vertices
    Tarjan *t = &tarjan[i];     // Handy access
    Tarjan *tdom = t->_dom;     // Handy access to immediate dominator
    if( tdom )  {               // Root has no immediate dominator
      t->_block->_idom = tdom->_block; // Set immediate dominator
      t->_dom_next = tdom->_dom_child; // Make me a sibling of parent's child
      tdom->_dom_child = t;     // Make me a child of my parent
    } else
      t->_block->_idom = NULL;  // Root
  }
  w->setdepth(number_of_blocks() + 1); // Set depth in dominator tree

}