Search in sources :

Example 36 with Local

use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.

the class AbstractCopyStmt method toCode.

@Override
public // todo: this probably needs a refactoring
void toCode(MethodVisitor visitor, ControlFlowGraph cfg) {
    if (expression instanceof VarExpr) {
        if (((VarExpr) expression).getLocal() == variable.getLocal()) {
            return;
        }
    }
    variable.getLocal().setTempLocal(false);
    expression.toCode(visitor, cfg);
    Type type = variable.getType();
    if (TypeUtils.isPrimitive(type)) {
        int[] cast = TypeUtils.getPrimitiveCastOpcodes(expression.getType(), type);
        for (int i = 0; i < cast.length; i++) visitor.visitInsn(cast[i]);
    }
    Local local = variable.getLocal();
    if (local.isStack()) {
        visitor.visitVarInsn(TypeUtils.getVariableStoreOpcode(getType()), variable.getLocal().getCodeIndex());
        variable.getLocal().setTempLocal(true);
    } else {
        visitor.visitVarInsn(TypeUtils.getVariableStoreOpcode(getType()), variable.getLocal().getCodeIndex());
    }
}
Also used : Type(org.objectweb.asm.Type) VarExpr(org.mapleir.ir.code.expr.VarExpr) Local(org.mapleir.ir.locals.Local)

Example 37 with Local

use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.

the class BoissinotDestructor method intersect.

private boolean intersect(Local a, Local b) {
    if (a == b) {
        for (Entry<Local, CongruenceClass> e : congruenceClasses.entrySet()) {
            System.err.println(e.getKey() + " in " + e.getValue());
        }
        throw new IllegalArgumentException("me too thanks: " + a);
    }
    if (checkPreDomOrder(a, b))
        throw new IllegalArgumentException("b should dom a");
    BasicBlock defA = defuse.defs.get(a);
    // if it's liveOut it definitely intersects
    if (resolver.isLiveOut(defA, b))
        return true;
    // defA == defB or liveIn to intersect{
    if (!resolver.isLiveIn(defA, b) && defA != defuse.defs.get(b))
        return false;
    // ambiguous case. we need to check if use(dom) occurs after def(def), n that case it interferes. otherwise no
    int domUseIndex = defuse.lastUseIndex.getNonNull(b).getOrDefault(defA, -1);
    if (domUseIndex == -1) {
        return false;
    }
    int defDefIndex = defuse.defIndex.get(a);
    return domUseIndex > defDefIndex;
}
Also used : BasicBlock(org.mapleir.ir.cfg.BasicBlock) Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal)

Example 38 with Local

use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.

the class BoissinotDestructor method checkInterfereSingle.

private boolean checkInterfereSingle(CongruenceClass red, CongruenceClass blue) {
    Local a = red.first();
    Local b = blue.first();
    // we want a > b in dom order (b is parent)
    if (checkPreDomOrder(a, b)) {
        Local c = a;
        a = b;
        b = c;
    }
    if (intersect(a, b) && values.getNonNull(a) != values.getNonNull(b)) {
        return true;
    } else {
        equalAncIn.put(a, b);
        red.add(b);
        congruenceClasses.put(b, red);
        return false;
    }
}
Also used : Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal)

Example 39 with Local

use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.

the class BoissinotDestructor method checkInterfere.

private boolean checkInterfere(CongruenceClass red, CongruenceClass blue) {
    Stack<Local> dom = new Stack<>();
    Stack<Boolean> domClasses = new Stack<>();
    int nr = 0, nb = 0;
    Local ir = red.first(), ib = blue.first();
    // end sentinels
    Local lr = red.last(), lb = blue.last();
    boolean redHasNext = true, blueHasNext = true;
    // these have no parents so we have to manually init them
    equalAncOut.put(ir, null);
    equalAncOut.put(ib, null);
    do {
        Local current;
        boolean currentClass;
        if (!blueHasNext || (redHasNext && checkPreDomOrder(ir, ib))) {
            // current = red[ir++]
            current = ir;
            currentClass = true;
            nr++;
            if (redHasNext = ir != lr)
                ir = red.higher(ir);
        } else {
            // current = blue[ib++]
            current = ib;
            currentClass = false;
            nb++;
            if (blueHasNext = ib != lb)
                ib = blue.higher(ib);
        }
        if (!dom.isEmpty()) {
            Local parent;
            boolean parentClass;
            do {
                parent = dom.pop();
                parentClass = domClasses.pop();
                if (parentClass)
                    nr--;
                else
                    nb--;
            } while (!dom.isEmpty() && !checkPreDomOrder(parent, current));
            if (interference(current, parent, currentClass == parentClass))
                return true;
        }
        dom.push(current);
        domClasses.push(currentClass);
    } while ((redHasNext && nb > 0) || (blueHasNext && nr > 0) || (redHasNext && blueHasNext));
    return false;
}
Also used : Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal)

