Пример #1
0
  private void readAll() throws Exception {
    lir_.entry_pc = pc_;

    if (readOp() != SPOpcode.proc) throw new Exception("invalid method, first op must be PROC");

    while (pc_ < (long) file_.code().bytes().length) {
      current_pc_ = pc_;
      SPOpcode op = readOp();
      if (op == SPOpcode.proc) break;
      add(readInstruction(op));
    }

    lir_.exit_pc = pc_;
  }
Пример #2
0
  private LGraph buildBlocks() throws Exception {
    lir_.entry = new LBlock(lir_.entry_pc);
    BlockBuilder builder = new BlockBuilder(lir_);
    LBlock entry = builder.parse();

    // Get an RPO ordering of the blocks, since we don't have predecessors yet.
    LBlock[] blocks = BlockAnalysis.Order(entry);

    // Remove dead references.
    // Ignore blocks that are unreachable and are always jumped over
    // e.g.
    // if(1 != 1)
    //   loop()..
    for (LBlock block : blocks) {
      int numPredecessors = block.numPredecessors();
      for (int i = 0; i < numPredecessors; i++) {
        if (!ContainsBlock(blocks, block.getPredecessor(i))) {
          block.removePredecessor(block.getPredecessor(i));
          numPredecessors--;
        }
      }
    }

    if (!BlockAnalysis.IsReducible(blocks))
      throw new Exception("control flow graph is not reducible");

    // Split critical edges in the graph (is this even needed?)
    BlockAnalysis.SplitCriticalEdges(blocks);

    // Reorder the blocks since we could have introduced new nodes.
    blocks = BlockAnalysis.Order(entry);
    assert (BlockAnalysis.IsReducible(blocks));

    BlockAnalysis.ComputeDominators(blocks);
    BlockAnalysis.ComputeImmediateDominators(blocks);
    BlockAnalysis.ComputeDominatorTree(blocks);
    BlockAnalysis.FindLoops(blocks);

    LGraph graph = new LGraph();
    graph.blocks = blocks;
    graph.entry = blocks[0];
    if (lir_.argDepth > 0) graph.nargs = ((lir_.argDepth - 12) / 4) + 1;
    else graph.nargs = 0;

    return graph;
  }
Пример #3
0
    public LBlock parse() {
      for (int i = 0; i < lir_.instructions.size(); i++) {
        LInstruction ins = lir_.instructions.get(i);

        if (lir_.isTarget(ins.pc())) {
          // This instruction is the target of a basic block, so
          // finish the old one.
          LBlock next = lir_.blockOfTarget(ins.pc());

          // Multiple instructions could be at the same pc,
          // because of decomposition, so make sure we're not
          // transitioning to the same block.
          if (block_ != next) {
            // Add implicit control flow to make further algorithms easier.
            if (block_ != null) {
              assert (!pending_.get(pending_.size() - 1).isControl());
              pending_.add(new LGoto(next));
              next.addPredecessor(block_);
            }

            // Fallthrough to the next block.
            transitionBlocks(next);
          }
        }

        // If there is no block present, we assume this is dead code.
        if (block_ == null) continue;

        pending_.add(ins);

        switch (ins.op()) {
          case Return:
            {
              // A return terminates the current block.
              transitionBlocks(null);
              break;
            }

          case Jump:
            {
              LJump jump = (LJump) ins;
              jump.target().addPredecessor(block_);
              transitionBlocks(null);
              break;
            }

          case JumpCondition:
            {
              LJumpCondition jcc = (LJumpCondition) ins;
              jcc.trueTarget().addPredecessor(block_);
              jcc.falseTarget().addPredecessor(block_);

              // The next iteration will pick the false target up.
              assert (lir_.instructions.get(i + 1).pc() == jcc.falseTarget().pc());
              transitionBlocks(null);
              break;
            }

          case Switch:
            {
              LSwitch switch_ = (LSwitch) ins;
              for (int j = 0; j < switch_.numSuccessors(); j++) {
                switch_.getSuccessor(j).addPredecessor(block_);
              }
              transitionBlocks(null);
              break;
            }

          default:
            break;
        }
      }
      return lir_.entry;
    }
Пример #4
0
 private int trackStack(int offset) {
   if (offset < 0) return offset;
   // 32 is max args
   if (offset > lir_.argDepth && ((offset - 12) / 4) + 1 <= 32) lir_.argDepth = offset;
   return offset;
 }