Search in sources :

Example 6 with UnreachableOperand

use of org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand in project JikesRVM by JikesRVM.

the class LeaveSSA method normalizeSSA.

/**
 * Avoid potential lost copy and other associated problems by
 * Sreedhar's naive translation from TSSA to CSSA. Guards are rather
 * trivial to un-SSA so they have already been removed from the IR.
 * This algorithm is very wasteful of registers so needs good
 * coalescing.
 * @param ir the IR to work upon
 */
// NB this was an aborted attempt to fix a bug in leave SSA
@SuppressWarnings("unused")
private static void normalizeSSA(IR ir) {
    for (Instruction s = ir.firstInstructionInCodeOrder(), sentinel = ir.lastInstructionInCodeOrder(), nextInstr = null; s != sentinel; s = nextInstr) {
        // cache so we don't process inserted instructions
        nextInstr = s.nextInstructionInCodeOrder();
        if (Phi.conforms(s) && !s.getBasicBlock().isExceptionHandlerBasicBlock()) {
            // We ignore exception handler BBs as they cause problems when inserting copies
            if (DEBUG)
                VM.sysWriteln("Processing " + s + " of basic block " + s.getBasicBlock());
            // Does the phi instruction have an unreachable operand?
            boolean hasUnreachable = false;
            // 1. Naively copy source operands into predecessor blocks
            for (int index = 0; index < Phi.getNumberOfPreds(s); index++) {
                Operand op = Phi.getValue(s, index);
                if (op.isRegister()) {
                    // Get rval
                    Register rval = op.asRegister().getRegister();
                    if (rval.isValidation()) {
                        // ignore guards
                        continue;
                    } else {
                        // Make rval'
                        Register rvalPrime = ir.regpool.getReg(rval);
                        // Make copy instruction
                        Instruction copy = SSA.makeMoveInstruction(ir, rvalPrime, rval, op.getType());
                        // Insert a copy of rval to rval' in predBlock
                        BasicBlock pred = Phi.getPred(s, index).block;
                        pred.appendInstructionRespectingTerminalBranch(copy);
                        if (DEBUG)
                            VM.sysWriteln("Inserted rval copy of " + copy + " into basic block " + pred);
                        // Rename rval to rval' in phi instruction
                        op.asRegister().setRegister(rvalPrime);
                    }
                } else if (op instanceof UnreachableOperand) {
                    hasUnreachable = true;
                }
            }
            // 2. Naively copy the result if there were no unreachable operands
            if (!hasUnreachable) {
                Operand op = Phi.getResult(s);
                if (!op.isRegister()) {
                // ignore heap operands
                } else {
                    // Get lval
                    Register lval = op.asRegister().getRegister();
                    // Make lval'
                    Register lvalPrime = ir.regpool.getReg(lval);
                    // Make copy instruction
                    Instruction copy = SSA.makeMoveInstruction(ir, lval, lvalPrime, op.getType());
                    // Insert a copy of lval' to lval after phi instruction
                    s.insertAfter(copy);
                    // Rename lval to lval' in phi instruction
                    op.asRegister().setRegister(lvalPrime);
                    if (DEBUG)
                        VM.sysWriteln("Inserted lval copy of " + copy + " after " + s);
                }
            }
        }
    }
}
Also used : Register(org.jikesrvm.compilers.opt.ir.Register) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 7 with UnreachableOperand

use of org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand in project JikesRVM by JikesRVM.

the class LeaveSSA method scheduleCopies.

/**
 * Record pending copy operations needed to insert at the end of a basic
 * block.<p>
 *
 * TODO: this procedure is getting long and ugly.  Rewrite or refactor
 * it.
 * @param bb the basic block to process
 * @param live valid liveness information for the IR
 */
