Search in sources :

Example 26 with ExecutionContext

use of com.jopdesign.common.code.ExecutionContext in project jop by jop-devel.

the class MethodCacheAnalysis method findClassificationChanges.

private Set<MethodInfo> findClassificationChanges(MethodInfo method, final int deltaBlocks, Collection<MethodInfo> removed, final boolean update) {
    if (analysisType == AnalysisType.ALWAYS_HIT || analysisType == AnalysisType.ALWAYS_MISS || (deltaBlocks == 0 && removed.isEmpty())) {
        return Collections.emptySet();
    }
    Set<ExecutionContext> roots = callGraph.getNodes(method);
    // First, go up and find all nodes where one or more methods need to be removed from the reachable methods set
    final Map<ExecutionContext, Set<MethodInfo>> removeMethods = findRemovedMethods(roots, removed);
    // next, calculate blocks of removed methods
    final Map<MethodInfo, Integer> blocks = new LinkedHashMap<MethodInfo, Integer>(removed.size());
    for (MethodInfo m : removed) {
        int size = MiscUtils.bytesToWords(getMethodSize(m));
        blocks.put(m, cache.requiredNumberOfBlocks(size));
    }
    // finally, go up all invokers, sum up reachable method set changes and deltaBlocks per node, check all-fit
    final Set<MethodInfo> changeSet = new LinkedHashSet<MethodInfo>();
    DFSVisitor<ExecutionContext, ContextEdge> visitor = new EmptyDFSVisitor<ExecutionContext, ContextEdge>() {

        @Override
        public void preorder(ExecutionContext node) {
            Set<MethodInfo> remove = removeMethods.get(node);
            int oldBlocks = cacheBlocks.get(node);
            int newBlocks = oldBlocks;
            if (remove != null) {
                if (update) {
                    reachableMethods.get(node).removeAll(remove);
                }
                for (MethodInfo r : remove) {
                    newBlocks -= blocks.get(r);
                }
            }
            newBlocks += deltaBlocks;
            if (update) {
                cacheBlocks.put(node, newBlocks);
            }
            boolean oldFit = cache.allFit(oldBlocks);
            boolean newFit = cache.allFit(newBlocks);
            if (oldFit != newFit) {
                changeSet.add(node.getMethodInfo());
                if (update) {
                    classifyChanges.add(node.getMethodInfo());
                }
            }
        }
    };
    DFSTraverser<ExecutionContext, ContextEdge> traverser = new DFSTraverser<ExecutionContext, ContextEdge>(visitor);
    traverser.traverse(callGraph.getReversedGraph(), roots);
    return changeSet;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) EmptyDFSVisitor(com.jopdesign.common.graphutils.DFSTraverser.EmptyDFSVisitor) ContextEdge(com.jopdesign.common.code.CallGraph.ContextEdge) LinkedHashMap(java.util.LinkedHashMap) DFSTraverser(com.jopdesign.common.graphutils.DFSTraverser) ExecutionContext(com.jopdesign.common.code.ExecutionContext) MethodInfo(com.jopdesign.common.MethodInfo)

Example 27 with ExecutionContext

use of com.jopdesign.common.code.ExecutionContext 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)

Example 28 with ExecutionContext

use of com.jopdesign.common.code.ExecutionContext in project jop by jop-devel.

the class MethodCacheAnalysis method getMissCountChangeSet.

/**
     * @param ecp exec count provider
     * @return all methods for which the cache costs of the contained invoke sites changed, either due to classification
     *         changes or due to execution count changes.
     */
