use of com.android.dx.rop.code.BasicBlockList in project buck by facebook.
the class SsaBasicBlock method newFromRop.
/**
* Creates a new SSA basic block from a ROP form basic block.
*
* @param rmeth original method
* @param basicBlockIndex index this block will have
* @param parent method of this block predecessor set will be
* updated
* @return new instance
*/
public static SsaBasicBlock newFromRop(RopMethod rmeth, int basicBlockIndex, final SsaMethod parent) {
BasicBlockList ropBlocks = rmeth.getBlocks();
BasicBlock bb = ropBlocks.get(basicBlockIndex);
SsaBasicBlock result = new SsaBasicBlock(basicBlockIndex, bb.getLabel(), parent);
InsnList ropInsns = bb.getInsns();
result.insns.ensureCapacity(ropInsns.size());
for (int i = 0, sz = ropInsns.size(); i < sz; i++) {
result.insns.add(new NormalSsaInsn(ropInsns.get(i), result));
}
result.predecessors = SsaMethod.bitSetFromLabelList(ropBlocks, rmeth.labelToPredecessors(bb.getLabel()));
result.successors = SsaMethod.bitSetFromLabelList(ropBlocks, bb.getSuccessors());
result.successorList = SsaMethod.indexListFromLabelList(ropBlocks, bb.getSuccessors());
if (result.successorList.size() != 0) {
int primarySuccessor = bb.getPrimarySuccessor();
result.primarySuccessor = (primarySuccessor < 0) ? -1 : ropBlocks.indexOfLabel(primarySuccessor);
}
return result;
}
use of com.android.dx.rop.code.BasicBlockList in project J2ME-Loader by nikita36078.
the class SsaMethod method convertRopToSsaBlocks.
private void convertRopToSsaBlocks(RopMethod rmeth) {
BasicBlockList ropBlocks = rmeth.getBlocks();
int sz = ropBlocks.size();
blocks = new ArrayList<SsaBasicBlock>(sz + 2);
for (int i = 0; i < sz; i++) {
SsaBasicBlock sbb = SsaBasicBlock.newFromRop(rmeth, i, this);
blocks.add(sbb);
}
// Add an no-op entry block.
int origEntryBlockIndex = rmeth.getBlocks().indexOfLabel(rmeth.getFirstLabel());
SsaBasicBlock entryBlock = blocks.get(origEntryBlockIndex).insertNewPredecessor();
entryBlockIndex = entryBlock.getIndex();
// This gets made later.
exitBlockIndex = -1;
}
use of com.android.dx.rop.code.BasicBlockList in project J2ME-Loader by nikita36078.
the class SsaToRop method convertBasicBlocks.
/**
* @return rop-form basic block list
*/
private BasicBlockList convertBasicBlocks() {
ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
// Exit block may be null.
SsaBasicBlock exitBlock = ssaMeth.getExitBlock();
ssaMeth.computeReachability();
int ropBlockCount = ssaMeth.getCountReachableBlocks();
// Don't count the exit block, if it exists and is reachable.
ropBlockCount -= (exitBlock != null && exitBlock.isReachable()) ? 1 : 0;
BasicBlockList result = new BasicBlockList(ropBlockCount);
// Convert all the reachable blocks except the exit block.
int ropBlockIndex = 0;
for (SsaBasicBlock b : blocks) {
if (b.isReachable() && b != exitBlock) {
result.set(ropBlockIndex++, convertBasicBlock(b));
}
}
// The exit block, which is discarded, must do nothing.
if (exitBlock != null && exitBlock.getInsns().size() != 0) {
throw new RuntimeException("Exit block must have no insns when leaving SSA form");
}
return result;
}
use of com.android.dx.rop.code.BasicBlockList in project J2ME-Loader by nikita36078.
the class RopTranslator method pickOrder.
/**
* Picks an order for the blocks by doing "trace" analysis.
*/
private void pickOrder() {
BasicBlockList blocks = method.getBlocks();
int sz = blocks.size();
int maxLabel = blocks.getMaxLabel();
int[] workSet = Bits.makeBitSet(maxLabel);
int[] tracebackSet = Bits.makeBitSet(maxLabel);
for (int i = 0; i < sz; i++) {
BasicBlock one = blocks.get(i);
Bits.set(workSet, one.getLabel());
}
int[] order = new int[sz];
int at = 0;
/*
* Starting with the designated "first label" (that is, the
* first block of the method), add that label to the order,
* and then pick its first as-yet unordered successor to
* immediately follow it, giving top priority to the primary
* (aka default) successor (if any). Keep following successors
* until the trace runs out of possibilities. Then, continue
* by finding an unordered chain containing the first as-yet
* unordered block, and adding it to the order, and so on.
*/
for (int label = method.getFirstLabel(); label != -1; label = Bits.findFirst(workSet, 0)) {
/*
* Attempt to trace backward from the chosen block to an
* as-yet unordered predecessor which lists the chosen
* block as its primary successor, and so on, until we
* fail to find such an unordered predecessor. Start the
* trace with that block. Note that the first block in the
* method has no predecessors, so in that case this loop
* will simply terminate with zero iterations and without
* picking a new starter block.
*/
traceBack: for (; ; ) {
IntList preds = method.labelToPredecessors(label);
int psz = preds.size();
for (int i = 0; i < psz; i++) {
int predLabel = preds.get(i);
if (Bits.get(tracebackSet, predLabel)) {
/*
* We found a predecessor loop; stop tracing back
* from here.
*/
break;
}
if (!Bits.get(workSet, predLabel)) {
// This one's already ordered.
continue;
}
BasicBlock pred = blocks.labelToBlock(predLabel);
if (pred.getPrimarySuccessor() == label) {
// Found one!
label = predLabel;
Bits.set(tracebackSet, label);
continue traceBack;
}
}
// Failed to find a better block to start the trace.
break;
}
/*
* Trace a path from the chosen block to one of its
* unordered successors (hopefully the primary), and so
* on, until we run out of unordered successors.
*/
while (label != -1) {
Bits.clear(workSet, label);
Bits.clear(tracebackSet, label);
order[at] = label;
at++;
BasicBlock one = blocks.labelToBlock(label);
BasicBlock preferredBlock = blocks.preferredSuccessorOf(one);
if (preferredBlock == null) {
break;
}
int preferred = preferredBlock.getLabel();
int primary = one.getPrimarySuccessor();
if (Bits.get(workSet, preferred)) {
/*
* Order the current block's preferred successor
* next, as it has yet to be scheduled.
*/
label = preferred;
} else if ((primary != preferred) && (primary >= 0) && Bits.get(workSet, primary)) {
/*
* The primary is available, so use that.
*/
label = primary;
} else {
/*
* There's no obvious candidate, so pick the first
* one that's available, if any.
*/
IntList successors = one.getSuccessors();
int ssz = successors.size();
label = -1;
for (int i = 0; i < ssz; i++) {
int candidate = successors.get(i);
if (Bits.get(workSet, candidate)) {
label = candidate;
break;
}
}
}
}
}
if (at != sz) {
// There was a duplicate block label.
throw new RuntimeException("shouldn't happen");
}
this.order = order;
}
use of com.android.dx.rop.code.BasicBlockList in project J2ME-Loader by nikita36078.
the class StdCatchBuilder method getCatchTypes.
/**
* {@inheritDoc}
*/
public HashSet<Type> getCatchTypes() {
HashSet<Type> result = new HashSet<Type>(20);
BasicBlockList blocks = method.getBlocks();
int size = blocks.size();
for (int i = 0; i < size; i++) {
BasicBlock block = blocks.get(i);
TypeList catches = block.getLastInsn().getCatches();
int catchSize = catches.size();
for (int j = 0; j < catchSize; j++) {
result.add(catches.getType(j));
}
}
return result;
}
Aggregations