use of com.android.dx.rop.code.RegisterSpecList in project J2ME-Loader by nikita36078.
the class NormalSsaInsn method changeOneSource.
/**
* Changes one of the insn's sources. New source should be of same type
* and category.
*
* @param index {@code >=0;} index of source to change
* @param newSpec spec for new source
*/
public final void changeOneSource(int index, RegisterSpec newSpec) {
RegisterSpecList origSources = insn.getSources();
int sz = origSources.size();
RegisterSpecList newSources = new RegisterSpecList(sz);
for (int i = 0; i < sz; i++) {
newSources.set(i, i == index ? newSpec : origSources.get(i));
}
newSources.setImmutable();
RegisterSpec origSpec = origSources.get(index);
if (origSpec.getReg() != newSpec.getReg()) {
/*
* If the register remains unchanged, we're only changing
* the type or local var name so don't update use list
*/
getBlock().getParent().onSourceChanged(this, origSpec, newSpec);
}
insn = insn.withNewRegisters(getResult(), newSources);
}
use of com.android.dx.rop.code.RegisterSpecList in project J2ME-Loader by nikita36078.
the class NormalSsaInsn method setNewSources.
/**
* Changes the source list of the insn. New source list should be the
* same size and consist of sources of identical types.
*
* @param newSources non-null new sources list.
*/
public final void setNewSources(RegisterSpecList newSources) {
RegisterSpecList origSources = insn.getSources();
if (origSources.size() != newSources.size()) {
throw new RuntimeException("Sources counts don't match");
}
insn = insn.withNewRegisters(getResult(), newSources);
}
use of com.android.dx.rop.code.RegisterSpecList in project J2ME-Loader by nikita36078.
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;
}
use of com.android.dx.rop.code.RegisterSpecList in project J2ME-Loader by nikita36078.
the class SCCP method replaceConstants.
/**
* Replaces TypeBearers in source register specs with constant type
* bearers if possible. These are then referenced in later optimization
* steps.
*/
private void replaceConstants() {
for (int reg = 0; reg < regCount; reg++) {
if (latticeValues[reg] != CONSTANT) {
continue;
}
if (!(latticeConstants[reg] instanceof TypedConstant)) {
// We can't do much with these
continue;
}
SsaInsn defn = ssaMeth.getDefinitionForRegister(reg);
TypeBearer typeBearer = defn.getResult().getTypeBearer();
if (typeBearer.isConstant()) {
/*
* The definition was a constant already.
* The uses should be as well.
*/
continue;
}
// Update the destination RegisterSpec with the constant value
RegisterSpec dest = defn.getResult();
RegisterSpec newDest = dest.withType((TypedConstant) latticeConstants[reg]);
defn.setResult(newDest);
/*
* Update the sources RegisterSpec's of all non-move uses.
* These will be used in later steps.
*/
for (SsaInsn insn : ssaMeth.getUseListForRegister(reg)) {
if (insn.isPhiOrMove()) {
continue;
}
NormalSsaInsn nInsn = (NormalSsaInsn) insn;
RegisterSpecList sources = insn.getSources();
int index = sources.indexOfRegister(reg);
RegisterSpec spec = sources.get(index);
RegisterSpec newSpec = spec.withType((TypedConstant) latticeConstants[reg]);
nInsn.changeOneSource(index, newSpec);
}
}
}
use of com.android.dx.rop.code.RegisterSpecList in project J2ME-Loader by nikita36078.
the class SCCP method simulateMath.
/**
* Simulates math insns, if possible.
*
* @param insn non-null insn to simulate
* @param resultType basic type of the result
* @return constant result or null if not simulatable.
*/
private Constant simulateMath(SsaInsn insn, int resultType) {
Insn ropInsn = insn.getOriginalRopInsn();
int opcode = insn.getOpcode().getOpcode();
RegisterSpecList sources = insn.getSources();
int regA = sources.get(0).getReg();
Constant cA;
Constant cB;
if (latticeValues[regA] != CONSTANT) {
cA = null;
} else {
cA = latticeConstants[regA];
}
if (sources.size() == 1) {
CstInsn cstInsn = (CstInsn) ropInsn;
cB = cstInsn.getConstant();
} else {
/* sources.size() == 2 */
int regB = sources.get(1).getReg();
if (latticeValues[regB] != CONSTANT) {
cB = null;
} else {
cB = latticeConstants[regB];
}
}
if (cA == null || cB == null) {
// TODO handle a constant of 0 with MUL or AND
return null;
}
switch(resultType) {
case Type.BT_INT:
int vR;
boolean skip = false;
int vA = ((CstInteger) cA).getValue();
int vB = ((CstInteger) cB).getValue();
switch(opcode) {
case RegOps.ADD:
vR = vA + vB;
break;
case RegOps.SUB:
// 1 source for reverse sub, 2 sources for regular sub
if (sources.size() == 1) {
vR = vB - vA;
} else {
vR = vA - vB;
}
break;
case RegOps.MUL:
vR = vA * vB;
break;
case RegOps.DIV:
if (vB == 0) {
skip = true;
// just to hide a warning
vR = 0;
} else {
vR = vA / vB;
}
break;
case RegOps.AND:
vR = vA & vB;
break;
case RegOps.OR:
vR = vA | vB;
break;
case RegOps.XOR:
vR = vA ^ vB;
break;
case RegOps.SHL:
vR = vA << vB;
break;
case RegOps.SHR:
vR = vA >> vB;
break;
case RegOps.USHR:
vR = vA >>> vB;
break;
case RegOps.REM:
if (vB == 0) {
skip = true;
// just to hide a warning
vR = 0;
} else {
vR = vA % vB;
}
break;
default:
throw new RuntimeException("Unexpected op");
}
return skip ? null : CstInteger.make(vR);
default:
// not yet supported
return null;
}
}
Aggregations