private void scheduleCopies(BasicBlock bb, LiveAnalysis live) {
    if (DEBUG)
        VM.sysWriteln("scheduleCopies: " + bb);
    // compute out liveness from information in LiveAnalysis
    LiveSet out = new LiveSet();
    for (Enumeration<BasicBlock> outBlocks = bb.getOut(); outBlocks.hasMoreElements(); ) {
        BasicBlock ob = outBlocks.nextElement();
        LiveAnalysis.BBLiveElement le = live.getLiveInfo(ob);
        out.add(le.getIn());
    }
    // usedByAnother represents the set of registers that appear on the
    // left-hand side of subsequent phi nodes.  This is important, since
    // we be careful to order copies if the same register appears as the
    // source and dest of copies in the same basic block.
    HashSet<Register> usedByAnother = new HashSet<Register>(4);
    // for each basic block successor b of bb, if we make a block on the
    // critical edge bb->b, then store this critical block.
    HashMap<BasicBlock, BasicBlock> criticalBlocks = new HashMap<BasicBlock, BasicBlock>(4);
    // For each critical basic block b in which we are inserting copies: return the
    // mapping of registers to names implied by the copies that have
    // already been inserted into b.
    HashMap<BasicBlock, HashMap<Register, Register>> currentNames = new HashMap<BasicBlock, HashMap<Register, Register>>(4);
    // Additionally store the current names for the current basic block bb.
    HashMap<Register, Register> bbNames = new HashMap<Register, Register>(4);
    // copySet is a linked-list of copies we need to insert in this block.
    final LinkedList<Copy> copySet = new LinkedList<Copy>();
    /* Worklist is actually used like a stack - should we make this an Stack ?? */
    final LinkedList<Copy> workList = new LinkedList<Copy>();
    // collect copies required in this block.  These copies move
    // the appropriate rval into the lval of each phi node in
    // control children of the current block.
    Enumeration<BasicBlock> e = bb.getOut();
    while (e.hasMoreElements()) {
        BasicBlock bbs = e.nextElement();
        if (bbs.isExit())
            continue;
        for (Instruction phi = bbs.firstInstruction(); phi != bbs.lastInstruction(); phi = phi.nextInstructionInCodeOrder()) {
            if (phi.operator() != PHI)
                continue;
            for (int index = 0; index < Phi.getNumberOfPreds(phi); index++) {
                if (Phi.getPred(phi, index).block != bb)
                    continue;
                Operand rval = Phi.getValue(phi, index);
                if (rval.isRegister() && Phi.getResult(phi).asRegister().getRegister() == rval.asRegister().getRegister()) {
                    continue;
                }
                Copy c = new Copy(phi, index);
                copySet.add(0, c);
                if (c.source instanceof RegisterOperand) {
                    Register r = c.source.asRegister().getRegister();
                    usedByAnother.add(r);
                }
            }
        }
    }
    // the set of needed copies.
    for (Iterator<Copy> copySetIter = copySet.iterator(); copySetIter.hasNext(); ) {
        Copy c = copySetIter.next();
        if (!usedByAnother.contains(c.destination.getRegister())) {
            workList.add(0, c);
            copySetIter.remove();
        }
    }
    // while there is any more work to do.
    while (!workList.isEmpty() || !copySet.isEmpty()) {
        // while there are copies that can be correctly inserted.
        while (!workList.isEmpty()) {
            Copy c = workList.remove(0);
            Register r = c.destination.getRegister();
            TypeReference tt = c.destination.getType();
            if (VM.VerifyAssertions && tt == null) {
                tt = TypeReference.Int;
                VM.sysWriteln("SSA, warning: null type in " + c.destination);
            }
            Register rr = null;
            if (c.source.isRegister())
                rr = c.source.asRegister().getRegister();
            boolean shouldSplitBlock = !c.phi.getBasicBlock().isExceptionHandlerBasicBlock() && ((ir.options.SSA_SPLITBLOCK_TO_AVOID_RENAME && out.contains(r)) || (rr != null && ir.options.SSA_SPLITBLOCK_FOR_LOCAL_LIVE && usedBelowCopy(bb, rr)));
            if (ir.options.SSA_SPLITBLOCK_INTO_INFREQUENT) {
                if (!bb.getInfrequent() && c.phi.getBasicBlock().getInfrequent() && !c.phi.getBasicBlock().isExceptionHandlerBasicBlock()) {
                    shouldSplitBlock = true;
                }
            }
            // new name.
            if (out.contains(r) && !shouldSplitBlock) {
                if (!globalRenamePhis.contains(r)) {
                    Register t = ir.regpool.getReg(r);
                    Instruction save = SSA.makeMoveInstruction(ir, t, r, tt);
                    if (DEBUG) {
                        VM.sysWriteln("Inserting " + save + " before " + c.phi + " in " + c.phi.getBasicBlock());
                    }
                    c.phi.insertAfter(save);
                    globalRenamePhis.add(r);
                    globalRenameTable.add(save);
                }
            }
            Instruction ci = null;
            // insert copy operation required to remove phi
            if (c.source instanceof ConstantOperand) {
                if (c.source instanceof UnreachableOperand) {
                    ci = null;
                } else {
                    ci = SSA.makeMoveInstruction(ir, r, (ConstantOperand) c.source);
                }
            } else if (c.source instanceof RegisterOperand) {
                if (shouldSplitBlock) {
                    if (DEBUG)
                        VM.sysWriteln("splitting edge: " + bb + "->" + c.phi.getBasicBlock());
                    BasicBlock criticalBlock = criticalBlocks.get(c.phi.getBasicBlock());
                    if (criticalBlock == null) {
                        criticalBlock = IRTools.makeBlockOnEdge(bb, c.phi.getBasicBlock(), ir);
                        if (c.phi.getBasicBlock().getInfrequent()) {
                            criticalBlock.setInfrequent();
                        }
                        splitSomeBlock = true;
                        criticalBlocks.put(c.phi.getBasicBlock(), criticalBlock);
                        HashMap<Register, Register> newNames = new HashMap<Register, Register>(4);
                        currentNames.put(criticalBlock, newNames);
                    }
                    Register sr = c.source.asRegister().getRegister();
                    HashMap<Register, Register> criticalBlockNames = currentNames.get(criticalBlock);
                    Register nameForSR = criticalBlockNames.get(sr);
                    if (nameForSR == null) {
                        nameForSR = bbNames.get(sr);
                        if (nameForSR == null)
                            nameForSR = sr;
                    }
                    if (DEBUG)
                        VM.sysWriteln("dest(r): " + r);
                    if (DEBUG)
                        VM.sysWriteln("sr: " + sr + ", nameForSR: " + nameForSR);
                    ci = SSA.makeMoveInstruction(ir, r, nameForSR, tt);
                    criticalBlockNames.put(sr, r);
                    criticalBlock.appendInstructionRespectingTerminalBranch(ci);
                } else {
                    Register sr = c.source.asRegister().getRegister();
                    Register nameForSR = bbNames.get(sr);
                    if (nameForSR == null)
                        nameForSR = sr;
                    if (DEBUG)
                        VM.sysWriteln("not splitting edge: " + bb + "->" + c.phi.getBasicBlock());
                    if (DEBUG)
                        VM.sysWriteln("dest(r): " + r);
                    if (DEBUG)
                        VM.sysWriteln("sr: " + sr + ", nameForSR: " + nameForSR);
                    ci = SSA.makeMoveInstruction(ir, r, nameForSR, tt);
                    bbNames.put(sr, r);
                    SSA.addAtEnd(ir, bb, ci, c.phi.getBasicBlock().isExceptionHandlerBasicBlock());
                }
                // ugly hack: having already added ci; set ci to null to skip remaining code;
                ci = null;
            } else {
                throw new OptimizingCompilerException("Unexpected phi operand " + c.source + " encountered during SSA teardown", true);
            }
            if (ci != null) {
                if (shouldSplitBlock) {
                    if (DEBUG)
                        VM.sysWriteln("splitting edge: " + bb + "->" + c.phi.getBasicBlock());
                    BasicBlock criticalBlock = criticalBlocks.get(c.phi.getBasicBlock());
                    if (criticalBlock == null) {
                        criticalBlock = IRTools.makeBlockOnEdge(bb, c.phi.getBasicBlock(), ir);
                        if (c.phi.getBasicBlock().getInfrequent()) {
                            criticalBlock.setInfrequent();
                        }
                        splitSomeBlock = true;
                        criticalBlocks.put(c.phi.getBasicBlock(), criticalBlock);
                        HashMap<Register, Register> newNames = new HashMap<Register, Register>(4);
                        currentNames.put(criticalBlock, newNames);
                    }
                    criticalBlock.appendInstructionRespectingTerminalBranch(ci);
                } else {
                    SSA.addAtEnd(ir, bb, ci, c.phi.getBasicBlock().isExceptionHandlerBasicBlock());
                }
            }
            // current copy to the work list.
            if (c.source instanceof RegisterOperand) {
                Register saved = c.source.asRegister().getRegister();
                Iterator<Copy> copySetIter = copySet.iterator();
                while (copySetIter.hasNext()) {
                    Copy cc = copySetIter.next();
                    if (cc.destination.asRegister().getRegister() == saved) {
                        workList.add(0, cc);
                        copySetIter.remove();
                    }
                }
            }
        }
        // safely overwritten.  so, add that copy to the work list.
        if (!copySet.isEmpty()) {
            Copy c = copySet.remove(0);
            Register tt = ir.regpool.getReg(c.destination.getRegister());
            SSA.addAtEnd(ir, bb, SSA.makeMoveInstruction(ir, tt, c.destination.getRegister(), c.destination.getType()), c.phi.getBasicBlock().isExceptionHandlerBasicBlock());
            bbNames.put(c.destination.getRegister(), tt);
            workList.add(0, c);
        }
    }
}
Also used : LiveSet(org.jikesrvm.compilers.opt.liveness.LiveSet) HashMap(java.util.HashMap) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TypeReference(org.jikesrvm.classloader.TypeReference) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) HashSet(java.util.HashSet) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) LiveAnalysis(org.jikesrvm.compilers.opt.liveness.LiveAnalysis) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) LinkedList(java.util.LinkedList) Register(org.jikesrvm.compilers.opt.ir.Register)

