Search in sources :

Example 1 with SuperGraphEdge

use of com.jopdesign.common.code.SuperGraph.SuperGraphEdge 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) CFGEdge(com.jopdesign.common.code.ControlFlowGraph.CFGEdge) HashSet(java.util.HashSet) 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 2 with SuperGraphEdge

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

the class Segment method exportDOT.

/**
 * Export to DOT file
 * @param dotFile
 * @throws IOException
 */
public void exportDOT(File dotFile) throws IOException {
    FileWriter dotWriter = new FileWriter(dotFile);
    AdvancedDOTExporter.DOTNodeLabeller<SuperGraphNode> nodeLabeller = new AdvancedDOTExporter.DefaultNodeLabeller<SuperGraphNode>() {

        @Override
        public String getLabel(SuperGraphNode node) {
            StringBuilder sb = new StringBuilder();
            /* for entry nodes: method + call string */
            if (node.getCFGNode().getId() == 0) {
                sb.append(node.getContextCFG().getCfg().getMethodInfo().getFQMethodName() + "\n");
                int i = 1;
                for (InvokeSite is : node.getContextCFG().getCallString()) {
                    sb.append(" #" + i + " " + is.getInvoker().getFQMethodName() + " / " + is.getInstructionHandle().getPosition() + "\n");
                    i += 1;
                }
            } else /* for other nodes: basic block export */
            {
                sb.append(node.getCFGNode().toString());
            }
            return sb.toString();
        }
    };
    DOTLabeller<SuperGraphEdge> edgeLabeller = new AdvancedDOTExporter.DefaultDOTLabeller<SuperGraphEdge>() {

        @Override
        public String getLabel(SuperGraphEdge edge) {
            return "";
        }

        @Override
        public boolean setAttributes(SuperGraphEdge edge, Map<String, String> ht) {
            super.setAttributes(edge, ht);
            if (edge instanceof SuperReturnEdge) {
                ht.put("style", "dotted");
                ht.put("arrowhead", "empty");
            } else if (edge instanceof SuperInvokeEdge) {
                ht.put("style", "dotted");
            }
            return true;
        }
    };
    AdvancedDOTExporter<SuperGraphNode, SuperGraphEdge> de = new AdvancedDOTExporter<SuperGraphNode, SuperGraphEdge>(nodeLabeller, edgeLabeller);
    de.exportDOTDiGraph(dotWriter, this.getNodes(), this.getEdges(), new AdvancedDOTExporter.GraphAdapter<SuperGraphNode, SuperGraphEdge>() {

        @Override
        public SuperGraphNode getEdgeSource(SuperGraphEdge e) {
            return e.getSource();
        }

        @Override
        public SuperGraphNode getEdgeTarget(SuperGraphEdge e) {
            return e.getTarget();
        }
    });
    dotWriter.close();
}
Also used : FileWriter(java.io.FileWriter) SuperReturnEdge(com.jopdesign.common.code.SuperGraph.SuperReturnEdge) SuperInvokeEdge(com.jopdesign.common.code.SuperGraph.SuperInvokeEdge) AdvancedDOTExporter(com.jopdesign.common.graphutils.AdvancedDOTExporter) SuperGraphEdge(com.jopdesign.common.code.SuperGraph.SuperGraphEdge) SuperGraphNode(com.jopdesign.common.code.SuperGraph.SuperGraphNode) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with SuperGraphEdge

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

the class Segment method buildSegment.

/**
 * Collect all supergraph edges which are part of the segment.
 * As segments are allowed to be interprocedural, we require that
 * control flow graphs have return edges, and that return edges
 * are in the exit set if they are not part of the segment.
 */
private Set<SuperGraphEdge> buildSegment() {
    nodes = new HashMap<SuperGraph.ContextCFG, List<SuperGraphNode>>();
    edges = new HashSet<SuperGraphEdge>();
    otherEntries = new HashSet<SuperGraphEdge>();
    HashSet<SuperGraphEdge> actualExits = new HashSet<SuperGraphEdge>();
    Stack<SuperGraphEdge> worklist = new Stack<SuperGraphEdge>();
    /* push all targets of entry edges on the worklist */
    worklist.addAll(entries);
    while (!worklist.isEmpty()) {
        SuperGraphEdge current = worklist.pop();
        if (edges.contains(current))
            continue;
        /* continue if marked black */
        edges.add(current);
        /* If this is an exit egde, remember that it has been visited, and continue */
        if (exits.contains(current)) {
            actualExits.add(current);
            continue;
        }
        /* Otherwise add the target node and push all successors on the worklist */
        SuperGraphNode target = current.getTarget();
        MiscUtils.addToList(nodes, target.getContextCFG(), target);
        Iterators.addAll(worklist, sg.getSuccessorEdges(current));
    }
    exits = actualExits;
    for (SuperGraphNode node : getNodes()) {
        for (SuperGraphEdge edge : sg.incomingEdgesOf(node)) {
            if (!edges.contains(edge)) {
                otherEntries.add(edge);
            }
        }
    }
    /* for all nodes find entries which are not part of the segment; this are "otherEntries" */
    return edges;
}
Also used : ContextCFG(com.jopdesign.common.code.SuperGraph.ContextCFG) SuperGraphEdge(com.jopdesign.common.code.SuperGraph.SuperGraphEdge) SuperGraphNode(com.jopdesign.common.code.SuperGraph.SuperGraphNode) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet) Stack(java.util.Stack)

