Search in sources :

Example 26 with VarExpr

use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.

the class SSAGenPass method processDeferredTranslations.

private int processDeferredTranslations() {
    int i = 0;
    Iterator<Entry<VersionedLocal, Set<VarExpr>>> it = pool.uses.entrySet().iterator();
    while (it.hasNext()) {
        Entry<VersionedLocal, Set<VarExpr>> e = it.next();
        VersionedLocal vl = e.getKey();
        if (deferred.contains(vl) || vl.isStack()) {
            Set<VarExpr> useSet = e.getValue();
            AbstractCopyStmt def = pool.defs.get(vl);
            if (def != null && useSet.size() == 1) {
                /* In this case, the only place that the value
					 * of this assignment will be used is at the use site.
					 * Since that value can not be spread until this one
					 * is, we can propagate it.*/
                if (def.getOpcode() != Opcode.PHI_STORE) {
                    VarExpr use = useSet.iterator().next();
                    LatestValue val = latest.get(vl);
                    // System.out.println();
                    // System.out.println();
                    // System.out.println(def);
                    // System.out.println(use);
                    /* phi var*/
                    Expr rhs = def.getExpression();
                    if (use.getParent() != null) {
                        if (canTransferHandlers(def.getBlock(), use.getBlock()) && val.canPropagate(def, use.getRootParent(), use, false)) {
                            CodeUnit parent = use.getParent();
                            if (rhs.getOpcode() == Opcode.CATCH) {
                                // CodeUnit rp = use.getRootParent();
                                // System.out.println("DENIED NIGGA");
                                // System.out.println("replace " + vl + " with " + rhs);
                                // System.out.println(" in " + parent);
                                // System.out.println(" kill def: " + def);
                                // System.out.println();
                                deferred.remove(vl);
                                continue;
                            // check to see if we're moving it to the
                            // first expression in the block, if we aren't
                            // then deny, otherwise we can get rid of the local.
                            // if(rp.getBlock().indexOf(rp) != 1 || rp.enumerateExecutionOrder().indexOf(use) != 0) {
                            // 
                            // }
                            }
                            rhs.unlink();
                            def.delete();
                            pool.defs.remove(vl);
                            useSet.clear();
                            parent.overwrite(rhs, parent.indexOf(use));
                            i++;
                            it.remove();
                        }
                    }
                }
            }
        }
    }
    return i;
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) LatestValue(org.mapleir.ir.cfg.builder.ssaopt.LatestValue) Entry(java.util.Map.Entry) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) InitialisedObjectExpr(org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) Constraint(org.mapleir.ir.cfg.builder.ssaopt.Constraint) CodeUnit(org.mapleir.ir.code.CodeUnit)

Example 27 with VarExpr

use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.

the class SSAGenPass method prune.

private boolean prune(AbstractCopyStmt def) {
    if (def.isSynthetic()) {
        return false;
    }
    Expr e = def.getExpression();
    if (canPrune(e)) {
        for (Expr s : e.enumerateWithSelf()) {
            if (s.getOpcode() == Opcode.LOCAL_LOAD) {
                VarExpr v = (VarExpr) s;
                VersionedLocal vl = (VersionedLocal) v.getLocal();
                pool.uses.get(vl).remove(v);
            }
        }
        def.delete();
        return true;
    }
    return false;
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) InitialisedObjectExpr(org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr)

Example 28 with VarExpr

use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.

the class LatestValue method canPropagate.

public boolean canPropagate(AbstractCopyStmt def, Stmt use, Expr tail, boolean debug) {
    Local local = def.getVariable().getLocal();
    Set<Stmt> path = findReachable(def, use);
    path.remove(def);
    path.add(use);
    if (debug) {
        System.out.println();
        System.out.println("from " + def);
        System.out.println("to " + use);
        System.out.println(this);
        System.out.println("constraints: " + constraints.size());
        for (Constraint c : constraints) {
            System.out.println(" " + c);
        }
        System.out.println(" path:");
        for (Stmt s : path) {
            System.out.println("  " + s);
        }
    }
    for (Stmt stmt : path) {
        if (stmt != use) {
            for (CodeUnit s : stmt.enumerateWithSelf()) {
                for (Constraint c : constraints) {
                    if (c.fails(s)) {
                        if (debug) {
                            System.out.println("  Fail: " + c);
                            System.out.println("  stmt: " + stmt);
                            System.out.println("     c: " + s);
                        }
                        return false;
                    }
                }
            }
        } else {
            if (constraints.size() > 0) {
                for (CodeUnit s : stmt.enumerateExecutionOrder()) {
                    if (s == tail && (s.getOpcode() == Opcode.LOCAL_LOAD && ((VarExpr) s).getLocal() == local)) {
                        break;
                    } else {
                        for (Constraint c : constraints) {
                            if (c.fails(s)) {
                                if (debug) {
                                    System.out.println("  Fail: " + c);
                                    System.out.println("  stmt: " + stmt);
                                    System.out.println("     c: " + s);
                                }
                                return false;
                            }
                        }
                    }
                }
            }
        }
    }
    return true;
}
Also used : Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) VarExpr(org.mapleir.ir.code.expr.VarExpr) Stmt(org.mapleir.ir.code.Stmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) CodeUnit(org.mapleir.ir.code.CodeUnit)

Example 29 with VarExpr

use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.

the class LocalsPool method realloc.

/* public Local newLocal(boolean isStack) {
		int index = cache.size();
		while(true) {
			String key = key(index, isStack);
			if(!cache.containsKey(key)) {
				return get(index, isStack);
			}
		}
	} */
