use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class BoissinotDestructor method merge.
private void merge(CongruenceClass conClassA, CongruenceClass conClassB) {
conClassA.addAll(conClassB);
for (Local l : conClassB) congruenceClasses.put(l, conClassA);
for (Local l : conClassA) {
Local in = equalAncIn.get(l);
Local out = equalAncOut.get(l);
if (in != null && out != null)
equalAncIn.put(l, checkPreDomOrder(in, out) ? in : out);
else
equalAncIn.put(l, in != null ? in : out != null ? out : null);
}
}
use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class BoissinotDestructor method applyRemapping.
// Flatten ccs so that each local in each cc is replaced with a new representative local.
private void applyRemapping() {
GenericBitSet<BasicBlock> processed = cfg.createBitSet();
GenericBitSet<BasicBlock> processed2 = cfg.createBitSet();
for (Local e : remap.keySet()) {
for (BasicBlock used : defuse.uses.getNonNull(e)) {
if (processed.contains(used))
continue;
processed.add(used);
for (Stmt stmt : used) {
for (Expr s : stmt.enumerateOnlyChildren()) {
if (s.getOpcode() == Opcode.LOCAL_LOAD) {
VarExpr v = (VarExpr) s;
v.setLocal(remap.getOrDefault(v.getLocal(), v.getLocal()));
}
}
}
}
BasicBlock b = defuse.defs.get(e);
if (processed2.contains(b))
continue;
processed2.add(b);
for (Iterator<Stmt> it = b.iterator(); it.hasNext(); ) {
Stmt stmt = it.next();
if (stmt instanceof ParallelCopyVarStmt) {
ParallelCopyVarStmt copy = (ParallelCopyVarStmt) stmt;
for (Iterator<CopyPair> it2 = copy.pairs.iterator(); it2.hasNext(); ) {
CopyPair p = it2.next();
p.source = remap.getOrDefault(p.source, p.source);
p.targ = remap.getOrDefault(p.targ, p.targ);
if (p.source == p.targ)
it2.remove();
}
if (copy.pairs.isEmpty())
it.remove();
} else if (stmt instanceof CopyVarStmt) {
AbstractCopyStmt copy = (AbstractCopyStmt) stmt;
VarExpr v = copy.getVariable();
v.setLocal(remap.getOrDefault(v.getLocal(), v.getLocal()));
if (!copy.isSynthetic() && copy.getExpression().getOpcode() == Opcode.LOCAL_LOAD)
if (((VarExpr) copy.getExpression()).getLocal() == v.getLocal())
it.remove();
} else if (stmt instanceof CopyPhiStmt) {
throw new IllegalArgumentException("Phi copy still in block?");
}
}
}
for (Local e : remap.keySet()) {
defuse.defs.remove(e);
defuse.uses.remove(e);
}
}
use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class BoissinotDestructor method coalesceCopies.
// Coalesce parallel and standard copies based on value interference, dropping coalesced copies
private void coalesceCopies() {
// if they do not interfere merge the conClasses and those two vars can be coalesced. delete the copy.
for (BasicBlock b : dom_dfs.getPreOrder()) {
for (Iterator<Stmt> it = b.iterator(); it.hasNext(); ) {
Stmt stmt = it.next();
if (stmt instanceof CopyVarStmt) {
CopyVarStmt copy = (CopyVarStmt) stmt;
if (!copy.isSynthetic() && copy.getExpression() instanceof VarExpr) {
Local lhs = copy.getVariable().getLocal();
Local rhs = ((VarExpr) copy.getExpression()).getLocal();
if (!isReservedRegister((VersionedLocal) rhs)) {
if (tryCoalesceCopyValue(lhs, rhs)) {
// System.out.println("COPYKILL(1) " + lhs + " == " + rhs);
it.remove();
}
if (tryCoalesceCopySharing(lhs, rhs)) {
// System.out.println("SHAREKILL(1) " + lhs + " == " + rhs);
it.remove();
}
}
}
} else if (stmt instanceof ParallelCopyVarStmt) {
// we need to do it for each one. if all of the copies are
// removed then remove the pcvs
ParallelCopyVarStmt copy = (ParallelCopyVarStmt) stmt;
for (Iterator<CopyPair> pairIter = copy.pairs.listIterator(); pairIter.hasNext(); ) {
CopyPair pair = pairIter.next();
Local lhs = pair.targ, rhs = pair.source;
if (!isReservedRegister((VersionedLocal) rhs)) {
if (tryCoalesceCopyValue(lhs, rhs)) {
// System.out.println("COPYKILL(2) " + lhs + " == " + rhs);
pairIter.remove();
}
if (tryCoalesceCopySharing(lhs, rhs)) {
// System.out.println("SHAREKILL(2) " + lhs + " == " + rhs);
pairIter.remove();
}
}
}
if (copy.pairs.isEmpty())
it.remove();
}
}
}
}
use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class BoissinotDestructor method tryCoalesceCopySharing.
// Process the copy a = b. Returns true of a and b can be coalesced via sharing.
private boolean tryCoalesceCopySharing(Local a, Local b) {
// if (!DO_SHARE_COALESCE)
// return false;
CongruenceClass pccX = getCongruenceClass(a);
CongruenceClass pccY = getCongruenceClass(b);
for (Local c : values.get(a)) {
if (c == b || c == a || !checkPreDomOrder(c, a) || !intersect(a, c))
continue;
CongruenceClass pccZ = getCongruenceClass(c);
// If X = Z and X != Y, the copy is redundant.
if (pccX == pccZ && pccX != pccY) {
return true;
}
// after a and b have been coalesced as c already has the correct value.
if (pccY != pccX && pccY != pccZ && pccX != pccZ && tryCoalesceCopyValue(a, c)) {
return true;
}
}
return false;
}
use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class BoissinotDestructor method coalescePhis.
// Initialize ccs based on phis and drop phi statements
private void coalescePhis() {
GenericBitSet<BasicBlock> processed = cfg.createBitSet();
for (Entry<Local, CopyPhiStmt> e : defuse.phiDefs.entrySet()) {
Local l = e.getKey();
BasicBlock b = e.getValue().getBlock();
// since we are now in csaa, phi locals never interfere and are in the same congruence class.
// therefore we can coalesce them all together and drop phis. with this, we leave cssa.
PhiExpr phi = e.getValue().getExpression();
CongruenceClass pcc = new CongruenceClass();
pcc.add(l);
congruenceClasses.put(l, pcc);
for (Expr ex : phi.getArguments().values()) {
VarExpr v = (VarExpr) ex;
Local argL = v.getLocal();
pcc.add(argL);
congruenceClasses.put(argL, pcc);
}
// we can simply drop all the phis without further consideration
if (!processed.contains(b)) {
processed.add(b);
Iterator<Stmt> it = b.iterator();
while (it.hasNext()) {
Stmt stmt = it.next();
if (stmt.getOpcode() == Opcode.PHI_STORE) {
it.remove();
} else {
break;
}
}
}
}
defuse.phiDefs.clear();
}
Aggregations