public Set<MethodInfo> getMissCountChangeSet(ExecFrequencyProvider ecp) {
    if (analysisType == AnalysisType.ALWAYS_HIT)
        return Collections.emptySet();
    Set<MethodInfo> countChanges = new LinkedHashSet<MethodInfo>(classifyChanges);
    // we check the exec analysis for changed exec counts,
    // need to update change sets since cache miss counts changed for cache-misses
    Set<MethodInfo> methods = ecp.getChangeSet();
    if (analysisType == AnalysisType.ALWAYS_MISS) {
        countChanges.addAll(methods);
        return countChanges;
    }
    for (MethodInfo method : methods) {
        if (!allFit(method)) {
            countChanges.add(method);
        }
    }
    if (analysisType == AnalysisType.ALL_FIT_REGIONS) {
        for (MethodInfo method : ecp.getChangeSet()) {
            if (!classifyChanges.contains(method)) {
                continue;
            }
            // all methods for which the classification changed and for which the exe count changed..
            for (ExecutionContext context : callGraph.getNodes(method)) {
                // add all reachable methods
                countChanges.addAll(reachableMethods.get(context));
            }
        }
    }
    return countChanges;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ExecutionContext(com.jopdesign.common.code.ExecutionContext) MethodInfo(com.jopdesign.common.MethodInfo)

Example 29 with ExecutionContext

use of com.jopdesign.common.code.ExecutionContext in project jop by jop-devel.

the class WCAInvoker method runAnalysis.

///////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////
private Set<MethodInfo> runAnalysis(DirectedGraph<ExecutionContext, ContextEdge> reversed) {
    // Phew. The WCA only runs on acyclic callgraphs, we can therefore assume the
    // reversed graph to be a DAG
    TopologicalOrderIterator<ExecutionContext, ContextEdge> topOrder = new TopologicalOrderIterator<ExecutionContext, ContextEdge>(reversed);
    Set<MethodInfo> changed = new LinkedHashSet<MethodInfo>();
    while (topOrder.hasNext()) {
        ExecutionContext node = topOrder.next();
        // At times like this I really wish Java would have type aliases ..
        RecursiveWcetAnalysis<AnalysisContextLocal>.LocalWCETSolution<AnalysisContextLocal> sol = recursiveAnalysis.computeSolution(node.getMethodInfo(), new AnalysisContextLocal(cacheApproximation, node.getCallString()));
        wcaNodeFlow.put(node, sol.getNodeFlowVirtual());
        // TODO some logging would be nice, keep target-method WCET for comparison of speedup
        if (node.getMethodInfo().equals(wcetTool.getTargetMethod())) {
            lastWCET = sol.getCost().getCost();
            logger.info("WCET: " + lastWCET);
        }
        changed.add(node.getMethodInfo());
    }
    return changed;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ExecutionContext(com.jopdesign.common.code.ExecutionContext) TopologicalOrderIterator(org.jgrapht.traverse.TopologicalOrderIterator) MethodInfo(com.jopdesign.common.MethodInfo) AnalysisContextLocal(com.jopdesign.wcet.analysis.AnalysisContextLocal) RecursiveWcetAnalysis(com.jopdesign.wcet.analysis.RecursiveWcetAnalysis) ContextEdge(com.jopdesign.common.code.CallGraph.ContextEdge)

Example 30 with ExecutionContext

use of com.jopdesign.common.code.ExecutionContext in project jop by jop-devel.

the class WCAInvoker method getExecFrequency.

public long getExecFrequency(MethodInfo method, CFGNode block) {
    long flow = 0;
    for (ExecutionContext node : wcetTool.getCallGraph().getNodes(method)) {
        Long value = wcaNodeFlow.get(node).get(block);
        flow += value;
    }
    return flow;
}
Also used : ExecutionContext(com.jopdesign.common.code.ExecutionContext)

Aggregations

ExecutionContext (com.jopdesign.common.code.ExecutionContext)34 MethodInfo (com.jopdesign.common.MethodInfo)15 ContextEdge (com.jopdesign.common.code.CallGraph.ContextEdge)11 LinkedHashSet (java.util.LinkedHashSet)10 ControlFlowGraph (com.jopdesign.common.code.ControlFlowGraph)6 CFGNode (com.jopdesign.common.code.ControlFlowGraph.CFGNode)6 Set (java.util.Set)4 MethodCode (com.jopdesign.common.MethodCode)3 BasicBlockNode (com.jopdesign.common.code.ControlFlowGraph.BasicBlockNode)3 LoopBound (com.jopdesign.common.code.LoopBound)3 DFSTraverser (com.jopdesign.common.graphutils.DFSTraverser)3 EmptyDFSVisitor (com.jopdesign.common.graphutils.DFSTraverser.EmptyDFSVisitor)3 AppInfoError (com.jopdesign.common.misc.AppInfoError)3 ArrayList (java.util.ArrayList)3 LinkedHashMap (java.util.LinkedHashMap)3 InstructionHandle (org.apache.bcel.generic.InstructionHandle)3 ClassInfo (com.jopdesign.common.ClassInfo)2 BasicBlock (com.jopdesign.common.code.BasicBlock)2 CallGraph (com.jopdesign.common.code.CallGraph)2 InvokeSite (com.jopdesign.common.code.InvokeSite)2