Search in sources :

Example 66 with Instruction

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

the class EnterSSA method patchPEIgeneratedValues.

/**
 * Work around some problems with PEI-generated values and
 * handlers.  Namely, if a PEI has a return value, rename the
 * result register before and after the PEI in order to reflect the fact
 * that the PEI may not actually assign the result register.
 */
private void patchPEIgeneratedValues() {
    // this only applies if there are exception handlers
    if (!ir.hasReachableExceptionHandlers())
        return;
    HashSet<Pair<BasicBlock, RegisterOperand>> needed = new HashSet<Pair<BasicBlock, RegisterOperand>>(4);
    Enumeration<BasicBlock> blocks = ir.getBasicBlocks();
    while (blocks.hasMoreElements()) {
        BasicBlock block = blocks.nextElement();
        if (block.getExceptionalOut().hasMoreElements()) {
            Instruction pei = block.lastRealInstruction();
            if (pei != null && pei.isPEI() && ResultCarrier.conforms(pei)) {
                boolean copyNeeded = false;
                RegisterOperand v = ResultCarrier.getResult(pei);
                // void calls and the like... :(
                if (v != null) {
                    Register orig = v.getRegister();
                    {
                        Enumeration<BasicBlock> out = block.getApplicableExceptionalOut(pei);
                        while (out.hasMoreElements()) {
                            BasicBlock exp = out.nextElement();
                            LiveSet explive = live.getLiveInfo(exp).getIn();
                            if (explive.contains(orig)) {
                                copyNeeded = true;
                                break;
                            }
                        }
                    }
                    if (copyNeeded) {
                        Enumeration<BasicBlock> out = block.getApplicableExceptionalOut(pei);
                        while (out.hasMoreElements()) {
                            BasicBlock exp = out.nextElement();
                            needed.add(new Pair<BasicBlock, RegisterOperand>(exp, v));
                        }
                    }
                }
            }
        }
    }
    // having determine where copies should be inserted, now insert them.
    if (!needed.isEmpty()) {
        for (Pair<BasicBlock, RegisterOperand> copy : needed) {
            BasicBlock inBlock = copy.first;
            RegisterOperand registerOp = copy.second;
            TypeReference type = registerOp.getType();
            Register register = registerOp.getRegister();
            Register temp = ir.regpool.getReg(register);
            inBlock.prependInstruction(SSA.makeMoveInstruction(ir, register, temp, type));
            Enumeration<BasicBlock> outBlocks = inBlock.getIn();
            while (outBlocks.hasMoreElements()) {
                BasicBlock outBlock = outBlocks.nextElement();
                Instruction x = SSA.makeMoveInstruction(ir, temp, register, type);
                SSA.addAtEnd(ir, outBlock, x, true);
            }
        }
        // Recompute liveness information.  You might be tempted to incrementally
        // update it, but it's tricky, so resist.....do the obvious, but easy thing!
        prepare();
    }
}
Also used : LiveSet(org.jikesrvm.compilers.opt.liveness.LiveSet) Enumeration(java.util.Enumeration) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) TypeReference(org.jikesrvm.classloader.TypeReference) Pair(org.jikesrvm.util.Pair) HashSet(java.util.HashSet)

Example 67 with Instruction

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

the class EnterSSA method search2.

/**
 * This routine is the guts of the SSA construction phase for heap array
 * SSA.  The renaming algorithm is analagous to the algorithm for
 * scalars See <code> renameSymbolicRegisters </code> for more details.
 *
 * @param X the current basic block being traversed
 * @param stacks a structure holding the current names for each heap
 * variable
 * used and defined by each instruction.
 */
