* If the given {@link Node} cannot be reached (in the control flow graph),
* then {@code null} is returned.
*/
protected S runAnalysisFor(Node node, boolean before) {
Block block = node.getBlock();
TransferInput transferInput = stores.get(block);
if (transferInput == null) {
return null;
}
return runAnalysisFor(node, before, transferInput);
}
/**
* Runs the analysis again within the block of {@code node} and returns the
* store at the location of {@code node}. If {@code before} is true, then
* the store immediately before the {@link Node} {@code node} is returned.
* Otherwise, the store after {@code node} is returned.
*/
public static , S extends Store> S runAnalysisFor(
Node node, boolean before, TransferInput transferInput) {
assert node != null;
Block block = node.getBlock();
assert transferInput != null;
Analysis analysis = transferInput.analysis;
Node oldCurrentNode = analysis.currentNode;
if (analysis.isRunning) {
return analysis.currentInput.getRegularStore();
}
analysis.isRunning = true;
try {
switch (block.getType()) {
case REGULAR_BLOCK: {
RegularBlock rb = (RegularBlock) block;
// Apply transfer function to contents until we found the node
// we
// are looking for.
TransferInput store = transferInput;
TransferResult transferResult = null;
for (Node n : rb.getContents()) {
analysis.currentNode = n;
if (n == node && before) {
return store.getRegularStore();
}
transferResult = analysis.callTransferFunction(n, store);
if (n == node) {
return transferResult.getRegularStore();
}
store = new TransferInput<>(n, analysis, transferResult);
}
// This point should never be reached. If the block of 'node' is
// 'block', then 'node' must be part of the contents of 'block'.
assert false;
return null;
}
case EXCEPTION_BLOCK: {
ExceptionBlock eb = (ExceptionBlock) block;
// apply transfer function to content
assert eb.getNode() == node;
if (before) {
return transferInput.getRegularStore();
}
analysis.currentNode = node;
TransferResult transferResult = analysis
.callTransferFunction(node, transferInput);
return transferResult.getRegularStore();
}
default:
// Only regular blocks and exceptional blocks can hold nodes.
assert false;
break;
}
return null;
} finally {
analysis.currentNode = oldCurrentNode;
analysis.isRunning = false;
}
}
}