use of com.taobao.android.dx.rop.code.PlainInsn in project atlas by alibaba.
the class LiteralOpUpgrader method replacePlainInsn.
/**
* Replaces an SsaInsn containing a PlainInsn with a new PlainInsn. The
* new PlainInsn is constructed with a new RegOp and new sources.
*
* TODO move this somewhere else.
*
* @param insn {@code non-null;} an SsaInsn containing a PlainInsn
* @param newSources {@code non-null;} new sources list for new insn
* @param newOpcode A RegOp from {@link RegOps}
* @param cst {@code null-ok;} constant for new instruction, if any
*/
private void replacePlainInsn(NormalSsaInsn insn, RegisterSpecList newSources, int newOpcode, Constant cst) {
Insn originalRopInsn = insn.getOriginalRopInsn();
Rop newRop = Rops.ropFor(newOpcode, insn.getResult(), newSources, cst);
Insn newRopInsn;
if (cst == null) {
newRopInsn = new PlainInsn(newRop, originalRopInsn.getPosition(), insn.getResult(), newSources);
} else {
newRopInsn = new PlainCstInsn(newRop, originalRopInsn.getPosition(), insn.getResult(), newSources, cst);
}
NormalSsaInsn newInsn = new NormalSsaInsn(newRopInsn, insn.getBlock());
List<SsaInsn> insns = insn.getBlock().getInsns();
ssaMeth.onInsnRemoved(insn);
insns.set(insns.lastIndexOf(insn), newInsn);
ssaMeth.onInsnAdded(newInsn);
}
use of com.taobao.android.dx.rop.code.PlainInsn 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.PlainInsn 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.PlainInsn in project atlas by alibaba.
the class ConstCollector method fixLocalAssignment.
/**
* Inserts mark-locals if necessary when changing a register. If
* the definition of {@code origReg} is associated with a local
* variable, then insert a mark-local for {@code newReg} just below
* it. We expect the definition of {@code origReg} to ultimately
* be removed by the dead code eliminator
*
* @param origReg {@code non-null;} original register
* @param newReg {@code non-null;} new register that will replace
* {@code origReg}
*/
private void fixLocalAssignment(RegisterSpec origReg, RegisterSpec newReg) {
for (SsaInsn use : ssaMeth.getUseListForRegister(origReg.getReg())) {
RegisterSpec localAssignment = use.getLocalAssignment();
if (localAssignment == null) {
continue;
}
if (use.getResult() == null) {
/*
* This is a mark-local. it will be updated when all uses
* are updated.
*/
continue;
}
LocalItem local = localAssignment.getLocalItem();
// Un-associate original use.
use.setResultLocal(null);
// Now add a mark-local to the new reg immediately after.
newReg = newReg.withLocalItem(local);
SsaInsn newInsn = SsaInsn.makeFromRop(new PlainInsn(Rops.opMarkLocal(newReg), SourcePosition.NO_INFO, null, RegisterSpecList.make(newReg)), use.getBlock());
ArrayList<SsaInsn> insns = use.getBlock().getInsns();
insns.add(insns.indexOf(use) + 1, newInsn);
}
}
use of com.taobao.android.dx.rop.code.PlainInsn in project atlas by alibaba.
the class ConstCollector method run.
/**
* Applies the optimization.
*/
private void run() {
int regSz = ssaMeth.getRegCount();
ArrayList<TypedConstant> constantList = getConstsSortedByCountUse();
int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS);
SsaBasicBlock start = ssaMeth.getEntryBlock();
// Constant to new register containing the constant
HashMap<TypedConstant, RegisterSpec> newRegs = new HashMap<TypedConstant, RegisterSpec>(toCollect);
for (int i = 0; i < toCollect; i++) {
TypedConstant cst = constantList.get(i);
RegisterSpec result = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst);
Rop constRop = Rops.opConst(cst);
if (constRop.getBranchingness() == Rop.BRANCH_NONE) {
start.addInsnToHead(new PlainCstInsn(Rops.opConst(cst), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY, cst));
} else {
// We need two new basic blocks along with the new insn
SsaBasicBlock entryBlock = ssaMeth.getEntryBlock();
SsaBasicBlock successorBlock = entryBlock.getPrimarySuccessor();
// Insert a block containing the const insn.
SsaBasicBlock constBlock = entryBlock.insertNewSuccessor(successorBlock);
constBlock.replaceLastInsn(new ThrowingCstInsn(constRop, SourcePosition.NO_INFO, RegisterSpecList.EMPTY, StdTypeList.EMPTY, cst));
// Insert a block containing the move-result-pseudo insn.
SsaBasicBlock resultBlock = constBlock.insertNewSuccessor(successorBlock);
PlainInsn insn = new PlainInsn(Rops.opMoveResultPseudo(result.getTypeBearer()), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY);
resultBlock.addInsnToHead(insn);
}
newRegs.put(cst, result);
}
updateConstUses(newRegs, regSz);
}
Aggregations