use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.
the class SreedharDestructor method checkCoalesce.
private boolean checkCoalesce(CopyVarStmt copy) {
// Only coalesce simple copies x=y.
if (copy.isSynthetic() || copy.getExpression().getOpcode() != LOCAL_LOAD)
return false;
Local localX = copy.getVariable().getLocal();
Local localY = ((VarExpr) copy.getExpression()).getLocal();
GenericBitSet<Local> pccX = pccs.getNonNull(localX), pccY = pccs.getNonNull(localY);
// Trivial case: Now that we are in CSSA, we can simply drop copies within the same pcc.
if (pccX == pccY)
return true;
boolean xEmpty = pccX.isEmpty(), yEmpty = pccY.isEmpty();
// Case 1 - If pcc[x] and pcc[y] are empty the copy can be removed regardless of interference.
if (xEmpty & yEmpty)
return true;
else // interfere with any local in (pcc[x]-x).
if (xEmpty ^ yEmpty) {
if (checkPccSingle(yEmpty ? pccX : pccY, yEmpty ? localX : localY, yEmpty ? localY : localX))
return false;
} else // interferes with any local in (pcc[x]-x) and not local in pcc[x] interferes with any local in (pcc[y]-y).
if (checkPccDouble(pccX, localX, pccY, localY))
return false;
// No interference, copy can be removed
return true;
}
use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.
the class SreedharDestructor method insertEnd.
private Local insertEnd(Local xi, BasicBlock lk, Type type) {
Local spill = locals.makeLatestVersion(xi);
CopyVarStmt newCopy = new CopyVarStmt(new VarExpr(spill, type), new VarExpr(xi, type));
if (lk.isEmpty())
lk.add(newCopy);
else if (!lk.get(lk.size() - 1).canChangeFlow())
lk.add(newCopy);
else
lk.add(lk.size() - 1, newCopy);
return spill;
}
use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.
the class SreedharDestructor method leaveSSA.
// ============================================================================================================= //
// ================================================== Leave SSA ================================================ //
// ============================================================================================================= //
private void leaveSSA() {
// Flatten pccs into one variable through remapping
// System.out.println("remap:");
Map<Local, Local> remap = new HashMap<>();
for (Entry<Local, GenericBitSet<Local>> entry : pccs.entrySet()) {
GenericBitSet<Local> pcc = entry.getValue();
if (pcc.isEmpty())
continue;
Local local = entry.getKey();
if (remap.containsKey(local))
continue;
Local newLocal = locals.makeLatestVersion(local);
remap.put(local, newLocal);
// System.out.println(" " + local + " -> " + newLocal);
for (Local pccLocal : pcc) {
remap.put(pccLocal, newLocal);
// System.out.println(" " + pccLocal + " -> " + newLocal);
}
}
for (BasicBlock b : cfg.vertices()) {
for (Iterator<Stmt> it = b.iterator(); it.hasNext(); ) {
Stmt stmt = it.next();
// We can now simply drop all phi statements.
if (stmt instanceof CopyPhiStmt) {
it.remove();
continue;
}
// Apply remappings
if (stmt instanceof CopyVarStmt) {
VarExpr lhs = ((CopyVarStmt) stmt).getVariable();
Local copyTarget = lhs.getLocal();
lhs.setLocal(remap.getOrDefault(copyTarget, copyTarget));
}
for (Expr child : stmt.enumerateOnlyChildren()) {
if (child.getOpcode() == LOCAL_LOAD) {
VarExpr var = (VarExpr) child;
Local loadSource = var.getLocal();
var.setLocal(remap.getOrDefault(loadSource, loadSource));
}
}
}
}
// System.out.println();
}
use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.
the class SreedharDestructor method insertStart.
// replace the phi target xi with xi' and place a temp copy xi = xi' after all phi statements.
private Local insertStart(PhiResource res, Type type) {
BasicBlock li = res.block;
Local xi = res.local;
if (li.isEmpty())
throw new IllegalStateException("Trying to resolve phi target interference in empty block " + li);
Local spill = locals.makeLatestVersion(xi);
int i;
for (i = 0; i < li.size() && li.get(i).getOpcode() == Opcode.PHI_STORE; i++) {
CopyPhiStmt copyPhi = (CopyPhiStmt) li.get(i);
VarExpr copyTarget = copyPhi.getVariable();
if (copyTarget.getLocal() == xi)
copyTarget.setLocal(spill);
}
li.add(i, new CopyVarStmt(new VarExpr(xi, type), new VarExpr(spill, type)));
return spill;
}
use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.
the class SreedharDestructor method buildInterference.
private void buildInterference() {
for (BasicBlock b : cfg.vertices()) {
// not a copy!
GenericBitSet<Local> in = liveness.in(b);
// not a copy!
GenericBitSet<Local> out = liveness.out(b);
// in interfere in
for (Local l : in) interfere.getNonNull(l).addAll(in);
// out interfere out
for (Local l : out) interfere.getNonNull(l).addAll(out);
// backwards traverse for dealing with variables that are defined and used in the same block
GenericBitSet<Local> intraLive = out.copy();
ListIterator<Stmt> it = b.listIterator(b.size());
while (it.hasPrevious()) {
Stmt stmt = it.previous();
if (stmt instanceof CopyVarStmt) {
CopyVarStmt copy = (CopyVarStmt) stmt;
Local defLocal = copy.getVariable().getLocal();
intraLive.remove(defLocal);
}
for (Expr child : stmt.enumerateOnlyChildren()) {
if (stmt.getOpcode() == LOCAL_LOAD) {
Local usedLocal = ((VarExpr) child).getLocal();
if (intraLive.add(usedLocal)) {
interfere.getNonNull(usedLocal).addAll(intraLive);
for (Local l : intraLive) interfere.get(l).add(usedLocal);
}
}
}
}
}
// System.out.println("Interference:");
// for (Entry<Local, GenericBitSet<Local>> entry : interfere.entrySet())
// System.out.println(" " + entry.getKey() + " : " + entry.getValue());
// System.out.println();
}
Aggregations