Search in sources :

Example 21 with Stmt

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

the class SSAGenPass method searchImpl.

private void searchImpl(BasicBlock b) {
    Iterator<Stmt> it = b.iterator();
    while (it.hasNext()) {
        Stmt stmt = it.next();
        int opcode = stmt.getOpcode();
        if (opcode == Opcode.POP) {
            PopStmt pop = (PopStmt) stmt;
            if (!ConstraintUtil.isUncopyable(pop.getExpression())) {
                it.remove();
                continue;
            }
        }
        if (opcode == Opcode.PHI_STORE) {
            /* We can rename these any time as these
				 * are visited before all other statements
				 * in a block (since they are always
				 * the starting statements of a block, if
				 * that block contains phi statements).
				 */
            CopyPhiStmt copy = (CopyPhiStmt) stmt;
            generate(copy);
        } else {
            /* Translates locals into their latest SSA
				 * versioned locals.
				 * 
				 * Do this before a LOCAL_STORE (x = ...)
				 * so that the target local isn't defined
				 * before the use so that copies in the
				 * form x = x; do not get mangled into
				 * x0 = x0 after SSA renaming.
				 * 
				 * We rename phi args later as the source
				 * local can originate from exotic blocks.
				 */
            translate(stmt, true, false);
        }
        if (opcode == Opcode.LOCAL_STORE) {
            /* Generate the target local after
				 * renaming the source pool.uses. 
				 */
            CopyVarStmt copy = (CopyVarStmt) stmt;
            generate(copy);
        }
    }
}
Also used : PopStmt(org.mapleir.ir.code.stmt.PopStmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) Constraint(org.mapleir.ir.cfg.builder.ssaopt.Constraint) SwitchStmt(org.mapleir.ir.code.stmt.SwitchStmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) PopStmt(org.mapleir.ir.code.stmt.PopStmt) ThrowStmt(org.mapleir.ir.code.stmt.ThrowStmt) UnconditionalJumpStmt(org.mapleir.ir.code.stmt.UnconditionalJumpStmt) Stmt(org.mapleir.ir.code.Stmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) ConditionalJumpStmt(org.mapleir.ir.code.stmt.ConditionalJumpStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt)

Example 22 with Stmt

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

the class SSAGenPass method fixPhiArgs.

private void fixPhiArgs(BasicBlock b, BasicBlock succ) {
    for (Stmt stmt : succ) {
        if (stmt.getOpcode() == Opcode.PHI_STORE) {
            CopyPhiStmt copy = (CopyPhiStmt) stmt;
            PhiExpr phi = copy.getExpression();
            Expr e = phi.getArgument(b);
            if (e.getOpcode() == Opcode.LOCAL_LOAD) {
                VarExpr v = (VarExpr) e;
                translate(v, true, true);
                VersionedLocal ssaL = (VersionedLocal) v.getLocal();
                Type t = types.get(ssaL);
                copy.getVariable().setType(t);
                phi.setType(t);
            } else {
                throw new IllegalArgumentException(phi + ", " + e);
            }
        } else {
            /* No need to search the rest of the block
				 * after we have visited the phis as they
				 * precede all other statements.
				 */
            break;
        }
    }
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) Type(org.objectweb.asm.Type) 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) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) SwitchStmt(org.mapleir.ir.code.stmt.SwitchStmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) PopStmt(org.mapleir.ir.code.stmt.PopStmt) ThrowStmt(org.mapleir.ir.code.stmt.ThrowStmt) UnconditionalJumpStmt(org.mapleir.ir.code.stmt.UnconditionalJumpStmt) Stmt(org.mapleir.ir.code.Stmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) ConditionalJumpStmt(org.mapleir.ir.code.stmt.ConditionalJumpStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt)

Example 23 with Stmt

use of org.mapleir.ir.code.Stmt 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 24 with Stmt

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

the class ControlFlowGraphDecorator method outputBlock.

private void outputBlock(BasicBlock n, StringBuilder sb2) {
    Iterator<Stmt> it = n.iterator();
    TabbedStringWriter sw = new TabbedStringWriter();
    int insn = 0;
    while (it.hasNext()) {
        Stmt stmt = it.next();
        sw.print(insn++ + ". ");
        stmt.toString(sw);
        sw.print("\n");
    }
    sb2.append(sw.toString());
}
Also used : TabbedStringWriter(org.mapleir.stdlib.util.TabbedStringWriter) Stmt(org.mapleir.ir.code.Stmt)

Example 25 with Stmt

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

Aggregations

Stmt (org.mapleir.ir.code.Stmt)53 BasicBlock (org.mapleir.ir.cfg.BasicBlock)35 Expr (org.mapleir.ir.code.Expr)29 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)28 VarExpr (org.mapleir.ir.code.expr.VarExpr)26 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)25 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)24 Local (org.mapleir.ir.locals.Local)21 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)19 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)15 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)13 UnconditionalJumpStmt (org.mapleir.ir.code.stmt.UnconditionalJumpStmt)13 ThrowStmt (org.mapleir.ir.code.stmt.ThrowStmt)12 PopStmt (org.mapleir.ir.code.stmt.PopStmt)11 SwitchStmt (org.mapleir.ir.code.stmt.SwitchStmt)11 HashSet (java.util.HashSet)10 ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)9 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)8 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)8 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)7