use of org.mapleir.ir.code.stmt.copy.AbstractCopyStmt 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.ir.code.stmt.copy.AbstractCopyStmt in project maple-ir by LLVM-but-worse.
the class SSAGenPass method updatePhiArgTypes.
private void updatePhiArgTypes(Set<BasicBlock> vis) {
// update types for phi args
for (BasicBlock b : order) {
for (Stmt s : b) {
if (s.getOpcode() != Opcode.PHI_STORE) {
break;
}
CopyPhiStmt cps = (CopyPhiStmt) s;
for (Entry<BasicBlock, Expr> e : cps.getExpression().getArguments().entrySet()) {
BasicBlock src = e.getKey();
if (vis.contains(src))
continue;
VarExpr v = (VarExpr) e.getValue();
Local l = v.getLocal();
// what if the def is never reached?
AbstractCopyStmt def = pool.defs.get(l);
v.setType(def.getType());
}
}
}
}
use of org.mapleir.ir.code.stmt.copy.AbstractCopyStmt in project maple-ir by LLVM-but-worse.
the class SSAGenPass method resolveShadowedLocals.
private void resolveShadowedLocals() {
Set<VersionedLocal> visited = new HashSet<>();
for (Entry<VersionedLocal, Set<VersionedLocal>> e : shadowed.entrySet()) {
if (!visited.contains(e.getKey())) {
Set<VersionedLocal> set = e.getValue();
visited.addAll(set);
Set<VersionedLocal> lvars = new HashSet<>();
for (VersionedLocal l : set) {
if (!l.isStack()) {
lvars.add(l);
}
}
/* find a suitable spill variable:
* favour lvars
* favour lowest version */
VersionedLocal spill;
if (lvars.isEmpty()) {
/* all vars are svars. */
spill = findLowest(set);
} else if (lvars.size() == 1) {
spill = lvars.iterator().next();
} else {
/* multiple lvars. // TODO: tweak? */
// System.err.println(e.getKey() + " " + lvars);
spill = findLowest(lvars);
}
// System.out.println(set + " spill; " + spill);
/* now that we've chosen a spill var, we
* find the original copy, i.e. the one
* which has a runtime computed value
* as it's rhs. we then replace the
* target of that copy to the spill
* var and remove the definitions of the
* shadowed vars. we then rename all
* uses of the shadowed vars with the
* spill. */
Set<AbstractCopyStmt> orig = new HashSet<>();
Set<VarExpr> spillUses = pool.uses.get(spill);
// System.out.println(set);
for (VersionedLocal vl : set) {
AbstractCopyStmt copy = pool.defs.get(vl);
// System.out.println(vl);
Expr ex = copy.getExpression();
if (vl != spill) {
if (ex.getOpcode() != Opcode.LOCAL_LOAD) {
orig.add(copy);
} else {
// System.out.println("del1: " + copy);
removeSimpleCopy(copy);
}
/* transfer the uses of each shadowed
* var to the spill var, since we
* rename all of the shadowed vars. */
Set<VarExpr> useSet = pool.uses.get(vl);
// System.out.println("uses of " + vl + " ; " + useSet);
for (VarExpr v : useSet) {
v.setLocal(spill);
}
spillUses.addAll(useSet);
useSet.clear();
pool.uses.remove(vl);
} else {
// System.out.println("del2: " + copy);
removeSimpleCopy(copy);
}
pool.defs.remove(vl);
}
if (orig.size() != 1) {
throw new UnsupportedOperationException(String.format("set:%s, spill:%s, orig:%s", set, spill, orig));
}
AbstractCopyStmt copy = orig.iterator().next();
copy.getVariable().setLocal(spill);
pool.defs.put(spill, copy);
}
}
}
use of org.mapleir.ir.code.stmt.copy.AbstractCopyStmt in project maple-ir by LLVM-but-worse.
the class ExpressionEvaluator method eval.
public ConstantExpr eval(LocalsPool pool, Expr e) {
if (e.getOpcode() == CONST_LOAD) {
return ((ConstantExpr) e).copy();
} else if (e.getOpcode() == ARITHMETIC) {
ArithmeticExpr ae = (ArithmeticExpr) e;
Expr l = ae.getLeft();
Expr r = ae.getRight();
Expr le = eval(pool, l);
Expr re = eval(pool, r);
if (le != null && re != null) {
ConstantExpr lc = (ConstantExpr) le;
ConstantExpr rc = (ConstantExpr) re;
EvaluationFunctor<Number> b = factory.arithmetic(lc.getType(), rc.getType(), ae.getType(), ae.getOperator());
return new ConstantExpr(b.eval(lc.getConstant(), rc.getConstant()));
}
} else if (e.getOpcode() == NEGATE) {
NegationExpr neg = (NegationExpr) e;
Expr e2 = eval(pool, neg.getExpression());
if (e2 != null) {
ConstantExpr ce = (ConstantExpr) e2;
EvaluationFunctor<Number> b = factory.negate(e2.getType());
return new ConstantExpr(b.eval(ce.getConstant()));
}
} else if (e.getOpcode() == LOCAL_LOAD) {
VarExpr v = (VarExpr) e;
Local l = v.getLocal();
AbstractCopyStmt def = pool.defs.get(l);
Expr rhs = def.getExpression();
if (rhs.getOpcode() == LOCAL_LOAD) {
VarExpr v2 = (VarExpr) rhs;
// synthetic copies lhs = rhs;
if (v2.getLocal() == l) {
return null;
}
}
return eval(pool, rhs);
} else if (e.getOpcode() == CAST) {
CastExpr cast = (CastExpr) e;
Expr e2 = eval(pool, cast.getExpression());
if (e2 != null) {
ConstantExpr ce = (ConstantExpr) e2;
if (!ce.getType().equals(cast.getExpression().getType())) {
throw new IllegalStateException(ce.getType() + " : " + cast.getExpression().getType());
}
Type from = ce.getType();
Type to = cast.getType();
boolean p1 = TypeUtils.isPrimitive(from);
boolean p2 = TypeUtils.isPrimitive(to);
if (p1 != p2) {
throw new IllegalStateException(from + " to " + to);
}
if (!p1 && !p2) {
return null;
}
EvaluationFunctor<Number> b = factory.cast(from, to);
return new ConstantExpr(b.eval(ce.getConstant()), to);
}
} else if (e.getOpcode() == COMPARE) {
ComparisonExpr comp = (ComparisonExpr) e;
Expr l = comp.getLeft();
Expr r = comp.getRight();
Expr le = eval(pool, l);
Expr re = eval(pool, r);
if (le != null && re != null) {
ConstantExpr lc = (ConstantExpr) le;
ConstantExpr rc = (ConstantExpr) re;
EvaluationFunctor<Number> b = factory.compare(lc.getType(), rc.getType(), comp.getComparisonType());
return new ConstantExpr(b.eval(lc.getConstant(), rc.getConstant()), Type.INT_TYPE);
}
}
return null;
}
use of org.mapleir.ir.code.stmt.copy.AbstractCopyStmt in project maple-ir by LLVM-but-worse.
the class PoolLocalValueResolver method checkRecursive.
private void checkRecursive(Local l) {
Set<Local> visited = new HashSet<>();
Queue<Local> worklist = new LinkedList<>();
worklist.add(l);
while (!worklist.isEmpty()) {
l = worklist.poll();
AbstractCopyStmt copy = pool.defs.get(l);
Set<Local> set = new HashSet<>();
Expr rhs = copy.getExpression();
if (rhs.getOpcode() == Opcode.LOCAL_LOAD) {
set.add(((VarExpr) rhs).getLocal());
} else if (rhs.getOpcode() == Opcode.PHI) {
for (Expr e : ((PhiExpr) rhs).getArguments().values()) {
set.add(((VarExpr) e).getLocal());
}
}
for (Local v : set) {
if (visited.contains(v)) {
System.err.println(copy.getBlock().getGraph());
System.err.printf("visited: %s%n", visited);
System.err.printf(" copy: %s%n", copy);
System.err.printf(" dup: %s%n", v);
throw new RuntimeException();
}
}
worklist.addAll(set);
visited.addAll(set);
}
}
Aggregations