Search in sources :

Example 6 with CopyPhiStmt

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

the class SSADefUseMap method build.

protected void build(BasicBlock b, Stmt stmt, Set<Local> usedLocals) {
    if (stmt instanceof AbstractCopyStmt) {
        AbstractCopyStmt copy = (AbstractCopyStmt) stmt;
        Local l = copy.getVariable().getLocal();
        defs.put(l, b);
        if (copy instanceof CopyPhiStmt) {
            phiDefs.put(l, (CopyPhiStmt) copy);
            PhiExpr phi = (PhiExpr) copy.getExpression();
            for (Entry<BasicBlock, Expr> en : phi.getArguments().entrySet()) {
                Local ul = ((VarExpr) en.getValue()).getLocal();
                uses.getNonNull(ul).add(en.getKey());
                phiUses.get(b).add(ul);
            }
            return;
        }
    }
    for (Local usedLocal : usedLocals) uses.getNonNull(usedLocal).add(b);
}
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) Local(org.mapleir.ir.locals.Local) VarExpr(org.mapleir.ir.code.expr.VarExpr) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt)

Example 7 with CopyPhiStmt

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

the class SreedharDestructor method csaa_iii.

// ============================================================================================================= //
// =================================================== CSSA ==================================================== //
// ============================================================================================================= //
private void csaa_iii() {
    // iterate over each phi expression
    for (Entry<Local, CopyPhiStmt> entry : defuse.phiDefs.entrySet()) {
        // System.out.println("process phi " + entry.getValue());
        // x0
        Local phiTarget = entry.getKey();
        CopyPhiStmt copy = entry.getValue();
        // l0
        BasicBlock defBlock = defuse.defs.get(phiTarget);
        PhiExpr phi = copy.getExpression();
        candidateResourceSet.clear();
        unresolvedNeighborsMap.clear();
        // Initialize phiResources set for convenience
        final GenericBitSet<PhiResource> phiResources = phiResSetCreator.create();
        phiResources.add(new PhiResource(defBlock, phiTarget, true));
        for (Entry<BasicBlock, Expr> phiEntry : phi.getArguments().entrySet()) phiResources.add(new PhiResource(phiEntry.getKey(), ((VarExpr) phiEntry.getValue()).getLocal(), false));
        // Determine what copies are needed using the four cases.
        handleInterference(phiResources);
        // Process unresolved resources
        resolveDeferred();
        // System.out.println("  Cand: " + candidateResourceSet);
        // Resolve the candidate resources
        Type phiType = phi.getType();
        for (PhiResource toResolve : candidateResourceSet) {
            if (toResolve.isTarget)
                resolvePhiTarget(toResolve, phiType);
            else
                for (Entry<BasicBlock, Expr> phiArg : phi.getArguments().entrySet()) {
                    VarExpr phiVar = (VarExpr) phiArg.getValue();
                    if (phiVar.getLocal() == toResolve.local)
                        phiVar.setLocal(resolvePhiSource(toResolve.local, phiArg.getKey(), phiType));
                }
        }
        // System.out.println("  interference: ");
        // for (Entry<Local, GenericBitSet<Local>> entry2 : interfere.entrySet())
        // System.out.println("    " + entry2.getKey() + " : " + entry2.getValue());
        // System.out.println("  post-inserted: " + copy);
        // Merge pccs for all locals in phi
        final GenericBitSet<Local> phiLocals = locals.createBitSet();
        phiLocals.add(copy.getVariable().getLocal());
        for (Entry<BasicBlock, Expr> phiEntry : phi.getArguments().entrySet()) phiLocals.add(((VarExpr) phiEntry.getValue()).getLocal());
        for (Local phiLocal : phiLocals) pccs.put(phiLocal, phiLocals);
        // Nullify singleton pccs
        for (GenericBitSet<Local> pcc : pccs.values()) if (pcc.size() <= 1)
            pcc.clear();
    // System.out.println("  pccs:");
    // for (Entry<Local, GenericBitSet<Local>> entry2 : pccs.entrySet())
    // System.out.println("    " + entry2.getKey() + " : " + entry2.getValue());
    // System.out.println();
    }
}
Also used : BasicBlock(org.mapleir.ir.cfg.BasicBlock) Local(org.mapleir.ir.locals.Local) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) Type(org.objectweb.asm.Type) Entry(java.util.Map.Entry) 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)

