Search in sources :

Example 6 with TreeNode

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

the class GlobalCSE method globalCSE.

/**
 * Recursively descend over all blocks dominated by b. For each
 * instruction in the block, if it defines a GVN then record it in
 * the available expressions. If the GVN already exists in the
 * available expressions then eliminate the instruction and change
 * all uses of the result of the instruction to be uses of the first
 * instruction to define the result of this expression.
 * @param b the current block to process
 */
private void globalCSE(BasicBlock b) {
    Instruction next, inst;
    // Iterate over instructions in b
    inst = b.firstInstruction();
    while (!BBend.conforms(inst)) {
        next = inst.nextInstructionInCodeOrder();
        // check instruction is safe for GCSE, {@see shouldCSE}
        if (!shouldCSE(inst)) {
            inst = next;
            continue;
        }
        // check the instruction defines a result
        RegisterOperand result = getResult(inst);
        if (result == null) {
            inst = next;
            continue;
        }
        // get the value number for this result. The value number for
        // the same sub-expression is shared by all results showing they
        // can be eliminated. If the value number is UNKNOWN the result
        // is negative.
        int vn = valueNumbers.getValueNumber(result);
        if (vn < 0) {
            inst = next;
            continue;
        }
        // was this the first definition of the value number?
        Integer Vn = vn;
        Instruction former = avail.get(Vn);
        if (former == null) {
            // first occurance of value number, record it in the available
            // expressions
            avail.put(Vn, inst);
        } else {
            // this value number has been seen before so we can use the
            // earlier version
            // NB instead of trying to repair Heap SSA, we rebuild it
            // after CSE
            // relink scalar dependencies - make all uses of the current
            // instructions result use the first definition of the result
            // by the earlier expression
            RegisterOperand formerDef = getResult(former);
            Register reg = result.getRegister();
            formerDef.getRegister().setSpansBasicBlock();
            Enumeration<RegisterOperand> uses = DefUse.uses(reg);
            while (uses.hasMoreElements()) {
                RegisterOperand use = uses.nextElement();
                DefUse.transferUse(use, formerDef);
            }
            if (verbose) {
                VM.sysWriteln("using      " + former + "\n" + "instead of " + inst);
            }
            // remove the redundant instruction
            inst.remove();
        }
        inst = next;
    }
    // end of instruction iteration
    // Recurse over all blocks that this block dominates
    Enumeration<TreeNode> e = dominator.getChildren(b);
    while (e.hasMoreElements()) {
        DominatorTreeNode n = (DominatorTreeNode) e.nextElement();
        BasicBlock bl = n.getBlock();
        // don't process infrequently executed basic blocks
        if (ir.options.FREQ_FOCUS_EFFORT && bl.getInfrequent())
            continue;
        globalCSE(bl);
    }
    // Iterate over instructions in this basic block removing
    // available expressions that had been created for this block
    inst = b.firstInstruction();
    while (!BBend.conforms(inst)) {
        next = inst.nextInstructionInCodeOrder();
        if (!shouldCSE(inst)) {
            inst = next;
            continue;
        }
        RegisterOperand result = getResult(inst);
        if (result == null) {
            inst = next;
            continue;
        }
        int vn = valueNumbers.getValueNumber(result);
        if (vn < 0) {
            inst = next;
            continue;
        }
        Integer Vn = vn;
        Instruction former = avail.get(Vn);
        if (former == inst) {
            avail.remove(Vn);
        }
        inst = next;
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) DominatorTreeNode(org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode) DominatorTreeNode(org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode) TreeNode(org.jikesrvm.compilers.opt.util.TreeNode) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 7 with TreeNode

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

the class DominanceFrontier method perform.

/**
 * Calculate the dominance frontier for each basic block in the
 * CFG. Stores the result in the DominatorTree for the governing
 * IR.
 *
 * <p> NOTE: The dominator tree MUST be calculated BEFORE calling this
 *      routine.
 *
 * @param ir the governing IR
 */
@Override
public void perform(IR ir) {
    final boolean DEBUG = false;
    // make sure the dominator computation completed successfully
    if (!ir.HIRInfo.dominatorsAreComputed) {
        return;
    }
    // make sure dominator tree is computed
    if (ir.HIRInfo.dominatorTree == null) {
        return;
    }
    // for each X in a bottom-up traversal of the dominator tree do
    DominatorTree tree = ir.HIRInfo.dominatorTree;
    for (Enumeration<TreeNode> x = tree.getBottomUpEnumerator(); x.hasMoreElements(); ) {
        DominatorTreeNode v = (DominatorTreeNode) x.nextElement();
        BasicBlock X = v.getBlock();
        if (DEBUG) {
            System.out.println("Computing frontier for node " + X);
        }
        BitVector DF = new BitVector(ir.getMaxBasicBlockNumber() + 1);
        v.setDominanceFrontier(DF);
        // for each Y in Succ(X) do
        for (Enumeration<BasicBlock> y = X.getOut(); y.hasMoreElements(); ) {
            BasicBlock Y = y.nextElement();
            // skip EXIT node
            if (Y.isExit()) {
                continue;
            }
            // if (idom(Y)!=X) then DF(X) <- DF(X) U Y
            if (LTDominatorInfo.getIdom(Y, ir) != X) {
                DF.set(Y.getNumber());
            }
        }
        if (DEBUG) {
            System.out.println("After local " + DF);
        }
        // for each Z in {idom(z) = X} do
        for (Enumeration<TreeNode> z = tree.getChildren(X); z.hasMoreElements(); ) {
            DominatorTreeNode zVertex = (DominatorTreeNode) z.nextElement();
            BasicBlock Z = zVertex.getBlock();
            if (DEBUG) {
                System.out.println("Processing Z = " + Z);
            }
            // for each Y in DF(Z) do
            for (Enumeration<BasicBlock> y = zVertex.domFrontierEnumerator(ir); y.hasMoreElements(); ) {
                BasicBlock Y = y.nextElement();
                // if (idom(Y)!=X) then DF(X) <- DF(X) U Y
                if (LTDominatorInfo.getIdom(Y, ir) != X) {
                    DF.set(Y.getNumber());
                }
            }
        }
        if (DEBUG) {
            System.out.println("After up " + DF);
        }
    }
    if (DEBUG) {
        for (Enumeration<BasicBlock> bbEnum = ir.cfg.basicBlocks(); bbEnum.hasMoreElements(); ) {
            BasicBlock block = bbEnum.nextElement();
            if (block.isExit()) {
                continue;
            }
            System.out.println(block + " DF: " + tree.getDominanceFrontier(block));
        }
    }
}
Also used : BitVector(org.jikesrvm.util.BitVector) TreeNode(org.jikesrvm.compilers.opt.util.TreeNode) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock)

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