Search in sources :

Example 1 with ContextCFG

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

the class JavaOneProcessPerSupergraphTranslator method computeMethodNestingDepths.

private void computeMethodNestingDepths() throws BadGraphException {
    this.methodMNDs = new HashMap<MethodInfo, Integer>();
    /* for super graph nodes in topological order */
    for (ContextCFG n : superGraph.topologicalOrderIterator().getTopologicalTraversal()) {
        MethodInfo methodInvoked = n.getCfg().getMethodInfo();
        int maxCaller = 0;
        for (Pair<SuperGraph.SuperInvokeEdge, SuperGraph.SuperReturnEdge> callSite : superGraph.getCallSitesInvoking(n)) {
            ControlFlowGraph.InvokeNode callSiteNode = callSite.first().getInvokeNode();
            ControlFlowGraph cfgInvoker = callSiteNode.invokerFlowGraph();
            int callerRootDepth = methodMNDs.get(cfgInvoker.getMethodInfo());
            int nestingDepth = cfgInvoker.getLoopColoring().getLoopColor(callSiteNode).size();
            maxCaller = Math.max(maxCaller, callerRootDepth + nestingDepth);
        }
        Integer oldValue = methodMNDs.get(methodInvoked);
        if (oldValue == null)
            oldValue = 0;
        methodMNDs.put(methodInvoked, Math.max(oldValue, maxCaller));
    }
    if (config.debug)
        MiscUtils.printMap(System.out, methodMNDs, 30, 0);
}
Also used : ContextCFG(com.jopdesign.common.code.SuperGraph.ContextCFG) ControlFlowGraph(com.jopdesign.common.code.ControlFlowGraph) MethodInfo(com.jopdesign.common.MethodInfo)

Example 2 with ContextCFG

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

the class Segment method synchronizedSegment.

/**
	 * Create an interprocedural segment for a synchronized block. Currently we do
	 * not split basic blocks here, so either you are happy with basic block granularity,
	 * or you split the basic block while loading.
	 * @param targetBlock The block containing the monitorenter instruction
	 * @param monitorEnter The monitor enter instruction
	 * @param callString   The context for the method
	 * @param cfgProvider A control flow graph provider
	 * @param callStringLength Length of the callstrings
	 * @param infeasibles Information about infeasible edges (null if no information available)
	 *
	 * @return a segment representing executions of the synchronized block
	 */
public static Segment synchronizedSegment(ContextCFG ccfg, CFGNode entryNode, InstructionHandle monitorEnter, CFGProvider cfgProvider, int callStringLength, InfeasibleEdgeProvider infeasibles) {
    if (infeasibles == null) {
        infeasibles = InfeasibleEdgeProvider.NO_INFEASIBLES;
    }
    ControlFlowGraph cfg = ccfg.getCfg();
    SuperGraph superGraph = new SuperGraph(cfgProvider, cfg, ccfg.getCallString(), callStringLength, infeasibles);
    ContextCFG rootMethod = superGraph.getRootNode();
    /* lift entry edges */
    Set<SuperGraphEdge> entryEdges = Iterators.addAll(new HashSet<SuperGraphEdge>(), superGraph.liftCFGEdges(rootMethod, cfg.incomingEdgesOf(entryNode)));
    /* find exit blocks (might also be in the same block) */
    /* monitorenter followed bei monitorexit in same block => segment only contains this block */
    Set<CFGEdge> monitorExitEdges = new HashSet<CFGEdge>();
    CFGNode currentNode = entryNode;
    int currentNestingLevel = 1;
    Iterator<InstructionHandle> insIter = currentNode.getBasicBlock().getInstructions().iterator();
    while (insIter.hasNext()) {
        if (insIter.next() == monitorEnter)
            break;
    }
    Stack<Pair<CFGNode, Integer>> todo = new Stack<Pair<CFGNode, Integer>>();
    Set<CFGNode> visited = new HashSet<CFGNode>();
    do {
        boolean isExit = false;
        while (insIter.hasNext()) {
            InstructionHandle ih = insIter.next();
            if (ih.getInstruction() instanceof MONITOREXIT) {
                /* blocks outgoing edges terminate segment */
                currentNestingLevel--;
                if (currentNestingLevel == 0) {
                    isExit = true;
                    // If monitorexit is not implemented in Java, the outgoing edges of the
                    // basic block that contains monitorexit end the synchronized block.
                    // In order to avoid imprecision, it is advisable that monitorexit is the
                    // last statement in the basic block.
                    // We also handle the case when monitorexit is implemented in Java. In this case,
                    // currentNode will be a SpecialInvokeNode, urrentNode's only
                    // successor will be the corresponding ReturnNode, and the outgoing edges of
                    // the ReturnNode are the exit edges for the synchronized segment.
                    CFGNode onlySuccessor = Iterators.fromSingleton(cfg.getSuccessors(currentNode));
                    if (onlySuccessor != null && onlySuccessor instanceof ControlFlowGraph.ReturnNode) {
                        Iterators.addAll(monitorExitEdges, cfg.outgoingEdgesOf(onlySuccessor));
                    } else {
                        Iterators.addAll(monitorExitEdges, cfg.outgoingEdgesOf(currentNode));
                    }
                    break;
                }
            } else if (ih.getInstruction() instanceof MONITORENTER) {
                currentNestingLevel++;
            }
        }
        if (!isExit) {
            for (CFGNode node : cfg.getSuccessors(currentNode)) {
                todo.add(new Pair<CFGNode, Integer>(node, currentNestingLevel));
            }
        }
        currentNode = null;
        while (!todo.isEmpty()) {
            Pair<CFGNode, Integer> nextPair = todo.pop();
            CFGNode nextNode = nextPair.first();
            if (!visited.contains(nextNode)) {
                visited.add(nextNode);
                if (cfg.outgoingEdgesOf(nextNode).isEmpty()) {
                    throw new AssertionError("Found monitor-exit free path from monitorenter to the end of a function. In: " + cfg);
                } else if (nextNode.getBasicBlock() == null) {
                    for (CFGNode node : cfg.getSuccessors(nextNode)) {
                        todo.add(new Pair<CFGNode, Integer>(node, nextPair.second()));
                    }
                } else {
                    currentNode = nextNode;
                    currentNestingLevel = nextPair.second();
                    insIter = currentNode.getBasicBlock().getInstructions().iterator();
                    break;
                }
            }
        }
    } while (currentNode != null);
    Set<SuperGraphEdge> exitEdges = Iterators.addAll(new HashSet<SuperGraphEdge>(), superGraph.liftCFGEdges(rootMethod, monitorExitEdges));
    return new Segment(superGraph, entryEdges, exitEdges);
}
Also used : MONITORENTER(org.apache.bcel.generic.MONITORENTER) InstructionHandle(org.apache.bcel.generic.InstructionHandle) MONITOREXIT(org.apache.bcel.generic.MONITOREXIT) HashSet(java.util.HashSet) CFGEdge(com.jopdesign.common.code.ControlFlowGraph.CFGEdge) Pair(com.jopdesign.common.graphutils.Pair) CFGNode(com.jopdesign.common.code.ControlFlowGraph.CFGNode) Stack(java.util.Stack) ContextCFG(com.jopdesign.common.code.SuperGraph.ContextCFG) SuperGraphEdge(com.jopdesign.common.code.SuperGraph.SuperGraphEdge)

