use of com.jopdesign.common.code.ControlFlowGraph.CFGNode in project jop by jop-devel.
the class SuperGraph method createSuperGraph.
private void createSuperGraph() {
Stack<ContextCFG> todo = new Stack<ContextCFG>();
todo.push(rootNode);
superGraph.addVertex(rootNode);
while (!todo.empty()) {
ContextCFG current = todo.pop();
if (!current.getCfg().areVirtualInvokesResolved()) {
throw new AssertionError("Virtual dispatch nodes not yet supported for supergraph (file a bug)");
}
ControlFlowGraph currentCFG = current.getCfg();
CallString currentCS = current.getCallString();
Collection<CFGEdge> infeasibleEdges = infeasibleEdgeProvider.getInfeasibleEdges(currentCFG, currentCS);
for (CFGNode node : current.getCfg().vertexSet()) {
if (node instanceof ControlFlowGraph.InvokeNode) {
/* skip node if all incoming edges are infeasible in the current call context */
boolean infeasible = true;
for (CFGEdge e : current.getCfg().incomingEdgesOf(node)) {
if (!infeasibleEdges.contains(e)) {
infeasible = false;
}
}
if (infeasible)
continue;
ControlFlowGraph.InvokeNode iNode = (ControlFlowGraph.InvokeNode) node;
Set<MethodInfo> impls = iNode.getImplementingMethods();
if (impls.size() == 0) {
throw new AssertionError("No implementations for iNode available");
} else if (impls.size() != 1) {
throw new AssertionError("Unresolved virtual Dispatch for " + iNode + ": " + impls);
}
for (MethodInfo impl : impls) {
ControlFlowGraph invokedCFG = cfgProvider.getFlowGraph(impl);
CallString invokedCS = currentCS.push(iNode, callstringLength);
/* skip node if receiver is infeasible in current call context */
if (infeasibleEdgeProvider.isInfeasibleReceiver(impl, invokedCS)) {
Logger.getLogger(this.getClass()).info("createSuperGraph(): infeasible receiver " + impl);
continue;
}
ContextCFG invoked = new ContextCFG(invokedCFG, invokedCS);
if (!superGraph.containsVertex(invoked)) {
superGraph.addVertex(invoked);
todo.push(invoked);
}
addEdge(iNode, current, invoked);
}
}
}
}
}
use of com.jopdesign.common.code.ControlFlowGraph.CFGNode in project jop by jop-devel.
the class CFGCallgraphBuilder method findInvokeSites.
@Override
protected Set<InvokeSite> findInvokeSites(MethodCode code) {
ControlFlowGraph cfg = code.getControlFlowGraph(false);
Set<InvokeSite> invokeSites = new LinkedHashSet<InvokeSite>();
// Basic blocks however are not removed from the block list..
for (CFGNode node : cfg.vertexSet()) {
BasicBlock bb = node.getBasicBlock();
if (bb == null)
continue;
// but hey, invokeSites is a set anyway..
for (InstructionHandle ih : bb.getInstructions()) {
if (code.isInvokeSite(ih)) {
invokeSites.add(code.getInvokeSite(ih));
}
}
}
return invokeSites;
}
use of com.jopdesign.common.code.ControlFlowGraph.CFGNode in project jop by jop-devel.
the class WCETEventHandler method loadLoopAnnotations.
/**
* load annotations for the flow graph.
*
* @param cfg the control flow graph of the method
* @throws BadAnnotationException if an annotations is missing
*/
public void loadLoopAnnotations(ControlFlowGraph cfg) throws BadAnnotationException {
SourceAnnotations wcaMap;
MethodInfo method = cfg.getMethodInfo();
MethodCode code = method.getCode();
ExecutionContext eCtx = new ExecutionContext(cfg.getMethodInfo());
for (CFGNode n : cfg.getLoopColoring().getHeadOfLoops()) {
BasicBlockNode headOfLoop = (BasicBlockNode) n;
BasicBlock block = headOfLoop.getBasicBlock();
// check if loopbound has already been loaded
if (block.getLoopBound() != null) {
// or at least check if the source-annotation is tighter than what is currently set?
continue;
}
Set<LoopBound> bounds = new HashSet<LoopBound>(2);
InstructionHandle first = block.getFirstInstruction();
InstructionHandle last = first;
ClassInfo sourceInfo = method.getCode().getSourceClassInfo(block.getFirstInstruction());
for (InstructionHandle ih : block.getInstructions()) {
ClassInfo cls = method.getCode().getSourceClassInfo(ih);
boolean isLast = ih.equals(block.getLastInstruction());
if (!cls.equals(sourceInfo) || isLast) {
try {
wcaMap = getAnnotations(method.getCode().getSourceClassInfo(block.getFirstInstruction()));
} catch (IOException e) {
throw new BadAnnotationException("IO Error reading annotation: " + e.getMessage(), e);
}
if (isLast) {
last = ih;
}
// search for loop annotation in range
int sourceRangeStart = code.getLineNumber(first);
int sourceRangeStop = code.getLineNumber(last);
bounds.addAll(wcaMap.annotationsForLineRange(sourceRangeStart, sourceRangeStop + 1));
first = ih;
}
last = ih;
}
if (bounds.size() > 1) {
String reason = "Ambiguous Annotation [" + bounds + "]";
throw new BadAnnotationException(reason, code, block);
}
LoopBound loopAnnot = null;
if (bounds.size() == 1) {
loopAnnot = bounds.iterator().next();
}
// if we have loop bounds from DFA analysis, use them
loopAnnot = dfaLoopBound(block, eCtx, loopAnnot);
if (loopAnnot == null) {
// Bit of a hack: if we load CFGs before the callgraph is constructed, this will log errors anyway
if (ignoreMissingLoopBounds) {
logger.trace("No loop bound annotation: " + method + ":" + n + " " + getLineRangeText(code, block) + ".\nApproximating with " + DEFAULT_LOOP_BOUND + ", but result is not safe anymore.");
} else if (project.getCallGraph() != null && !project.getCallGraph().containsMethod(method)) {
logger.debug("No loop bound annotation for non-WCET method: " + method + ":" + n + " " + getLineRangeText(code, block) + ".\nApproximating with " + DEFAULT_LOOP_BOUND);
} else {
logger.error("No loop bound annotation: " + method + ":" + n + " " + getLineRangeText(code, block) + ".\nApproximating with " + DEFAULT_LOOP_BOUND + ", but result is not safe anymore.");
}
loopAnnot = LoopBound.defaultBound(DEFAULT_LOOP_BOUND);
}
block.setLoopBound(loopAnnot);
}
}
use of com.jopdesign.common.code.ControlFlowGraph.CFGNode in project jop by jop-devel.
the class RecursiveWcetAnalysis method updateReport.
// FIXME: [recursive-wcet-analysis] Report generation is a big mess
// FIXME: [recursive-wcet-analysis] For now, we only add line costs once per method
private void updateReport(CacheKey key, LocalWCETSolution sol) {
MethodInfo m = key.m;
HashMap<CFGNode, String> nodeFlowCostDescrs = new HashMap<CFGNode, String>();
updateClassReport(key, sol);
Map<String, Object> stats = new HashMap<String, Object>();
stats.put("WCET", sol.getCost());
stats.put("mode", key.ctx);
MethodCacheAnalysis mca = new MethodCacheAnalysis(getWCETTool());
stats.put("all-methods-fit-in-cache", mca.isPersistenceRegion(getWCETTool(), m, key.ctx.getCallString(), EnumSet.allOf(PersistenceCheck.class)));
getWCETTool().getReport().addDetailedReport(m, "WCET_" + key.ctx.toString(), stats, nodeFlowCostDescrs, sol.getEdgeFlow());
}
use of com.jopdesign.common.code.ControlFlowGraph.CFGNode in project jop by jop-devel.
the class RecursiveWcetAnalysis method updateClassReport.
/**
* Update class report (cost per line number)
*
* @param key
* @param sol FIXME: Currently only reported once per method
*/
private void updateClassReport(CacheKey key, LocalWCETSolution sol) {
MethodInfo m = key.m;
if (costsPerLineReported.contains(m))
return;
costsPerLineReported.add(m);
Map<CFGNode, WcetCost> nodeCosts = sol.getNodeCostMap();
HashMap<CFGNode, String> nodeFlowCostDescrs = new HashMap<CFGNode, String>();
// for autogenerated code
long anonymousCost = 0;
for (Entry<CFGNode, WcetCost> entry : nodeCosts.entrySet()) {
CFGNode n = entry.getKey();
WcetCost cost = entry.getValue();
if (sol.getNodeFlow(n) > 0) {
nodeFlowCostDescrs.put(n, cost.toString());
BasicBlock basicBlock = n.getBasicBlock();
/* prototyping */
if (basicBlock != null) {
Map<ClassInfo, TreeSet<Integer>> lineMap = basicBlock.getSourceLines();
if (lineMap.isEmpty()) {
logger.error("No source code lines associated with basic block " + basicBlock + " in " + m + " ! ");
continue;
}
// we attach to the first class in the map only
ClassInfo cli = lineMap.keySet().iterator().next();
TreeSet<Integer> lineRange = lineMap.get(cli);
ClassReport cr = getWCETTool().getReport().getClassReport(cli);
long newCost = sol.getNodeFlow(n) * nodeCosts.get(n).getCost();
// Autogenerated code, attach to next entry
if (lineRange.isEmpty()) {
anonymousCost += newCost;
continue;
} else {
newCost += anonymousCost;
anonymousCost = 0;
}
Long oldCost = (Long) cr.getLineProperty(lineRange.first(), "cost");
if (oldCost == null)
oldCost = 0L;
if (logger.isTraceEnabled()) {
logger.trace("Attaching cost " + oldCost + " + " + newCost + " to line " + lineRange.first() + " in " + basicBlock.getMethodInfo());
}
cr.addLineProperty(lineRange.first(), "cost", oldCost + newCost);
for (int i : lineRange) {
cr.addLineProperty(i, "color", "red");
}
}
} else {
nodeFlowCostDescrs.put(n, "" + nodeCosts.get(n).getCost());
}
}
}
Aggregations