Processes a single block.
RegisterSpecSet primaryState = resultInfo.mutableCopyOfStarts(label);
BasicBlock block = blocks.labelToBlock(label);
InsnList insns = block.getInsns();
int insnSz = insns.size();
/*
* We may have to treat the last instruction specially: If it
* can (but doesn't always) throw, and the exception can be
* caught within the same method, then we need to use the
* state *before* executing it to be what is merged into
* exception targets.
*/
boolean canThrowDuringLastInsn = block.hasExceptionHandlers() &&
(insns.getLast().getResult() != null);
int freezeSecondaryStateAt = insnSz - 1;
RegisterSpecSet secondaryState = primaryState;
/*
* Iterate over the instructions, adding information for each place
* that the active variable set changes.
*/
for (int i = 0; i < insnSz; i++) {
if (canThrowDuringLastInsn && (i == freezeSecondaryStateAt)) {
// Until this point, primaryState == secondaryState.
primaryState.setImmutable();
primaryState = primaryState.mutableCopy();
}
Insn insn = insns.get(i);
RegisterSpec result;
result = insn.getLocalAssignment();
if (result == null) {
/*
* If an assignment assigns over an existing local, make
* sure to mark the local as going out of scope.
*/
result = insn.getResult();
if (result != null
&& primaryState.get(result.getReg()) != null) {
primaryState.remove(primaryState.get(result.getReg()));
}
continue;
}
result = result.withSimpleType();
RegisterSpec already = primaryState.get(result);
/*
* The equals() check ensures we only add new info if
* the instruction causes a change to the set of
* active variables.
*/
if (!result.equals(already)) {
/*
* If this insn represents a local moving from one register
* to another, remove the association between the old register
* and the local.
*/
RegisterSpec previous
= primaryState.localItemToSpec(result.getLocalItem());
if (previous != null
&& (previous.getReg() != result.getReg())) {
primaryState.remove(previous);
}
resultInfo.addAssignment(insn, result);
primaryState.put(result);
}
}
primaryState.setImmutable();
/*
* Merge this state into the start state for each successor,
* and update the work set where required (that is, in cases
* where the start state for a block changes).
*/
IntList successors = block.getSuccessors();
int succSz = successors.size();
int primarySuccessor = block.getPrimarySuccessor();
for (int i = 0; i < succSz; i++) {
int succ = successors.get(i);
RegisterSpecSet state = (succ == primarySuccessor) ?
primaryState : secondaryState;
if (resultInfo.mergeStarts(succ, state)) {
Bits.set(workSet, succ);
}
}