Methods Summary |
---|
public abstract com.android.dx.ssa.RegisterMapper | allocateRegisters()Runs the algorithm.
|
protected int | getCategoryForSsaReg(int reg)Returns the category (width) of the definition site of the register.
Returns 1 for undefined registers.
SsaInsn definition;
definition = ssaMeth.getDefinitionForRegister(reg);
if (definition == null) {
// an undefined reg
return 1;
} else {
return definition.getResult().getCategory();
}
|
protected com.android.dx.rop.code.RegisterSpec | getDefinitionSpecForSsaReg(int reg)Returns the RegisterSpec of the definition of the register.
SsaInsn definition;
definition = ssaMeth.getDefinitionForRegister(reg);
return definition == null ? null : definition.getResult();
|
protected final com.android.dx.rop.code.RegisterSpec | insertMoveBefore(com.android.dx.ssa.SsaInsn insn, com.android.dx.rop.code.RegisterSpec reg)Inserts a move instruction for a specified SSA register before a
specified instruction, creating a new SSA register and adjusting the
interference graph in the process. The insn currently must be the
last insn in a block.
SsaBasicBlock block = insn.getBlock();
ArrayList<SsaInsn> insns = block.getInsns();
int insnIndex = insns.indexOf(insn);
if (insnIndex < 0 ) {
throw new IllegalArgumentException (
"specified insn is not in this block");
}
if (insnIndex != insns.size() - 1) {
/*
* Presently, the interference updater only works when
* adding before the last insn, and the last insn must have no
* result
*/
throw new IllegalArgumentException(
"Adding move here not supported:" + insn.toHuman());
}
/*
* Get new register and make new move instruction
*/
// new result must not have associated local variable
RegisterSpec newRegSpec = RegisterSpec.make(ssaMeth.makeNewSsaReg(),
reg.getTypeBearer());
SsaInsn toAdd;
toAdd = SsaInsn.makeFromRop(
new PlainInsn(Rops.opMove(newRegSpec.getType()),
SourcePosition.NO_INFO, newRegSpec,
RegisterSpecList.make(reg)), block);
insns.add(insnIndex, toAdd);
int newReg = newRegSpec.getReg();
/*
* Adjust interference graph based on what's live out of the current
* block and what's used by the final instruction.
*/
IntSet liveOut = block.getLiveOutRegs();
RegisterSpec result = insn.getResult();
int resultReg = (result == null) ? -1 : result.getReg();
IntIterator liveOutIter = liveOut.iterator();
while(liveOutIter.hasNext()) {
interference.add(newReg, liveOutIter.next());
}
// Everything that's a source in the last insn interferes
RegisterSpecList sources = insn.getSources();
int szSources = sources.size();
for (int i = 0; i < szSources; i++) {
interference.add(newReg, sources.get(i).getReg());
}
ssaMeth.onInsnsChanged();
return newRegSpec;
|
protected boolean | isDefinitionMoveParam(int reg)Returns true if the definition site of this register is a
move-param (ie, this is a method parameter)
SsaInsn defInsn = ssaMeth.getDefinitionForRegister(reg);
if (defInsn instanceof NormalSsaInsn) {
NormalSsaInsn ndefInsn = (NormalSsaInsn) defInsn;
return ndefInsn.getOpcode().getOpcode() == RegOps.MOVE_PARAM;
}
return false;
|
public abstract boolean | wantsParamsMovedHigh()Indicates whether the method params were allocated at the bottom
of the namespace, and thus should be moved up to the top of the
namespace after phi removal.
|