Search in sources :

Example 1 with TreeNode

use of org.jikesrvm.compilers.opt.util.TreeNode 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 2 with TreeNode

use of org.jikesrvm.compilers.opt.util.TreeNode in project JikesRVM by JikesRVM.

the class LeaveSSA method performRename.

// substitute variables renamed in control parents
private void performRename(BasicBlock bb, DominatorTree dom, VariableStacks s) {
    if (DEBUG)
        VM.sysWriteln("performRename: " + bb);
    Enumeration<Instruction> e = bb.forwardRealInstrEnumerator();
    while (e.hasMoreElements()) {
        Instruction i = e.nextElement();
        Enumeration<Operand> ee = i.getUses();
        while (ee.hasMoreElements()) {
            Operand o = ee.nextElement();
            if (o instanceof RegisterOperand) {
                Register r1 = ((RegisterOperand) o).getRegister();
                if (r1.isValidation())
                    continue;
                Operand r2 = s.peek(r1);
                if (r2 != null) {
                    if (DEBUG) {
                        VM.sysWriteln("replace operand in " + i + "(" + r2 + " for " + o);
                    }
                    i.replaceOperand(o, r2.copy());
                }
            }
        }
    }
    // record renamings required in children
    e = bb.forwardRealInstrEnumerator();
    while (e.hasMoreElements()) {
        Instruction i = e.nextElement();
        if (globalRenameTable.contains(i)) {
            Register original = Move.getVal(i).asRegister().getRegister();
            RegisterOperand rename = Move.getResult(i);
            if (DEBUG)
                VM.sysWriteln("record rename " + rename + " for " + original);
            s.push(original, rename);
        }
    }
    // insert copies in control children
    Enumeration<TreeNode> children = dom.getChildren(bb);
    while (children.hasMoreElements()) {
        BasicBlock c = ((DominatorTreeNode) children.nextElement()).getBlock();
        performRename(c, dom, s);
    }
    // pop renamings from this block off stack
    e = bb.forwardRealInstrEnumerator();
    while (e.hasMoreElements()) {
        Instruction i = e.nextElement();
        if (globalRenameTable.contains(i)) {
            Register original = Move.getVal(i).asRegister().getRegister();
            s.pop(original);
        }
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) DominatorTreeNode(org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode) 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) TreeNode(org.jikesrvm.compilers.opt.util.TreeNode) DominatorTreeNode(org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 3 with TreeNode

use of org.jikesrvm.compilers.opt.util.TreeNode in project JikesRVM by JikesRVM.

the class LeaveSSA method insertCopies.

/**
 * Insert copy instructions into a basic block to safely translate out
 * of SSA form.
 *
 * @param bb the basic block
 * @param dom a valid dominator tree for the IR
 * @param live valid liveness information for the IR
 */
private void insertCopies(BasicBlock bb, DominatorTree dom, LiveAnalysis live) {
    // add copies required in this block to remove phis.
    // (record renaming required by simultaneous liveness in global tables)
    scheduleCopies(bb, live);
    // insert copies in control children
    Enumeration<TreeNode> children = dom.getChildren(bb);
    while (children.hasMoreElements()) {
        BasicBlock c = ((DominatorTreeNode) children.nextElement()).getBlock();
        insertCopies(c, dom, live);
    }
}
Also used : DominatorTreeNode(org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode) TreeNode(org.jikesrvm.compilers.opt.util.TreeNode) DominatorTreeNode(org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock)

Example 4 with TreeNode

use of org.jikesrvm.compilers.opt.util.TreeNode in project JikesRVM by JikesRVM.

the class OptEncodedCallSiteTree method getEncoding.

@Interruptible
public static int[] getEncoding(CallSiteTree tree) {
    int size = 0;
    if (tree.isEmpty()) {
        return null;
    } else {
        Enumeration<TreeNode> e = tree.elements();
        while (e.hasMoreElements()) {
            TreeNode x = e.nextElement();
            if (x.getLeftChild() == null) {
                size += 2;
            } else {
                size += 3;
            }
        }
        int[] encoding = new int[size];
        getEncoding((CallSiteTreeNode) tree.getRoot(), 0, -1, encoding);
        return encoding;
    }
}
Also used : TreeNode(org.jikesrvm.compilers.opt.util.TreeNode) CallSiteTreeNode(org.jikesrvm.compilers.opt.inlining.CallSiteTreeNode) Interruptible(org.vmmagic.pragma.Interruptible)

Example 5 with TreeNode

use of org.jikesrvm.compilers.opt.util.TreeNode 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

TreeNode (org.jikesrvm.compilers.opt.util.TreeNode)7 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)6 DominatorTreeNode (org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode)5 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)4 Register (org.jikesrvm.compilers.opt.ir.Register)3 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)3 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)2 HeapOperand (org.jikesrvm.compilers.opt.ir.operand.HeapOperand)2 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)2 UnreachableOperand (org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand)2 HashMap (java.util.HashMap)1 CallSiteTreeNode (org.jikesrvm.compilers.opt.inlining.CallSiteTreeNode)1 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)1 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)1 BitVector (org.jikesrvm.util.BitVector)1 Interruptible (org.vmmagic.pragma.Interruptible)1