use of com.taobao.android.dx.rop.code.Rop in project atlas by alibaba.
the class LiteralOpUpgrader method replacePlainInsn.
/**
* Replaces an SsaInsn containing a PlainInsn with a new PlainInsn. The
* new PlainInsn is constructed with a new RegOp and new sources.
*
* TODO move this somewhere else.
*
* @param insn {@code non-null;} an SsaInsn containing a PlainInsn
* @param newSources {@code non-null;} new sources list for new insn
* @param newOpcode A RegOp from {@link RegOps}
* @param cst {@code null-ok;} constant for new instruction, if any
*/
private void replacePlainInsn(NormalSsaInsn insn, RegisterSpecList newSources, int newOpcode, Constant cst) {
Insn originalRopInsn = insn.getOriginalRopInsn();
Rop newRop = Rops.ropFor(newOpcode, insn.getResult(), newSources, cst);
Insn newRopInsn;
if (cst == null) {
newRopInsn = new PlainInsn(newRop, originalRopInsn.getPosition(), insn.getResult(), newSources);
} else {
newRopInsn = new PlainCstInsn(newRop, originalRopInsn.getPosition(), insn.getResult(), newSources, cst);
}
NormalSsaInsn newInsn = new NormalSsaInsn(newRopInsn, insn.getBlock());
List<SsaInsn> insns = insn.getBlock().getInsns();
ssaMeth.onInsnRemoved(insn);
insns.set(insns.lastIndexOf(insn), newInsn);
ssaMeth.onInsnAdded(newInsn);
}
use of com.taobao.android.dx.rop.code.Rop in project atlas by alibaba.
the class LiteralOpUpgrader method tryReplacingWithConstant.
/**
* Tries to replace an instruction with a const instruction. The given
* instruction must have a constant result for it to be replaced.
*
* @param insn {@code non-null;} instruction to try to replace
* @return true if the instruction was replaced
*/
private boolean tryReplacingWithConstant(NormalSsaInsn insn) {
Insn originalRopInsn = insn.getOriginalRopInsn();
Rop opcode = originalRopInsn.getOpcode();
RegisterSpec result = insn.getResult();
if (result != null && !ssaMeth.isRegALocal(result) && opcode.getOpcode() != RegOps.CONST) {
TypeBearer type = insn.getResult().getTypeBearer();
if (type.isConstant() && type.getBasicType() == Type.BT_INT) {
// Replace the instruction with a constant
replacePlainInsn(insn, RegisterSpecList.EMPTY, RegOps.CONST, (Constant) type);
// Remove the source as well if this is a move-result-pseudo
if (opcode.getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {
int pred = insn.getBlock().getPredecessors().nextSetBit(0);
ArrayList<SsaInsn> predInsns = ssaMeth.getBlocks().get(pred).getInsns();
NormalSsaInsn sourceInsn = (NormalSsaInsn) predInsns.get(predInsns.size() - 1);
replacePlainInsn(sourceInsn, RegisterSpecList.EMPTY, RegOps.GOTO, null);
}
return true;
}
}
return false;
}
use of com.taobao.android.dx.rop.code.Rop in project atlas by alibaba.
the class SsaToRop method verifyValidExitPredecessor.
/**
* Validates that a basic block is a valid end predecessor. It must
* end in a RETURN or a THROW. Throws a runtime exception on error.
*
* @param b {@code non-null;} block to validate
* @throws RuntimeException on error
*/
private void verifyValidExitPredecessor(SsaBasicBlock b) {
ArrayList<SsaInsn> insns = b.getInsns();
SsaInsn lastInsn = insns.get(insns.size() - 1);
Rop opcode = lastInsn.getOpcode();
if (opcode.getBranchingness() != Rop.BRANCH_RETURN && opcode != Rops.THROW) {
throw new RuntimeException("Exit predecessor must end" + " in valid exit statement.");
}
}
use of com.taobao.android.dx.rop.code.Rop in project atlas by alibaba.
the class ConstCollector method run.
/**
* Applies the optimization.
*/
private void run() {
int regSz = ssaMeth.getRegCount();
ArrayList<TypedConstant> constantList = getConstsSortedByCountUse();
int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS);
SsaBasicBlock start = ssaMeth.getEntryBlock();
// Constant to new register containing the constant
HashMap<TypedConstant, RegisterSpec> newRegs = new HashMap<TypedConstant, RegisterSpec>(toCollect);
for (int i = 0; i < toCollect; i++) {
TypedConstant cst = constantList.get(i);
RegisterSpec result = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst);
Rop constRop = Rops.opConst(cst);
if (constRop.getBranchingness() == Rop.BRANCH_NONE) {
start.addInsnToHead(new PlainCstInsn(Rops.opConst(cst), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY, cst));
} else {
// We need two new basic blocks along with the new insn
SsaBasicBlock entryBlock = ssaMeth.getEntryBlock();
SsaBasicBlock successorBlock = entryBlock.getPrimarySuccessor();
// Insert a block containing the const insn.
SsaBasicBlock constBlock = entryBlock.insertNewSuccessor(successorBlock);
constBlock.replaceLastInsn(new ThrowingCstInsn(constRop, SourcePosition.NO_INFO, RegisterSpecList.EMPTY, StdTypeList.EMPTY, cst));
// Insert a block containing the move-result-pseudo insn.
SsaBasicBlock resultBlock = constBlock.insertNewSuccessor(successorBlock);
PlainInsn insn = new PlainInsn(Rops.opMoveResultPseudo(result.getTypeBearer()), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY);
resultBlock.addInsnToHead(insn);
}
newRegs.put(cst, result);
}
updateConstUses(newRegs, regSz);
}
use of com.taobao.android.dx.rop.code.Rop in project atlas by alibaba.
the class EscapeAnalysis method insertThrowingInsnBefore.
/**
* Inserts a new ThrowingInsn before the given instruction.
* TODO: move this somewhere more appropriate
*
* @param insn {@code non-null;} instruction to insert before
* @param newSources {@code non-null;} sources of new instruction
* @param newResult {@code non-null;} result of new instruction
* @param newOpcode opcode of new instruction
* @param cst {@code null-ok;} constant for new instruction, if any
*/
private void insertThrowingInsnBefore(SsaInsn insn, RegisterSpecList newSources, RegisterSpec newResult, int newOpcode, Constant cst) {
Insn origRopInsn = insn.getOriginalRopInsn();
Rop newRop = Rops.ropFor(newOpcode, newResult, newSources, cst);
Insn newRopInsn;
if (cst == null) {
newRopInsn = new ThrowingInsn(newRop, origRopInsn.getPosition(), newSources, StdTypeList.EMPTY);
} else {
newRopInsn = new ThrowingCstInsn(newRop, origRopInsn.getPosition(), newSources, StdTypeList.EMPTY, cst);
}
NormalSsaInsn newInsn = new NormalSsaInsn(newRopInsn, insn.getBlock());
List<SsaInsn> insns = insn.getBlock().getInsns();
insns.add(insns.lastIndexOf(insn), newInsn);
ssaMeth.onInsnAdded(newInsn);
}
Aggregations