use of com.jopdesign.common.code.ControlFlowGraph.CFGNode in project jop by jop-devel.
the class JavaOneProcessPerMethodTranslator method recordLoops.
private void recordLoops(MethodInfo mi, TemplateBuilder pb) {
ControlFlowGraph cfg = project.getFlowGraph(mi);
for (CFGNode hol : cfg.getLoopColoring().getHeadOfLoops()) {
LoopBound bound = hol.getLoopBound();
int nesting = cfg.getLoopColoring().getLoopColor(hol).size();
pb.addLoop(hol, nesting, bound);
}
}
use of com.jopdesign.common.code.ControlFlowGraph.CFGNode in project jop by jop-devel.
the class WCAInvoker method updateWCEP.
private void updateWCEP() {
if (!provideWCAExecCount)
return;
execCounts.clear();
for (MethodInfo root : getWcaTargets()) {
execCounts.put(root, 1L);
}
NodeVisitor<ExecutionContext> visitor = new NodeVisitor<ExecutionContext>() {
@Override
public boolean visitNode(ExecutionContext context) {
MethodInfo method = context.getMethodInfo();
MethodCode code = method.getCode();
long ec = getExecCount(method);
// skip methods which are not on the WCET path.. we can ship iterating over the childs too..
if (ec == 0)
return false;
// iterate over all blocks in the CFG, find all invokes and add block execution counts to invokees
ControlFlowGraph cfg = method.getCode().getControlFlowGraph(false);
for (CFGNode node : cfg.getGraph().vertexSet()) {
if (node instanceof InvokeNode) {
InvokeNode inv = (InvokeNode) node;
long ef = getExecFrequency(method, node);
for (MethodInfo invokee : inv.getImplementingMethods()) {
addExecCount(invokee, ec * ef);
}
} else if (node instanceof BasicBlockNode) {
// check if we have a JVM invoke here (or an invoke not in a dedicated node..)
for (InstructionHandle ih : node.getBasicBlock().getInstructions()) {
if (!code.isInvokeSite(ih))
continue;
long ef = getExecFrequency(method, node);
for (MethodInfo invokee : method.getAppInfo().findImplementations(code.getInvokeSite(ih))) {
addExecCount(invokee, ec * ef);
}
}
}
}
return true;
}
};
TopologicalTraverser<ExecutionContext, ContextEdge> topOrder = new TopologicalTraverser<ExecutionContext, ContextEdge>(wcetTool.getCallGraph().getGraph(), visitor);
topOrder.traverse();
}
use of com.jopdesign.common.code.ControlFlowGraph.CFGNode in project jop by jop-devel.
the class ExecFrequencyAnalysis method getExecFrequency.
public long getExecFrequency(ExecutionContext context, InstructionHandle ih) {
MethodInfo method = context.getMethodInfo();
// By loading the CFG, loopbounds are attached to the blocks if the WCA tool is loaded
ControlFlowGraph cfg = method.getCode().getControlFlowGraph(false);
LoopColoring<CFGNode, CFGEdge> lc = cfg.getLoopColoring();
BasicBlockNode node = cfg.getHandleNode(ih, true);
if (node == null) {
// THIS IS UNSAFE! but what can you do ...
return 1;
}
long ef = 1;
for (CFGNode hol : lc.getLoopColor(node)) {
LoopBound lb = hol.getLoopBound();
if (lb != null) {
if (lb.isDefaultBound() && !analyses.isWCAMethod(method)) {
ef *= DEFAULT_ACET_LOOP_BOUND;
} else {
ef *= lb.getUpperBound(context);
}
} else {
ef *= DEFAULT_ACET_LOOP_BOUND;
}
}
return ef;
}
use of com.jopdesign.common.code.ControlFlowGraph.CFGNode in project jop by jop-devel.
the class Segment method synchronizedSegment.
/**
* Create an interprocedural segment for a synchronized block. Currently we do
* not split basic blocks here, so either you are happy with basic block granularity,
* or you split the basic block while loading.
* @param targetBlock The block containing the monitorenter instruction
* @param monitorEnter The monitor enter instruction
* @param callString The context for the method
* @param cfgProvider A control flow graph provider
* @param callStringLength Length of the callstrings
* @param infeasibles Information about infeasible edges (null if no information available)
*
* @return a segment representing executions of the synchronized block
*/
public static Segment synchronizedSegment(ContextCFG ccfg, CFGNode entryNode, InstructionHandle monitorEnter, CFGProvider cfgProvider, int callStringLength, InfeasibleEdgeProvider infeasibles) {
if (infeasibles == null) {
infeasibles = InfeasibleEdgeProvider.NO_INFEASIBLES;
}
ControlFlowGraph cfg = ccfg.getCfg();
SuperGraph superGraph = new SuperGraph(cfgProvider, cfg, ccfg.getCallString(), callStringLength, infeasibles);
ContextCFG rootMethod = superGraph.getRootNode();
/* lift entry edges */
Set<SuperGraphEdge> entryEdges = Iterators.addAll(new HashSet<SuperGraphEdge>(), superGraph.liftCFGEdges(rootMethod, cfg.incomingEdgesOf(entryNode)));
/* find exit blocks (might also be in the same block) */
/* monitorenter followed bei monitorexit in same block => segment only contains this block */
Set<CFGEdge> monitorExitEdges = new HashSet<CFGEdge>();
CFGNode currentNode = entryNode;
int currentNestingLevel = 1;
Iterator<InstructionHandle> insIter = currentNode.getBasicBlock().getInstructions().iterator();
while (insIter.hasNext()) {
if (insIter.next() == monitorEnter)
break;
}
Stack<Pair<CFGNode, Integer>> todo = new Stack<Pair<CFGNode, Integer>>();
Set<CFGNode> visited = new HashSet<CFGNode>();
do {
boolean isExit = false;
while (insIter.hasNext()) {
InstructionHandle ih = insIter.next();
if (ih.getInstruction() instanceof MONITOREXIT) {
/* blocks outgoing edges terminate segment */
currentNestingLevel--;
if (currentNestingLevel == 0) {
isExit = true;
// If monitorexit is not implemented in Java, the outgoing edges of the
// basic block that contains monitorexit end the synchronized block.
// In order to avoid imprecision, it is advisable that monitorexit is the
// last statement in the basic block.
// We also handle the case when monitorexit is implemented in Java. In this case,
// currentNode will be a SpecialInvokeNode, urrentNode's only
// successor will be the corresponding ReturnNode, and the outgoing edges of
// the ReturnNode are the exit edges for the synchronized segment.
CFGNode onlySuccessor = Iterators.fromSingleton(cfg.getSuccessors(currentNode));
if (onlySuccessor != null && onlySuccessor instanceof ControlFlowGraph.ReturnNode) {
Iterators.addAll(monitorExitEdges, cfg.outgoingEdgesOf(onlySuccessor));
} else {
Iterators.addAll(monitorExitEdges, cfg.outgoingEdgesOf(currentNode));
}
break;
}
} else if (ih.getInstruction() instanceof MONITORENTER) {
currentNestingLevel++;
}
}
if (!isExit) {
for (CFGNode node : cfg.getSuccessors(currentNode)) {
todo.add(new Pair<CFGNode, Integer>(node, currentNestingLevel));
}
}
currentNode = null;
while (!todo.isEmpty()) {
Pair<CFGNode, Integer> nextPair = todo.pop();
CFGNode nextNode = nextPair.first();
if (!visited.contains(nextNode)) {
visited.add(nextNode);
if (cfg.outgoingEdgesOf(nextNode).isEmpty()) {
throw new AssertionError("Found monitor-exit free path from monitorenter to the end of a function. In: " + cfg);
} else if (nextNode.getBasicBlock() == null) {
for (CFGNode node : cfg.getSuccessors(nextNode)) {
todo.add(new Pair<CFGNode, Integer>(node, nextPair.second()));
}
} else {
currentNode = nextNode;
currentNestingLevel = nextPair.second();
insIter = currentNode.getBasicBlock().getInstructions().iterator();
break;
}
}
}
} while (currentNode != null);
Set<SuperGraphEdge> exitEdges = Iterators.addAll(new HashSet<SuperGraphEdge>(), superGraph.liftCFGEdges(rootMethod, monitorExitEdges));
return new Segment(superGraph, entryEdges, exitEdges);
}
use of com.jopdesign.common.code.ControlFlowGraph.CFGNode in project jop by jop-devel.
the class SuperGraph method incomingEdgesOf.
/**
* The incoming edges are generated as follows:
* <ul>
* <li/>return node: superedge returning to the caller
* <li/>entry node: superedge invoking the node's method
* <li/>other: intraprocedural CFG edge
* </ul>
* @param node
* @return
*/
public Iterable<SuperGraphEdge> incomingEdgesOf(SuperGraphNode node) {
CFGNode cfgNode = node.getCFGNode();
if (cfgNode instanceof ReturnNode) {
/* return node: incoming edges are callgraph return edges */
final ReturnNode retNode = (ReturnNode) cfgNode;
Set<SuperEdge> cgReturnEdges = superGraph.incomingEdgesOf(node.getContextCFG());
return new Filter<SuperGraphEdge>() {
@Override
protected boolean include(SuperGraphEdge e) {
if (!(e instanceof SuperReturnEdge))
return false;
SuperReturnEdge retEdge = (SuperReturnEdge) e;
return retEdge.getReturnNode().equals(retNode);
}
}.<SuperGraphEdge>filter(cgReturnEdges);
} else if (cfgNode instanceof VirtualNode && ((VirtualNode) cfgNode).getKind() == VirtualNodeKind.ENTRY) {
/* entry node: superedge invoking the node's method */
Set<SuperEdge> cgInvokeEdges = superGraph.incomingEdgesOf(node.getContextCFG());
return new Filter<SuperGraphEdge>() {
@Override
protected boolean include(SuperGraphEdge e) {
return (e instanceof SuperInvokeEdge);
}
}.<SuperGraphEdge>filter(cgInvokeEdges);
} else {
/* standard edges: incoming edges of cfg node */
return liftCFGEdges(node.getContextCFG(), node.getContextCFG().getCfg().incomingEdgesOf(cfgNode));
}
}
Aggregations