use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class AbstractCopyStmt method toCode.
@Override
public // todo: this probably needs a refactoring
void toCode(MethodVisitor visitor, ControlFlowGraph cfg) {
if (expression instanceof VarExpr) {
if (((VarExpr) expression).getLocal() == variable.getLocal()) {
return;
}
}
variable.getLocal().setTempLocal(false);
expression.toCode(visitor, cfg);
Type type = variable.getType();
if (TypeUtils.isPrimitive(type)) {
int[] cast = TypeUtils.getPrimitiveCastOpcodes(expression.getType(), type);
for (int i = 0; i < cast.length; i++) visitor.visitInsn(cast[i]);
}
Local local = variable.getLocal();
if (local.isStack()) {
visitor.visitVarInsn(TypeUtils.getVariableStoreOpcode(getType()), variable.getLocal().getCodeIndex());
variable.getLocal().setTempLocal(true);
} else {
visitor.visitVarInsn(TypeUtils.getVariableStoreOpcode(getType()), variable.getLocal().getCodeIndex());
}
}
use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class BoissinotDestructor method intersect.
private boolean intersect(Local a, Local b) {
if (a == b) {
for (Entry<Local, CongruenceClass> e : congruenceClasses.entrySet()) {
System.err.println(e.getKey() + " in " + e.getValue());
}
throw new IllegalArgumentException("me too thanks: " + a);
}
if (checkPreDomOrder(a, b))
throw new IllegalArgumentException("b should dom a");
BasicBlock defA = defuse.defs.get(a);
// if it's liveOut it definitely intersects
if (resolver.isLiveOut(defA, b))
return true;
// defA == defB or liveIn to intersect{
if (!resolver.isLiveIn(defA, b) && defA != defuse.defs.get(b))
return false;
// ambiguous case. we need to check if use(dom) occurs after def(def), n that case it interferes. otherwise no
int domUseIndex = defuse.lastUseIndex.getNonNull(b).getOrDefault(defA, -1);
if (domUseIndex == -1) {
return false;
}
int defDefIndex = defuse.defIndex.get(a);
return domUseIndex > defDefIndex;
}
use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class BoissinotDestructor method checkInterfereSingle.
private boolean checkInterfereSingle(CongruenceClass red, CongruenceClass blue) {
Local a = red.first();
Local b = blue.first();
// we want a > b in dom order (b is parent)
if (checkPreDomOrder(a, b)) {
Local c = a;
a = b;
b = c;
}
if (intersect(a, b) && values.getNonNull(a) != values.getNonNull(b)) {
return true;
} else {
equalAncIn.put(a, b);
red.add(b);
congruenceClasses.put(b, red);
return false;
}
}
use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class BoissinotDestructor method checkInterfere.
private boolean checkInterfere(CongruenceClass red, CongruenceClass blue) {
Stack<Local> dom = new Stack<>();
Stack<Boolean> domClasses = new Stack<>();
int nr = 0, nb = 0;
Local ir = red.first(), ib = blue.first();
// end sentinels
Local lr = red.last(), lb = blue.last();
boolean redHasNext = true, blueHasNext = true;
// these have no parents so we have to manually init them
equalAncOut.put(ir, null);
equalAncOut.put(ib, null);
do {
Local current;
boolean currentClass;
if (!blueHasNext || (redHasNext && checkPreDomOrder(ir, ib))) {
// current = red[ir++]
current = ir;
currentClass = true;
nr++;
if (redHasNext = ir != lr)
ir = red.higher(ir);
} else {
// current = blue[ib++]
current = ib;
currentClass = false;
nb++;
if (blueHasNext = ib != lb)
ib = blue.higher(ib);
}
if (!dom.isEmpty()) {
Local parent;
boolean parentClass;
do {
parent = dom.pop();
parentClass = domClasses.pop();
if (parentClass)
nr--;
else
nb--;
} while (!dom.isEmpty() && !checkPreDomOrder(parent, current));
if (interference(current, parent, currentClass == parentClass))
return true;
}
dom.push(current);
domClasses.push(currentClass);
} while ((redHasNext && nb > 0) || (blueHasNext && nr > 0) || (redHasNext && blueHasNext));
return false;
}
use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class BoissinotDestructor method copyPhiOperands.
private void copyPhiOperands(BasicBlock b) {
NullPermeableHashMap<BasicBlock, List<PhiRes>> wl = new NullPermeableHashMap<>(new ListCreator<>());
ParallelCopyVarStmt dst_copy = new ParallelCopyVarStmt();
for (Stmt stmt : b) {
// phis only appear at the start of a block.
if (stmt.getOpcode() != Opcode.PHI_STORE) {
break;
}
CopyPhiStmt copy = (CopyPhiStmt) stmt;
PhiExpr phi = copy.getExpression();
// so that we can parallelise the copy when we insert it.
for (Entry<BasicBlock, Expr> e : phi.getArguments().entrySet()) {
BasicBlock h = e.getKey();
// these are validated in init().
VarExpr v = (VarExpr) e.getValue();
PhiRes r = new PhiRes(copy.getVariable().getLocal(), phi, h, v.getLocal(), v.getType());
wl.getNonNull(h).add(r);
}
// for each x0, where x0 is a phi copy target, create a new variable z0 for
// a copy x0 = z0 and replace the phi copy target to z0.
Local x0 = copy.getVariable().getLocal();
Local z0 = locals.makeLatestVersion(x0);
// x0 = z0
dst_copy.pairs.add(new CopyPair(x0, z0, copy.getVariable().getType()));
// z0 = phi(...)
copy.getVariable().setLocal(z0);
}
// resolve
if (dst_copy.pairs.size() > 0)
insertStart(b, dst_copy);
for (Entry<BasicBlock, List<PhiRes>> e : wl.entrySet()) {
BasicBlock p = e.getKey();
ParallelCopyVarStmt copy = new ParallelCopyVarStmt();
for (PhiRes r : e.getValue()) {
// for each xi source in a phi, create a new variable zi, and insert the copy
// zi = xi in the pred Li. then replace the phi arg from Li with zi.
Local xi = r.l;
Local zi = locals.makeLatestVersion(xi);
copy.pairs.add(new CopyPair(zi, xi, r.type));
// we consider phi args to be used in the pred instead of the block
// where the phi is, so we need to update the def/use maps here.
r.phi.setArgument(r.pred, new VarExpr(zi, r.type));
}
insertEnd(p, copy);
}
}
Aggregations