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());
}
}
}
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);
}
}
}
}
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;
}
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;
}
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;
}
Aggregations