Example 8 with UnreachableOperand

use of org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand in project JikesRVM by JikesRVM.

the class LeaveSSA method unSSAGuardsInit.

/**
 * Initialization for removal of guard phis.
 *
 * @param ir the governing IR, currently in SSA form
 */
private void unSSAGuardsInit(IR ir) {
    guardPhis = null;
    Enumeration<Instruction> e = ir.forwardInstrEnumerator();
    // visit all instructions, looking for guard phis
    inst2guardPhi = new HashMap<Instruction, Instruction>();
    while (e.hasMoreElements()) {
        Instruction inst = e.nextElement();
        if (!Phi.conforms(inst))
            continue;
        Operand res = Phi.getResult(inst);
        if (!(res instanceof RegisterOperand))
            continue;
        Register r = res.asRegister().getRegister();
        if (!r.isValidation())
            continue;
        // force all operands of Phis into registers.
        inst2guardPhi.put(inst, guardPhis);
        guardPhis = inst;
        int values = Phi.getNumberOfValues(inst);
        for (int i = 0; i < values; ++i) {
            Operand op = Phi.getValue(inst, i);
            if (!(op instanceof RegisterOperand)) {
                if (op instanceof TrueGuardOperand) {
                    BasicBlock bb = Phi.getPred(inst, i).block;
                    Instruction move = Move.create(GUARD_MOVE, res.asRegister().copyD2D(), new TrueGuardOperand());
                    move.setSourcePosition(SSA_SYNTH_BCI, ir.getGc().getInlineSequence());
                    bb.appendInstructionRespectingTerminalBranchOrPEI(move);
                } else if (op instanceof UnreachableOperand) {
                // do nothing
                } else {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.NOT_REACHED);
                }
            }
        }
    }
    guardRegUnion = new HashMap<Register, Integer>();
    associatedRegisters = new HashMap<Register, Register>();
    // visit all guard registers, init union/find
    for (Register r = ir.regpool.getFirstSymbolicRegister(); r != null; r = r.getNext()) {
        if (!r.isValidation())
            continue;
        guardRegUnion.put(r, Integer.valueOf(1));
        associatedRegisters.put(r, r);
    }
}
Also used : UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register)

