}
if (DEBUG) {
System.out.println("----------------------------------------------------------------------");
System.out.println(this.getClass().getName() + " iteration: " + numIterations + ", timestamp: " + timestamp);
MethodGen mg = cfg.getMethodGen();
System.out.println(mg.getClassName() + "." + mg.getName() + mg.getSignature());
System.out.println("----------------------------------------------------------------------");
}
if (numIterations >= MAX_ITERS + 9) {
throw new DataflowAnalysisException("Too many iterations (" + numIterations + ") in dataflow when analyzing "
+ getFullyQualifiedMethodName());
}
analysis.startIteration();
if (DEBUG && firstTime && blockOrder instanceof ReverseDFSOrder) {
ReverseDFSOrder rBlockOrder = (ReverseDFSOrder) blockOrder;
System.out.println("Entry point is: " + logicalEntryBlock());
System.out.println("Basic block order: ");
Iterator<BasicBlock> i = blockOrder.blockIterator();
while (i.hasNext()) {
BasicBlock block = i.next();
debug(block, "rBlockOrder " + rBlockOrder.rdfs.getDiscoveryTime(block) + "\n");
}
}
Iterator<BasicBlock> i = blockOrder.blockIterator();
if (numIterations > 3 && numIterations % 2 == 0 && blockOrder instanceof ReverseDFSOrder) {
if (DEBUG) {
System.out.println("Trying program order");
}
TreeSet<BasicBlock> bb = new TreeSet<BasicBlock>(new BackwardProgramOrder());
Iterator<BasicBlock> j = blockOrder.blockIterator();
while (j.hasNext()) {
BasicBlock block = j.next();
bb.add(block);
}
if (DEBUG) {
for (BasicBlock block : bb) {
debug(block, "\n");
}
}
i = bb.iterator();
}
if (DEBUG) {
dumpDataflow(analysis);
}
// For each block in CFG...
while (i.hasNext()) {
BasicBlock block = i.next();
// Get start fact for block.
Fact start = analysis.getStartFact(block);
assert start != null;
boolean needToRecompute = false;
// Get result facts for block,
Fact result = analysis.getResultFact(block);
assert result != null;
int originalResultTimestamp = analysis.getLastUpdateTimestamp(result);
// Meet all of the logical predecessor results into this block's
// start.
// Special case: if the block is the logical entry, then it gets
// the special "entry fact".
if (block == logicalEntryBlock()) {
analysis.makeFactTop(start);
analysis.initEntryFact(start);
if (DEBUG) {
debug(block, "Init entry fact ==> " + analysis.factToString(start) + "\n");
}
needToRecompute = true;
} else {
int lastCalculated = analysis.getLastUpdateTimestamp(start);
Iterator<Edge> predEdgeIter = logicalPredecessorEdgeIterator(block);
int predCount = 0;
int rawPredCount = 0;
while (predEdgeIter.hasNext()) {
Edge edge = predEdgeIter.next();
rawPredCount++;
if (needToRecompute) {
// don't need to check to see if we need to recompute.
if (firstTime && !sawBackEdge) {
// may need to se sawBackEdge
} else {
continue;
}
}
BasicBlock logicalPred = isForwards ? edge.getSource() : edge.getTarget();
int direction = blockOrder.compare(block, logicalPred);
if (DEBUG) {
debug(block, "direction " + direction + " for " + blockId(logicalPred) + "\n");
}
if (direction < 0) {
sawBackEdge = true;
}
// Get the predecessor result fact
Fact predFact = analysis.getResultFact(logicalPred);
int predLastUpdated = analysis.getLastUpdateTimestamp(predFact);
if (!analysis.isTop(predFact)) {
predCount++;
if (predLastUpdated >= lastCalculated) {
needToRecompute = true;
if (DEBUG) {
debug(block, "\n Need to recompute. My timestamp = " + lastCalculated + ", pred timestamp = "
+ predLastUpdated + ",\n pred fact = " + predFact + "\n");
}
// break;
}
}
}
if (predCount == 0) {
needToRecompute = true;
}
if (!needToRecompute) {
continue;
}
if (needToRecompute) {
analysis.makeFactTop(start);
predEdgeIter = logicalPredecessorEdgeIterator(block);
while (predEdgeIter.hasNext()) {
Edge edge = predEdgeIter.next();
BasicBlock logicalPred = isForwards ? edge.getSource() : edge.getTarget();
// Get the predecessor result fact
Fact predFact = analysis.getResultFact(logicalPred);
// Apply the edge transfer function.
Fact edgeFact = analysis.createFact();
analysis.copy(predFact, edgeFact);
analysis.edgeTransfer(edge, edgeFact);
if (DEBUG && !analysis.same(edgeFact, predFact)) {
debug(block, logicalPred, edge, "Edge transfer " + analysis.factToString(predFact) + " ==> "
+ analysis.factToString(edgeFact));
}
// Merge the predecessor fact (possibly transformed
// by the edge transfer function)
// into the block's start fact.
if (DEBUG) {
if (analysis.isTop(start)) {
debug(block, logicalPred, edge, "\n First pred is " + analysis.factToString(edgeFact)
+ "\n last updated at " + analysis.getLastUpdateTimestamp(predFact) + "\n");
} else {
debug(block, logicalPred, edge, "\n Meet " + analysis.factToString(start) + "\n with "
+ analysis.factToString(edgeFact)
+ "\n pred last updated at " + analysis.getLastUpdateTimestamp(predFact) + "\n");
}
}
if (analysis instanceof UnconditionalValueDerefAnalysis) {
((UnconditionalValueDerefAnalysis) analysis).meetInto((UnconditionalValueDerefSet) edgeFact,
edge, (UnconditionalValueDerefSet) start, rawPredCount == 1);
} else {
analysis.meetInto(edgeFact, edge, start);
}
analysis.setLastUpdateTimestamp(start, timestamp);
int pos = -1;
if (block.getFirstInstruction() != null) {
pos = block.getFirstInstruction().getPosition();
}
if (DEBUG) {
System.out.println(" [" + pos + "]==> " + analysis.factToString(start) + " @ " + timestamp
+ " \n");
}
}
}
}
if (DEBUG) {
debug(block, "start fact is " + analysis.factToString(start) + "\n");
}
// making a copy of result facts (so we can detect if it
// changed).
boolean resultWasTop = analysis.isTop(result);
Fact origResult = null;
if (!resultWasTop) {
origResult = analysis.createFact();
analysis.copy(result, origResult);
}
// if (true || analysis.isTop(start)) {
// Apply the transfer function.
analysis.transfer(block, null, start, result);
// } else {
// analysis.copy(start, result);
// }
if (DEBUG && SystemProperties.getBoolean("dataflow.blockdebug")) {
debug(block, "Dumping flow values for block:\n");
Iterator<org.apache.bcel.generic.InstructionHandle> ii = block.instructionIterator();
while (ii.hasNext()) {
org.apache.bcel.generic.InstructionHandle handle = ii.next();
Fact tmpResult = analysis.createFact();
analysis.transfer(block, handle, start, tmpResult);
System.out.println("\t" + handle + " " + analysis.factToString(tmpResult));
}
}
// See if the result changed.
if (DEBUG) {
debug(block, "orig result is " + (origResult == null ? "TOP" : analysis.factToString(origResult)) + "\n");
}
boolean thisResultChanged = false;
if (resultWasTop) {
thisResultChanged = !analysis.isTop(result);
} else {
thisResultChanged = !analysis.same(result, origResult);
}
if (thisResultChanged) {
timestamp++;
if (DEBUG) {
debug(block, "result changed at timestamp " + timestamp + "\n");
}
if (DEBUG && !needToRecompute) {
System.out.println("I thought I didn't need to recompute");
}
change = true;
analysis.setLastUpdateTimestamp(result, timestamp);
} else {
analysis.setLastUpdateTimestamp(result, originalResultTimestamp);
}
if (DEBUG) {
debug(block,
"result is " + analysis.factToString(result) + " @ timestamp "
+ analysis.getLastUpdateTimestamp(result) + "\n");
}
}
analysis.finishIteration();
if (!sawBackEdge) {
break;
}
} while (change);
if (DEBUG) {
System.out.println("-- Quiescence achieved-------------------------------------------------");
System.out.println(this.getClass().getName() + " iteration: " + numIterations + ", timestamp: " + timestamp);
MethodGen mg = cfg.getMethodGen();
System.out.println(mg.getClassName() + "." + mg.getName() + mg.getSignature());
new RuntimeException("Quiescence achieved----------------------------------------------------------------")
.printStackTrace(System.out);
}
DEBUG = debugWas;