public int realloc(ControlFlowGraph cfg) {
    NullPermeableHashMap<Local, Set<Type>> types = new NullPermeableHashMap<>(SetCreator.getInstance());
    int min = 0;
    Set<Local> safe = new HashSet<>();
    for (BasicBlock b : cfg.vertices()) {
        for (Stmt stmt : b) {
            if (stmt.getOpcode() == Opcode.LOCAL_STORE) {
                CopyVarStmt cp = (CopyVarStmt) stmt;
                VarExpr var = cp.getVariable();
                Local local = var.getLocal();
                if (!cp.isSynthetic()) {
                    types.getNonNull(local).add(var.getType());
                } else {
                    safe.add(local);
                }
                types.getNonNull(local).add(var.getType());
            }
            for (Expr s : stmt.enumerateOnlyChildren()) {
                if (s.getOpcode() == Opcode.LOCAL_LOAD) {
                    VarExpr var = (VarExpr) s;
                    Local local = var.getLocal();
                    types.getNonNull(local).add(var.getType());
                }
            }
        }
    }
    Map<Local, Type> stypes = new HashMap<>();
    for (Entry<Local, Set<Type>> e : types.entrySet()) {
        Set<Type> set = e.getValue();
        Set<Type> refined = new HashSet<>();
        if (set.size() > 1) {
            for (Type t : set) {
                refined.add(TypeUtils.asSimpleType(t));
            }
            if (refined.size() != 1) {
                boolean valid = false;
                if (refined.size() == 2) {
                    // TODO: proper check
                    Iterator<Type> it = refined.iterator();
                    if (it.next().getSize() == it.next().getSize()) {
                        Type t = refined.iterator().next();
                        refined.clear();
                        refined.add(t);
                        valid = true;
                    }
                }
                if (!valid) {
                    for (Entry<Local, Set<Type>> e1 : types.entrySet()) {
                        System.err.println(e1.getKey() + "  ==  " + e1.getValue());
                    }
                    // String.format("illegal typesets for %s, set=%s, refined=%s", args)
                    throw new RuntimeException("illegal typesets for " + e.getKey());
                }
            }
            Local l = e.getKey();
            stypes.put(l, refined.iterator().next());
        // if(!safe.contains(l)) {
        // stypes.put(l, refined.iterator().next());
        // }
        } else {
            Local l = e.getKey();
            stypes.put(l, set.iterator().next());
        // if(!safe.contains(l)) {
        // }
        }
    }
    // for(Entry<Local, Type> e : stypes.entrySet()) {
    // System.out.println(e.getKey() + "  ==  " + e.getValue());
    // }
    // lvars then svars, ordered of course,
    List<Local> wl = new ArrayList<>(stypes.keySet());
    // System.out.println("safe: " + safe);
    wl.sort(new Comparator<Local>() {

        @Override
        public int compare(Local o1, Local o2) {
            boolean s1 = safe.contains(o1);
            boolean s2 = safe.contains(o2);
            if (s1 && !s2) {
                return -1;
            } else if (!s1 && s2) {
                return 1;
            } else {
                return o1.compareTo(o2);
            }
        }
    });
    // System.out.println("wl: " + wl);
    Map<Local, Local> remap = new HashMap<>();
    int idx = min;
    for (Local l : wl) {
        Type type = stypes.get(l);
        Local newL = get(idx, false);
        if (l != newL) {
            remap.put(l, newL);
        }
        idx += type.getSize();
    }
    remap(cfg, remap);
    return idx;
}
Also used : GenericBitSet(org.mapleir.stdlib.collections.bitset.GenericBitSet) NullPermeableHashMap(org.mapleir.stdlib.collections.map.NullPermeableHashMap) Stmt(org.mapleir.ir.code.Stmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) NullPermeableHashMap(org.mapleir.stdlib.collections.map.NullPermeableHashMap) VarExpr(org.mapleir.ir.code.expr.VarExpr) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) BasicLocal(org.mapleir.ir.locals.impl.BasicLocal) Type(org.objectweb.asm.Type) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr)

Example 30 with VarExpr

use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.

the class LocalsPool method remap.

public static void remap(ControlFlowGraph cfg, Map<? extends Local, ? extends Local> remap) {
    for (BasicBlock b : cfg.vertices()) {
        for (Stmt stmt : b) {
            if (stmt.getOpcode() == Opcode.LOCAL_STORE) {
                VarExpr v = ((CopyVarStmt) stmt).getVariable();
                Local l = v.getLocal();
                if (remap.containsKey(l)) {
                    Local l2 = remap.get(l);
                    v.setLocal(l2);
                }
            }
            for (Expr s : stmt.enumerateOnlyChildren()) {
                if (s.getOpcode() == Opcode.LOCAL_LOAD) {
                    VarExpr v = (VarExpr) s;
                    Local l = v.getLocal();
                    if (remap.containsKey(l)) {
                        v.setLocal(remap.get(l));
                    }
                }
            }
        }
    }
}
Also used : VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) VarExpr(org.mapleir.ir.code.expr.VarExpr) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) BasicLocal(org.mapleir.ir.locals.impl.BasicLocal) Stmt(org.mapleir.ir.code.Stmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)

Aggregations

VarExpr (org.mapleir.ir.code.expr.VarExpr)51 Expr (org.mapleir.ir.code.Expr)37 Local (org.mapleir.ir.locals.Local)32 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)31 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)30 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)29 BasicBlock (org.mapleir.ir.cfg.BasicBlock)26 Stmt (org.mapleir.ir.code.Stmt)25 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)25 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)21 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)15 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)13 InitialisedObjectExpr (org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr)12 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)7 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)7 Type (org.objectweb.asm.Type)7 HashSet (java.util.HashSet)6 Constraint (org.mapleir.ir.cfg.builder.ssaopt.Constraint)6 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)5 PopStmt (org.mapleir.ir.code.stmt.PopStmt)5