use of com.jopdesign.common.misc.BadGraphError in project jop by jop-devel.
the class WCETTool method getFlowGraph.
/**
* Get the flowgraph of the given method.
* <p>
* A new callgraph is constructed when this method is called, changes to this graph are not
* automatically stored back to MethodCode. If you want to keep changes to the graph you need to keep a
* reference to this graph yourself.
* </p>
*
* @param mi the method to get the CFG for
* @return the CFG for the method.
*/
public ControlFlowGraph getFlowGraph(MethodInfo mi) {
if (!mi.hasCode()) {
throw new AssertionError("No CFG for MethodInfo " + mi);
}
ControlFlowGraph cfg;
try {
/* TODO We need to make sure that changes to the CFG are not compiled back automatically
* but CFG#compile() is not yet fully implemented anyways.
* We could add an option to MethodCode#getControlFlowGraph() to get a graph which will not be compiled back.
*
* We could also create a new graph instead, would allow us to create CFGs per callstring and be consistent
* with this.callgraph. But as long as neither this.callgraph and appInfo.callgraph are not modified
* after rebuildCallGraph() has been called, there is no difference.
*
* However, if we create a new graph we have to
* - keep the new graph, if we just recreate them modifications by analyses will be lost and some things
* like SuperGraph will break if we return new graphs every time.
* - provide a way to rebuild the CFGs if the code is modified, either by implementing WCETEventHandler.onMethodModified
* or by providing a dispose() method which must be called before the analysis starts after any code modifications.
* - when we do not use a CFG anymore (e.g. because we recreate it) we need to call CFG.dispose() so that it
* is not attached to the instruction handles anymore.
*/
//cfg = new ControlFlowGraph(mi, CallString.EMPTY, callGraph);
cfg = mi.getCode().getControlFlowGraph(false);
cfg.resolveVirtualInvokes();
cfg.insertReturnNodes();
cfg.insertContinueLoopNodes();
// cfg.insertSplitNodes();
// cfg.insertSummaryNodes();
} catch (BadGraphException e) {
// TODO handle this somehow??
throw new BadGraphError(e.getMessage(), e);
}
return cfg;
}
use of com.jopdesign.common.misc.BadGraphError in project jop by jop-devel.
the class MethodCode method getControlFlowGraph.
/**
* Get the control flow graph associated with this method code or create a new one.
* <p>
* By default, changes to the returned CFG are compiled back before the InstructionList of this method is accessed.
* If you want a CFG where changes to it are not compiled back automatically, use {@code new ControlFlowGraph(MethodInfo)}
* instead. Also if you want to construct a CFG for a specific context or with a different implementation finder,
* you need to construct a callgraph yourself, keep a reference to it as long as you want to keep modifications to the
* graph and you need ensure that changes to a graph invalidate other graphs of the same method yourself, if required.
* </p>
* @param clean if true, compile and recreate the graph if {@link ControlFlowGraph#isClean()} returns false.
* @return the CFG for this method.
*/
public ControlFlowGraph getControlFlowGraph(boolean clean) {
if (cfg != null && clean && !cfg.isClean()) {
cfg.compile();
cfg = null;
}
if (this.cfg == null) {
try {
cfg = new ControlFlowGraph(this.getMethodInfo());
// TODO we do this for now by default for the 'main' CFG on creation
cfg.registerHandleNodes();
for (AppEventHandler ah : AppInfo.getSingleton().getEventHandlers()) {
ah.onCreateMethodControlFlowGraph(cfg, clean);
}
} catch (BadGraphException e) {
throw new BadGraphError("Unable to create CFG for " + methodInfo, e);
}
}
return cfg;
}
use of com.jopdesign.common.misc.BadGraphError in project jop by jop-devel.
the class JavaOneProcessPerSupergraphTranslator method recordLoops.
// Global maximal nesting depth is given by the equation
// node.gmnd = node.method.gmnd + (node.loop ? node.loop.nestingDepth : 0)
// method.gmnd = max { cs.method.gmnd + cs.gmnd | cs <- method.callsites }
// Example:
// main() { for() for() X: f(); }
// f() { for() for(HOL) }
// nesting depth of HOL is 2
// gmnd of f is gmnd of X = 2 + gmnd of main = 2
// gmnd of HOL is 4
private void recordLoops(TemplateBuilder tBuilder) {
try {
computeMethodNestingDepths();
} catch (BadGraphException e) {
throw new BadGraphError(e);
}
for (MethodInfo m : methodInfos) {
ControlFlowGraph cfg = project.getFlowGraph(m);
for (Entry<CFGNode, LoopBound> entry : cfg.buildLoopBoundMap().entrySet()) {
CFGNode hol = entry.getKey();
LoopBound lb = entry.getValue();
int nesting = cfg.getLoopColoring().getLoopColor(hol).size();
int gmnd = nesting + methodMNDs.get(m);
tBuilder.addLoop(hol, gmnd, lb);
}
}
if (config.debug)
tBuilder.dumpLoops();
}
Aggregations