Search in sources :

Example 11 with Local

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

the class SSADefUseMap method computeWithIndices.

public void computeWithIndices(List<BasicBlock> preorder) {
    defs.clear();
    uses.clear();
    phiDefs.clear();
    phiUses.clear();
    lastUseIndex.clear();
    defIndex.clear();
    int index = 0;
    Set<Local> usedLocals = new HashSet<>();
    for (BasicBlock b : preorder) {
        for (Stmt stmt : b) {
            phiUses.getNonNull(b);
            usedLocals.clear();
            for (Expr s : stmt.enumerateOnlyChildren()) if (s.getOpcode() == Opcode.LOCAL_LOAD)
                usedLocals.add(((VarExpr) s).getLocal());
            buildIndex(b, stmt, index++, usedLocals);
            build(b, stmt, usedLocals);
        }
    }
}
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) HashSet(java.util.HashSet) Stmt(org.mapleir.ir.code.Stmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)

Example 12 with Local

use of org.mapleir.ir.locals.Local 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 13 with Local

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

the class SreedharDestructor method checkPccDouble.

// Quadratic (lmao) coalesce check for coalesce case 3, returns true if the copy cannot be removed.
// But thanks to bitsets its linear time
private boolean checkPccDouble(GenericBitSet<Local> pccX, Local x, GenericBitSet<Local> pccY, Local y) {
    // System.out.println("  case 3");
    GenericBitSet<Local> pccYTrim = pccY.copy();
    pccYTrim.remove(y);
    for (Local lx : pccX) if (interfere.getNonNull(lx).containsAny(pccYTrim))
        return true;
    GenericBitSet<Local> pccXTrim = pccX.copy();
    pccXTrim.remove(x);
    for (Local ly : pccY) if (interfere.getNonNull(ly).containsAny(pccXTrim))
        return true;
    return false;
}
Also used : Local(org.mapleir.ir.locals.Local)

Example 14 with Local

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

the class SreedharDestructor method coalesce.

// ============================================================================================================= //
// ================================================== Coalescing =============================================== //
// ============================================================================================================= //
private void coalesce() {
    for (BasicBlock b : cfg.vertices()) {
        for (Iterator<Stmt> it = b.iterator(); it.hasNext(); ) {
            Stmt stmt = it.next();
            if (stmt instanceof CopyVarStmt) {
                CopyVarStmt copy = (CopyVarStmt) stmt;
                // System.out.println("check " + copy);
                if (checkCoalesce(copy)) {
                    // System.out.println("  coalescing");
                    // Remove the copy
                    it.remove();
                    // Merge pccs
                    GenericBitSet<Local> pccX = pccs.get(copy.getVariable().getLocal());
                    Local localY = ((VarExpr) copy.getExpression()).getLocal();
                    GenericBitSet<Local> pccY = pccs.get(localY);
                    pccX.add(localY);
                    pccX.addAll(pccY);
                    for (Local l : pccY) pccs.put(l, pccX);
                }
            }
        }
    }
// System.out.println("post-coalsce pccs:");
// for (Entry<Local, GenericBitSet<Local>> entry : pccs.entrySet())
// System.out.println("  " + entry.getKey() + " : " + entry.getValue());
// System.out.println();
}
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) Stmt(org.mapleir.ir.code.Stmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt)

Example 15 with Local

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

the class SreedharDestructor method checkCoalesce.

private boolean checkCoalesce(CopyVarStmt copy) {
    // Only coalesce simple copies x=y.
    if (copy.isSynthetic() || copy.getExpression().getOpcode() != LOCAL_LOAD)
        return false;
    Local localX = copy.getVariable().getLocal();
    Local localY = ((VarExpr) copy.getExpression()).getLocal();
    GenericBitSet<Local> pccX = pccs.getNonNull(localX), pccY = pccs.getNonNull(localY);
    // Trivial case: Now that we are in CSSA, we can simply drop copies within the same pcc.
    if (pccX == pccY)
        return true;
    boolean xEmpty = pccX.isEmpty(), yEmpty = pccY.isEmpty();
    // Case 1 - If pcc[x] and pcc[y] are empty the copy can be removed regardless of interference.
    if (xEmpty & yEmpty)
        return true;
    else // interfere with any local in (pcc[x]-x).
    if (xEmpty ^ yEmpty) {
        if (checkPccSingle(yEmpty ? pccX : pccY, yEmpty ? localX : localY, yEmpty ? localY : localX))
            return false;
    } else // interferes with any local in (pcc[x]-x) and not local in pcc[x] interferes with any local in (pcc[y]-y).
    if (checkPccDouble(pccX, localX, pccY, localY))
        return false;
    // No interference, copy can be removed
    return true;
}
Also used : Local(org.mapleir.ir.locals.Local) 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