use of org.mapleir.ir.code.stmt.copy.CopyVarStmt 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.code.stmt.copy.CopyVarStmt 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.code.stmt.copy.CopyVarStmt 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.code.stmt.copy.CopyVarStmt 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);
}
}
}
}
}
}
use of org.mapleir.ir.code.stmt.copy.CopyVarStmt in project maple-ir by LLVM-but-worse.
the class SSABlockLivenessAnalyser method precomputeBlock.
// compute def, use, and phi for given block
private void precomputeBlock(BasicBlock b) {
def.getNonNull(b);
use.getNonNull(b);
phiUse.getNonNull(b);
phiDef.getNonNull(b);
// we have to iterate in reverse order because a definition will kill a use in the current block
// this is so that uses do not escape a block if its def is in the same block. this is basically
// simulating a statement graph analysis
ListIterator<Stmt> it = b.listIterator(b.size());
while (it.hasPrevious()) {
Stmt stmt = it.previous();
int opcode = stmt.getOpcode();
if (opcode == Opcode.PHI_STORE) {
CopyPhiStmt copy = (CopyPhiStmt) stmt;
phiDef.get(b).add(copy.getVariable().getLocal());
PhiExpr phi = copy.getExpression();
for (Map.Entry<BasicBlock, Expr> e : phi.getArguments().entrySet()) {
BasicBlock exprSource = e.getKey();
Expr phiExpr = e.getValue();
GenericBitSet<Local> useSet = phiUse.get(b).getNonNull(exprSource);
if (phiExpr.getOpcode() == Opcode.LOCAL_LOAD) {
useSet.add(((VarExpr) phiExpr).getLocal());
} else
for (Expr child : phiExpr.enumerateOnlyChildren()) {
if (child.getOpcode() == Opcode.LOCAL_LOAD) {
useSet.add(((VarExpr) child).getLocal());
}
}
}
} else {
if (opcode == Opcode.LOCAL_STORE) {
CopyVarStmt copy = (CopyVarStmt) stmt;
Local l = copy.getVariable().getLocal();
def.get(b).add(l);
use.get(b).remove(l);
Expr e = copy.getExpression();
// adding it as live-in.
if (e.getOpcode() == Opcode.CATCH) {
if (hasNaturalPredecessors(cfg, b)) {
use.get(b).add(l);
}
}
}
for (Expr c : stmt.enumerateOnlyChildren()) {
if (c.getOpcode() == Opcode.LOCAL_LOAD) {
VarExpr v = (VarExpr) c;
use.get(b).add(v.getLocal());
}
}
}
}
}
Aggregations