Example 3 with ContextCFG

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

the class MethodCacheAnalysis method findPersistenceSegmentCover.

/** Find a segment cover (i.e., a set of segments covering all execution paths)
	 *  where each segment in the set is persistent (a cache persistence region (CPR))
	 *  
	 *  <h2>The simplest algorithm for a segment S (for acyclic callgraphs)</h2>
	 *   <ul><li/>Check whether S itself is CPR; if so, return S
	 *       <li/>Otherwise, create subsegments S' for each invoked method,
	 *       <li/>and single node segments for each access
	 *   </ul>
	 * @param segment the parent segment
	 * @param checks the strategy to use to determine whether a segment is a persistence region
	 * @param avoidOverlap whether overlapping segments should be avoided
	 * @param extraCostOut additional cost for edges which are considered as always-miss or not-cached
	 * @return
	 */
protected Collection<Segment> findPersistenceSegmentCover(Segment segment, EnumSet<PersistenceCheck> checks, boolean avoidOverlap, Map<SuperGraphEdge, Long> extraCostOut) {
    List<Segment> cover = new ArrayList<Segment>();
    /* We currently only support entries to one CFG */
    Set<ContextCFG> entryMethods = new HashSet<ContextCFG>();
    for (SuperGraphEdge entryEdge : segment.getEntryEdges()) {
        entryMethods.add(entryEdge.getTarget().getContextCFG());
    }
    if (entryMethods.size() != 1) {
        throw new AssertionError("findPersistenceSegmentCover: only supporting segments with unique entry method");
    }
    if (this.isPersistenceRegion(segment, checks)) {
        // System.err.println("Adding cover segment for: "+entryMethods);
        cover.add(segment);
    } else {
        for (Pair<SuperInvokeEdge, SuperReturnEdge> invocation : segment.getCallSitesFrom(entryMethods.iterator().next())) {
            ContextCFG callee = invocation.first().getCallee();
            // System.err.println("Recursively analyzing: "+callee);
            Segment subSegment = Segment.methodSegment(callee, segment.getSuperGraph());
            Collection<Segment> subRegions = findPersistenceSegmentCover(subSegment, checks, avoidOverlap, extraCostOut);
            cover.addAll(subRegions);
            SuperReturnEdge rEdge = invocation.second();
            MiscUtils.incrementBy(extraCostOut, rEdge, getMissCost(rEdge), 0);
        }
    }
    return cover;
}
Also used : ContextCFG(com.jopdesign.common.code.SuperGraph.ContextCFG) ArrayList(java.util.ArrayList) SuperGraphEdge(com.jopdesign.common.code.SuperGraph.SuperGraphEdge) SuperReturnEdge(com.jopdesign.common.code.SuperGraph.SuperReturnEdge) Segment(com.jopdesign.common.code.Segment) HashSet(java.util.HashSet) SuperInvokeEdge(com.jopdesign.common.code.SuperGraph.SuperInvokeEdge)

