pruneExceptionalOut();
pruneExceptionalOut(ir);
  public final boolean mergeFallThrough(OPT_IR ir) {    if (getNumberOfNormalOut() != 1) return false; // this has other out edges.    OPT_BasicBlock succBB = (OPT_BasicBlock)next;    if (succBB == null || !pointsOut(succBB)) {       // get the successor from the CFG rather than the code order (case (b))      succBB = getNormalOut().next();      if (succBB.isExit()) return false;      if (succBB.lastRealInstruction() == null ||	  !succBB.lastRealInstruction().isUnconditionalBranch())	return false;    }    if (succBB.isExceptionHandlerBasicBlock()) return false; // must preserve special exception info!    if (succBB.getNumberOfIn() != 1) return false; // succBB has other in edges    // Different in scope Exception handlers?    if (!isExceptionHandlerEquivalent (succBB)) return false;        // There may be a redundant goto at the end of this -- remove it.    // There may also be redundant conditional branches (also to succBB).    // Remove them as well.    // Branch instructions to blocks other than succBB are errors.    if (VM.VerifyAssertions) {      for (OPT_InstructionEnumeration e = enumerateBranchInstructions();           e.hasMoreElements(); ) {        OPT_BasicBlockEnumeration targets = e.next().getBranchTargets();        while (targets.hasMoreElements()) {          VM.assert(targets.next() == succBB);        }      }    }    OPT_Instruction s = this.end.getPrev();    while (s.isBranch()) {      s = s.remove();    }    // splice together the instruction lists of the two basic blocks into    // a single list and update this's BBEND info    this.end.getPrev().linkWithNext(succBB.start.getNext());    end = succBB.end;    BBend.setBlock(end, new OPT_BasicBlockOperand(this));    // Add succBB's CFG sucessors to this's CFG out edges     for (OutEdgeEnum e = succBB.getOut(); e.hasMoreElements(); ) {      OPT_BasicBlock out = e.next();      this.insertOut(out);    }        // Blow away sucBB.    ir.cfg.removeFromCFGAndCodeOrder(succBB);    // Merge misc BB state    setCanThrowExceptions(canThrowExceptions() || succBB.canThrowExceptions());    setMayThrowUncaughtException(mayThrowUncaughtException() || 				 succBB.mayThrowUncaughtException());    setUnsafeToSchedule(isUnsafeToSchedule() || succBB.isUnsafeToSchedule());    if (succBB.getInfrequent()) setInfrequent();    return true;  }    /**   * Convert a block in the FCFG into the equivalent set of    * CFG blocks by splitting the original block into sub-blocks   * at each PEI that reaches at least one exception handelr.   * NOTE: This is sufficient for intraprocedural analysis, since the   * only program point at which the "wrong" answers will    * be computed is the exit node, but is not good enough for   * interprocedural analyses.  To do an interprocedural analysis,   * either the analysis needs to deal with the FCFG or all nodes   * that modify globally visible state must be unfactored.   * @see OPT_IR#unfactor   * @param ir the containing IR object   */  final void unfactor(OPT_IR ir) {    for (OPT_InstructionEnumeration e = forwardRealInstrEnumerator();	 e.hasMoreElements();){      OPT_Instruction s = e.next();      Enumeration expOuts = getApplicableExceptionalOut(s);      if (expOuts.hasMoreElements() && e.hasMoreElements()) {	OPT_BasicBlock next = splitNodeWithLinksAt(s, ir);	next.unfactor(ir);	pruneExceptionalOut();	return;      }    }