boolean bbEnded = false;
boolean bbEndedWithControlXfer = false;
for (Instr i : instrs) {
Operation iop = i.operation;
if (iop == Operation.LABEL) {
Label l = ((LABEL_Instr) i)._lbl;
prevBB = currBB;
newBB = createNewBB(l, g, _bbMap, nestedExceptionRegions);
if (!bbEndedWithControlXfer) // Jump instruction bbs dont add an edge to the succeeding bb by default
{
g.addEdge(currBB, newBB);
}
currBB = newBB;
// Add forward reference edges
List<BasicBlock> frefs = forwardRefs.get(l);
if (frefs != null) {
for (BasicBlock b : frefs) {
g.addEdge(b, newBB);
}
}
bbEnded = false;
bbEndedWithControlXfer = false;
} else if (bbEnded && (iop != Operation.EXC_REGION_END)) {
prevBB = currBB;
newBB = createNewBB(g, _bbMap, nestedExceptionRegions);
if (!bbEndedWithControlXfer) // Jump instruction bbs dont add an edge to the succeeding bb by default
{
g.addEdge(currBB, newBB); // currBB cannot be null!
}
currBB = newBB;
bbEnded = false;
bbEndedWithControlXfer = false;
}
if (i instanceof ExceptionRegionStartMarkerInstr) {
// SSS: Do we need this anymore?
// currBB.addInstr(i);
ExceptionRegionStartMarkerInstr rbsmi = (ExceptionRegionStartMarkerInstr)i;
ExceptionRegion rr = new ExceptionRegion(rbsmi._rescueBlockLabels);
rr.addBB(currBB);
allExceptionRegions.add(rr);
if (nestedExceptionRegions.empty())
_outermostERs.add(rr);
else
nestedExceptionRegions.peek().addNestedRegion(rr);
nestedExceptionRegions.push(rr);
} else if (i instanceof ExceptionRegionEndMarkerInstr) {
// SSS: Do we need this anymore?
// currBB.addInstr(i);
nestedExceptionRegions.pop().setEndBB(currBB);
} else if (iop.endsBasicBlock()) {
bbEnded = true;
currBB.addInstr(i);
Label tgt;
if (i instanceof BranchInstr) {
tgt = ((BranchInstr) i).getJumpTarget();
} else if (i instanceof JumpInstr) {
tgt = ((JumpInstr) i).getJumpTarget();
bbEndedWithControlXfer = true;
} // CASE IR instructions are dummy instructions
// -- all when/then clauses have been converted into if-then-else blocks
else if (i instanceof CaseInstr) {
tgt = null;
} // SSS FIXME: To be done
else if (i instanceof BREAK_Instr) {
tgt = null;
retBBs.add(currBB); // the break instruction transfers control to the end of this closure cfg
bbEndedWithControlXfer = true;
} else if (i instanceof ReturnInstr) {
tgt = null;
retBBs.add(currBB);
bbEndedWithControlXfer = true;
} else if (i instanceof THROW_EXCEPTION_Instr) {
tgt = null;
excBBs.add(currBB);
bbEndedWithControlXfer = true;
} else if (i instanceof JUMP_INDIRECT_Instr) {
tgt = null;
bbEndedWithControlXfer = true;
Set<Label> retAddrs = retAddrMap.get(((JUMP_INDIRECT_Instr) i).getJumpTarget());
for (Label l : retAddrs) {
addEdge(g, currBB, l, _bbMap, forwardRefs);
}
// Record the target bb for the retaddr var for any set_addr instrs that appear later and use the same retaddr var
retAddrTargetMap.put(((JUMP_INDIRECT_Instr) i).getJumpTarget(), currBB);
} else {
tgt = null;
}
if (tgt != null) {
addEdge(g, currBB, tgt, _bbMap, forwardRefs);
}
} else if (iop != Operation.LABEL) {
currBB.addInstr(i);
}
if (i instanceof SET_RETADDR_Instr) {
Variable v = i.getResult();
Label tgtLbl = ((SET_RETADDR_Instr) i).getReturnAddr();
BasicBlock tgtBB = retAddrTargetMap.get(v);
// If we have the target bb, add the edge
// If not, record it for fixup later
if (tgtBB != null) {
addEdge(g, tgtBB, tgtLbl, _bbMap, forwardRefs);