use of org.mapleir.flowgraph.edges.ImmediateEdge 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.flowgraph.edges.ImmediateEdge in project maple-ir by LLVM-but-worse.
the class DeadCodeEliminationPass method process.
public void process(ControlFlowGraph cfg) {
LocalsPool lp = cfg.getLocals();
boolean c;
do {
c = false;
SimpleDfs<BasicBlock> dfs = new SimpleDfs<>(cfg, cfg.getEntries().iterator().next(), SimpleDfs.PRE);
List<BasicBlock> pre = dfs.getPreOrder();
for (BasicBlock b : new HashSet<>(cfg.vertices())) {
if (!pre.contains(b)) {
// System.out.println("proc1: " + b);
for (FlowEdge<BasicBlock> fe : new HashSet<>(cfg.getEdges(b))) {
cfg.exciseEdge(fe);
}
// System.out.println("removed: ");
for (Stmt stmt : b) {
// System.out.println(" " + (b.indexOf(stmt)) + ". " + stmt);
if (stmt instanceof AbstractCopyStmt) {
AbstractCopyStmt copy = (AbstractCopyStmt) stmt;
lp.defs.remove(copy.getVariable().getLocal());
// System.out.println(" kill1 " + copy.getVariable().getLocal());
}
for (Expr e : stmt.enumerateOnlyChildren()) {
if (e.getOpcode() == Opcode.LOCAL_LOAD) {
VarExpr v = (VarExpr) e;
lp.uses.get(v.getLocal()).remove(v);
// System.out.println(" kill2 " + v.getLocal());
}
}
}
cfg.removeVertex(b);
deadBlocks++;
c = true;
} else {
// System.out.println("proc2: " + b);
UnconditionalJumpEdge<BasicBlock> uncond = null;
for (FlowEdge<BasicBlock> fe : cfg.getEdges(b)) {
if (fe.getType() == FlowEdges.UNCOND) {
uncond = (UnconditionalJumpEdge<BasicBlock>) fe;
}
}
if (uncond != null) {
BasicBlock dst = uncond.dst();
List<BasicBlock> verts = new ArrayList<>(cfg.vertices());
if (verts.indexOf(b) + 1 == verts.indexOf(dst)) {
ImmediateEdge<BasicBlock> im = new ImmediateEdge<>(b, dst);
cfg.exciseEdge(uncond);
cfg.addEdge(b, im);
Stmt stmt = b.remove(b.size() - 1);
if (stmt.getOpcode() != Opcode.UNCOND_JUMP) {
throw new IllegalStateException(b + " : " + stmt);
}
immediateJumps++;
c = true;
}
}
// if(cfg.getMethod().toString().equals("cf.k(IIIIII)V")) {}
Iterator<Stmt> it = b.iterator();
while (it.hasNext()) {
Stmt stmt = it.next();
if (stmt.getOpcode() == Opcode.LOCAL_STORE) {
AbstractCopyStmt copy = (AbstractCopyStmt) stmt;
if (copy.isSynthetic()) {
continue;
}
Local l = copy.getVariable().getLocal();
LocalsPool pool = cfg.getLocals();
// System.out.println("copy: "+ copy);
if (!ConstraintUtil.isUncopyable(copy.getExpression()) && pool.uses.get(l).size() == 0) {
for (Expr e : copy.getExpression().enumerateWithSelf()) {
if (e.getOpcode() == Opcode.LOCAL_LOAD) {
VarExpr v = (VarExpr) e;
Local l2 = v.getLocal();
pool.uses.remove(l2);
}
}
pool.uses.remove(l);
pool.defs.remove(l);
it.remove();
deadLocals++;
c = true;
}
} else if (stmt.getOpcode() == Opcode.NOP) {
it.remove();
c = true;
}
}
}
}
// for now
} while (c);
}
use of org.mapleir.flowgraph.edges.ImmediateEdge in project maple-ir by LLVM-but-worse.
the class ControlFlowGraphDumper method linearize.
private void linearize() {
if (cfg.getEntries().size() != 1)
throw new IllegalStateException("CFG doesn't have exactly 1 entry");
BasicBlock entry = cfg.getEntries().iterator().next();
// Build bundle graph
Map<BasicBlock, BlockBundle> bundles = new HashMap<>();
Map<BlockBundle, List<BlockBundle>> bunches = new HashMap<>();
// Build bundles
List<BasicBlock> topoorder = new SimpleDfs<>(cfg, entry, SimpleDfs.TOPO).getTopoOrder();
for (BasicBlock b : topoorder) {
if (// Already in a bundle
bundles.containsKey(b))
continue;
if (// Look for heads of bundles only
b.getIncomingImmediateEdge() != null)
continue;
BlockBundle bundle = new BlockBundle();
while (b != null) {
bundle.add(b);
bundles.put(b, bundle);
b = b.getImmediate();
}
List<BlockBundle> bunch = new ArrayList<>();
bunch.add(bundle);
bunches.put(bundle, bunch);
}
// Group bundles by exception ranges
for (ExceptionRange<BasicBlock> range : cfg.getRanges()) {
BlockBundle prevBundle = null;
for (BasicBlock b : range.getNodes()) {
BlockBundle curBundle = bundles.get(b);
if (prevBundle == null) {
prevBundle = curBundle;
continue;
}
if (curBundle != prevBundle) {
List<BlockBundle> bunchA = bunches.get(prevBundle);
List<BlockBundle> bunchB = bunches.get(curBundle);
if (bunchA != bunchB) {
bunchA.addAll(bunchB);
for (BlockBundle bundle : bunchB) {
bunches.put(bundle, bunchA);
}
}
prevBundle = curBundle;
}
}
}
// Rebuild bundles
bundles.clear();
for (Map.Entry<BlockBundle, List<BlockBundle>> e : bunches.entrySet()) {
BlockBundle bundle = e.getKey();
if (bundles.containsKey(bundle.getFirst()))
continue;
BlockBundle bunch = new BlockBundle();
e.getValue().forEach(bunch::addAll);
for (BasicBlock b : bunch) bundles.put(b, bunch);
}
// Connect bundle graph
BundleGraph bundleGraph = new BundleGraph();
BlockBundle entryBundle = bundles.get(entry);
bundleGraph.addVertex(entryBundle);
for (BasicBlock b : topoorder) {
for (FlowEdge<BasicBlock> e : cfg.getEdges(b)) {
if (e instanceof ImmediateEdge)
continue;
BlockBundle src = bundles.get(b);
bundleGraph.addEdge(src, new FastGraphEdgeImpl<>(src, bundles.get(e.dst())));
}
}
// Linearize & flatten
order = new IndexedList<>();
// for efficiency
Set<BlockBundle> bundlesSet = new HashSet<>(bundles.values());
ControlFlowGraphDumper.linearize(bundlesSet, bundleGraph, entryBundle).forEach(order::addAll);
}
Aggregations