/**
  * Remove unreachable code
  *
  * @param ir the IR to optimize
  */
 private void removeUnreachableCode(IR ir) {
   boolean removedCode = false;
   BasicBlock entry = ir.cfg.entry();
   ir.cfg.clearDFS();
   entry.sortDFS();
   for (BasicBlock node = entry; node != null; ) {
     // save it now before removeFromCFGAndCodeOrder nulls it out!!!
     BasicBlock nextNode = (BasicBlock) node.getNext();
     if (!node.dfsVisited()) {
       for (BasicBlockEnumeration e = node.getOut(); e.hasMoreElements(); ) {
         BasicBlock target = e.next();
         if (target != node && !target.isExit() && target.dfsVisited()) {
           SSA.purgeBlockFromPHIs(node, target);
         }
       }
       ir.cfg.removeFromCFGAndCodeOrder(node);
       removedCode = true;
     }
     node = nextNode;
   }
   if (removedCode) {
     ir.cfg.compactNodeNumbering();
     ir.HIRInfo.dominatorTree = null;
     ir.HIRInfo.dominatorsAreComputed = false;
   }
 }
  /**
   * Print the nodes that dominate each basic block
   *
   * @param ir the IR
   */
  private void printResults(IR ir) {
    if (forward) {
      System.out.println(
          "Results of dominators computation for method " + ir.method.getName() + "\n");
      System.out.println("   Here's the CFG:");
      System.out.println(ir.cfg);
      System.out.println("\n\n  Here's the Dominator Info:");
    } else {
      System.out.println(
          "Results of Post-Dominators computation for method " + ir.method.getName() + "\n");
      System.out.println("   Here's the CFG:");
      System.out.println(ir.cfg);
      System.out.println("\n\n  Here's the Post-Dominator Info:");
    }

    for (Enumeration<BasicBlock> bbEnum = cfg.basicBlocks(); bbEnum.hasMoreElements(); ) {
      BasicBlock block = bbEnum.nextElement();
      // We don't compute a result for the exit node for forward direction
      if (!forward || !block.isExit()) {
        System.out.println(
            "Dominators of " + block + ":" + LTDominatorInfo.getInfo(block).dominators(block, ir));
      }
    }
    System.out.println("\n");
  }
  /**
   * The goal of this step is to perform a DFS numbering on the CFG, starting at the root. The exit
   * node is not included.
   */
  private void step1() {
    // allocate the vertex array, one element for each basic block, starting
    // at 1
    vertex = new BasicBlock[cfg.numberOfNodes() + 1];
    DFSCounter = 0;
    if (DEBUG) {
      System.out.println("Initializing blocks:");
    }

    // Initialize each block with an empty set of predecessors and
    // a 0 for a semidominator
    for (Enumeration<BasicBlock> bbEnum = cfg.basicBlocks(); bbEnum.hasMoreElements(); ) {
      BasicBlock block = bbEnum.nextElement();
      // We don't compute a result for the exit node in the forward direction
      if (!forward || !block.isExit()) {
        block.scratchObject = new LTDominatorInfo(block);
        if (DEBUG) {
          printNextNodes(block);
        }
      }
    }

    DFS();

    if (DEBUG) {
      System.out.println("DFSCounter: " + DFSCounter + ", CFG Nodes: " + cfg.numberOfNodes());
      printDFSNumbers();
    }
  }
 /** Print the result of the DFS numbering performed in Step 1 */
 private void printDFSNumbers() {
   for (Enumeration<BasicBlock> bbEnum = cfg.basicBlocks(); bbEnum.hasMoreElements(); ) {
     BasicBlock block = bbEnum.nextElement();
     // We don't compute a result for the exit node for forward direction
     if (forward && block.isExit()) {
       continue;
     }
     LTDominatorInfo info = (LTDominatorInfo) block.scratchObject;
     System.out.println(" " + block + " " + info);
   }
   // Visit each node in reverse DFS order, except for the root, which
   // has number 1
   for (int i = 1; i <= DFSCounter; i++) {
     System.out.println(" Vertex: " + i + " " + vertex[i]);
   }
 }
  /**
   * The non-recursive depth-first numbering code called from Step 1. The recursive version was too
   * costly on the toba benchmark on Linux/IA32.
   *
   * @param block the basic block to process
   */
  protected void DFS(BasicBlock block) {

    // push node on to the emulated activation stack
    push(block);

    recurse:
    while (!empty()) {

      block = peek();
      if (DEBUG) {
        System.out.println(" Processing (peek)" + block);
      }

      if (block == null) {
        if (DEBUG) {
          System.out.println(" Popping");
        }
        pop(); // return
        continue;
      }

      // The current Dominance Frontier and SSA code assumes the exit
      // node will not be part of the (regular) dominator solution.
      // To avoid this from happening we screen it out here for forward CFG
      //
      // However, it really shouldn't be in the CFG, if it isn't a node!
      if (forward && block == cfg.exit()) {
        if (DEBUG) {
          System.out.println(" Popping");
        }
        pop(); // return
        continue;
      }

      BasicBlockEnumeration e;
      e = LTDominatorInfo.getInfo(block).getEnum();

      if (e == null) {
        if (DEBUG) {
          System.out.println(" Initial processing of " + block);
        }

        DFSCounter++;
        LTDominatorInfo.getInfo(block).setSemiDominator(DFSCounter);
        vertex[DFSCounter] = block;
        e = getNextNodes(block);
      } else {
        if (DEBUG) {
          System.out.println(" Resuming processing of " + block);
        }
      }

      while (e.hasMoreElements()) {
        BasicBlock next = e.next();

        if (DEBUG) {
          System.out.println("    Inspecting next node: " + next);
        }

        // We treat the exit node as not being in the CFG for forward direction
        if (forward && next.isExit()) {
          continue; // inner loop
        }
        if (getSemi(next) == 0) {
          LTDominatorInfo.getInfo(next).setParent(block);

          // simulate a recursive call
          // save the enumeration state for resumption later
          LTDominatorInfo.getInfo(block).setEnum(e);

          if (DEBUG) {
            System.out.println(" Pushing" + next);
          }
          push(next);
          continue recurse;
        }
      } // while more nexts
      // "Pop" from the emulated activiation stack
      if (DEBUG) {
        System.out.println(" Popping");
      }
      pop();
    } // while stack not empty loop
  }