use of com.android.dx.rop.code.RopMethod in project buck by facebook.
the class Optimizer method optimize.
/**
* Runs optimization algorthims over this method, and returns a new
* instance of RopMethod with the changes.
*
* @param rmeth method to process
* @param paramWidth the total width, in register-units, of this method's
* parameters
* @param isStatic true if this method has no 'this' pointer argument.
* @param inPreserveLocals true if local variable info should be preserved,
* at the cost of some registers and insns
* @param inAdvice {@code non-null;} translation advice
* @param steps set of optional optimization steps to run
* @return optimized method
*/
public static RopMethod optimize(RopMethod rmeth, int paramWidth, boolean isStatic, boolean inPreserveLocals, TranslationAdvice inAdvice, EnumSet<OptionalStep> steps) {
SsaMethod ssaMeth = null;
preserveLocals = inPreserveLocals;
advice = inAdvice;
ssaMeth = SsaConverter.convertToSsaMethod(rmeth, paramWidth, isStatic);
runSsaFormSteps(ssaMeth, steps);
RopMethod resultMeth = SsaToRop.convertToRopMethod(ssaMeth, false);
if (resultMeth.getBlocks().getRegCount() > advice.getMaxOptimalRegisterCount()) {
// Try to see if we can squeeze it under the register count bar
resultMeth = optimizeMinimizeRegisters(rmeth, paramWidth, isStatic, steps);
}
return resultMeth;
}
use of com.android.dx.rop.code.RopMethod in project buck by facebook.
the class Optimizer method optimizeMinimizeRegisters.
/**
* Runs the optimizer with a strategy to minimize the number of rop-form
* registers used by the end result. Dex bytecode does not have instruction
* forms that take register numbers larger than 15 for all instructions.
* If we've produced a method that uses more than 16 registers, try again
* with a different strategy to see if we can get under the bar. The end
* result will be much more efficient.
*
* @param rmeth method to process
* @param paramWidth the total width, in register-units, of this method's
* parameters
* @param isStatic true if this method has no 'this' pointer argument.
* @param steps set of optional optimization steps to run
* @return optimized method
*/
private static RopMethod optimizeMinimizeRegisters(RopMethod rmeth, int paramWidth, boolean isStatic, EnumSet<OptionalStep> steps) {
SsaMethod ssaMeth;
RopMethod resultMeth;
ssaMeth = SsaConverter.convertToSsaMethod(rmeth, paramWidth, isStatic);
EnumSet<OptionalStep> newSteps = steps.clone();
/*
* CONST_COLLECTOR trades insns for registers, which is not an
* appropriate strategy here.
*/
newSteps.remove(OptionalStep.CONST_COLLECTOR);
runSsaFormSteps(ssaMeth, newSteps);
resultMeth = SsaToRop.convertToRopMethod(ssaMeth, true);
return resultMeth;
}
use of com.android.dx.rop.code.RopMethod in project J2ME-Loader by nikita36078.
the class IdenticalBlockCombiner method process.
/**
* Runs algorithm. TODO: This is n^2, and could be made linear-ish with
* a hash. In particular, hash the contents of each block and only
* compare blocks with the same hash.
*
* @return {@code non-null;} new method that has been processed
*/
public RopMethod process() {
int szBlocks = blocks.size();
// indexed by label
BitSet toDelete = new BitSet(blocks.getMaxLabel());
// For each non-deleted block...
for (int bindex = 0; bindex < szBlocks; bindex++) {
BasicBlock b = blocks.get(bindex);
if (toDelete.get(b.getLabel())) {
// doomed block
continue;
}
IntList preds = ropMethod.labelToPredecessors(b.getLabel());
// ...look at all of it's predecessors that have only one succ...
int szPreds = preds.size();
for (int i = 0; i < szPreds; i++) {
int iLabel = preds.get(i);
BasicBlock iBlock = blocks.labelToBlock(iLabel);
if (toDelete.get(iLabel) || iBlock.getSuccessors().size() > 1 || iBlock.getFirstInsn().getOpcode().getOpcode() == RegOps.MOVE_RESULT) {
continue;
}
IntList toCombine = new IntList();
// ...and see if they can be combined with any other preds...
for (int j = i + 1; j < szPreds; j++) {
int jLabel = preds.get(j);
BasicBlock jBlock = blocks.labelToBlock(jLabel);
if (jBlock.getSuccessors().size() == 1 && compareInsns(iBlock, jBlock)) {
toCombine.add(jLabel);
toDelete.set(jLabel);
}
}
combineBlocks(iLabel, toCombine);
}
}
for (int i = szBlocks - 1; i >= 0; i--) {
if (toDelete.get(newBlocks.get(i).getLabel())) {
newBlocks.set(i, null);
}
}
newBlocks.shrinkToFit();
newBlocks.setImmutable();
return new RopMethod(newBlocks, ropMethod.getFirstLabel());
}
use of com.android.dx.rop.code.RopMethod in project J2ME-Loader by nikita36078.
the class SsaToRop method convert.
/**
* Performs the conversion.
*
* @return {@code non-null;} rop-form output
*/
private RopMethod convert() {
if (DEBUG) {
interference.dumpToStdout();
}
// These are other allocators for debugging or historical comparison:
// allocator = new NullRegisterAllocator(ssaMeth, interference);
// allocator = new FirstFitAllocator(ssaMeth, interference);
RegisterAllocator allocator = new FirstFitLocalCombiningAllocator(ssaMeth, interference, minimizeRegisters);
RegisterMapper mapper = allocator.allocateRegisters();
if (DEBUG) {
System.out.println("Printing reg map");
System.out.println(((BasicRegisterMapper) mapper).toHuman());
}
ssaMeth.setBackMode();
ssaMeth.mapRegisters(mapper);
removePhiFunctions();
if (allocator.wantsParamsMovedHigh()) {
moveParametersToHighRegisters();
}
removeEmptyGotos();
RopMethod ropMethod = new RopMethod(convertBasicBlocks(), ssaMeth.blockIndexToRopLabel(ssaMeth.getEntryBlockIndex()));
ropMethod = new IdenticalBlockCombiner(ropMethod).process();
return ropMethod;
}
use of com.android.dx.rop.code.RopMethod in project buck by facebook.
the class IdenticalBlockCombiner method process.
/**
* Runs algorithm. TODO: This is n^2, and could be made linear-ish with
* a hash. In particular, hash the contents of each block and only
* compare blocks with the same hash.
*
* @return {@code non-null;} new method that has been processed
*/
public RopMethod process() {
int szBlocks = blocks.size();
// indexed by label
BitSet toDelete = new BitSet(blocks.getMaxLabel());
// For each non-deleted block...
for (int bindex = 0; bindex < szBlocks; bindex++) {
BasicBlock b = blocks.get(bindex);
if (toDelete.get(b.getLabel())) {
// doomed block
continue;
}
IntList preds = ropMethod.labelToPredecessors(b.getLabel());
// ...look at all of it's predecessors that have only one succ...
int szPreds = preds.size();
for (int i = 0; i < szPreds; i++) {
int iLabel = preds.get(i);
BasicBlock iBlock = blocks.labelToBlock(iLabel);
if (toDelete.get(iLabel) || iBlock.getSuccessors().size() > 1 || iBlock.getFirstInsn().getOpcode().getOpcode() == RegOps.MOVE_RESULT) {
continue;
}
IntList toCombine = new IntList();
// ...and see if they can be combined with any other preds...
for (int j = i + 1; j < szPreds; j++) {
int jLabel = preds.get(j);
BasicBlock jBlock = blocks.labelToBlock(jLabel);
if (jBlock.getSuccessors().size() == 1 && compareInsns(iBlock, jBlock)) {
toCombine.add(jLabel);
toDelete.set(jLabel);
}
}
combineBlocks(iLabel, toCombine);
}
}
for (int i = szBlocks - 1; i >= 0; i--) {
if (toDelete.get(newBlocks.get(i).getLabel())) {
newBlocks.set(i, null);
}
}
newBlocks.shrinkToFit();
newBlocks.setImmutable();
return new RopMethod(newBlocks, ropMethod.getFirstLabel());
}
Aggregations