Search in sources :

Example 6 with BasicBlockOperand

use of org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand 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 7 with BasicBlockOperand

use of org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand 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)

Example 8 with BasicBlockOperand

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

the class SSA method purgeBlockFromPHIs.

/**
 * Fix up any PHI instructions in the given target block to reflect that
 * the given source block is no longer a predecessor of target.
 * The basic algorithm is to erase the PHI operands related to the edge
 * from source to target by sliding the other PHI operands down as required.
 *
 * @param source the source block to remove from PHIs in target
 * @param target the target block that may contain PHIs to update.
 */
static void purgeBlockFromPHIs(BasicBlock source, BasicBlock target) {
    for (Enumeration<Instruction> e = target.forwardRealInstrEnumerator(); e.hasMoreElements(); ) {
        Instruction s = e.nextElement();
        // all done (assume PHIs are first!)
        if (s.operator() != PHI)
            return;
        int numPairs = Phi.getNumberOfPreds(s);
        int dst = 0;
        for (int src = 0; src < numPairs; src++) {
            BasicBlockOperand bbop = Phi.getPred(s, src);
            if (bbop.block == source) {
                Phi.setValue(s, src, null);
                Phi.setPred(s, src, null);
            } else {
                if (src != dst) {
                    Phi.setValue(s, dst, Phi.getClearValue(s, src));
                    Phi.setPred(s, dst, Phi.getClearPred(s, src));
                }
                dst++;
            }
        }
        for (int i = dst; i < numPairs; i++) {
            Phi.setValue(s, i, null);
            Phi.setPred(s, i, null);
        }
    }
}
Also used : BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 9 with BasicBlockOperand

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

the class SSA method replaceBlockInPhis.

/**
 * Update PHI instructions in the target block so that any PHIs that
 * come from basic block B1, now come from basic block B2.
 *
 * @param target the target block that may contain PHIs to update.
 * @param B1 the block to replace in the phi instructions
 * @param B2 the replacement block for B1
 */
static void replaceBlockInPhis(BasicBlock target, BasicBlock B1, BasicBlock B2) {
    for (Enumeration<Instruction> e = target.forwardRealInstrEnumerator(); e.hasMoreElements(); ) {
        Instruction s = e.nextElement();
        // all done (assume PHIs are first!)
        if (s.operator() != PHI)
            return;
        int numPairs = Phi.getNumberOfPreds(s);
        for (int src = 0; src < numPairs; src++) {
            BasicBlockOperand bbop = Phi.getPred(s, src);
            if (bbop.block == B1) {
                Phi.setPred(s, src, new BasicBlockOperand(B2));
            }
        }
    }
}
Also used : BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 10 with BasicBlockOperand

use of org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand 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)

Aggregations

Instruction (org.jikesrvm.compilers.opt.ir.Instruction)12 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)12 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)9 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)8 HeapOperand (org.jikesrvm.compilers.opt.ir.operand.HeapOperand)7 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)7 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)5 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)5 IREnumeration (org.jikesrvm.compilers.opt.ir.IREnumeration)4 Register (org.jikesrvm.compilers.opt.ir.Register)4 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)4 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)4 HashMap (java.util.HashMap)3 Enumeration (java.util.Enumeration)2 TypeReference (org.jikesrvm.classloader.TypeReference)2 DominatorTreeNode (org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode)2 TreeNode (org.jikesrvm.compilers.opt.util.TreeNode)2 ExceptionHandlerBasicBlock (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)1 OsrPoint (org.jikesrvm.compilers.opt.ir.OsrPoint)1 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)1