Search in sources :

Example 6 with BitVector

use of org.jikesrvm.util.BitVector in project JikesRVM by JikesRVM.

the class IR method verifyUseFollowsDef.

/**
 * Check whether uses follow definitions and in SSA form that
 * variables aren't multiply defined
 *
 * @param where location of verify in compilation
 * @param definedVariables variables already defined on this path
 * @param curBB the current BB to work on
 * @param visitedBBs the blocks already visited (to avoid cycles)
 * @param path a record of the path taken to reach this basic block
 * @param maxPathLength the maximum number of basic blocks that will be followed
 * @param traceExceptionEdges    should paths from exceptions be validated?
 */
private void verifyUseFollowsDef(String where, HashSet<Object> definedVariables, BasicBlock curBB, BitVector visitedBBs, ArrayList<BasicBlock> path, int maxPathLength, boolean traceExceptionEdges) {
    if (path.size() > maxPathLength) {
        return;
    }
    path.add(curBB);
    // Process instructions in block
    IREnumeration.AllInstructionsEnum instructions = new IREnumeration.AllInstructionsEnum(this, curBB);
    while (instructions.hasMoreElements()) {
        Instruction instruction = instructions.nextElement();
        // Special phi handling case
        if (Phi.conforms(instruction)) {
            if ((!inSSAForm()) && (!inSSAFormAwaitingReEntry())) {
                verror(where, "Phi node encountered but SSA not computed");
            }
            // Find predecessors that we have already visited
            for (int i = 0; i < Phi.getNumberOfPreds(instruction); i++) {
                BasicBlock phi_pred = Phi.getPred(instruction, i).block;
                if (phi_pred.getNumber() > basicBlockMap.length) {
                    verror(where, "Phi predecessor not a valid basic block " + phi_pred);
                }
                if ((curBB != phi_pred) && path.contains(phi_pred)) {
                    // This predecessor has been visited on this path so the
                    // variable should be defined
                    Object variable = getVariableUse(where, Phi.getValue(instruction, i));
                    if ((variable != null) && (!definedVariables.contains(variable))) {
                        StringBuilder pathString = new StringBuilder();
                        for (int j = 0; j < path.size(); j++) {
                            pathString.append(path.get(j).getNumber());
                            if (j < (path.size() - 1)) {
                                pathString.append("->");
                            }
                        }
                        verror(where, "Use of " + variable + " before definition: " + instruction + "\npath: " + pathString);
                    }
                }
            }
        } else {
            // General use follows def test
            IREnumeration.AllUsesEnum useOperands = new IREnumeration.AllUsesEnum(this, instruction);
            while (useOperands.hasMoreElements()) {
                Object variable = getVariableUse(where, useOperands.nextElement());
                if ((variable != null) && (!definedVariables.contains(variable))) {
                    if (instruction.operator().toString().indexOf("xor") != -1)
                        continue;
                    StringBuilder pathString = new StringBuilder();
                    for (int i = 0; i < path.size(); i++) {
                        pathString.append(path.get(i).getNumber());
                        if (i < (path.size() - 1)) {
                            pathString.append("->");
                        }
                    }
                    verror(where, "Use of " + variable + " before definition: " + instruction + "\npath: " + pathString);
                }
            }
        }
        // Add definitions to defined variables
        IREnumeration.AllDefsEnum defOperands = new IREnumeration.AllDefsEnum(this, instruction);
        while (defOperands.hasMoreElements()) {
            Object variable = getVariableDef(where, defOperands.nextElement());
            // Check that a variable isn't defined twice when we believe we're in SSA form
            if (variable != null) {
                if ((inSSAForm()) && (!inSSAFormAwaitingReEntry())) {
                    if (definedVariables.contains(variable)) {
                        verror(where, "Single assignment broken - multiple definitions of " + variable);
                    }
                }
                definedVariables.add(variable);
            }
        }
    }
    // Recurse to next BBs
    visitedBBs.set(curBB.getNumber());
    Enumeration<BasicBlock> outBlocks;
    if (traceExceptionEdges) {
        // <-- very slow
        outBlocks = curBB.getOut();
    } else {
        outBlocks = curBB.getNormalOut();
    }
    while (outBlocks.hasMoreElements()) {
        BasicBlock out = outBlocks.nextElement();
        if (!visitedBBs.get(out.getNumber())) {
            verifyUseFollowsDef(where, new HashSet<Object>(definedVariables), out, new BitVector(visitedBBs), new ArrayList<BasicBlock>(path), maxPathLength, traceExceptionEdges);
            visitedBBs.set(out.getNumber());
        }
    }
}
Also used : BitVector(org.jikesrvm.util.BitVector)

Example 7 with BitVector

use of org.jikesrvm.util.BitVector in project JikesRVM by JikesRVM.