Example 8 with CopyPhiStmt

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

the class SreedharDestructor method leaveSSA.

// ============================================================================================================= //
// ================================================== Leave SSA ================================================ //
// ============================================================================================================= //
private void leaveSSA() {
    // Flatten pccs into one variable through remapping
    // System.out.println("remap:");
    Map<Local, Local> remap = new HashMap<>();
    for (Entry<Local, GenericBitSet<Local>> entry : pccs.entrySet()) {
        GenericBitSet<Local> pcc = entry.getValue();
        if (pcc.isEmpty())
            continue;
        Local local = entry.getKey();
        if (remap.containsKey(local))
            continue;
        Local newLocal = locals.makeLatestVersion(local);
        remap.put(local, newLocal);
        // System.out.println("  " + local + " -> " + newLocal);
        for (Local pccLocal : pcc) {
            remap.put(pccLocal, newLocal);
        // System.out.println("  " + pccLocal + " -> " + newLocal);
        }
    }
    for (BasicBlock b : cfg.vertices()) {
        for (Iterator<Stmt> it = b.iterator(); it.hasNext(); ) {
            Stmt stmt = it.next();
            // We can now simply drop all phi statements.
            if (stmt instanceof CopyPhiStmt) {
                it.remove();
                continue;
            }
            // Apply remappings
            if (stmt instanceof CopyVarStmt) {
                VarExpr lhs = ((CopyVarStmt) stmt).getVariable();
                Local copyTarget = lhs.getLocal();
                lhs.setLocal(remap.getOrDefault(copyTarget, copyTarget));
            }
            for (Expr child : stmt.enumerateOnlyChildren()) {
                if (child.getOpcode() == LOCAL_LOAD) {
                    VarExpr var = (VarExpr) child;
                    Local loadSource = var.getLocal();
                    var.setLocal(remap.getOrDefault(loadSource, loadSource));
                }
            }
        }
    }
// System.out.println();
}
Also used : HashMap(java.util.HashMap) NullPermeableHashMap(org.mapleir.stdlib.collections.map.NullPermeableHashMap) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Local(org.mapleir.ir.locals.Local) GenericBitSet(org.mapleir.stdlib.collections.bitset.GenericBitSet) Stmt(org.mapleir.ir.code.Stmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) 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) VarExpr(org.mapleir.ir.code.expr.VarExpr)

Example 9 with CopyPhiStmt

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

the class SreedharDestructor method insertStart.

// replace the phi target xi with xi' and place a temp copy xi = xi' after all phi statements.
private Local insertStart(PhiResource res, Type type) {
    BasicBlock li = res.block;
    Local xi = res.local;
    if (li.isEmpty())
        throw new IllegalStateException("Trying to resolve phi target interference in empty block " + li);
    Local spill = locals.makeLatestVersion(xi);
    int i;
    for (i = 0; i < li.size() && li.get(i).getOpcode() == Opcode.PHI_STORE; i++) {
        CopyPhiStmt copyPhi = (CopyPhiStmt) li.get(i);
        VarExpr copyTarget = copyPhi.getVariable();
        if (copyTarget.getLocal() == xi)
            copyTarget.setLocal(spill);
    }
    li.add(i, new CopyVarStmt(new VarExpr(xi, type), new VarExpr(spill, type)));
    return spill;
}
Also used : CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) 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 10 with CopyPhiStmt

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

the class ControlFlowGraph method exciseEdge.

/**
 * Properly removes the edge, and cleans up phi uses in fe.dst of phi arguments from fe.src.
 * @param fe Edge to excise phi uses.
 */
public void exciseEdge(FlowEdge<BasicBlock> fe) {
    if (!this.containsEdge(fe.src(), fe))
        throw new IllegalArgumentException("Graph does not contain the specified edge");
    removeEdge(fe.src(), fe);
    for (Stmt stmt : fe.dst()) {
        if (stmt.getOpcode() == PHI_STORE) {
            CopyPhiStmt phs = (CopyPhiStmt) stmt;
            PhiExpr phi = phs.getExpression();
            BasicBlock pred = fe.src();
            VarExpr arg = (VarExpr) phi.getArgument(pred);
            VersionedLocal l = (VersionedLocal) arg.getLocal();
            locals.uses.get(l).remove(arg);
            phi.removeArgument(pred);
        } else {
            return;
        }
    }
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) Stmt(org.mapleir.ir.code.Stmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt)

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