Example 9 with UnreachableOperand

use of org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand in project JikesRVM by JikesRVM.

the class EnterSSA method search.

/**
 * This routine is the guts of the SSA construction phase for scalars.  See
 * renameSymbolicRegisters for more details.
 *
 * @param X basic block to search dominator tree from
 * @param S stack of names for each register
 */
private void search(BasicBlock X, Stack<RegisterOperand>[] S) {
    if (DEBUG)
        System.out.println("SEARCH " + X);
    HashMap<Register, Register> pushedRegs = new HashMap<Register, Register>();
    for (Enumeration<Instruction> ie = X.forwardInstrEnumerator(); ie.hasMoreElements(); ) {
        Instruction A = ie.nextElement();
        if (A.operator() != PHI) {
            // replace each use
            for (int u = A.getNumberOfDefs(); u < A.getNumberOfOperands(); u++) {
                Operand op = A.getOperand(u);
                if (op instanceof RegisterOperand) {
                    RegisterOperand rop = (RegisterOperand) op;
                    Register r1 = rop.getRegister();
                    if (r1.isSSA())
                        continue;
                    if (r1.isPhysical())
                        continue;
                    RegisterOperand r2 = S[r1.getNumber()].peek();
                    if (DEBUG)
                        System.out.println("REPLACE NORMAL USE " + r1 + " with " + r2);
                    if (r2 != null) {
                        rop.setRegister(r2.getRegister());
                        DefUse.recordUse(rop);
                    }
                }
            }
        }
        // replace each def
        for (int d = 0; d < A.getNumberOfDefs(); d++) {
            Operand op = A.getOperand(d);
            if (op instanceof RegisterOperand) {
                RegisterOperand rop = (RegisterOperand) op;
                Register r1 = rop.getRegister();
                if (r1.isSSA())
                    continue;
                if (r1.isPhysical())
                    continue;
                Register r2 = ir.regpool.getReg(r1);
                if (DEBUG)
                    System.out.println("PUSH " + r2 + " FOR " + r1 + " BECAUSE " + A);
                S[r1.getNumber()].push(new RegisterOperand(r2, rop.getType()));
                rop.setRegister(r2);
                pushedRegs.put(r2, r1);
            }
        }
    }
    if (DEBUG)
        System.out.println("SEARCH (second loop) " + X);
    for (Enumeration<BasicBlock> y = X.getOut(); y.hasMoreElements(); ) {
        BasicBlock Y = y.nextElement();
        if (DEBUG)
            System.out.println(" Successor: " + Y);
        int j = numPredProcessed[Y.getNumber()]++;
        if (Y.isExit())
            continue;
        Instruction s = Y.firstRealInstruction();
        if (s == null)
            continue;
        // replace use USE in each PHI instruction
        if (DEBUG)
            System.out.println(" Predecessor: " + j);
        while (s.operator() == PHI) {
            Operand val = Phi.getValue(s, j);
            if (val.isRegister()) {
                Register r1 = ((RegisterOperand) Phi.getValue(s, j)).getRegister();
                // ignore registers already marked SSA by a previous pass
                if (!r1.isSSA()) {
                    RegisterOperand r2 = S[r1.getNumber()].peek();
                    if (r2 == null) {
                        // in this case, the register is never defined along
                        // this particular control flow path into the basic
                        // block.
                        Phi.setValue(s, j, new UnreachableOperand());
                    } else {
                        RegisterOperand rop = r2.copyRO();
                        Phi.setValue(s, j, rop);
                        DefUse.recordUse(rop);
                    }
                    Phi.setPred(s, j, new BasicBlockOperand(X));
                }
            }
            s = s.nextInstructionInCodeOrder();
        }
    }
    if (DEBUG)
        System.out.println("SEARCH (third loop) " + X);
    for (Enumeration<TreeNode> c = ir.HIRInfo.dominatorTree.getChildren(X); c.hasMoreElements(); ) {
        DominatorTreeNode v = (DominatorTreeNode) c.nextElement();
        search(v.getBlock(), S);
    }
    if (DEBUG)
        System.out.println("SEARCH (fourth loop) " + X);
    for (Enumeration<Instruction> a = X.forwardInstrEnumerator(); a.hasMoreElements(); ) {
        Instruction A = a.nextElement();
        // loop over each def
        for (int d = 0; d < A.getNumberOfDefs(); d++) {
            Operand newOp = A.getOperand(d);
            if (newOp == null)
                continue;
            if (!newOp.isRegister())
                continue;
            Register newReg = newOp.asRegister().getRegister();
            if (newReg.isSSA())
                continue;
            if (newReg.isPhysical())
                continue;
            Register r1 = pushedRegs.get(newReg);
            S[r1.getNumber()].pop();
            if (DEBUG)
                System.out.println("POP " + r1);
        }
    }
    // end of fourth loop
    if (DEBUG)
        System.out.println("FINISHED SEARCH " + X);
}
Also used : BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) HashMap(java.util.HashMap) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) DominatorTreeNode(org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode) TreeNode(org.jikesrvm.compilers.opt.util.TreeNode) DominatorTreeNode(org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode)

