use of org.mapleir.ir.code.stmt.copy.AbstractCopyStmt in project maple-ir by LLVM-but-worse.
the class SSAGenPass method unstackDefs.
private void unstackDefs(BasicBlock b) {
for (Stmt s : b) {
if (s.getOpcode() == Opcode.PHI_STORE || s.getOpcode() == Opcode.LOCAL_STORE) {
AbstractCopyStmt cvs = (AbstractCopyStmt) s;
Local l = cvs.getVariable().getLocal();
l = builder.graph.getLocals().get(l.getIndex(), l.isStack());
stacks.get(l).pop();
}
}
}
use of org.mapleir.ir.code.stmt.copy.AbstractCopyStmt in project maple-ir by LLVM-but-worse.
the class SSAGenPass method processDeferredTranslations.
private int processDeferredTranslations() {
int i = 0;
Iterator<Entry<VersionedLocal, Set<VarExpr>>> it = pool.uses.entrySet().iterator();
while (it.hasNext()) {
Entry<VersionedLocal, Set<VarExpr>> e = it.next();
VersionedLocal vl = e.getKey();
if (deferred.contains(vl) || vl.isStack()) {
Set<VarExpr> useSet = e.getValue();
AbstractCopyStmt def = pool.defs.get(vl);
if (def != null && useSet.size() == 1) {
/* In this case, the only place that the value
* of this assignment will be used is at the use site.
* Since that value can not be spread until this one
* is, we can propagate it.*/
if (def.getOpcode() != Opcode.PHI_STORE) {
VarExpr use = useSet.iterator().next();
LatestValue val = latest.get(vl);
// System.out.println();
// System.out.println();
// System.out.println(def);
// System.out.println(use);
/* phi var*/
Expr rhs = def.getExpression();
if (use.getParent() != null) {
if (canTransferHandlers(def.getBlock(), use.getBlock()) && val.canPropagate(def, use.getRootParent(), use, false)) {
CodeUnit parent = use.getParent();
if (rhs.getOpcode() == Opcode.CATCH) {
// CodeUnit rp = use.getRootParent();
// System.out.println("DENIED NIGGA");
// System.out.println("replace " + vl + " with " + rhs);
// System.out.println(" in " + parent);
// System.out.println(" kill def: " + def);
// System.out.println();
deferred.remove(vl);
continue;
// check to see if we're moving it to the
// first expression in the block, if we aren't
// then deny, otherwise we can get rid of the local.
// if(rp.getBlock().indexOf(rp) != 1 || rp.enumerateExecutionOrder().indexOf(use) != 0) {
//
// }
}
rhs.unlink();
def.delete();
pool.defs.remove(vl);
useSet.clear();
parent.overwrite(rhs, parent.indexOf(use));
i++;
it.remove();
}
}
}
}
}
}
return i;
}
use of org.mapleir.ir.code.stmt.copy.AbstractCopyStmt in project maple-ir by LLVM-but-worse.
the class LatestValue method canPropagate.
public boolean canPropagate(AbstractCopyStmt def, Stmt use, Expr tail, boolean debug) {
Local local = def.getVariable().getLocal();
Set<Stmt> path = findReachable(def, use);
path.remove(def);
path.add(use);
if (debug) {
System.out.println();
System.out.println("from " + def);
System.out.println("to " + use);
System.out.println(this);
System.out.println("constraints: " + constraints.size());
for (Constraint c : constraints) {
System.out.println(" " + c);
}
System.out.println(" path:");
for (Stmt s : path) {
System.out.println(" " + s);
}
}
for (Stmt stmt : path) {
if (stmt != use) {
for (CodeUnit s : stmt.enumerateWithSelf()) {
for (Constraint c : constraints) {
if (c.fails(s)) {
if (debug) {
System.out.println(" Fail: " + c);
System.out.println(" stmt: " + stmt);
System.out.println(" c: " + s);
}
return false;
}
}
}
} else {
if (constraints.size() > 0) {
for (CodeUnit s : stmt.enumerateExecutionOrder()) {
if (s == tail && (s.getOpcode() == Opcode.LOCAL_LOAD && ((VarExpr) s).getLocal() == local)) {
break;
} else {
for (Constraint c : constraints) {
if (c.fails(s)) {
if (debug) {
System.out.println(" Fail: " + c);
System.out.println(" stmt: " + stmt);
System.out.println(" c: " + s);
}
return false;
}
}
}
}
}
}
}
return true;
}
use of org.mapleir.ir.code.stmt.copy.AbstractCopyStmt in project maple-ir by LLVM-but-worse.
the class PoolLocalValueResolver method getValues.
@Override
public TaintableSet<Expr> getValues(ControlFlowGraph cfg, Local l) {
if (cfg.getLocals() != pool) {
throw new UnsupportedOperationException();
}
AbstractCopyStmt copy = pool.defs.get(l);
TaintableSet<Expr> set = new TaintableSet<>();
if (copy.getOpcode() == Opcode.PHI_STORE) {
// checkRecursive(l);
// PhiExpr phi = ((CopyPhiStmt) copy).getExpression();
/*for(Expr e : phi.getArguments().values()) {
if(e.getOpcode() == Opcode.LOCAL_LOAD) {
Local l2 = ((VarExpr) e).getLocal();
if(l2 == l) {
throw new RuntimeException(copy.toString());
}
}
}*/
// set.addAll(phi.getArguments().values());
} else {
// set.add(copy.getExpression());
}
set.add(copy.getExpression());
return set;
}
use of org.mapleir.ir.code.stmt.copy.AbstractCopyStmt in project maple-ir by LLVM-but-worse.
the class ConstantParameterPass method inlineConstant.
private void inlineConstant(ControlFlowGraph cfg, int argLocalIndex, Object o) {
/* we don't actually demote the synthetic copy
* here as we would also need to change the
* method desc and we can't do that until
* later so we defer it. */
LocalsPool pool = cfg.getLocals();
/* create the spill variable but not the
* actual definition yet. */
VersionedLocal argLocal = pool.get(argLocalIndex, 0, false);
VersionedLocal spill = pool.makeLatestVersion(argLocal);
AbstractCopyStmt synthParamCopy = pool.defs.get(argLocal);
ConstantExpr rhsVal = new ConstantExpr(o, synthParamCopy.getType() == Type.BOOLEAN_TYPE ? Type.BYTE_TYPE : synthParamCopy.getType());
/* we have to maintain local references in
* phis as opposed to direct constant refs,
* so we go through every use of the argLocal
* and either replace it with the constant or
* a reference to the spill local if it is in
* a phi. */
Set<VarExpr> spillUses = new HashSet<>();
boolean requireSpill = false;
Iterator<VarExpr> it = pool.uses.get(argLocal).iterator();
while (it.hasNext()) {
VarExpr v = it.next();
if (v.getParent() == null) {
/* the use is in a phi, we can't
* remove the def.
*
* we also replace the old var
* with the new spill one so we
* have to add this as a use of
* the new spill local. */
spillUses.add(v);
v.setLocal(spill);
requireSpill = true;
} else {
CodeUnit par = v.getParent();
par.overwrite(rhsVal.copy(), par.indexOf(v));
}
/* this use is no longer associated
* with the old argLocal. */
it.remove();
}
if (pool.uses.get(argLocal).size() != 0) {
throw new IllegalStateException(String.format("l:%s, uses:%s", argLocal, pool.uses.get(argLocal)));
}
if (requireSpill) {
/* generate the copy for the spill (v = const) */
CopyVarStmt spillCopy = new CopyVarStmt(new VarExpr(spill, synthParamCopy.getVariable().getType()), rhsVal);
synthParamCopy.getBlock().add(spillCopy);
/* initialise data entries for the new spill
* variable. */
pool.defs.put(spill, spillCopy);
pool.uses.put(spill, spillUses);
}
}
Aggregations