Search in sources :

Example 1 with PopStmt

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

the class SSAGenPass method aggregateInitialisers.

private void aggregateInitialisers() {
    for (BasicBlock b : builder.graph.vertices()) {
        for (Stmt stmt : new ArrayList<>(b)) {
            if (stmt.getOpcode() == Opcode.POP) {
                PopStmt pop = (PopStmt) stmt;
                Expr expr = pop.getExpression();
                if (expr.getOpcode() == Opcode.INVOKE) {
                    InvocationExpr invoke = (InvocationExpr) expr;
                    if (invoke.getCallType() == InvocationExpr.CallType.SPECIAL && invoke.getName().equals("<init>")) {
                        Expr inst = invoke.getPhysicalReceiver();
                        if (inst.getOpcode() == Opcode.LOCAL_LOAD) {
                            VarExpr var = (VarExpr) inst;
                            VersionedLocal local = (VersionedLocal) var.getLocal();
                            AbstractCopyStmt def = pool.defs.get(local);
                            Expr rhs = def.getExpression();
                            if (rhs.getOpcode() == Opcode.ALLOC_OBJ) {
                                // replace pop(x.<init>()) with x := new Klass();
                                // remove x := new Klass;
                                // here we are assuming that the new object
                                // can't be used until it is initialised.
                                Expr[] args = invoke.getParameterExprs();
                                // we want to reuse the exprs, so free it first.
                                pop.deleteAt(0);
                                Expr[] newArgs = Arrays.copyOf(args, args.length);
                                for (int i = args.length - 1; i >= 0; i--) {
                                    args[i].unlink();
                                }
                                // remove the old def
                                def.delete();
                                int index = b.indexOf(pop);
                                // add a copy statement before the pop (x = newExpr)
                                InitialisedObjectExpr newExpr = new InitialisedObjectExpr(invoke.getOwner(), invoke.getDesc(), newArgs);
                                CopyVarStmt newCvs = new CopyVarStmt(var, newExpr);
                                pool.defs.put(local, newCvs);
                                pool.uses.get(local).remove(var);
                                b.add(index, newCvs);
                                // remove the pop statement
                                b.remove(pop);
                                // update the latestval constraints
                                LatestValue lval = latest.get(local);
                                if (lval.hasConstraints()) {
                                    /* need to check this out (shouldn't happen) */
                                    System.out.println("Constraints:");
                                    for (Constraint c : lval.getConstraints()) {
                                        System.out.println("  " + c);
                                    }
                                    throw new IllegalStateException(lval.toString());
                                } else {
                                    lval.makeConstraints(newExpr);
                                }
                            }
                        } else if (inst.getOpcode() == Opcode.ALLOC_OBJ) {
                            // replace pop(new Klass.<init>(args)) with pop(new Klass(args))
                            // UninitialisedObjectExpr obj = (UninitialisedObjectExpr) inst;
                            Expr[] args = invoke.getParameterExprs();
                            // we want to reuse the exprs, so free it first.
                            invoke.unlink();
                            for (Expr e : args) {
                                e.unlink();
                            }
                            Expr[] newArgs = Arrays.copyOf(args, args.length);
                            InitialisedObjectExpr newExpr = new InitialisedObjectExpr(invoke.getOwner(), invoke.getDesc(), newArgs);
                            // replace pop contents
                            // no changes to defs or uses
                            pop.setExpression(newExpr);
                        } else {
                            System.err.println(b);
                            System.err.println("Stmt: " + stmt.getDisplayName() + ". " + stmt);
                            System.err.println("Inst: " + inst);
                            System.err.println(builder.graph);
                            throw new RuntimeException("interesting1 " + inst.getClass());
                        }
                    }
                }
            }
        }
    }
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) Constraint(org.mapleir.ir.cfg.builder.ssaopt.Constraint) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) InitialisedObjectExpr(org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr) Constraint(org.mapleir.ir.cfg.builder.ssaopt.Constraint) 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) LatestValue(org.mapleir.ir.cfg.builder.ssaopt.LatestValue) 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) PopStmt(org.mapleir.ir.code.stmt.PopStmt) VarExpr(org.mapleir.ir.code.expr.VarExpr) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr)

Example 2 with PopStmt

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

the class SSAGenPass method searchImpl.

private void searchImpl(BasicBlock b) {
    Iterator<Stmt> it = b.iterator();
    while (it.hasNext()) {
        Stmt stmt = it.next();
        int opcode = stmt.getOpcode();
        if (opcode == Opcode.POP) {
            PopStmt pop = (PopStmt) stmt;
            if (!ConstraintUtil.isUncopyable(pop.getExpression())) {
                it.remove();
                continue;
            }
        }
        if (opcode == Opcode.PHI_STORE) {
            /* We can rename these any time as these
				 * are visited before all other statements
				 * in a block (since they are always
				 * the starting statements of a block, if
				 * that block contains phi statements).
				 */
            CopyPhiStmt copy = (CopyPhiStmt) stmt;
            generate(copy);
        } else {
            /* Translates locals into their latest SSA
				 * versioned locals.
				 * 
				 * Do this before a LOCAL_STORE (x = ...)
				 * so that the target local isn't defined
				 * before the use so that copies in the
				 * form x = x; do not get mangled into
				 * x0 = x0 after SSA renaming.
				 * 
				 * We rename phi args later as the source
				 * local can originate from exotic blocks.
				 */
            translate(stmt, true, false);
        }
        if (opcode == Opcode.LOCAL_STORE) {
            /* Generate the target local after
				 * renaming the source pool.uses. 
				 */
            CopyVarStmt copy = (CopyVarStmt) stmt;
            generate(copy);
        }
    }
}
Also used : PopStmt(org.mapleir.ir.code.stmt.PopStmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) Constraint(org.mapleir.ir.cfg.builder.ssaopt.Constraint) 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)

Aggregations

Constraint (org.mapleir.ir.cfg.builder.ssaopt.Constraint)2 Stmt (org.mapleir.ir.code.Stmt)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 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)2 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)2 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)2 BasicBlock (org.mapleir.ir.cfg.BasicBlock)1 LatestValue (org.mapleir.ir.cfg.builder.ssaopt.LatestValue)1 Expr (org.mapleir.ir.code.Expr)1 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)1 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)1 VarExpr (org.mapleir.ir.code.expr.VarExpr)1 InitialisedObjectExpr (org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr)1 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)1 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)1