use of com.taobao.android.dx.ssa.SsaBasicBlock in project atlas by alibaba.
the class SsaToRop method removePhiFunctions.
/**
* See Appel 19.6. To remove the phi instructions in an edge-split
* SSA representation we know we can always insert a move in a
* predecessor block.
*/
private void removePhiFunctions() {
ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
for (SsaBasicBlock block : blocks) {
// Add moves in all the pred blocks for each phi insn.
block.forEachPhiInsn(new PhiVisitor(blocks));
// Delete the phi insns.
block.removeAllPhiInsns();
}
/*
* After all move insns have been added, sort them so they don't
* destructively interfere.
*/
for (SsaBasicBlock block : blocks) {
block.scheduleMovesFromPhis();
}
}
use of com.taobao.android.dx.ssa.SsaBasicBlock in project atlas by alibaba.
the class SsaToRop method convertBasicBlock.
/**
* Converts a single basic block to rop form.
*
* @param block SSA block to process
* @return {@code non-null;} ROP block
*/
private BasicBlock convertBasicBlock(SsaBasicBlock block) {
IntList successorList = block.getRopLabelSuccessorList();
int primarySuccessorLabel = block.getPrimarySuccessorRopLabel();
// Filter out any reference to the SSA form's exit block.
// Exit block may be null.
SsaBasicBlock exitBlock = ssaMeth.getExitBlock();
int exitRopLabel = (exitBlock == null) ? -1 : exitBlock.getRopLabel();
if (successorList.contains(exitRopLabel)) {
if (successorList.size() > 1) {
throw new RuntimeException("Exit predecessor must have no other successors" + Hex.u2(block.getRopLabel()));
} else {
successorList = IntList.EMPTY;
primarySuccessorLabel = -1;
verifyValidExitPredecessor(block);
}
}
successorList.setImmutable();
BasicBlock result = new BasicBlock(block.getRopLabel(), convertInsns(block.getInsns()), successorList, primarySuccessorLabel);
return result;
}
use of com.taobao.android.dx.ssa.SsaBasicBlock in project atlas by alibaba.
the class FirstFitLocalCombiningAllocator method handleCheckCastResults.
/**
* Handles check cast results to reuse the same source register.
* Inserts a move if it can't map the same register to both and the
* check cast is not caught.
*/
private void handleCheckCastResults() {
for (NormalSsaInsn insn : moveResultPseudoInsns) {
RegisterSpec moveRegSpec = insn.getResult();
int moveReg = moveRegSpec.getReg();
BitSet predBlocks = insn.getBlock().getPredecessors();
// Expect one predecessor block only
if (predBlocks.cardinality() != 1) {
continue;
}
SsaBasicBlock predBlock = ssaMeth.getBlocks().get(predBlocks.nextSetBit(0));
ArrayList<SsaInsn> insnList = predBlock.getInsns();
/**
* If the predecessor block has a check-cast, it will be the last
* instruction
*/
SsaInsn checkCastInsn = insnList.get(insnList.size() - 1);
if (checkCastInsn.getOpcode().getOpcode() != RegOps.CHECK_CAST) {
continue;
}
RegisterSpec checkRegSpec = checkCastInsn.getSources().get(0);
int checkReg = checkRegSpec.getReg();
/**
* See if either register is already mapped. Most likely the move
* result will be mapped already since the cast result is stored
* in a local variable.
*/
int category = checkRegSpec.getCategory();
boolean moveMapped = ssaRegsMapped.get(moveReg);
boolean checkMapped = ssaRegsMapped.get(checkReg);
if (moveMapped & !checkMapped) {
int moveRopReg = mapper.oldToNew(moveReg);
checkMapped = tryMapReg(checkRegSpec, moveRopReg, category);
}
if (checkMapped & !moveMapped) {
int checkRopReg = mapper.oldToNew(checkReg);
moveMapped = tryMapReg(moveRegSpec, checkRopReg, category);
}
// Map any unmapped registers to anything available
if (!moveMapped || !checkMapped) {
int ropReg = findNextUnreservedRopReg(paramRangeEnd, category);
ArrayList<RegisterSpec> ssaRegs = new ArrayList<RegisterSpec>(2);
ssaRegs.add(moveRegSpec);
ssaRegs.add(checkRegSpec);
while (!tryMapRegs(ssaRegs, ropReg, category, false)) {
ropReg = findNextUnreservedRopReg(ropReg + 1, category);
}
}
/*
* If source and result have a different mapping, insert a move so
* they can have the same mapping. Don't do this if the check cast
* is caught, since it will overwrite a potentially live value.
*/
boolean hasExceptionHandlers = checkCastInsn.getOriginalRopInsn().getCatches().size() != 0;
int moveRopReg = mapper.oldToNew(moveReg);
int checkRopReg = mapper.oldToNew(checkReg);
if (moveRopReg != checkRopReg && !hasExceptionHandlers) {
((NormalSsaInsn) checkCastInsn).changeOneSource(0, insertMoveBefore(checkCastInsn, checkRegSpec));
addMapping(checkCastInsn.getSources().get(0), moveRopReg);
}
}
}
Aggregations