private void search2(BasicBlock X, HashMap<Object, Stack<HeapOperand<Object>>> stacks) {
    if (DEBUG)
        System.out.println("SEARCH2 " + X);
    SSADictionary dictionary = ir.HIRInfo.dictionary;
    for (Enumeration<Instruction> ie = dictionary.getAllInstructions(X); ie.hasMoreElements(); ) {
        Instruction A = ie.nextElement();
        if (!dictionary.usesHeapVariable(A) && !dictionary.defsHeapVariable(A))
            continue;
        if (A.operator() != PHI) {
            // replace the Heap variables USED by this instruction
            HeapOperand<Object>[] uses = dictionary.getHeapUses(A);
            if (uses != null) {
                // Generic array problem
                @SuppressWarnings("unchecked") HeapOperand<Object>[] newUses = new HeapOperand[uses.length];
                for (int i = 0; i < uses.length; i++) {
                    Stack<HeapOperand<Object>> S = stacks.get(uses[i].getHeapType());
                    newUses[i] = S.peek().copy();
                    if (DEBUG) {
                        System.out.println("NORMAL USE PEEK " + newUses[i]);
                    }
                }
                dictionary.replaceUses(A, newUses);
            }
        }
        // replace any Heap variable DEF
        if (A.operator() != PHI) {
            HeapOperand<Object>[] defs = dictionary.getHeapDefs(A);
            if (defs != null) {
                for (HeapOperand<Object> operand : dictionary.replaceDefs(A, X)) {
                    Stack<HeapOperand<Object>> S = stacks.get(operand.getHeapType());
                    S.push(operand);
                    if (DEBUG)
                        System.out.println("PUSH " + operand + " FOR " + operand.getHeapType());
                }
            }
        } else {
            HeapOperand<Object>[] r = dictionary.replaceDefs(A, X);
            Stack<HeapOperand<Object>> S = stacks.get(r[0].getHeapType());
            S.push(r[0]);
            if (DEBUG)
                System.out.println("PUSH " + r[0] + " FOR " + r[0].getHeapType());
        }
    }
    for (Enumeration<BasicBlock> y = X.getOut(); y.hasMoreElements(); ) {
        BasicBlock Y = y.nextElement();
        if (Y.isExit())
            continue;
        int j = numPredProcessed[Y.getNumber()]++;
        // replace each USE in each HEAP-PHI function for Y
        for (Iterator<Instruction> hp = dictionary.getHeapPhiInstructions(Y); hp.hasNext(); ) {
            Instruction s = hp.next();
            // Down-cast to a generic type
            @SuppressWarnings("unchecked") HeapOperand<Object> H1 = (HeapOperand) Phi.getResult(s);
            Stack<HeapOperand<Object>> S = stacks.get(H1.getHeapType());
            HeapOperand<Object> H2 = S.peek();
            Phi.setValue(s, j, new HeapOperand<Object>(H2.getHeapVariable()));
            Phi.setPred(s, j, new BasicBlockOperand(X));
        }
    }
    for (Enumeration<TreeNode> c = ir.HIRInfo.dominatorTree.getChildren(X); c.hasMoreElements(); ) {
        DominatorTreeNode v = (DominatorTreeNode) c.nextElement();
        search2(v.getBlock(), stacks);
    }
    for (Enumeration<Instruction> a = dictionary.getAllInstructions(X); a.hasMoreElements(); ) {
        Instruction A = a.nextElement();
        if (!dictionary.usesHeapVariable(A) && !dictionary.defsHeapVariable(A))
            continue;
        // retrieve the Heap Variables defined by A
        if (A.operator() != PHI) {
            HeapOperand<Object>[] defs = dictionary.getHeapDefs(A);
            if (defs != null) {
                for (HeapOperand<Object> def : defs) {
                    Stack<HeapOperand<Object>> S = stacks.get(def.getHeapType());
                    S.pop();
                    if (DEBUG)
                        System.out.println("POP " + def.getHeapType());
                }
            }
        } else {
            // Down-cast to a generic type
            @SuppressWarnings("unchecked") HeapOperand<Object> H = (HeapOperand) Phi.getResult(A);
            Stack<HeapOperand<Object>> S = stacks.get(H.getHeapType());
            S.pop();
            if (DEBUG)
                System.out.println("POP " + H.getHeapType());
        }
    }
    // end of fourth loop
    if (DEBUG)
        System.out.println("END SEARCH2 " + X);
}
Also used : BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) DominatorTreeNode(org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode) TreeNode(org.jikesrvm.compilers.opt.util.TreeNode) DominatorTreeNode(org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode)

Example 68 with Instruction

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