the class EnterSSA method insertHeapPhiFunctions.

/**
 * Insert phi functions for heap array SSA heap variables.
 *
 * @param ir the governing IR
 */
private void insertHeapPhiFunctions(IR ir) {
    Iterator<HeapVariable<Object>> e = ir.HIRInfo.dictionary.getHeapVariables();
    while (e.hasNext()) {
        HeapVariable<Object> H = e.next();
        if (DEBUG)
            System.out.println("Inserting phis for Heap " + H);
        if (DEBUG)
            System.out.println("Start iterated frontier...");
        BitVector defH = H.getDefBlocks();
        if (DEBUG)
            System.out.println(H + " DEFINED IN " + defH);
        BitVector needsPhi = DominanceFrontier.getIteratedDominanceFrontier(ir, defH);
        if (DEBUG)
            System.out.println(H + " NEEDS PHI " + needsPhi);
        if (DEBUG)
            System.out.println("Done.");
        for (int b = 0; b < needsPhi.length(); b++) {
            if (needsPhi.get(b)) {
                BasicBlock bb = ir.getBasicBlock(b);
                ir.HIRInfo.dictionary.createHeapPhiInstruction(bb, H);
            }
        }
    }
}
Also used : BitVector(org.jikesrvm.util.BitVector) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock)

Example 8 with BitVector

use of org.jikesrvm.util.BitVector in project JikesRVM by JikesRVM.

the class CFGTransformations method loopPredecessors.

private static BasicBlock[] loopPredecessors(LSTNode n) {
    BasicBlock header = n.header;
    BitVector loop = n.getLoop();
    int i = 0;
    Enumeration<BasicBlock> be = header.getIn();
    while (be.hasMoreElements()) if (!inLoop(be.nextElement(), loop))
        i++;
    BasicBlock[] res = new BasicBlock[i];
    i = 0;
    be = header.getIn();
    while (be.hasMoreElements()) {
        BasicBlock in = be.nextElement();
        if (!inLoop(in, loop))
            res[i++] = in;
    }
    return res;
}
Also used : BitVector(org.jikesrvm.util.BitVector) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock)

Example 9 with BitVector

use of org.jikesrvm.util.BitVector in project JikesRVM by JikesRVM.

the class DominanceFrontier method getIteratedDominanceFrontier.

/**
 * Calculate the iterated dominance frontier for a set of basic blocks
 * represented by a BitVector.
 *
 * <p> NOTE: The dominance frontiers for the IR MUST be calculated
 *    BEFORE calling this routine.
 *
 * @param ir The governing IR
 * @param S  The {@link BitVector} representing the set of basic blocks
 * @return an {@link BitVector} representing the dominance frontier for
 *    the set
 */
public static BitVector getIteratedDominanceFrontier(IR ir, BitVector S) {
    BitVector DFi = getDominanceFrontier(ir, S);
    while (true) {
        BitVector DFiplus1 = getDominanceFrontier(ir, DFi);
        DFiplus1.or(DFi);
        if (DFi.equals(DFiplus1)) {
            break;
        }
        DFi = DFiplus1;
    }
    return DFi;
}
Also used : BitVector(org.jikesrvm.util.BitVector)

Example 10 with BitVector

use of org.jikesrvm.util.BitVector in project JikesRVM by JikesRVM.

the class DominanceFrontier method getDominanceFrontier.

/**
 * Calculate the dominance frontier for the set of basic blocks
 * represented by a BitVector.
 *
 * <p> NOTE: The dominance frontiers for the IR MUST be calculated
 *    BEFORE calling this routine.
 *
 * @param ir the governing IR
 * @param bits the BitVector representing the set of basic blocks
 * @return a BitVector representing the dominance frontier for the set
 */
public static BitVector getDominanceFrontier(IR ir, BitVector bits) {
    BitVector result = new BitVector(ir.getMaxBasicBlockNumber() + 1);
    DominatorTree dTree = ir.HIRInfo.dominatorTree;
    for (int i = 0; i < bits.length(); i++) {
        if (bits.get(i)) {
            result.or(dTree.getDominanceFrontier(i));
        }
    }
    return result;
}
Also used : BitVector(org.jikesrvm.util.BitVector)

Aggregations

BitVector (org.jikesrvm.util.BitVector)20 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)12 ExceptionHandlerBasicBlock (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)3 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)2 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)2 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)2 HashSet (java.util.HashSet)1 IR (org.jikesrvm.compilers.opt.ir.IR)1 Register (org.jikesrvm.compilers.opt.ir.Register)1 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)1 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)1 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)1 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)1 HeapOperand (org.jikesrvm.compilers.opt.ir.operand.HeapOperand)1 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)1 UnreachableOperand (org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand)1 TreeNode (org.jikesrvm.compilers.opt.util.TreeNode)1