/**
* 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;
}