use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class ControlFlowGraphDumper method dump.
public void dump() {
// Clear methodnode
m.instructions.removeAll(true);
m.tryCatchBlocks.clear();
m.visitCode();
for (BasicBlock b : cfg.vertices()) {
b.resetLabel();
}
// Linearize
linearize();
// Fix edges
naturalise();
// Sanity check linearization
verifyOrdering();
// Dump code
for (BasicBlock b : order) {
m.visitLabel(b.getLabel());
for (Stmt stmt : b) {
stmt.toCode(m, null);
}
}
terminalLabel = new LabelNode();
m.visitLabel(terminalLabel.getLabel());
// Dump ranges
for (ExceptionRange<BasicBlock> er : cfg.getRanges()) {
dumpRange(er);
}
// Sanity check
verifyRanges();
m.visitEnd();
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class ControlFlowGraphDumper method verifyOrdering.
private void verifyOrdering() {
ListIterator<BasicBlock> it = order.listIterator();
while (it.hasNext()) {
BasicBlock b = it.next();
for (FlowEdge<BasicBlock> e : cfg.getEdges(b)) {
if (e.getType() == FlowEdges.IMMEDIATE) {
if (it.hasNext()) {
BasicBlock n = it.next();
it.previous();
if (n != e.dst()) {
throw new IllegalStateException("Illegal flow " + e + " > " + n);
}
} else {
throw new IllegalStateException("Trailing " + e);
}
}
}
}
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class ControlFlowGraphDumper method naturalise.
private void naturalise() {
for (int i = 0; i < order.size(); i++) {
BasicBlock b = order.get(i);
for (FlowEdge<BasicBlock> e : new HashSet<>(cfg.getEdges(b))) {
BasicBlock dst = e.dst();
if (e instanceof ImmediateEdge && order.indexOf(dst) != i + 1) {
// Fix immediates
b.add(new UnconditionalJumpStmt(dst));
cfg.removeEdge(b, e);
cfg.addEdge(b, new UnconditionalJumpEdge<>(b, dst));
} else if (e instanceof UnconditionalJumpEdge && order.indexOf(dst) == i + 1) {
// Remove extraneous gotos
for (ListIterator<Stmt> it = b.listIterator(b.size()); it.hasPrevious(); ) {
if (it.previous() instanceof UnconditionalJumpStmt) {
it.remove();
break;
}
}
cfg.removeEdge(b, e);
cfg.addEdge(b, new ImmediateEdge<>(b, dst));
}
}
}
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class ControlFlowGraphDumper method dumpRange.
private void dumpRange(ExceptionRange<BasicBlock> er) {
// Determine exception type
Type type;
Set<Type> typeSet = er.getTypes();
if (typeSet.size() != 1) {
// TODO: find base exception
type = TypeUtils.THROWABLE;
} else {
type = typeSet.iterator().next();
}
final Label handler = er.getHandler().getLabel();
List<BasicBlock> range = er.get();
range.sort(Comparator.comparing(order::indexOf));
Label start;
int rangeIdx = -1, orderIdx;
do {
if (++rangeIdx == range.size()) {
System.err.println("[warn] range is absent: " + m);
return;
}
BasicBlock b = range.get(rangeIdx);
orderIdx = order.indexOf(b);
start = b.getLabel();
} while (orderIdx == -1);
for (; ; ) {
// check for endpoints
if (orderIdx + 1 == order.size()) {
// end of method
m.visitTryCatchBlock(start, terminalLabel.getLabel(), handler, type.getInternalName());
break;
} else if (rangeIdx + 1 == range.size()) {
// end of range
Label end = order.get(orderIdx + 1).getLabel();
m.visitTryCatchBlock(start, end, handler, type.getInternalName());
break;
}
// check for discontinuity
BasicBlock nextBlock = range.get(rangeIdx + 1);
int nextOrderIdx = order.indexOf(nextBlock);
if (nextOrderIdx - orderIdx > 1) {
// blocks in-between, end the handler and begin anew
System.err.println("[warn] Had to split up a range: " + m);
Label end = order.get(orderIdx + 1).getLabel();
m.visitTryCatchBlock(start, end, handler, type.getInternalName());
start = nextBlock.getLabel();
}
// next
rangeIdx++;
if (nextOrderIdx != -1)
orderIdx = nextOrderIdx;
}
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class DominanceLivenessAnalyser method isLiveOut.
public boolean isLiveOut(BasicBlock q, Local a) {
BasicBlock defBlock = defuse.defs.get(a);
GenericBitSet<BasicBlock> uses = defuse.uses.getNonNull(a);
if (defBlock == q) {
return !uses.relativeComplement(defBlock).isEmpty() || defuse.phiUses.get(defBlock).contains(a);
}
boolean targ = !backTargets.contains(q);
GenericBitSet<BasicBlock> sdomdef = sdoms.getNonNull(defBlock);
if (sdomdef.contains(q)) {
GenericBitSet<BasicBlock> tqa = tq.get(q).intersect(sdomdef);
for (BasicBlock t : tqa) {
GenericBitSet<BasicBlock> u = uses.copy();
if (t == q && targ)
u.remove(q);
GenericBitSet<BasicBlock> rtt = rv.getNonNull(t).intersect(u);
if (!rtt.isEmpty())
return true;
}
}
return false;
}
Aggregations