Example 40 with Local

use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.

the class BoissinotDestructor method copyPhiOperands.

private void copyPhiOperands(BasicBlock b) {
    NullPermeableHashMap<BasicBlock, List<PhiRes>> wl = new NullPermeableHashMap<>(new ListCreator<>());
    ParallelCopyVarStmt dst_copy = new ParallelCopyVarStmt();
    for (Stmt stmt : b) {
        // phis only appear at the start of a block.
        if (stmt.getOpcode() != Opcode.PHI_STORE) {
            break;
        }
        CopyPhiStmt copy = (CopyPhiStmt) stmt;
        PhiExpr phi = copy.getExpression();
        // so that we can parallelise the copy when we insert it.
        for (Entry<BasicBlock, Expr> e : phi.getArguments().entrySet()) {
            BasicBlock h = e.getKey();
            // these are validated in init().
            VarExpr v = (VarExpr) e.getValue();
            PhiRes r = new PhiRes(copy.getVariable().getLocal(), phi, h, v.getLocal(), v.getType());
            wl.getNonNull(h).add(r);
        }
        // for each x0, where x0 is a phi copy target, create a new variable z0 for
        // a copy x0 = z0 and replace the phi copy target to z0.
        Local x0 = copy.getVariable().getLocal();
        Local z0 = locals.makeLatestVersion(x0);
        // x0 = z0
        dst_copy.pairs.add(new CopyPair(x0, z0, copy.getVariable().getType()));
        // z0 = phi(...)
        copy.getVariable().setLocal(z0);
    }
    // resolve
    if (dst_copy.pairs.size() > 0)
        insertStart(b, dst_copy);
    for (Entry<BasicBlock, List<PhiRes>> e : wl.entrySet()) {
        BasicBlock p = e.getKey();
        ParallelCopyVarStmt copy = new ParallelCopyVarStmt();
        for (PhiRes r : e.getValue()) {
            // for each xi source in a phi, create a new variable zi, and insert the copy
            // zi = xi in the pred Li. then replace the phi arg from Li with zi.
            Local xi = r.l;
            Local zi = locals.makeLatestVersion(xi);
            copy.pairs.add(new CopyPair(zi, xi, r.type));
            // we consider phi args to be used in the pred instead of the block
            // where the phi is, so we need to update the def/use maps here.
            r.phi.setArgument(r.pred, new VarExpr(zi, r.type));
        }
        insertEnd(p, copy);
    }
}
Also used : BasicBlock(org.mapleir.ir.cfg.BasicBlock) Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) Stmt(org.mapleir.ir.code.Stmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) NullPermeableHashMap(org.mapleir.stdlib.collections.map.NullPermeableHashMap) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr)

Aggregations

Local (org.mapleir.ir.locals.Local)49 VarExpr (org.mapleir.ir.code.expr.VarExpr)33 BasicBlock (org.mapleir.ir.cfg.BasicBlock)29 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)24 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)24 Expr (org.mapleir.ir.code.Expr)23 Stmt (org.mapleir.ir.code.Stmt)22 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)21 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)18 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)18 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)10 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)7 HashSet (java.util.HashSet)6 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)5 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)5 PopStmt (org.mapleir.ir.code.stmt.PopStmt)5 SwitchStmt (org.mapleir.ir.code.stmt.SwitchStmt)5 ThrowStmt (org.mapleir.ir.code.stmt.ThrowStmt)5 UnconditionalJumpStmt (org.mapleir.ir.code.stmt.UnconditionalJumpStmt)5 LocalsPool (org.mapleir.ir.locals.LocalsPool)5