Example 10 with UnreachableOperand

use of org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand in project JikesRVM by JikesRVM.

the class Simplifier method getObjTib.

private static DefUseEffect getObjTib(Instruction s, OptOptions opts) {
    if (opts.SIMPLIFY_TIB_OPS) {
        Operand op = GuardedUnary.getVal(s);
        if (op.isNullConstant()) {
            // Simplify to an unreachable operand, this instruction is dead code
            // guarded by a nullcheck that should already have been simplified
            RegisterOperand result = GetField.getClearResult(s);
            Move.mutate(s, IRTools.getMoveOp(result.getType()), result, new UnreachableOperand());
            return DefUseEffect.MOVE_FOLDED;
        } else if (op.isConstant()) {
            final TypeReference typeRef = op.getType();
            if (typeRef.isResolved()) {
                Move.mutate(s, REF_MOVE, GuardedUnary.getClearResult(s), new TIBConstantOperand(op.getType().peekType()));
                return DefUseEffect.MOVE_FOLDED;
            }
        } else {
            RegisterOperand rop = op.asRegister();
            TypeReference typeRef = rop.getType();
            // Is the type of this register only one possible type?
            if (typeRef.isResolved() && rop.isPreciseType() && typeRef.resolve().isInstantiated()) {
                // before simplifying ensure that the type is instantiated, this stops
                // constant propagation potentially moving the TIB constant before the
                // runtime call that instantiates it
                Move.mutate(s, REF_MOVE, GuardedUnary.getClearResult(s), new TIBConstantOperand(typeRef.peekType()));
                return DefUseEffect.MOVE_FOLDED;
            }
        }
    }
    return DefUseEffect.UNCHANGED;
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) CodeConstantOperand(org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) TypeReference(org.jikesrvm.classloader.TypeReference)

Aggregations

UnreachableOperand (org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand)10 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)9 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)9 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)7 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)6 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)6 Register (org.jikesrvm.compilers.opt.ir.Register)5 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)4 TypeReference (org.jikesrvm.classloader.TypeReference)3 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)3 HeapOperand (org.jikesrvm.compilers.opt.ir.operand.HeapOperand)3 ObjectConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand)3 TIBConstantOperand (org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand)3 HashMap (java.util.HashMap)2 OptimizingCompilerException (org.jikesrvm.compilers.opt.OptimizingCompilerException)2 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)2 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)2 CodeConstantOperand (org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand)2 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)2 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)2