public LBlock parse() { for (int i = 0; i < lir_.instructions.Count; i++) { LInstruction ins = lir_.instructions[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) { //Debug.Assert(!pending_[pending_.Count - 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 Opcode.Return: { // A return terminates the current block. transitionBlocks(null); break; } case Opcode.Jump: { LJump jump = (LJump)ins; jump.target.addPredecessor(block_); transitionBlocks(null); break; } case Opcode.JumpCondition: { LJumpCondition jcc = (LJumpCondition)ins; jcc.trueTarget.addPredecessor(block_); jcc.falseTarget.addPredecessor(block_); // The next iteration will pick the false target up. //Debug.Assert(lir_.instructions[i + 1].pc == jcc.falseTarget.pc); transitionBlocks(null); break; } case Opcode.Switch: { LSwitch switch_ = (LSwitch)ins; for (int j = 0; j < switch_.numSuccessors; j++) { switch_.getSuccessor(j).addPredecessor(block_); } transitionBlocks(null); break; } } } return(lir_.entry); }
public void setInstructions(LInstruction[] instructions) { instructions_ = instructions; }
private LInstruction add(LInstruction ins) { ins.setPc(current_pc_); lir_.instructions.Add(ins); return(ins); }
private LInstruction add(LInstruction ins) { ins.setPc(current_pc_); lir_.instructions.Add(ins); return ins; }