Example 4 with SuperGraphEdge

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

the class MethodCacheAnalysis method addMissOnceConstraints.

/**
 * Add miss once constraints for all subsegments in the persistence cover of the given segment
 * @param segment
 * @param ipetSolver
 * @return
 */
@Override
public Set<SuperGraphEdge> addMissOnceConstraints(Segment segment, IPETSolver<SuperGraphEdge> ipetSolver) {
    Set<SuperGraphEdge> missEdges = new HashSet<SuperGraphEdge>();
    Map<SuperGraphEdge, Long> extraCost = new HashMap<SuperGraphEdge, Long>();
    Collection<Segment> cover = findPersistenceSegmentCover(segment, EnumSet.allOf(PersistenceCheck.class), false, extraCost);
    int segmentCounter = 0;
    for (Segment persistenceSegment : cover) {
        /* we need to distinguish edges which are shared between persistence segments */
        String key = KEY + "_" + (++segmentCounter);
        missEdges.addAll(addPersistenceSegmentConstraints(persistenceSegment, getCacheAccessesByTag(persistenceSegment).entrySet(), ipetSolver, EDGE_MISS_COST, key));
    }
    for (Entry<SuperGraphEdge, Long> entry : extraCost.entrySet()) {
        missEdges.add(fixedAdditionalCostEdge(entry.getKey(), KEY + "_am", 0, entry.getValue(), ipetSolver));
    }
    return missEdges;
}
Also used : HashMap(java.util.HashMap) SuperGraphEdge(com.jopdesign.common.code.SuperGraph.SuperGraphEdge) CallString(com.jopdesign.common.code.CallString) Segment(com.jopdesign.common.code.Segment) HashSet(java.util.HashSet)

Example 5 with SuperGraphEdge

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

the class MethodCacheAnalysis method addMissOnceCost.

/**
 * Add miss once cost: for each method cache persistence segment, add maximum miss cost to the segment entries
 * @param segment
 * @param ipetSolver
 * @param peristenceChecks which checks to perform
 * @throws LpSolveException
 * @throws InvalidFlowFactException
 */
@Override
public Set<SuperGraphEdge> addMissOnceCost(Segment segment, IPETSolver<SuperGraphEdge> ipetSolver, EnumSet<PersistenceCheck> checks) throws InvalidFlowFactException, LpSolveException {
    Set<SuperGraphEdge> missEdges = new HashSet<SuperGraphEdge>();
    Map<SuperGraphEdge, Long> extraCost = new HashMap<SuperGraphEdge, Long>();
    Collection<Segment> cover = findPersistenceSegmentCover(segment, checks, true, extraCost);
    int tag = 0;
    for (Segment persistenceSegment : cover) {
        tag++;
        /* Collect all cache accesses */
        long cost = computeMissOnceCost(persistenceSegment, getCacheAccessesByTag(persistenceSegment).entrySet(), EDGE_MISS_COST, true, KEY + ".addMissOnceCost", wcetTool);
        F1<SuperGraphEdge, Long> costModel = MiscUtils.const1(cost);
        Set<SuperGraphEdge> costEdges = addFixedCostEdges(persistenceSegment.getEntryEdges(), ipetSolver, costModel, KEY + "_miss_once", tag);
        missEdges.addAll(costEdges);
    }
    for (Entry<SuperGraphEdge, Long> entry : extraCost.entrySet()) {
        missEdges.add(fixedAdditionalCostEdge(entry.getKey(), KEY + "_am", 0, entry.getValue(), ipetSolver));
    }
    return missEdges;
}
Also used : HashMap(java.util.HashMap) SuperGraphEdge(com.jopdesign.common.code.SuperGraph.SuperGraphEdge) Segment(com.jopdesign.common.code.Segment) HashSet(java.util.HashSet)

Aggregations

SuperGraphEdge (com.jopdesign.common.code.SuperGraph.SuperGraphEdge)25 HashSet (java.util.HashSet)12 ContextCFG (com.jopdesign.common.code.SuperGraph.ContextCFG)9 SuperGraphNode (com.jopdesign.common.code.SuperGraph.SuperGraphNode)8 ArrayList (java.util.ArrayList)8 Segment (com.jopdesign.common.code.Segment)7 HashMap (java.util.HashMap)7 CFGNode (com.jopdesign.common.code.ControlFlowGraph.CFGNode)5 SuperInvokeEdge (com.jopdesign.common.code.SuperGraph.SuperInvokeEdge)5 CallString (com.jopdesign.common.code.CallString)4 SuperReturnEdge (com.jopdesign.common.code.SuperGraph.SuperReturnEdge)4 CFGEdge (com.jopdesign.common.code.ControlFlowGraph.CFGEdge)3 AccessCostInfo (com.jopdesign.wcet.analysis.cache.ObjectCacheAnalysis.AccessCostInfo)3 LinearConstraint (com.jopdesign.wcet.ipet.LinearConstraint)3 InstructionHandle (org.apache.bcel.generic.InstructionHandle)3 SymbolicAddress (com.jopdesign.dfa.analyses.SymbolicAddress)2 IPETConfig (com.jopdesign.wcet.ipet.IPETConfig)2 ObjectCacheCost (com.jopdesign.wcet.jop.ObjectCache.ObjectCacheCost)2 File (java.io.File)2 FileWriter (java.io.FileWriter)2