use of com.jopdesign.common.MethodInfo 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.MethodInfo in project jop by jop-devel.
the class WCETAnalysis method run.
private boolean run() {
/* Initialize */
try {
wcetTool.setTopLevelLogger(exec.getExecLogger());
exec.info("Loading project");
wcetTool.initialize(wcetTool.getProjectConfig().doLoadLinkInfo(), true);
} catch (Exception e) {
exec.logException("Loading project", e);
return false;
}
// exploreCacheAnalysis();
// project.getLinkerInfo().dump(System.out);
// new ConstantCache(project).build().dumpStats();
/* Perf-Test */
// for(int i = 0; i < 50; i++) {
// RecursiveAnalysis<StaticCacheApproximation> an =
// new RecursiveAnalysis<StaticCacheApproximation>(project,new RecursiveAnalysis.LocalIPETStrategy());
// an.computeWCET(project.getTargetMethod(),StaticCacheApproximation.ALWAYS_HIT);
// }
// System.err.println("Total solver time (50): "+LpSolveWrapper.getSolverTime());
// System.exit(1);
MethodInfo targetMethod = wcetTool.getTargetMethod();
if (wcetTool.getProjectConfig().doObjectCacheAnalysis()) {
ObjectCacheEvaluation oca = new ObjectCacheEvaluation(wcetTool);
return oca.run(targetMethod);
} else {
return runWCETAnalysis(targetMethod);
}
}
use of com.jopdesign.common.MethodInfo in project jop by jop-devel.
the class UppAalAnalysis method run.
private boolean run(ExecHelper exec) {
File uppaalOutDir;
try {
project.setTopLevelLogger(tlLogger);
tlLogger.info("Loading project");
project.initialize(true, true);
uppaalOutDir = project.getOutDir("uppaal");
} catch (Exception e) {
exec.logException("loading project", e);
return false;
}
UppaalAnalysis ua = new UppaalAnalysis(tlLogger, project, uppaalOutDir);
List<MethodInfo> methods = project.getCallGraph().getReachableImplementations(project.getTargetMethod());
Collections.reverse(methods);
List<WCETEntry> entries = new ArrayList<WCETEntry>();
for (MethodInfo m : methods) {
if (project.computeCyclomaticComplexity(m) > ECC_TRESHOLD) {
tlLogger.info("Skipping UppAal translation for " + m + " because extended cyclomatic complexity " + project.computeCyclomaticComplexity(m) + " > treshold");
} else {
tlLogger.info("Starting UppAal translation for " + m);
WcetCost wcet;
try {
wcet = ua.calculateWCET(m);
entries.add(new WCETEntry(m, wcet.getCost(), ua.getSearchtime(), ua.getSolvertimemax()));
} catch (Exception e) {
exec.logException("Uppaal calculation", e);
return false;
}
}
}
for (WCETEntry entry : entries) {
System.out.println("***" + entry.target.toString());
System.out.println(" wcet: " + entry.wcet);
System.out.println(" complex: " + project.computeCyclomaticComplexity(entry.target));
System.out.println(" searchT: " + entry.searchtime);
System.out.println(" solverTmax: " + entry.solvertime);
}
return true;
}
use of com.jopdesign.common.MethodInfo 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.MethodInfo in project jop by jop-devel.
the class WCETEventHandler method dfaLoopBound.
/**
* Get a loop bound from the DFA for a certain loop and call string and
* merge it with the annotated value.
* @return The loop bound to be used for further computations
*/
public LoopBound dfaLoopBound(BasicBlock headOfLoopBlock, ExecutionContext eCtx, LoopBound annotatedBound) {
LoopBounds lbAnalysis = project.getDfaLoopBounds();
if (lbAnalysis == null)
return annotatedBound;
MethodInfo methodInfo = headOfLoopBlock.getMethodInfo();
int dfaUpperBound;
// FIXME: Bad style
try {
dfaUpperBound = lbAnalysis.getBound(headOfLoopBlock.getLastInstruction(), eCtx.getCallString());
} catch (NullPointerException ex) {
logger.error("Failed to retrieve DFA loop bound values", ex);
dfaUpperBound = -1;
}
if (dfaUpperBound < 0) {
if (!printedLoopBoundInfoMessage.contains(headOfLoopBlock)) {
logger.info("No DFA bound for " + methodInfo + "/" + headOfLoopBlock + ". Using manual bound: " + annotatedBound);
printedLoopBoundInfoMessage.add(headOfLoopBlock);
}
return annotatedBound;
}
LoopBound loopBound;
if (annotatedBound == null) {
loopBound = LoopBound.boundedAbove(dfaUpperBound);
logger.debug("Only DFA bound for " + methodInfo + "headOfLoopBlock");
} else {
loopBound = annotatedBound.clone();
// More testing would be nice
loopBound.addBound(LoopBoundExpr.numUpperBound(dfaUpperBound), SymbolicMarker.LOOP_ENTRY);
long loopUb = annotatedBound.getSimpleLoopBound().upperBound(eCtx);
if (dfaUpperBound < loopUb) {
/* This isn't unusual (context dependent loop bounds) */
if (logger.isDebugEnabled()) {
logger.debug("DFA analysis reports a smaller upper bound :" + dfaUpperBound + " < " + loopUb + " for " + methodInfo + "/" + headOfLoopBlock);
}
} else if (dfaUpperBound > loopUb) {
/* In principle this is possible, but usually a bad sign */
logger.warn("DFA analysis reports a larger upper bound: " + dfaUpperBound + " > " + loopUb + " for " + methodInfo);
} else {
if (logger.isDebugEnabled()) {
logger.debug("DFA and annotated loop bounds match for " + methodInfo);
}
}
}
if (!printedLoopBoundInfoMessage.contains(headOfLoopBlock)) {
logger.info("DFA bound for " + methodInfo + "/" + headOfLoopBlock + ": " + loopBound + ". Manual bound info: " + annotatedBound);
printedLoopBoundInfoMessage.add(headOfLoopBlock);
}
return loopBound;
}
Aggregations