use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class Form22b method isCompatible.
/** {@inheritDoc} */
@Override
public boolean isCompatible(DalvInsn insn) {
RegisterSpecList regs = insn.getRegisters();
if (!((insn instanceof CstInsn) && (regs.size() == 2) && unsignedFitsInByte(regs.get(0).getReg()) && unsignedFitsInByte(regs.get(1).getReg()))) {
return false;
}
CstInsn ci = (CstInsn) insn;
Constant cst = ci.getConstant();
if (!(cst instanceof CstLiteralBits)) {
return false;
}
CstLiteralBits cb = (CstLiteralBits) cst;
return cb.fitsInInt() && signedFitsInByte(cb.getIntBits());
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class DeadCodeRemover method run.
/**
* Runs the dead code remover.
*/
private void run() {
pruneDeadInstructions();
HashSet<SsaInsn> deletedInsns = new HashSet<SsaInsn>();
ssaMeth.forEachInsn(new NoSideEffectVisitor(worklist));
int regV;
while (0 <= (regV = worklist.nextSetBit(0))) {
worklist.clear(regV);
if (useList[regV].size() == 0 || isCircularNoSideEffect(regV, null)) {
SsaInsn insnS = ssaMeth.getDefinitionForRegister(regV);
// This insn has already been deleted.
if (deletedInsns.contains(insnS)) {
continue;
}
RegisterSpecList sources = insnS.getSources();
int sz = sources.size();
for (int i = 0; i < sz; i++) {
// Delete this insn from all usage lists.
RegisterSpec source = sources.get(i);
useList[source.getReg()].remove(insnS);
if (!hasSideEffect(ssaMeth.getDefinitionForRegister(source.getReg()))) {
/*
* Only registers whose definition has no side effect
* should be added back to the worklist.
*/
worklist.set(source.getReg());
}
}
// Schedule this insn for later deletion.
deletedInsns.add(insnS);
}
}
ssaMeth.deleteInsns(deletedInsns);
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class EscapeAnalysis method processUse.
/**
* Handles non-phi uses of new objects. Checks to see how instruction is
* used and updates the escape state accordingly.
*
* @param def {@code non-null;} register holding definition of new object
* @param use {@code non-null;} use of object being processed
* @param escSet {@code non-null;} EscapeSet for the object
* @param regWorklist {@code non-null;} worklist of instructions left to
* process for this object
*/
private void processUse(RegisterSpec def, SsaInsn use, EscapeSet escSet, ArrayList<RegisterSpec> regWorklist) {
int useOpcode = use.getOpcode().getOpcode();
switch(useOpcode) {
case RegOps.MOVE:
// Follow uses of the move by adding it to the worklist
escSet.regSet.set(use.getResult().getReg());
regWorklist.add(use.getResult());
break;
case RegOps.IF_EQ:
case RegOps.IF_NE:
case RegOps.CHECK_CAST:
// Compared objects can't be replaced, so promote if necessary
if (escSet.escape.compareTo(EscapeState.METHOD) < 0) {
escSet.escape = EscapeState.METHOD;
}
break;
case RegOps.APUT:
// For array puts, check for a constant array index
RegisterSpec putIndex = use.getSources().get(2);
if (!putIndex.getTypeBearer().isConstant()) {
// If not constant, array can't be replaced
escSet.replaceableArray = false;
}
// Intentional fallthrough
case RegOps.PUT_FIELD:
// Skip non-object puts
RegisterSpec putValue = use.getSources().get(0);
if (putValue.getTypeBearer().getBasicType() != Type.BT_OBJECT) {
break;
}
escSet.replaceableArray = false;
// Raise 1st object's escape state to 2nd if 2nd is higher
RegisterSpecList sources = use.getSources();
if (sources.get(0).getReg() == def.getReg()) {
int setIndex = findSetIndex(sources.get(1));
if (setIndex != latticeValues.size()) {
EscapeSet parentSet = latticeValues.get(setIndex);
addEdge(parentSet, escSet);
if (escSet.escape.compareTo(parentSet.escape) < 0) {
escSet.escape = parentSet.escape;
}
}
} else {
int setIndex = findSetIndex(sources.get(0));
if (setIndex != latticeValues.size()) {
EscapeSet childSet = latticeValues.get(setIndex);
addEdge(escSet, childSet);
if (childSet.escape.compareTo(escSet.escape) < 0) {
childSet.escape = escSet.escape;
}
}
}
break;
case RegOps.AGET:
// For array gets, check for a constant array index
RegisterSpec getIndex = use.getSources().get(1);
if (!getIndex.getTypeBearer().isConstant()) {
// If not constant, array can't be replaced
escSet.replaceableArray = false;
}
break;
case RegOps.PUT_STATIC:
// Static puts cause an object to escape globally
escSet.escape = EscapeState.GLOBAL;
break;
case RegOps.INVOKE_STATIC:
case RegOps.INVOKE_VIRTUAL:
case RegOps.INVOKE_SUPER:
case RegOps.INVOKE_DIRECT:
case RegOps.INVOKE_INTERFACE:
case RegOps.RETURN:
case RegOps.THROW:
// These operations cause an object to escape interprocedurally
escSet.escape = EscapeState.INTER;
break;
default:
break;
}
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class EscapeAnalysis method replaceUse.
/**
* Replaces the use for a scalar replaceable array. Gets and puts become
* move instructions, and array lengths and fills are handled. Can also
* identify ArrayIndexOutOfBounds exceptions and throw them if detected.
*
* @param use {@code non-null;} move result instruction for array
* @param prev {@code non-null;} instruction for instantiating new array
* @param newRegs {@code non-null;} mapping of array indices to new
* registers
* @param deletedInsns {@code non-null;} set of instructions marked for
* deletion
*/
private void replaceUse(SsaInsn use, SsaInsn prev, ArrayList<RegisterSpec> newRegs, HashSet<SsaInsn> deletedInsns) {
int index;
int length = newRegs.size();
SsaInsn next;
RegisterSpecList sources;
RegisterSpec source, result;
CstLiteralBits indexReg;
switch(use.getOpcode().getOpcode()) {
case RegOps.AGET:
// Replace array gets with moves
next = getMoveForInsn(use);
sources = use.getSources();
indexReg = ((CstLiteralBits) sources.get(1).getTypeBearer());
index = indexReg.getIntBits();
if (index < length) {
source = newRegs.get(index);
result = source.withReg(next.getResult().getReg());
insertPlainInsnBefore(next, RegisterSpecList.make(source), result, RegOps.MOVE, null);
} else {
// Throw an exception if the index is out of bounds
insertExceptionThrow(next, sources.get(1), deletedInsns);
deletedInsns.add(next.getBlock().getInsns().get(2));
}
deletedInsns.add(next);
break;
case RegOps.APUT:
// Replace array puts with moves
sources = use.getSources();
indexReg = ((CstLiteralBits) sources.get(2).getTypeBearer());
index = indexReg.getIntBits();
if (index < length) {
source = sources.get(0);
result = source.withReg(newRegs.get(index).getReg());
insertPlainInsnBefore(use, RegisterSpecList.make(source), result, RegOps.MOVE, null);
// Update the newReg entry to mark value as unknown now
newRegs.set(index, result.withSimpleType());
} else {
// Throw an exception if the index is out of bounds
insertExceptionThrow(use, sources.get(2), deletedInsns);
}
break;
case RegOps.ARRAY_LENGTH:
// Replace array lengths with const instructions
TypeBearer lengthReg = prev.getSources().get(0).getTypeBearer();
//CstInteger lengthReg = CstInteger.make(length);
next = getMoveForInsn(use);
insertPlainInsnBefore(next, RegisterSpecList.EMPTY, next.getResult(), RegOps.CONST, (Constant) lengthReg);
deletedInsns.add(next);
break;
case RegOps.MARK_LOCAL:
// Remove mark local instructions
break;
case RegOps.FILL_ARRAY_DATA:
// Create const instructions for each fill value
Insn ropUse = use.getOriginalRopInsn();
FillArrayDataInsn fill = (FillArrayDataInsn) ropUse;
ArrayList<Constant> constList = fill.getInitValues();
for (int i = 0; i < length; i++) {
RegisterSpec newFill = RegisterSpec.make(newRegs.get(i).getReg(), (TypeBearer) constList.get(i));
insertPlainInsnBefore(use, RegisterSpecList.EMPTY, newFill, RegOps.CONST, constList.get(i));
// Update the newRegs to hold the new const value
newRegs.set(i, newFill);
}
break;
default:
}
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class PhiInsn method getSources.
/**
* Gets sources. Constructed lazily from phi operand data structures and
* then cached.
*
* @return {@code non-null;} sources list
*/
@Override
public RegisterSpecList getSources() {
if (sources != null) {
return sources;
}
if (operands.size() == 0) {
// How'd this happen? A phi insn with no operand?
return RegisterSpecList.EMPTY;
}
int szSources = operands.size();
sources = new RegisterSpecList(szSources);
for (int i = 0; i < szSources; i++) {
Operand o = operands.get(i);
sources.set(i, o.regSpec);
}
sources.setImmutable();
return sources;
}
Aggregations