Search in sources :

Example 16 with CopyPhiStmt

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

Example 17 with CopyPhiStmt

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

the class SSADefUseMap method buildIndex.

protected void buildIndex(BasicBlock b, Stmt stmt, int index, Set<Local> usedLocals) {
    if (stmt instanceof AbstractCopyStmt) {
        AbstractCopyStmt copy = (AbstractCopyStmt) stmt;
        defIndex.put(copy.getVariable().getLocal(), index);
        if (copy instanceof CopyPhiStmt) {
            PhiExpr phi = ((CopyPhiStmt) copy).getExpression();
            for (Entry<BasicBlock, Expr> en : phi.getArguments().entrySet()) {
                lastUseIndex.getNonNull(((VarExpr) en.getValue()).getLocal()).put(en.getKey(), en.getKey().size());
            // lastUseIndex.get(ul).put(b, -1);
            }
            return;
        }
    }
    for (Local usedLocal : usedLocals) lastUseIndex.getNonNull(usedLocal).put(b, index);
}
Also used : 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) BasicBlock(org.mapleir.ir.cfg.BasicBlock) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) VarExpr(org.mapleir.ir.code.expr.VarExpr) Local(org.mapleir.ir.locals.Local) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt)

Example 18 with CopyPhiStmt

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

the class SreedharDestructor method init.

// ============================================================================================================= //
// =============================================== Initialization ============================================== //
// ============================================================================================================= //
private void init() {
    // init pccs
    for (CopyPhiStmt copyPhi : defuse.phiDefs.values()) {
        Local phiTarget = copyPhi.getVariable().getLocal();
        pccs.getNonNull(phiTarget).add(phiTarget);
        // System.out.println("Initphi " + phiTarget);
        for (Entry<BasicBlock, Expr> phiEntry : copyPhi.getExpression().getArguments().entrySet()) {
            if (phiEntry.getValue().getOpcode() != LOCAL_LOAD)
                throw new IllegalArgumentException("Phi arg is not local; instead is " + phiEntry.getValue().getClass().getSimpleName());
            Local phiSource = ((VarExpr) phiEntry.getValue()).getLocal();
            pccs.getNonNull(phiSource).add(phiSource);
        // System.out.println("Initphi " + phiSource);
        }
    }
    // System.out.println();
    // compute liveness
    (liveness = new SSABlockLivenessAnalyser(cfg)).compute();
    // writer.add("liveness", new LivenessDecorator<ControlFlowGraph, BasicBlock, FlowEdge<BasicBlock>>().setLiveness(liveness));
    buildInterference();
}
Also used : VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Local(org.mapleir.ir.locals.Local) VarExpr(org.mapleir.ir.code.expr.VarExpr) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt)

Example 19 with CopyPhiStmt

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

the class SreedharDestructor method resolvePhiSource.

private Local resolvePhiSource(Local xi, BasicBlock lk, Type phiType) {
    // Insert spill copy
    Local spill = insertEnd(xi, lk, phiType);
    // Update liveness
    GenericBitSet<Local> liveOut = liveness.out(lk);
    liveOut.add(spill);
    // xi can be removed from liveOut iff it isn't live into any succ or used in any succ phi.
    for (BasicBlock lj : succsCache.getNonNull(lk)) {
        if (!liveness.in(lj).contains(xi))
            removeFromOut: {
                for (int i = 0; i < lj.size() && lj.get(i).getOpcode() == Opcode.PHI_STORE; i++) if (((VarExpr) ((CopyPhiStmt) lj.get(i)).getExpression().getArguments().get(lk)).getLocal() == xi)
                    break removeFromOut;
                // poor man's for-else loop
                liveOut.remove(xi);
            }
    }
    // Reflexively update interference
    interfere.getNonNull(spill).addAll(liveOut);
    for (Local l : liveOut) interfere.get(l).add(spill);
    return spill;
}
Also used : BasicBlock(org.mapleir.ir.cfg.BasicBlock) Local(org.mapleir.ir.locals.Local) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt)

Example 20 with CopyPhiStmt

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

the class SSAGenPass method optimisePhis.

private void optimisePhis(BasicBlock b) {
    List<CopyPhiStmt> phis = new ArrayList<>();
    for (Stmt stmt : b) {
        if (stmt.getOpcode() == Opcode.PHI_STORE) {
            phis.add((CopyPhiStmt) stmt);
        } else {
            break;
        }
    }
    if (phis.size() > 1) {
        Set<Set<CopyPhiStmt>> ccs = findPhiClasses(phis);
        for (Set<CopyPhiStmt> cc : ccs) {
            CopyPhiStmt pref = chooseRealPhi(cc);
            // System.out.println("want to merge:");
            // for(CopyPhiStmt s : cc) {
            // System.out.println("  " + s);
            // }
            // System.out.println(" keeping " + pref);
            reduceClass(cc, pref);
        }
    }
}
Also used : CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) 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)

Aggregations

CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)20 VarExpr (org.mapleir.ir.code.expr.VarExpr)17 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)16 BasicBlock (org.mapleir.ir.cfg.BasicBlock)15 Expr (org.mapleir.ir.code.Expr)15 Local (org.mapleir.ir.locals.Local)14 Stmt (org.mapleir.ir.code.Stmt)13 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)13 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)12 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)10 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 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)4 InitialisedObjectExpr (org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr)4 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)4 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)4 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)2