/** * Helper method to perform optimizations around jumps when we get a labeling operation. Shared * with labelNext and labelCurrent methods * * @param l the Label object passed into the label operation * @param kind what kind of labeling operation are we doing (labelNext or labelCurrent) */ private void jumpOptimizations(Label l, LabelKind kind) { // Need to start looking at different indexes for label current vs. label next // this is because for a label next, the next instruction won't have come in yet. int idx = kind == LabelKind.LABEL_CURRENT ? 1 : 0; InstructionInfo prev = previous(idx); switch (prev.getOpcode()) { case OP_jump: { InstructionInfo prev2 = previous(idx + 1); Instruction insn = prev2.getInstruction(); if (insn != null && insn.isBranch() && insn.getTarget() == l) { // If the previous instructions were an if that jumped here, and it // only jumped over another jump, then we can invert the if instruction // and save a jump // iffalse L1, jump L2, L1 -> iftrue L2, L1 Instruction newIf = invertIf(prev2, prev); if (newIf != null) { if (kind == LabelKind.LABEL_CURRENT) { // labelCurrent, so we need to preserve the last instruction Instruction[] newInsns = {newIf, previous(0).getInstruction()}; replace(idx + 1, newInsns); } else { // labelNext so we can just delete the last instruction replace(idx + 1, newIf); } } } // If the previous instruction was a jump, and it just jumped // to the next instruction, then we can remove the jump and just fall // through // jump L1, L1 -> L1 else if (prev.getOperand(0) == l) { if (kind == LabelKind.LABEL_NEXT) // can just delete the jump because we don't have the next instruction yet delete(idx); else // replace the jump with its target replace(idx, previous(0).getInstruction()); } } } }
/** @return the immediate for the instruction, or -1 if there is no instruction */ public int getImmediate() { return insn != null ? insn.getImmediate() : -1; }
/** * Get the operand at index i from the underlying instruction * * @param i the index of the operand to fetch * @return the operand at index i, or null if there is no instruction */ public Object getOperand(int i) { return insn != null ? insn.getOperand(i) : null; }
/** @return the opcode of the Instruction, or -1 if there is no instruction */ public int getOpcode() { return insn != null ? insn.getOpcode() : -1; }