use of com.jopdesign.common.code.LoopBound in project jop by jop-devel.
the class AllocationWcetModel method getArrayBound.
private long getArrayBound(ExecutionContext context, InstructionHandle ih, int index) {
int srcLine = context.getMethodInfo().getCode().getLineNumberTable().getSourceLine(ih.getPosition());
// get annotated size
LoopBound annotated = null;
try {
SourceAnnotations annots = project.getAnnotations(context.getMethodInfo().getClassInfo());
annotated = annots.annotationsForLine(srcLine);
if (annotated == null) {
WCETTool.logger.info("No annotated bound for array at " + context + ":" + srcLine);
}
} catch (Exception exc) {
// TODO: anything else to do?
WCETTool.logger.warn("Problem reading annotated bound for array at " + context + ":" + srcLine, exc);
}
// get analyzed size
Interval analyzed = null;
Interval[] sizes = null;
if (project.getDfaLoopBounds() != null) {
sizes = project.getDfaLoopBounds().getArraySizes(ih, context.getCallString());
}
if (sizes == null) {
WCETTool.logger.info("No DFA available for array at " + context + ":" + srcLine);
} else {
analyzed = sizes[index];
if (analyzed == null) {
WCETTool.logger.info("No DFA bound for array at " + context + ":" + srcLine);
}
}
// compute which bound to use
if (analyzed != null && analyzed.hasUb()) {
if (annotated != null) {
if (annotated.getUpperBound(context) > analyzed.getUb()) {
WCETTool.logger.warn("DFA bound smaller than annotated bound for array at " + context + ":" + srcLine);
}
if (annotated.getUpperBound(context) < analyzed.getUb()) {
WCETTool.logger.warn("DFA bound larger than annotated bound for array at " + context + ":" + srcLine);
}
if (annotated.getUpperBound(context) == analyzed.getUb()) {
WCETTool.logger.info("DFA bound equals annotated bound for array at " + context + ":" + srcLine);
}
return Math.max(annotated.getUpperBound(context), analyzed.getUb());
} else {
return analyzed.getUb();
}
} else {
if (annotated != null) {
return annotated.getUpperBound(context);
} else {
WCETTool.logger.error("Cannot determine cost of unbounded array " + context.getMethodInfo().getFQMethodName() + ":" + srcLine + ".\nApproximating with 1024 words, but result is not safe anymore.");
return 1024;
}
}
}
use of com.jopdesign.common.code.LoopBound in project jop by jop-devel.
the class SourceAnnotationReader method readAnnotations.
/**
* Extract loop bound annotations for one class
* <p/>
* All annotations start with {@code // @WCA }, and belong to the last source code line encountered.
* A source code line is a line which has at least one token in it.
*
* @return a FlowFacts object encapsulating the annotations found in the source file of the given class
* @throws IOException
* @throws BadAnnotationException
*/
public SourceAnnotations readAnnotations(ClassInfo ci) throws IOException, BadAnnotationException {
SourceAnnotations flowFacts = new SourceAnnotations();
File fileName = getSourceFile(ci);
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line = null;
int lineNr = 1;
int sourceLineNr = 1;
while ((line = reader.readLine()) != null) {
if (!SourceAnnotationReader.isCommentLine(line)) {
sourceLineNr = lineNr;
}
LoopBound loopBound = SourceAnnotationReader.extractAnnotation(line);
if (loopBound != null) {
logger.debug("Adding loop bound @ " + sourceLineNr + ": " + loopBound);
flowFacts.addLoopBound(sourceLineNr, loopBound);
}
lineNr++;
}
logger.debug("Read WCA annotations for " + fileName);
return flowFacts;
}
use of com.jopdesign.common.code.LoopBound in project jop by jop-devel.
the class IPETUtils method loopBoundConstraints.
/**
* Compute flow constraints: Loop Bound constraints (Control Flow Graph only)
*
* @param g the flow graph
* @param ctx the invocation context
* @return A list of flow constraints
*/
public static <C extends CallStringProvider> List<LinearConstraint<IPETBuilder.ExecutionEdge>> loopBoundConstraints(ControlFlowGraph g, IPETBuilder<C> ctx) {
List<LinearConstraint<IPETBuilder.ExecutionEdge>> constraints = new ArrayList<LinearConstraint<IPETBuilder.ExecutionEdge>>();
// - for each loop with bound B
// -- sum(exit_loop_edges) * B <= sum(continue_loop_edges)
LoopColoring<CFGNode, ControlFlowGraph.CFGEdge> loops = g.getLoopColoring();
for (CFGNode hol : loops.getHeadOfLoops()) {
//LoopBound loopBound = g.getLoopBound(hol, ctx.getCallString());
LoopBound loopBound = ctx.getWCETTool().getLoopBound(hol, ctx.getCallString());
if (loopBound == null) {
throw new AppInfoError("No loop bound record for head of loop: " + hol + " : " + g.buildLoopBoundMap());
}
for (LinearConstraint<IPETBuilder.ExecutionEdge> loopConstraint : constraintsForLoop(loops, hol, loopBound, ctx)) {
constraints.add(loopConstraint);
}
}
return constraints;
}
use of com.jopdesign.common.code.LoopBound 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;
}
use of com.jopdesign.common.code.LoopBound 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);
}
}
Aggregations