use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class SSADefUseMap method computeWithIndices.
public void computeWithIndices(List<BasicBlock> preorder) {
defs.clear();
uses.clear();
phiDefs.clear();
phiUses.clear();
lastUseIndex.clear();
defIndex.clear();
int index = 0;
Set<Local> usedLocals = new HashSet<>();
for (BasicBlock b : preorder) {
for (Stmt stmt : b) {
phiUses.getNonNull(b);
usedLocals.clear();
for (Expr s : stmt.enumerateOnlyChildren()) if (s.getOpcode() == Opcode.LOCAL_LOAD)
usedLocals.add(((VarExpr) s).getLocal());
buildIndex(b, stmt, index++, usedLocals);
build(b, stmt, usedLocals);
}
}
}
use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class SreedharDestructor method csaa_iii.
// ============================================================================================================= //
// =================================================== CSSA ==================================================== //
// ============================================================================================================= //
private void csaa_iii() {
// iterate over each phi expression
for (Entry<Local, CopyPhiStmt> entry : defuse.phiDefs.entrySet()) {
// System.out.println("process phi " + entry.getValue());
// x0
Local phiTarget = entry.getKey();
CopyPhiStmt copy = entry.getValue();
// l0
BasicBlock defBlock = defuse.defs.get(phiTarget);
PhiExpr phi = copy.getExpression();
candidateResourceSet.clear();
unresolvedNeighborsMap.clear();
// Initialize phiResources set for convenience
final GenericBitSet<PhiResource> phiResources = phiResSetCreator.create();
phiResources.add(new PhiResource(defBlock, phiTarget, true));
for (Entry<BasicBlock, Expr> phiEntry : phi.getArguments().entrySet()) phiResources.add(new PhiResource(phiEntry.getKey(), ((VarExpr) phiEntry.getValue()).getLocal(), false));
// Determine what copies are needed using the four cases.
handleInterference(phiResources);
// Process unresolved resources
resolveDeferred();
// System.out.println(" Cand: " + candidateResourceSet);
// Resolve the candidate resources
Type phiType = phi.getType();
for (PhiResource toResolve : candidateResourceSet) {
if (toResolve.isTarget)
resolvePhiTarget(toResolve, phiType);
else
for (Entry<BasicBlock, Expr> phiArg : phi.getArguments().entrySet()) {
VarExpr phiVar = (VarExpr) phiArg.getValue();
if (phiVar.getLocal() == toResolve.local)
phiVar.setLocal(resolvePhiSource(toResolve.local, phiArg.getKey(), phiType));
}
}
// System.out.println(" interference: ");
// for (Entry<Local, GenericBitSet<Local>> entry2 : interfere.entrySet())
// System.out.println(" " + entry2.getKey() + " : " + entry2.getValue());
// System.out.println(" post-inserted: " + copy);
// Merge pccs for all locals in phi
final GenericBitSet<Local> phiLocals = locals.createBitSet();
phiLocals.add(copy.getVariable().getLocal());
for (Entry<BasicBlock, Expr> phiEntry : phi.getArguments().entrySet()) phiLocals.add(((VarExpr) phiEntry.getValue()).getLocal());
for (Local phiLocal : phiLocals) pccs.put(phiLocal, phiLocals);
// Nullify singleton pccs
for (GenericBitSet<Local> pcc : pccs.values()) if (pcc.size() <= 1)
pcc.clear();
// System.out.println(" pccs:");
// for (Entry<Local, GenericBitSet<Local>> entry2 : pccs.entrySet())
// System.out.println(" " + entry2.getKey() + " : " + entry2.getValue());
// System.out.println();
}
}
use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class SreedharDestructor method checkPccDouble.
// Quadratic (lmao) coalesce check for coalesce case 3, returns true if the copy cannot be removed.
// But thanks to bitsets its linear time
private boolean checkPccDouble(GenericBitSet<Local> pccX, Local x, GenericBitSet<Local> pccY, Local y) {
// System.out.println(" case 3");
GenericBitSet<Local> pccYTrim = pccY.copy();
pccYTrim.remove(y);
for (Local lx : pccX) if (interfere.getNonNull(lx).containsAny(pccYTrim))
return true;
GenericBitSet<Local> pccXTrim = pccX.copy();
pccXTrim.remove(x);
for (Local ly : pccY) if (interfere.getNonNull(ly).containsAny(pccXTrim))
return true;
return false;
}
use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class SreedharDestructor method coalesce.
// ============================================================================================================= //
// ================================================== Coalescing =============================================== //
// ============================================================================================================= //
private void coalesce() {
for (BasicBlock b : cfg.vertices()) {
for (Iterator<Stmt> it = b.iterator(); it.hasNext(); ) {
Stmt stmt = it.next();
if (stmt instanceof CopyVarStmt) {
CopyVarStmt copy = (CopyVarStmt) stmt;
// System.out.println("check " + copy);
if (checkCoalesce(copy)) {
// System.out.println(" coalescing");
// Remove the copy
it.remove();
// Merge pccs
GenericBitSet<Local> pccX = pccs.get(copy.getVariable().getLocal());
Local localY = ((VarExpr) copy.getExpression()).getLocal();
GenericBitSet<Local> pccY = pccs.get(localY);
pccX.add(localY);
pccX.addAll(pccY);
for (Local l : pccY) pccs.put(l, pccX);
}
}
}
}
// System.out.println("post-coalsce pccs:");
// for (Entry<Local, GenericBitSet<Local>> entry : pccs.entrySet())
// System.out.println(" " + entry.getKey() + " : " + entry.getValue());
// System.out.println();
}
use of org.mapleir.ir.locals.Local 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;
}
Aggregations