use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class SsaBasicBlock method scheduleUseBeforeAssigned.
/**
* Ensures that all move operations in this block occur such that
* reads of any register happen before writes to that register.
* NOTE: caller is expected to returnSpareRegisters()!
*
* TODO: See Briggs, et al "Practical Improvements to the Construction and
* Destruction of Static Single Assignment Form" section 5. a) This can
* be done in three passes.
*
* @param toSchedule List of instructions. Must consist only of moves.
*/
private void scheduleUseBeforeAssigned(List<SsaInsn> toSchedule) {
BitSet regsUsedAsSources = new BitSet(parent.getRegCount());
// TODO: Get rid of this.
BitSet regsUsedAsResults = new BitSet(parent.getRegCount());
int sz = toSchedule.size();
int insertPlace = 0;
while (insertPlace < sz) {
int oldInsertPlace = insertPlace;
// Record all registers used as sources in this block.
for (int i = insertPlace; i < sz; i++) {
setRegsUsed(regsUsedAsSources, toSchedule.get(i).getSources().get(0));
setRegsUsed(regsUsedAsResults, toSchedule.get(i).getResult());
}
/*
* If there are no circular dependencies, then there exists
* n instructions where n > 1 whose result is not used as a source.
*/
for (int i = insertPlace; i < sz; i++) {
SsaInsn insn = toSchedule.get(i);
/*
* Move these n registers to the front, since they overwrite
* nothing.
*/
if (!checkRegUsed(regsUsedAsSources, insn.getResult())) {
Collections.swap(toSchedule, i, insertPlace++);
}
}
/*
* If we've made no progress in this iteration, there's a
* circular dependency. Split it using the temp reg.
*/
if (oldInsertPlace == insertPlace) {
SsaInsn insnToSplit = null;
// Find an insn whose result is used as a source.
for (int i = insertPlace; i < sz; i++) {
SsaInsn insn = toSchedule.get(i);
if (checkRegUsed(regsUsedAsSources, insn.getResult()) && checkRegUsed(regsUsedAsResults, insn.getSources().get(0))) {
insnToSplit = insn;
/*
* We're going to split this insn; move it to the
* front.
*/
Collections.swap(toSchedule, insertPlace, i);
break;
}
}
// At least one insn will be set above.
RegisterSpec result = insnToSplit.getResult();
RegisterSpec tempSpec = result.withReg(parent.borrowSpareRegister(result.getCategory()));
NormalSsaInsn toAdd = new NormalSsaInsn(new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, tempSpec, insnToSplit.getSources()), this);
toSchedule.add(insertPlace++, toAdd);
RegisterSpecList newSources = RegisterSpecList.make(tempSpec);
NormalSsaInsn toReplace = new NormalSsaInsn(new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, result, newSources), this);
toSchedule.set(insertPlace, toReplace);
// The size changed.
sz = toSchedule.size();
}
regsUsedAsSources.clear();
regsUsedAsResults.clear();
}
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class SsaBasicBlock method addMoveToEnd.
/**
* Adds a move instruction to the end of this basic block, just
* before the last instruction. If the result of the final instruction
* is the source in question, then the move is placed at the beginning of
* the primary successor block. This is for unversioned registers.
*
* @param result move destination
* @param source move source
*/
public void addMoveToEnd(RegisterSpec result, RegisterSpec source) {
if (result.getReg() == source.getReg()) {
// Sometimes we end up with no-op moves. Ignore them here.
return;
}
/*
* The last Insn has to be a normal SSA insn: a phi can't branch
* or return or cause an exception, etc.
*/
NormalSsaInsn lastInsn;
lastInsn = (NormalSsaInsn) insns.get(insns.size() - 1);
if (lastInsn.getResult() != null || lastInsn.getSources().size() > 0) {
for (int i = successors.nextSetBit(0); i >= 0; i = successors.nextSetBit(i + 1)) {
SsaBasicBlock succ;
succ = parent.getBlocks().get(i);
succ.addMoveToBeginning(result, source);
}
} else {
/*
* We can safely add a move to the end of the block just
* before the last instruction, because the final insn does
* not assign to anything.
*/
RegisterSpecList sources = RegisterSpecList.make(source);
NormalSsaInsn toAdd = new NormalSsaInsn(new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, result, sources), this);
insns.add(insns.size() - 1, toAdd);
movesFromPhisAtEnd++;
}
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class SsaMethod method onSourcesChanged.
/**
* Updates the use list for a source list change.
*
* @param insn {@code insn non-null;} insn being changed.
* {@code insn.getSources()} must return the new source list.
* @param oldSources {@code null-ok;} list of sources that were
* previously used
*/
/*package*/
void onSourcesChanged(SsaInsn insn, RegisterSpecList oldSources) {
if (useList == null)
return;
if (oldSources != null) {
removeFromUseList(insn, oldSources);
}
RegisterSpecList sources = insn.getSources();
int szNew = sources.size();
for (int i = 0; i < szNew; i++) {
int reg = sources.get(i).getReg();
useList[reg].add(insn);
}
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class Form3rc method writeTo.
/** {@inheritDoc} */
@Override
public void writeTo(AnnotatedOutput out, DalvInsn insn) {
RegisterSpecList regs = insn.getRegisters();
int cpi = ((CstInsn) insn).getIndex();
int firstReg = (regs.size() == 0) ? 0 : regs.get(0).getReg();
int count = regs.getWordCount();
write(out, opcodeUnit(insn, count), (short) cpi, (short) firstReg);
}
use of com.taobao.android.dx.rop.code.RegisterSpecList in project atlas by alibaba.
the class Form51l method insnArgString.
/** {@inheritDoc} */
@Override
public String insnArgString(DalvInsn insn) {
RegisterSpecList regs = insn.getRegisters();
CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
return regs.get(0).regString() + ", " + literalBitsString(value);
}
Aggregations