use of org.mapleir.ir.cfg.BasicBlock 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.cfg.BasicBlock 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.cfg.BasicBlock 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();
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class BoissinotDestructor method computeValueInterference.
private void computeValueInterference() {
List<BasicBlock> topoorder = dom_dfs.getTopoOrder();
for (BasicBlock bl : topoorder) {
for (Stmt stmt : bl) {
int opcode = stmt.getOpcode();
if (opcode == Opcode.LOCAL_STORE) {
CopyVarStmt copy = (CopyVarStmt) stmt;
Expr e = copy.getExpression();
Local b = copy.getVariable().getLocal();
if (!copy.isSynthetic() && e.getOpcode() == Opcode.LOCAL_LOAD) {
LinkedHashSet<Local> vc = values.get(((VarExpr) e).getLocal());
vc.add(b);
values.put(b, vc);
} else {
values.getNonNull(b);
}
} else if (opcode == Opcode.PHI_STORE) {
CopyPhiStmt copy = (CopyPhiStmt) stmt;
values.getNonNull(copy.getVariable().getLocal());
} else if (opcode == ParallelCopyVarStmt.PARALLEL_STORE) {
ParallelCopyVarStmt copy = (ParallelCopyVarStmt) stmt;
for (CopyPair p : copy.pairs) {
LinkedHashSet<Local> valueClass = values.getNonNull(p.source);
valueClass.add(p.targ);
values.put(p.targ, valueClass);
}
}
}
}
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class BoissinotDestructor method liftPhiOperands.
private void liftPhiOperands() {
for (BasicBlock b : cfg.vertices()) {
for (Stmt stmt : new ArrayList<>(b)) {
if (stmt.getOpcode() == Opcode.PHI_STORE) {
CopyPhiStmt copy = (CopyPhiStmt) stmt;
for (Entry<BasicBlock, Expr> e : copy.getExpression().getArguments().entrySet()) {
Expr expr = e.getValue();
int opcode = expr.getOpcode();
if (opcode == Opcode.CONST_LOAD || opcode == Opcode.CATCH) {
VersionedLocal vl = locals.makeLatestVersion(locals.get(0, false));
CopyVarStmt cvs = new CopyVarStmt(new VarExpr(vl, expr.getType()), expr);
e.setValue(new VarExpr(vl, expr.getType()));
insertEnd(e.getKey(), cvs);
} else if (opcode != Opcode.LOCAL_LOAD) {
throw new IllegalArgumentException("Non-variable expression in phi: " + copy);
}
}
}
}
}
}
Aggregations