Search in sources :

Example 16 with CopyVarStmt

use of org.mapleir.ir.code.stmt.copy.CopyVarStmt in project maple-ir by LLVM-but-worse.

the class GenerationPass method addEntry.

private void addEntry(int index, Type type, BasicBlock b) {
    VarExpr var = _var_expr(index, type, false);
    CopyVarStmt stmt = selfDefine(var);
    builder.assigns.getNonNull(var.getLocal()).add(b);
    b.add(stmt);
}
Also used : CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt)

Example 17 with CopyVarStmt

use of org.mapleir.ir.code.stmt.copy.CopyVarStmt in project maple-ir by LLVM-but-worse.

the class GenerationPass method assign_stack.

// var[index] = expr
protected Type assign_stack(int index, Expr expr) {
    if (expr.getOpcode() == Opcode.LOCAL_LOAD) {
        VarExpr v = (VarExpr) expr;
        if (v.getIndex() == index && v.getLocal().isStack()) {
            return expr.getType();
        }
    }
    Type type = expr.getType();
    VarExpr var = _var_expr(index, type, true);
    CopyVarStmt stmt = copy(var, expr);
    addStmt(stmt);
    return type;
}
Also used : Type(org.objectweb.asm.Type) ComparisonType(org.mapleir.ir.code.stmt.ConditionalJumpStmt.ComparisonType) ValueComparisonType(org.mapleir.ir.code.expr.ComparisonExpr.ValueComparisonType) ArrayType(org.mapleir.ir.TypeUtils.ArrayType) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt)

Example 18 with CopyVarStmt

use of org.mapleir.ir.code.stmt.copy.CopyVarStmt 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 19 with CopyVarStmt

use of org.mapleir.ir.code.stmt.copy.CopyVarStmt 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)

Example 20 with CopyVarStmt

use of org.mapleir.ir.code.stmt.copy.CopyVarStmt in project maple-ir by LLVM-but-worse.

the class ConstantParameterPass method inlineConstant.

private void inlineConstant(ControlFlowGraph cfg, int argLocalIndex, Object o) {
    /* we don't actually demote the synthetic copy
		 * here as we would also need to change the
		 * method desc and we can't do that until
		 * later so we defer it. */
    LocalsPool pool = cfg.getLocals();
    /* create the spill variable but not the
		 * actual definition yet. */
    VersionedLocal argLocal = pool.get(argLocalIndex, 0, false);
    VersionedLocal spill = pool.makeLatestVersion(argLocal);
    AbstractCopyStmt synthParamCopy = pool.defs.get(argLocal);
    ConstantExpr rhsVal = new ConstantExpr(o, synthParamCopy.getType() == Type.BOOLEAN_TYPE ? Type.BYTE_TYPE : synthParamCopy.getType());
    /* we have to maintain local references in
		 * phis as opposed to direct constant refs,
		 * so we go through every use of the argLocal
		 * and either replace it with the constant or
		 * a reference to the spill local if it is in
		 * a phi. */
    Set<VarExpr> spillUses = new HashSet<>();
    boolean requireSpill = false;
    Iterator<VarExpr> it = pool.uses.get(argLocal).iterator();
    while (it.hasNext()) {
        VarExpr v = it.next();
        if (v.getParent() == null) {
            /* the use is in a phi, we can't
				 * remove the def. 
				 * 
				 * we also replace the old var
				 * with the new spill one so we
				 * have to add this as a use of
				 * the new spill local. */
            spillUses.add(v);
            v.setLocal(spill);
            requireSpill = true;
        } else {
            CodeUnit par = v.getParent();
            par.overwrite(rhsVal.copy(), par.indexOf(v));
        }
        /* this use is no longer associated
			 * with the old argLocal. */
        it.remove();
    }
    if (pool.uses.get(argLocal).size() != 0) {
        throw new IllegalStateException(String.format("l:%s, uses:%s", argLocal, pool.uses.get(argLocal)));
    }
    if (requireSpill) {
        /* generate the copy for the spill (v = const) */
        CopyVarStmt spillCopy = new CopyVarStmt(new VarExpr(spill, synthParamCopy.getVariable().getType()), rhsVal);
        synthParamCopy.getBlock().add(spillCopy);
        /* initialise data entries for the new spill
			 * variable. */
        pool.defs.put(spill, spillCopy);
        pool.uses.put(spill, spillUses);
    }
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) LocalsPool(org.mapleir.ir.locals.LocalsPool) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) VarExpr(org.mapleir.ir.code.expr.VarExpr) HashSet(java.util.HashSet) CodeUnit(org.mapleir.ir.code.CodeUnit)

Aggregations

CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)24 Stmt (org.mapleir.ir.code.Stmt)18 BasicBlock (org.mapleir.ir.cfg.BasicBlock)17 VarExpr (org.mapleir.ir.code.expr.VarExpr)17 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)16 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)14 Local (org.mapleir.ir.locals.Local)13 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)12 Expr (org.mapleir.ir.code.Expr)10 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)8 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)6 PopStmt (org.mapleir.ir.code.stmt.PopStmt)6 SwitchStmt (org.mapleir.ir.code.stmt.SwitchStmt)6 ThrowStmt (org.mapleir.ir.code.stmt.ThrowStmt)6 UnconditionalJumpStmt (org.mapleir.ir.code.stmt.UnconditionalJumpStmt)6 Constraint (org.mapleir.ir.cfg.builder.ssaopt.Constraint)5 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)5 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)5 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)3 Type (org.objectweb.asm.Type)3