Search in sources :

Example 41 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class SSAGenPass method updatePhiArgTypes.

private void updatePhiArgTypes(Set<BasicBlock> vis) {
    // update types for phi args
    for (BasicBlock b : order) {
        for (Stmt s : b) {
            if (s.getOpcode() != Opcode.PHI_STORE) {
                break;
            }
            CopyPhiStmt cps = (CopyPhiStmt) s;
            for (Entry<BasicBlock, Expr> e : cps.getExpression().getArguments().entrySet()) {
                BasicBlock src = e.getKey();
                if (vis.contains(src))
                    continue;
                VarExpr v = (VarExpr) e.getValue();
                Local l = v.getLocal();
                // what if the def is never reached?
                AbstractCopyStmt def = pool.defs.get(l);
                v.setType(def.getType());
            }
        }
    }
}
Also used : ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) InitialisedObjectExpr(org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) 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) VarExpr(org.mapleir.ir.code.expr.VarExpr) BasicLocal(org.mapleir.ir.locals.impl.BasicLocal) Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) 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) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt)

Example 42 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class SSAGenPass method insertPhis.

private void insertPhis(BasicBlock b, Local l, int i, LinkedList<BasicBlock> queue) {
    if (b == null || b == builder.head) {
        // exit
        return;
    }
    Local newl = builder.graph.getLocals().get(l.getIndex(), 0, l.isStack());
    for (BasicBlock x : doms.iteratedFrontier(b)) {
        if (insertion.get(x) < i) {
            // pruned SSA
            if (liveness.in(x).contains(l)) {
                if ((l == svar0) && handlers.contains(x)) /* == faster than contains. */
                {
                    /* Note: this is quite subtle. Since there is a
						 * copy, (svar0 = catch()) at the start of each
						 * handler block, technically any natural flowing
						 * svar0 definition is killed upon entry to the
						 * block, so it is not considered live. One way to
						 * check if the variable is live-in, therefore, is
						 * by checking whether svar0 is live-out of the
						 * catch() definition. We handle it here, since
						 * the previous liveness check which is used for
						 * pruned SSA will fail in this case. */
                    /* Ok fuck that that, it's considered live-in
						 * even if there is a catch()::
						 *  #see SSaBlockLivenessAnalyser.precomputeBlock*/
                    boolean naturalFlow = false;
                    for (FlowEdge<BasicBlock> e : builder.graph.getReverseEdges(x)) {
                        if (e.getType() != FlowEdges.TRYCATCH) {
                            naturalFlow = true;
                            break;
                        }
                    }
                    if (naturalFlow) {
                        CopyVarStmt catcher = null;
                        for (Stmt stmt : x) {
                            if (stmt.getOpcode() == Opcode.LOCAL_STORE) {
                                CopyVarStmt copy = (CopyVarStmt) stmt;
                                Expr e = copy.getExpression();
                                if (e.getOpcode() == Opcode.CATCH) {
                                    catcher = copy;
                                    break;
                                }
                            }
                        }
                        if (catcher == null) {
                            /* Handler but no catch copy?
								 * This can't happen since svar0 is
								 * the only reserved register for
								 * catch copies, and this block cannot
								 * be visited twice to insert a phi or
								 * psi(ephi) node. */
                            throw new IllegalStateException(x.getDisplayName());
                        }
                        /* Map<BasicBlock, Expression> vls = new HashMap<>();
							for(FlowEdge<BasicBlock> fe : builder.graph.getReverseEdges(x)) {
								vls.put(fe.src, new VarExpr(newl, null));
							}
							vls.put(x, catcher.getExpression().copy());
							catcher.delete();
							
							PhiExpr phi = new PhiExceptionExpr(vls);
							CopyPhiStmt assign = new CopyPhiStmt(new VarExpr(l, null), phi);
							
							x.add(0, assign); */
                        throw new UnsupportedOperationException(builder.method.toString());
                    }
                }
                if (builder.graph.getReverseEdges(x).size() > 1) {
                    Map<BasicBlock, Expr> vls = new HashMap<>();
                    for (FlowEdge<BasicBlock> fe : builder.graph.getReverseEdges(x)) {
                        vls.put(fe.src(), new VarExpr(newl, null));
                    }
                    PhiExpr phi = new PhiExpr(vls);
                    CopyPhiStmt assign = new CopyPhiStmt(new VarExpr(l, null), phi);
                    x.add(0, assign);
                }
            }
            insertion.put(x, i);
            if (process.get(x) < i) {
                process.put(x, i);
                queue.add(x);
            }
        }
    }
}
Also used : NullPermeableHashMap(org.mapleir.stdlib.collections.map.NullPermeableHashMap) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) BasicLocal(org.mapleir.ir.locals.impl.BasicLocal) Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) 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) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) InitialisedObjectExpr(org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) 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 43 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class SSAGenPass method search.

