/** Returns a new, optimized code info structure. */
  public CodeInfo getCodeInfo() {
    CodeInfo codeInfo;

    codeInfo =
        new CodeInfo(
            buildInstructionArray(), handlers, buildLineNumberInfo(), buildLocalVariableInfo());

    // replace instruction handles by actual instructions
    try {
      AccessorTransformer transformer =
          new AccessorTransformer() {
            public InstructionAccessor transform(
                InstructionAccessor accessor, AccessorContainer container) {
              // the only accessors to resolve are instruction handles
              return ((InstructionHandle) accessor).getInstruction();
            }
          };

      codeInfo.transformAccessors(transformer);
    } catch (BadAccessorException e) {
      throw new InconsistencyException(e.getMessage()); // !!!!
    }

    return codeInfo;
  }
  /** Install handles around instructions. */
  private InstructionHandle installInstructionHandles(CodeInfo info) {
    Instruction[] insns = info.getInstructions();

    InstructionHandle[] handles = new InstructionHandle[insns.length];
    for (int i = 0; i < handles.length; i++) {
      // this also sets the field next in handles
      handles[i] = new InstructionHandle(insns[i], i == 0 ? null : handles[i - 1]);
    }

    try {
      info.transformAccessors(new HandleCreator(insns, handles));
    } catch (BadAccessorException e) {
      // !!!DEBUG
      dumpCode(insns);
      // !!!DEBUG
      throw new InconsistencyException(e.getMessage()); // !!!!
    }

    return handles[0];
  }
  /**
   * Construct the control flow graph with the information code of a method.
   *
   * @param methodInfo informations on the method
   * @param info informations on the method code
   */
  public ControlFlowGraph(MethodInfo methodInfo, CodeInfo info) {
    this.info = info;
    graph = new Graph();
    subroutines = new HashMap();

    findBasicBlocks();

    generateQInsts(info.getInstructions(), methodInfo);

    constructSSAForm();

    optimize();

    if (DEBUG) {
      for (BasicBlock bb = firstBB; bb != null; bb = bb.getNext()) {
        System.out.println("\n" + bb);
        Iterator insts = bb.getAllSSAInstructions();
        while (insts.hasNext()) {
          QInst inst = (QInst) insts.next();
          System.out.println(inst);
        }
      }
    }
  }
 /** Constructs a new optimizer object. */
 public Optimizer(CodeInfo codeInfo) {
   setCodeStart(installInstructionHandles(codeInfo));
   this.handlers = codeInfo.getHandlers();
   this.localVariables = codeInfo.getLocalVariables();
 }