Search in sources :

Example 6 with LoopBound

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;
        }
    }
}
Also used : LoopBound(com.jopdesign.common.code.LoopBound) SourceAnnotations(com.jopdesign.wcet.annotations.SourceAnnotations) Interval(com.jopdesign.dfa.analyses.Interval)

Example 7 with LoopBound

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;
}
Also used : LoopBound(com.jopdesign.common.code.LoopBound) BufferedReader(java.io.BufferedReader) FileReader(java.io.FileReader) ClassFile(org.apache.bcel.util.ClassPath.ClassFile) File(java.io.File)

Example 8 with LoopBound

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;
}
Also used : CFGNode(com.jopdesign.common.code.ControlFlowGraph.CFGNode) LoopBound(com.jopdesign.common.code.LoopBound) ArrayList(java.util.ArrayList) ExecutionEdge(com.jopdesign.wcet.ipet.IPETBuilder.ExecutionEdge) AppInfoError(com.jopdesign.common.misc.AppInfoError) CFGEdge(com.jopdesign.common.code.ControlFlowGraph.CFGEdge)

Example 9 with LoopBound

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;
}
Also used : LoopBounds(com.jopdesign.dfa.analyses.LoopBounds) LoopBound(com.jopdesign.common.code.LoopBound) MethodInfo(com.jopdesign.common.MethodInfo)

Example 10 with 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);
    }
}
Also used : CFGNode(com.jopdesign.common.code.ControlFlowGraph.CFGNode) BasicBlockNode(com.jopdesign.common.code.ControlFlowGraph.BasicBlockNode) LoopBound(com.jopdesign.common.code.LoopBound) BasicBlock(com.jopdesign.common.code.BasicBlock) IOException(java.io.IOException) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ExecutionContext(com.jopdesign.common.code.ExecutionContext) MethodInfo(com.jopdesign.common.MethodInfo) BadAnnotationException(com.jopdesign.wcet.annotations.BadAnnotationException) MethodCode(com.jopdesign.common.MethodCode) SourceAnnotations(com.jopdesign.wcet.annotations.SourceAnnotations) HashSet(java.util.HashSet) ClassInfo(com.jopdesign.common.ClassInfo)

Aggregations

LoopBound (com.jopdesign.common.code.LoopBound)12 CFGNode (com.jopdesign.common.code.ControlFlowGraph.CFGNode)7 MethodInfo (com.jopdesign.common.MethodInfo)5 ControlFlowGraph (com.jopdesign.common.code.ControlFlowGraph)4 CFGEdge (com.jopdesign.common.code.ControlFlowGraph.CFGEdge)3 ExecutionContext (com.jopdesign.common.code.ExecutionContext)3 BasicBlockNode (com.jopdesign.common.code.ControlFlowGraph.BasicBlockNode)2 AppInfoError (com.jopdesign.common.misc.AppInfoError)2 SourceAnnotations (com.jopdesign.wcet.annotations.SourceAnnotations)2 ArrayList (java.util.ArrayList)2 ClassInfo (com.jopdesign.common.ClassInfo)1 MethodCode (com.jopdesign.common.MethodCode)1 BasicBlock (com.jopdesign.common.code.BasicBlock)1 ContextCFG (com.jopdesign.common.code.SuperGraph.ContextCFG)1 SuperGraphEdge (com.jopdesign.common.code.SuperGraph.SuperGraphEdge)1 BadGraphError (com.jopdesign.common.misc.BadGraphError)1 BadGraphException (com.jopdesign.common.misc.BadGraphException)1 Interval (com.jopdesign.dfa.analyses.Interval)1 LoopBounds (com.jopdesign.dfa.analyses.LoopBounds)1 BadAnnotationException (com.jopdesign.wcet.annotations.BadAnnotationException)1