private void search(BasicBlock b, Set<BasicBlock> vis) {
    if (vis.contains(b)) {
        return;
    }
    vis.add(b);
    searchImpl(b);
    List<FlowEdge<BasicBlock>> succs = new ArrayList<>();
    for (FlowEdge<BasicBlock> succE : builder.graph.getEdges(b)) {
        succs.add(succE);
    }
    succs.sort(Comparator.comparing(o -> o.dst()));
    for (FlowEdge<BasicBlock> succE : succs) {
        BasicBlock succ = succE.dst();
        fixPhiArgs(b, succ);
    }
    for (FlowEdge<BasicBlock> succE : succs) {
        BasicBlock succ = succE.dst();
        search(succ, vis);
    }
    unstackDefs(b);
    if (OPTIMISE) {
        optimisePhis(b);
    }
}
Also used : FlowEdge(org.mapleir.flowgraph.edges.FlowEdge) ConditionalJumpEdge(org.mapleir.flowgraph.edges.ConditionalJumpEdge) SwitchStmt(org.mapleir.ir.code.stmt.SwitchStmt) java.util(java.util) Constraint(org.mapleir.ir.cfg.builder.ssaopt.Constraint) ConstraintUtil(org.mapleir.ir.cfg.builder.ssaopt.ConstraintUtil) SSABlockLivenessAnalyser(org.mapleir.ir.algorithms.SSABlockLivenessAnalyser) FlowEdge(org.mapleir.flowgraph.edges.FlowEdge) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) BasicLocal(org.mapleir.ir.locals.impl.BasicLocal) Type(org.objectweb.asm.Type) UnconditionalJumpEdge(org.mapleir.flowgraph.edges.UnconditionalJumpEdge) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) SwitchEdge(org.mapleir.flowgraph.edges.SwitchEdge) Liveness(org.mapleir.ir.algorithms.Liveness) Opcode(org.mapleir.ir.code.Opcode) TarjanDominanceComputor(org.mapleir.flowgraph.algorithms.TarjanDominanceComputor) FlowEdges(org.mapleir.flowgraph.edges.FlowEdges) BasicBlock(org.mapleir.ir.cfg.BasicBlock) LatestValue(org.mapleir.ir.cfg.builder.ssaopt.LatestValue) InitialisedObjectExpr(org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr) PopStmt(org.mapleir.ir.code.stmt.PopStmt) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) ThrowStmt(org.mapleir.ir.code.stmt.ThrowStmt) Local(org.mapleir.ir.locals.Local) VarExpr(org.mapleir.ir.code.expr.VarExpr) ImmediateEdge(org.mapleir.flowgraph.edges.ImmediateEdge) Expr(org.mapleir.ir.code.Expr) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) CodeUnit(org.mapleir.ir.code.CodeUnit) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) SimpleDfs(org.mapleir.stdlib.collections.graph.algorithms.SimpleDfs) LabelNode(org.objectweb.asm.tree.LabelNode) UnconditionalJumpStmt(org.mapleir.ir.code.stmt.UnconditionalJumpStmt) LocalsPool(org.mapleir.ir.locals.LocalsPool) Stmt(org.mapleir.ir.code.Stmt) NullPermeableHashMap(org.mapleir.stdlib.collections.map.NullPermeableHashMap) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) ExceptionRange(org.mapleir.flowgraph.ExceptionRange) ConditionalJumpStmt(org.mapleir.ir.code.stmt.ConditionalJumpStmt) Entry(java.util.Map.Entry) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) SetCreator(org.mapleir.stdlib.collections.map.SetCreator) TryCatchEdge(org.mapleir.flowgraph.edges.TryCatchEdge) BasicBlock(org.mapleir.ir.cfg.BasicBlock)

Example 44 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class LatestValue method findReachable.

private Set<Stmt> findReachable(Stmt from, Stmt to) {
    Set<Stmt> res = new HashSet<>();
    BasicBlock f = from.getBlock();
    BasicBlock t = to.getBlock();
    int end = f == t ? f.indexOf(to) : f.size();
    for (int i = f.indexOf(from); i < end; i++) {
        res.add(f.get(i));
    }
    if (f != t) {
        for (BasicBlock r : cfg.wanderAllTrails(f, t)) {
            res.addAll(r);
        }
    }
    return res;
}
Also used : BasicBlock(org.mapleir.ir.cfg.BasicBlock) Stmt(org.mapleir.ir.code.Stmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) HashSet(java.util.HashSet)

Example 45 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class PhiExpr method equivalent.

@Override
public boolean equivalent(CodeUnit s) {
    if (s instanceof PhiExpr) {
        PhiExpr phi = (PhiExpr) s;
        Set<BasicBlock> sources = new HashSet<>();
        sources.addAll(arguments.keySet());
        sources.addAll(phi.arguments.keySet());
        if (sources.size() != arguments.size()) {
            return false;
        }
        for (BasicBlock b : sources) {
            Expr e1 = arguments.get(b);
            Expr e2 = phi.arguments.get(b);
            if (e1 == null || e2 == null) {
                return false;
            }
            if (!e1.equivalent(e2)) {
                return false;
            }
        }
        return true;
    }
    return false;
}
Also used : Expr(org.mapleir.ir.code.Expr) BasicBlock(org.mapleir.ir.cfg.BasicBlock) HashSet(java.util.HashSet)

Aggregations

BasicBlock (org.mapleir.ir.cfg.BasicBlock)70 Stmt (org.mapleir.ir.code.Stmt)37 Expr (org.mapleir.ir.code.Expr)34 Local (org.mapleir.ir.locals.Local)30 VarExpr (org.mapleir.ir.code.expr.VarExpr)29 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)25 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)24 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)22 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)19 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)19 HashSet (java.util.HashSet)12 ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)11 UnconditionalJumpStmt (org.mapleir.ir.code.stmt.UnconditionalJumpStmt)10 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)9 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)9 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)9 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)8 Type (org.objectweb.asm.Type)7 ArrayList (java.util.ArrayList)6 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)6