the class EnterSSA method computeNonLocals.

/**
 * Pass through the IR and calculate which registers are not
 * local to a basic block.  Store the result in the <code> nonLocalRegisters
 * </code> field.
 */
@SuppressWarnings("unused")
private void computeNonLocals() {
    nonLocalRegisters = new HashSet<Register>(20);
    Enumeration<BasicBlock> blocks = ir.getBasicBlocks();
    while (blocks.hasMoreElements()) {
        HashSet<Register> killed = new HashSet<Register>(5);
        BasicBlock block = blocks.nextElement();
        Enumeration<Instruction> instrs = block.forwardRealInstrEnumerator();
        while (instrs.hasMoreElements()) {
            Instruction instr = instrs.nextElement();
            Enumeration<Operand> uses = instr.getUses();
            while (uses.hasMoreElements()) {
                Operand op = uses.nextElement();
                if (op instanceof RegisterOperand) {
                    if (!killed.contains(op.asRegister().getRegister())) {
                        nonLocalRegisters.add(op.asRegister().getRegister());
                    }
                }
            }
            Enumeration<Operand> defs = instr.getDefs();
            while (defs.hasMoreElements()) {
                Operand op = defs.nextElement();
                if (op instanceof RegisterOperand) {
                    killed.add(op.asRegister().getRegister());
                }
            }
        }
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) 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) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) HashSet(java.util.HashSet)

Example 69 with Instruction

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

the class EnterSSA method registerCalls.

/**
 * Register every CALL instruction in this method with the
 * implicit heap array SSA look aside structure.
 * Namely, mark that this instruction defs and uses <em> every </em>
 * type of heap variable in the IR's SSA dictionary.
 *
 * @param ir the governing IR
 */
private void registerCalls(IR ir) {
    SSADictionary dictionary = ir.HIRInfo.dictionary;
    for (Enumeration<BasicBlock> bbe = ir.getBasicBlocks(); bbe.hasMoreElements(); ) {
        BasicBlock b = bbe.nextElement();
        for (Enumeration<Instruction> e = b.forwardInstrEnumerator(); e.hasMoreElements(); ) {
            Instruction s = e.nextElement();
            boolean isSynch = (s.operator() == READ_CEILING) || (s.operator() == WRITE_FLOOR) || (s.operator() == FENCE);
            if (isSynch || Call.conforms(s) || MonitorOp.conforms(s) || Prepare.conforms(s) || Attempt.conforms(s) || CacheOp.conforms(s) || s.isDynamicLinkingPoint()) {
                dictionary.registerUnknown(s, b);
            }
        }
    }
}
Also used : BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 70 with Instruction

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

the class SSADictionary method makePhiInstruction.

/**
 * Create a phi-function instruction for a heap variable
 *
 * @param H a symbolic variable for a Heap variable
 * @param bb the basic block holding the new phi function
 * instruction
 * @return the instruction <code> H = phi H,H,..,H </code>
 */
private static Instruction makePhiInstruction(HeapVariable<Object> H, BasicBlock bb) {
    int n = bb.getNumberOfIn();
    Enumeration<BasicBlock> in = bb.getIn();
    HeapOperand<Object> lhs = new HeapOperand<Object>(H);
    Instruction s = Phi.create(PHI, lhs, n);
    lhs.setInstruction(s);
    for (int i = 0; i < n; i++) {
        HeapOperand<Object> op = new HeapOperand<Object>(H);
        op.setInstruction(s);
        Phi.setValue(s, i, op);
        BasicBlock pred = in.nextElement();
        Phi.setPred(s, i, new BasicBlockOperand(pred));
    }
    return s;
}
Also used : HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Aggregations

Instruction (org.jikesrvm.compilers.opt.ir.Instruction)356 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)204 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)144 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)117 Register (org.jikesrvm.compilers.opt.ir.Register)106 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)72 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)61 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)61 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)54 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)53 Test (org.junit.Test)49 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)46 TypeReference (org.jikesrvm.classloader.TypeReference)38 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)38 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)35 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)33 HeapOperand (org.jikesrvm.compilers.opt.ir.operand.HeapOperand)33 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)31 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)28 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)27