Example 4 with ContextCFG

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

the class ObjectCacheAnalysis method contextForSegment.

/**
	 * XXX: temporary helper to bridge gap between two representations (segment and scope)
	 * @param segment
	 * @return the corresponding execution context
	 * @throws RuntimeException if the conversion is impossible
	 */
private ExecutionContext contextForSegment(Segment segment) {
    ContextCFG entry;
    Set<ContextCFG> entries = segment.getEntryCFGs();
    if (entries.size() != 1) {
        throw new RuntimeException("contextForSegment(): Currently we only support a single entry method");
    }
    entry = entries.iterator().next();
    return new ExecutionContext(entry.getCfg().getMethodInfo(), entry.getCallString());
}
Also used : ExecutionContext(com.jopdesign.common.code.ExecutionContext) ContextCFG(com.jopdesign.common.code.SuperGraph.ContextCFG)

Example 5 with ContextCFG

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

the class GlobalAnalysis method getLoopBounds.

/**
	 * <p>Get all loop bounds for the given segment.</p>
	 * <p>For each loop bound B for loop H relative to marker M:</p>
	 * <p>sum(M) * B &lt;= sum(continue-edges-of(H))</p>
     *
	 * @param segment
	 * @return
	 * @throws InvalidFlowFactException 
	 */
private static Iterable<LinearConstraint<SuperGraphEdge>> getLoopBounds(WCETTool wcetTool, Segment segment) throws InvalidFlowFactException {
    List<LinearConstraint<SuperGraphEdge>> constraints = new ArrayList<LinearConstraint<SuperGraphEdge>>();
    // For all CFG instances
    for (ContextCFG ccfg : segment.getCallGraphNodes()) {
        ControlFlowGraph cfg = ccfg.getCfg();
        // for all loops in the method
        LoopColoring<CFGNode, ControlFlowGraph.CFGEdge> loops = cfg.getLoopColoring();
        for (CFGNode hol : loops.getHeadOfLoops()) {
            LoopBound loopBound = wcetTool.getLoopBound(hol, ccfg.getContext().getCallString());
            if (loopBound == null) {
                throw new AppInfoError("No loop bound record for head of loop: " + hol + " : " + cfg.buildLoopBoundMap());
            }
            addLoopConstraints(constraints, segment, ccfg, hol, loops, loopBound);
        }
    }
    return constraints;
}
Also used : CFGNode(com.jopdesign.common.code.ControlFlowGraph.CFGNode) ContextCFG(com.jopdesign.common.code.SuperGraph.ContextCFG) LoopBound(com.jopdesign.common.code.LoopBound) ControlFlowGraph(com.jopdesign.common.code.ControlFlowGraph) ArrayList(java.util.ArrayList) SuperGraphEdge(com.jopdesign.common.code.SuperGraph.SuperGraphEdge) LinearConstraint(com.jopdesign.wcet.ipet.LinearConstraint) AppInfoError(com.jopdesign.common.misc.AppInfoError) CFGEdge(com.jopdesign.common.code.ControlFlowGraph.CFGEdge)

Aggregations

ContextCFG (com.jopdesign.common.code.SuperGraph.ContextCFG)10 SuperGraphEdge (com.jopdesign.common.code.SuperGraph.SuperGraphEdge)8 ArrayList (java.util.ArrayList)5 CFGNode (com.jopdesign.common.code.ControlFlowGraph.CFGNode)4 HashSet (java.util.HashSet)4 CFGEdge (com.jopdesign.common.code.ControlFlowGraph.CFGEdge)3 Segment (com.jopdesign.common.code.Segment)3 SuperInvokeEdge (com.jopdesign.common.code.SuperGraph.SuperInvokeEdge)3 MethodInfo (com.jopdesign.common.MethodInfo)2 ControlFlowGraph (com.jopdesign.common.code.ControlFlowGraph)2 SuperReturnEdge (com.jopdesign.common.code.SuperGraph.SuperReturnEdge)2 LinearConstraint (com.jopdesign.wcet.ipet.LinearConstraint)2 InstructionHandle (org.apache.bcel.generic.InstructionHandle)2 MONITORENTER (org.apache.bcel.generic.MONITORENTER)2 AppInfo (com.jopdesign.common.AppInfo)1 AppSetup (com.jopdesign.common.AppSetup)1 TestFramework (com.jopdesign.common.TestFramework)1 InvokeNode (com.jopdesign.common.code.ControlFlowGraph.InvokeNode)1 ExecutionContext (com.jopdesign.common.code.ExecutionContext)1 LoopBound (com.jopdesign.common.code.LoopBound)1