use of com.taobao.android.dx.rop.code.Rop in project atlas by alibaba.
the class EscapeAnalysis method processRegister.
/**
* Iterate through all the uses of a new object.
*
* @param result {@code non-null;} register where new object is stored
* @param escSet {@code non-null;} EscapeSet for the new object
*/
private void processRegister(RegisterSpec result, EscapeSet escSet) {
ArrayList<RegisterSpec> regWorklist = new ArrayList<RegisterSpec>();
regWorklist.add(result);
// Go through the worklist
while (!regWorklist.isEmpty()) {
int listSize = regWorklist.size() - 1;
RegisterSpec def = regWorklist.remove(listSize);
List<SsaInsn> useList = ssaMeth.getUseListForRegister(def.getReg());
// Handle all the uses of this register
for (SsaInsn use : useList) {
Rop useOpcode = use.getOpcode();
if (useOpcode == null) {
// Handle phis
processPhiUse(use, escSet, regWorklist);
} else {
// Handle other opcodes
processUse(def, use, escSet, regWorklist);
}
}
}
}
use of com.taobao.android.dx.rop.code.Rop in project atlas by alibaba.
the class SCCP method simulateBranch.
/**
* Simulates branch insns, if possible. Adds reachable successor blocks
* to the CFG worklists.
* @param insn branch to simulate
*/
private void simulateBranch(SsaInsn insn) {
Rop opcode = insn.getOpcode();
RegisterSpecList sources = insn.getSources();
boolean constantBranch = false;
boolean constantSuccessor = false;
// Check if the insn is a branch with a constant condition
if (opcode.getBranchingness() == Rop.BRANCH_IF) {
Constant cA = null;
Constant cB = null;
RegisterSpec specA = sources.get(0);
int regA = specA.getReg();
if (!ssaMeth.isRegALocal(specA) && latticeValues[regA] == CONSTANT) {
cA = latticeConstants[regA];
}
if (sources.size() == 2) {
RegisterSpec specB = sources.get(1);
int regB = specB.getReg();
if (!ssaMeth.isRegALocal(specB) && latticeValues[regB] == CONSTANT) {
cB = latticeConstants[regB];
}
}
// Calculate the result of the condition
if (cA != null && sources.size() == 1) {
switch(((TypedConstant) cA).getBasicType()) {
case Type.BT_INT:
constantBranch = true;
int vA = ((CstInteger) cA).getValue();
switch(opcode.getOpcode()) {
case RegOps.IF_EQ:
constantSuccessor = (vA == 0);
break;
case RegOps.IF_NE:
constantSuccessor = (vA != 0);
break;
case RegOps.IF_LT:
constantSuccessor = (vA < 0);
break;
case RegOps.IF_GE:
constantSuccessor = (vA >= 0);
break;
case RegOps.IF_LE:
constantSuccessor = (vA <= 0);
break;
case RegOps.IF_GT:
constantSuccessor = (vA > 0);
break;
default:
throw new RuntimeException("Unexpected op");
}
break;
default:
}
} else if (cA != null && cB != null) {
switch(((TypedConstant) cA).getBasicType()) {
case Type.BT_INT:
constantBranch = true;
int vA = ((CstInteger) cA).getValue();
int vB = ((CstInteger) cB).getValue();
switch(opcode.getOpcode()) {
case RegOps.IF_EQ:
constantSuccessor = (vA == vB);
break;
case RegOps.IF_NE:
constantSuccessor = (vA != vB);
break;
case RegOps.IF_LT:
constantSuccessor = (vA < vB);
break;
case RegOps.IF_GE:
constantSuccessor = (vA >= vB);
break;
case RegOps.IF_LE:
constantSuccessor = (vA <= vB);
break;
case RegOps.IF_GT:
constantSuccessor = (vA > vB);
break;
default:
throw new RuntimeException("Unexpected op");
}
break;
default:
}
}
}
/*
* If condition is constant, add only the target block to the
* worklist. Otherwise, add all successors to the worklist.
*/
SsaBasicBlock block = insn.getBlock();
if (constantBranch) {
int successorBlock;
if (constantSuccessor) {
successorBlock = block.getSuccessorList().get(1);
} else {
successorBlock = block.getSuccessorList().get(0);
}
addBlockToWorklist(ssaMeth.getBlocks().get(successorBlock));
branchWorklist.add(insn);
} else {
for (int i = 0; i < block.getSuccessorList().size(); i++) {
int successorBlock = block.getSuccessorList().get(i);
addBlockToWorklist(ssaMeth.getBlocks().get(successorBlock));
}
}
}
use of com.taobao.android.dx.rop.code.Rop in project atlas by alibaba.
the class NormalSsaInsn method hasSideEffect.
/**
* {@inheritDoc}
*
* TODO: Increase the scope of this.
* @param optimizer
*/
@Override
public boolean hasSideEffect(Optimizer optimizer) {
Rop opcode = getOpcode();
if (opcode.getBranchingness() != Rop.BRANCH_NONE) {
return true;
}
boolean hasLocalSideEffect = optimizer.getPreserveLocals() && getLocalAssignment() != null;
switch(opcode.getOpcode()) {
case RegOps.MOVE_RESULT:
case RegOps.MOVE:
case RegOps.CONST:
return hasLocalSideEffect;
default:
return true;
}
}
use of com.taobao.android.dx.rop.code.Rop in project atlas by alibaba.
the class Ropper method addReturnBlock.
/**
* Constructs and adds the return block, if necessary. The return
* block merely contains an appropriate {@code return}
* instruction.
*/
private void addReturnBlock() {
Rop returnOp = machine.getReturnOp();
if (returnOp == null) {
/*
* The method being converted never returns normally, so there's
* no need for a return block.
*/
return;
}
SourcePosition returnPos = machine.getReturnPosition();
int label = getSpecialLabel(RETURN);
if (isSynchronized()) {
InsnList insns = new InsnList(1);
Insn insn = new ThrowingInsn(Rops.MONITOR_EXIT, returnPos, RegisterSpecList.make(getSynchReg()), StdTypeList.EMPTY);
insns.set(0, insn);
insns.setImmutable();
int nextLabel = getSpecialLabel(SYNCH_RETURN);
BasicBlock bb = new BasicBlock(label, insns, IntList.makeImmutable(nextLabel), nextLabel);
addBlock(bb, IntList.EMPTY);
label = nextLabel;
}
InsnList insns = new InsnList(1);
TypeList sourceTypes = returnOp.getSources();
RegisterSpecList sources;
if (sourceTypes.size() == 0) {
sources = RegisterSpecList.EMPTY;
} else {
RegisterSpec source = RegisterSpec.make(0, sourceTypes.getType(0));
sources = RegisterSpecList.make(source);
}
Insn insn = new PlainInsn(returnOp, returnPos, null, sources);
insns.set(0, insn);
insns.setImmutable();
BasicBlock bb = new BasicBlock(label, insns, IntList.EMPTY, -1);
addBlock(bb, IntList.EMPTY);
}
use of com.taobao.android.dx.rop.code.Rop in project atlas by alibaba.
the class RopToDop method dopFor.
/**
* Returns the dalvik opcode appropriate for the given register-based
* instruction.
*
* @param insn {@code non-null;} the original instruction
* @return the corresponding dalvik opcode; one of the constants in
* {@link Dops}
*/
public static Dop dopFor(Insn insn) {
Rop rop = insn.getOpcode();
/*
* First, just try looking up the rop in the MAP of easy
* cases.
*/
Dop result = MAP.get(rop);
if (result != null) {
return result;
}
switch(rop.getOpcode()) {
case RegOps.MOVE_EXCEPTION:
return Dops.MOVE_EXCEPTION;
case RegOps.INVOKE_STATIC:
return Dops.INVOKE_STATIC;
case RegOps.INVOKE_VIRTUAL:
return Dops.INVOKE_VIRTUAL;
case RegOps.INVOKE_SUPER:
return Dops.INVOKE_SUPER;
case RegOps.INVOKE_DIRECT:
return Dops.INVOKE_DIRECT;
case RegOps.INVOKE_INTERFACE:
return Dops.INVOKE_INTERFACE;
case RegOps.NEW_ARRAY:
return Dops.NEW_ARRAY;
case RegOps.FILLED_NEW_ARRAY:
return Dops.FILLED_NEW_ARRAY;
case RegOps.FILL_ARRAY_DATA:
return Dops.FILL_ARRAY_DATA;
case RegOps.MOVE_RESULT:
{
RegisterSpec resultReg = insn.getResult();
if (resultReg == null) {
return Dops.NOP;
} else {
switch(resultReg.getBasicType()) {
case Type.BT_INT:
case Type.BT_FLOAT:
case Type.BT_BOOLEAN:
case Type.BT_BYTE:
case Type.BT_CHAR:
case Type.BT_SHORT:
return Dops.MOVE_RESULT;
case Type.BT_LONG:
case Type.BT_DOUBLE:
return Dops.MOVE_RESULT_WIDE;
case Type.BT_OBJECT:
return Dops.MOVE_RESULT_OBJECT;
default:
{
throw new RuntimeException("Unexpected basic type");
}
}
}
}
case RegOps.GET_FIELD:
{
CstFieldRef ref = (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
int basicType = ref.getBasicType();
switch(basicType) {
case Type.BT_BOOLEAN:
return Dops.IGET_BOOLEAN;
case Type.BT_BYTE:
return Dops.IGET_BYTE;
case Type.BT_CHAR:
return Dops.IGET_CHAR;
case Type.BT_SHORT:
return Dops.IGET_SHORT;
case Type.BT_INT:
return Dops.IGET;
}
break;
}
case RegOps.PUT_FIELD:
{
CstFieldRef ref = (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
int basicType = ref.getBasicType();
switch(basicType) {
case Type.BT_BOOLEAN:
return Dops.IPUT_BOOLEAN;
case Type.BT_BYTE:
return Dops.IPUT_BYTE;
case Type.BT_CHAR:
return Dops.IPUT_CHAR;
case Type.BT_SHORT:
return Dops.IPUT_SHORT;
case Type.BT_INT:
return Dops.IPUT;
}
break;
}
case RegOps.GET_STATIC:
{
CstFieldRef ref = (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
int basicType = ref.getBasicType();
switch(basicType) {
case Type.BT_BOOLEAN:
return Dops.SGET_BOOLEAN;
case Type.BT_BYTE:
return Dops.SGET_BYTE;
case Type.BT_CHAR:
return Dops.SGET_CHAR;
case Type.BT_SHORT:
return Dops.SGET_SHORT;
case Type.BT_INT:
return Dops.SGET;
}
break;
}
case RegOps.PUT_STATIC:
{
CstFieldRef ref = (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
int basicType = ref.getBasicType();
switch(basicType) {
case Type.BT_BOOLEAN:
return Dops.SPUT_BOOLEAN;
case Type.BT_BYTE:
return Dops.SPUT_BYTE;
case Type.BT_CHAR:
return Dops.SPUT_CHAR;
case Type.BT_SHORT:
return Dops.SPUT_SHORT;
case Type.BT_INT:
return Dops.SPUT;
}
break;
}
case RegOps.CONST:
{
Constant cst = ((ThrowingCstInsn) insn).getConstant();
if (cst instanceof CstType) {
return Dops.CONST_CLASS;
} else if (cst instanceof CstString) {
return Dops.CONST_STRING;
}
break;
}
}
throw new RuntimeException("unknown rop: " + rop);
}
Aggregations