Search in sources :

Example 1 with PhiExpr

use of org.mapleir.ir.code.expr.PhiExpr in project maple-ir by LLVM-but-worse.

the class BoissinotDestructor method coalescePhis.

// Initialize ccs based on phis and drop phi statements
private void coalescePhis() {
    GenericBitSet<BasicBlock> processed = cfg.createBitSet();
    for (Entry<Local, CopyPhiStmt> e : defuse.phiDefs.entrySet()) {
        Local l = e.getKey();
        BasicBlock b = e.getValue().getBlock();
        // since we are now in csaa, phi locals never interfere and are in the same congruence class.
        // therefore we can coalesce them all together and drop phis. with this, we leave cssa.
        PhiExpr phi = e.getValue().getExpression();
        CongruenceClass pcc = new CongruenceClass();
        pcc.add(l);
        congruenceClasses.put(l, pcc);
        for (Expr ex : phi.getArguments().values()) {
            VarExpr v = (VarExpr) ex;
            Local argL = v.getLocal();
            pcc.add(argL);
            congruenceClasses.put(argL, pcc);
        }
        // we can simply drop all the phis without further consideration
        if (!processed.contains(b)) {
            processed.add(b);
            Iterator<Stmt> it = b.iterator();
            while (it.hasNext()) {
                Stmt stmt = it.next();
                if (stmt.getOpcode() == Opcode.PHI_STORE) {
                    it.remove();
                } else {
                    break;
                }
            }
        }
    }
    defuse.phiDefs.clear();
}
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) Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) VarExpr(org.mapleir.ir.code.expr.VarExpr) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) 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)

Example 2 with PhiExpr

use of org.mapleir.ir.code.expr.PhiExpr in project maple-ir by LLVM-but-worse.

the class SSABlockLivenessAnalyser method precomputeBlock.

// compute def, use, and phi for given block
private void precomputeBlock(BasicBlock b) {
    def.getNonNull(b);
    use.getNonNull(b);
    phiUse.getNonNull(b);
    phiDef.getNonNull(b);
    // we have to iterate in reverse order because a definition will kill a use in the current block
    // this is so that uses do not escape a block if its def is in the same block. this is basically
    // simulating a statement graph analysis
    ListIterator<Stmt> it = b.listIterator(b.size());
    while (it.hasPrevious()) {
        Stmt stmt = it.previous();
        int opcode = stmt.getOpcode();
        if (opcode == Opcode.PHI_STORE) {
            CopyPhiStmt copy = (CopyPhiStmt) stmt;
            phiDef.get(b).add(copy.getVariable().getLocal());
            PhiExpr phi = copy.getExpression();
            for (Map.Entry<BasicBlock, Expr> e : phi.getArguments().entrySet()) {
                BasicBlock exprSource = e.getKey();
                Expr phiExpr = e.getValue();
                GenericBitSet<Local> useSet = phiUse.get(b).getNonNull(exprSource);
                if (phiExpr.getOpcode() == Opcode.LOCAL_LOAD) {
                    useSet.add(((VarExpr) phiExpr).getLocal());
                } else
                    for (Expr child : phiExpr.enumerateOnlyChildren()) {
                        if (child.getOpcode() == Opcode.LOCAL_LOAD) {
                            useSet.add(((VarExpr) child).getLocal());
                        }
                    }
            }
        } else {
            if (opcode == Opcode.LOCAL_STORE) {
                CopyVarStmt copy = (CopyVarStmt) stmt;
                Local l = copy.getVariable().getLocal();
                def.get(b).add(l);
                use.get(b).remove(l);
                Expr e = copy.getExpression();
                // adding it as live-in.
                if (e.getOpcode() == Opcode.CATCH) {
                    if (hasNaturalPredecessors(cfg, b)) {
                        use.get(b).add(l);
                    }
                }
            }
            for (Expr c : stmt.enumerateOnlyChildren()) {
                if (c.getOpcode() == Opcode.LOCAL_LOAD) {
                    VarExpr v = (VarExpr) c;
                    use.get(b).add(v.getLocal());
                }
            }
        }
    }
}
Also used : CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Local(org.mapleir.ir.locals.Local) 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) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) NullPermeableHashMap(org.mapleir.stdlib.collections.map.NullPermeableHashMap) Map(java.util.Map)

Example 3 with PhiExpr

use of org.mapleir.ir.code.expr.PhiExpr 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 4 with PhiExpr

use of org.mapleir.ir.code.expr.PhiExpr 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 5 with PhiExpr

use of org.mapleir.ir.code.expr.PhiExpr 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

PhiExpr (org.mapleir.ir.code.expr.PhiExpr)12 VarExpr (org.mapleir.ir.code.expr.VarExpr)11 Expr (org.mapleir.ir.code.Expr)10 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)9 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)8 Local (org.mapleir.ir.locals.Local)8 BasicBlock (org.mapleir.ir.cfg.BasicBlock)7 Stmt (org.mapleir.ir.code.Stmt)6 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)5 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)5 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)3 HashSet (java.util.HashSet)2 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)2 InitialisedObjectExpr (org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr)2 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)2 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)2 PopStmt (org.mapleir.ir.code.stmt.PopStmt)2 SwitchStmt (org.mapleir.ir.code.stmt.SwitchStmt)2 ThrowStmt (org.mapleir.ir.code.stmt.ThrowStmt)2 UnconditionalJumpStmt (org.mapleir.ir.code.stmt.UnconditionalJumpStmt)2