use of com.taobao.android.dx.rop.code.RopMethod in project atlas by alibaba.
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 RopMethod optimizeMinimizeRegisters(RopMethod rmeth, int paramWidth, boolean isStatic, EnumSet<OptionalStep> steps) {
SsaMethod ssaMeth;
RopMethod resultMeth;
ssaMeth = SsaConverter.convertToSsaMethod(this, 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(this, ssaMeth, true);
return resultMeth;
}
use of com.taobao.android.dx.rop.code.RopMethod in project atlas by alibaba.
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 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(this, rmeth, paramWidth, isStatic);
runSsaFormSteps(ssaMeth, steps);
RopMethod resultMeth = SsaToRop.convertToRopMethod(this, 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.taobao.android.dx.rop.code.RopMethod in project atlas by alibaba.
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(optimizer, 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.taobao.android.dx.rop.code.RopMethod in project atlas by alibaba.
the class Ropper method getRopMethod.
/**
* Extracts the resulting {@link RopMethod} from the instance.
*
* @return {@code non-null;} the method object
*/
private RopMethod getRopMethod() {
// Construct the final list of blocks.
int sz = result.size();
BasicBlockList bbl = new BasicBlockList(sz);
for (int i = 0; i < sz; i++) {
bbl.set(i, result.get(i));
}
bbl.setImmutable();
/*
* Note: The parameter assignment block is always the first
* that should be executed, hence the second argument to the
* constructor.
*/
return new RopMethod(bbl, getSpecialLabel(PARAM_ASSIGNMENT));
}
use of com.taobao.android.dx.rop.code.RopMethod in project atlas by alibaba.
the class OptimizerOptions method compareOptimizerStep.
/**
* Compares the output of the optimizer run normally with a run skipping
* some optional steps. Results are printed to stderr.
*
* @param nonOptRmeth {@code non-null;} origional rop method
* @param paramSize {@code >= 0;} parameter size of method
* @param isStatic true if this method has no 'this' pointer argument.
* @param args {@code non-null;} translator arguments
* @param advice {@code non-null;} translation advice
* @param rmeth {@code non-null;} method with all optimization steps run.
*/
public static void compareOptimizerStep(RopMethod nonOptRmeth, int paramSize, boolean isStatic, CfOptions args, TranslationAdvice advice, RopMethod rmeth) {
EnumSet<Optimizer.OptionalStep> steps;
steps = EnumSet.allOf(Optimizer.OptionalStep.class);
// This is the step to skip.
steps.remove(Optimizer.OptionalStep.CONST_COLLECTOR);
RopMethod skipRopMethod = new Optimizer().optimize(nonOptRmeth, paramSize, isStatic, args.localInfo, advice, steps);
int normalInsns = rmeth.getBlocks().getEffectiveInstructionCount();
int skipInsns = skipRopMethod.getBlocks().getEffectiveInstructionCount();
System.err.printf("optimize step regs:(%d/%d/%.2f%%)" + " insns:(%d/%d/%.2f%%)\n", rmeth.getBlocks().getRegCount(), skipRopMethod.getBlocks().getRegCount(), 100.0 * ((skipRopMethod.getBlocks().getRegCount() - rmeth.getBlocks().getRegCount()) / (float) skipRopMethod.getBlocks().getRegCount()), normalInsns, skipInsns, 100.0 * ((skipInsns - normalInsns) / (float) skipInsns));
}
Aggregations