Search in sources :

Example 31 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock 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 32 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock 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 33 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class SwitchStmt method sort.

private void sort() {
    List<Integer> keys = new ArrayList<>(targets.keySet());
    Collections.sort(keys);
    LinkedHashMap<Integer, BasicBlock> newMap = new LinkedHashMap<>();
    for (int key : keys) {
        BasicBlock targ = targets.get(key);
        newMap.put(key, targ);
    }
}
Also used : BasicBlock(org.mapleir.ir.cfg.BasicBlock)

Example 34 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class ConcreteStaticInvocationPass method accept.

@Override
public int accept(AnalysisContext cxt, IPass prev, List<IPass> completed) {
    int fixed = 0;
    InvocationResolver resolver = cxt.getInvocationResolver();
    for (ClassNode cn : cxt.getApplication().iterate()) {
        for (MethodNode mn : cn.methods) {
            ControlFlowGraph cfg = cxt.getIRCache().getFor(mn);
            for (BasicBlock b : cfg.vertices()) {
                for (Stmt stmt : b) {
                    for (Expr e : stmt.enumerateOnlyChildren()) {
                        if (e.getOpcode() == Opcode.INVOKE) {
                            InvocationExpr invoke = (InvocationExpr) e;
                            if (invoke.isStatic()) {
                                MethodNode invoked = resolver.resolveStaticCall(invoke.getOwner(), invoke.getName(), invoke.getDesc());
                                if (invoked != null) {
                                    if (!invoked.owner.name.equals(invoke.getOwner())) {
                                        invoke.setOwner(invoked.owner.name);
                                        fixed++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    System.out.printf("  corrected %d dodgy static calls.%n", fixed);
    return fixed;
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) MethodNode(org.objectweb.asm.tree.MethodNode) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) Expr(org.mapleir.ir.code.Expr) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) InvocationResolver(org.mapleir.app.service.InvocationResolver) BasicBlock(org.mapleir.ir.cfg.BasicBlock) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) Stmt(org.mapleir.ir.code.Stmt)

Example 35 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class ConstantExpressionReorderPass method transform.

private int transform(ControlFlowGraph ir) {
    int i = 0;
    for (BasicBlock b : ir.vertices()) {
        for (Stmt stmt : b) {
            if (stmt.getOpcode() == COND_JUMP) {
                ConditionalJumpStmt cjs = (ConditionalJumpStmt) stmt;
                Expr r = cjs.getRight();
                Expr l = cjs.getLeft();
                ComparisonType type = cjs.getComparisonType();
                if (type == ComparisonType.EQ || type == ComparisonType.NE) {
                    if (shouldReorder(r, l)) {
                        cjs.setRight(null);
                        cjs.setLeft(null);
                        cjs.setLeft(r);
                        cjs.setRight(l);
                        i++;
                    }
                }
            }
            for (Expr e : stmt.enumerateOnlyChildren()) {
                if (e.getOpcode() == ARITHMETIC) {
                    ArithmeticExpr arith = (ArithmeticExpr) e;
                    Expr r = arith.getRight();
                    Expr l = arith.getLeft();
                    Operator op = arith.getOperator();
                    if (!op.doesOrderMatter()) {
                        if (shouldReorder(r, l)) {
                            arith.setRight(null);
                            arith.setLeft(null);
                            arith.setLeft(r);
                            arith.setRight(l);
                            i++;
                        }
                    }
                }
            }
        }
    }
    return i;
}
Also used : ConditionalJumpStmt(org.mapleir.ir.code.stmt.ConditionalJumpStmt) Operator(org.mapleir.ir.code.expr.ArithmeticExpr.Operator) ComparisonType(org.mapleir.ir.code.stmt.ConditionalJumpStmt.ComparisonType) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) Expr(org.mapleir.ir.code.Expr) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Stmt(org.mapleir.ir.code.Stmt) ConditionalJumpStmt(org.mapleir.ir.code.stmt.ConditionalJumpStmt)

Aggregations

BasicBlock (org.mapleir.ir.cfg.BasicBlock)70 Stmt (org.mapleir.ir.code.Stmt)37 Expr (org.mapleir.ir.code.Expr)34 Local (org.mapleir.ir.locals.Local)30 VarExpr (org.mapleir.ir.code.expr.VarExpr)29 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)25 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)24 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)22 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)19 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)19 HashSet (java.util.HashSet)12 ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)11 UnconditionalJumpStmt (org.mapleir.ir.code.stmt.UnconditionalJumpStmt)10 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)9 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)9 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)9 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)8 Type (org.objectweb.asm.Type)7 ArrayList (java.util.ArrayList)6 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)6