Search in sources :

Example 16 with CFGNode

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);
                }
            }
        }
    }
}
Also used : InvokeNode(com.jopdesign.common.code.ControlFlowGraph.InvokeNode) CFGNode(com.jopdesign.common.code.ControlFlowGraph.CFGNode) Stack(java.util.Stack) InvokeNode(com.jopdesign.common.code.ControlFlowGraph.InvokeNode) MethodInfo(com.jopdesign.common.MethodInfo) CFGEdge(com.jopdesign.common.code.ControlFlowGraph.CFGEdge)

Example 17 with CFGNode

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;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) CFGNode(com.jopdesign.common.code.ControlFlowGraph.CFGNode) InstructionHandle(org.apache.bcel.generic.InstructionHandle)

Example 18 with CFGNode

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);
    }
}
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 19 with CFGNode

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());
}
Also used : CFGNode(com.jopdesign.common.code.ControlFlowGraph.CFGNode) HashMap(java.util.HashMap) MethodCacheAnalysis(com.jopdesign.wcet.analysis.cache.MethodCacheAnalysis) MethodInfo(com.jopdesign.common.MethodInfo)

Example 20 with CFGNode

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());
        }
    }
}
Also used : CFGNode(com.jopdesign.common.code.ControlFlowGraph.CFGNode) HashMap(java.util.HashMap) ClassReport(com.jopdesign.wcet.report.ClassReport) BasicBlock(com.jopdesign.common.code.BasicBlock) TreeSet(java.util.TreeSet) MethodInfo(com.jopdesign.common.MethodInfo) ClassInfo(com.jopdesign.common.ClassInfo)

Aggregations

CFGNode (com.jopdesign.common.code.ControlFlowGraph.CFGNode)28 MethodInfo (com.jopdesign.common.MethodInfo)13 ControlFlowGraph (com.jopdesign.common.code.ControlFlowGraph)13 CFGEdge (com.jopdesign.common.code.ControlFlowGraph.CFGEdge)10 LoopBound (com.jopdesign.common.code.LoopBound)7 ExecutionContext (com.jopdesign.common.code.ExecutionContext)6 HashMap (java.util.HashMap)6 InstructionHandle (org.apache.bcel.generic.InstructionHandle)6 SuperGraphEdge (com.jopdesign.common.code.SuperGraph.SuperGraphEdge)5 InvokeNode (com.jopdesign.common.code.ControlFlowGraph.InvokeNode)4 ContextCFG (com.jopdesign.common.code.SuperGraph.ContextCFG)4 ArrayList (java.util.ArrayList)4 HashSet (java.util.HashSet)4 BasicBlock (com.jopdesign.common.code.BasicBlock)3 BasicBlockNode (com.jopdesign.common.code.ControlFlowGraph.BasicBlockNode)3 LinkedHashSet (java.util.LinkedHashSet)3 Set (java.util.Set)3 ClassInfo (com.jopdesign.common.ClassInfo)2 MethodCode (com.jopdesign.common.MethodCode)2 ContextEdge (com.jopdesign.common.code.CallGraph.ContextEdge)2