Search in sources :

Example 1 with CFGNode

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

the class JavaOneProcessPerMethodTranslator method recordLoops.

private void recordLoops(MethodInfo mi, TemplateBuilder pb) {
    ControlFlowGraph cfg = project.getFlowGraph(mi);
    for (CFGNode hol : cfg.getLoopColoring().getHeadOfLoops()) {
        LoopBound bound = hol.getLoopBound();
        int nesting = cfg.getLoopColoring().getLoopColor(hol).size();
        pb.addLoop(hol, nesting, bound);
    }
}
Also used : CFGNode(com.jopdesign.common.code.ControlFlowGraph.CFGNode) LoopBound(com.jopdesign.common.code.LoopBound) ControlFlowGraph(com.jopdesign.common.code.ControlFlowGraph)

Example 2 with CFGNode

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

the class WCAInvoker method updateWCEP.

private void updateWCEP() {
    if (!provideWCAExecCount)
        return;
    execCounts.clear();
    for (MethodInfo root : getWcaTargets()) {
        execCounts.put(root, 1L);
    }
    NodeVisitor<ExecutionContext> visitor = new NodeVisitor<ExecutionContext>() {

        @Override
        public boolean visitNode(ExecutionContext context) {
            MethodInfo method = context.getMethodInfo();
            MethodCode code = method.getCode();
            long ec = getExecCount(method);
            // skip methods which are not on the WCET path.. we can ship iterating over the childs too..
            if (ec == 0)
                return false;
            // iterate over all blocks in the CFG, find all invokes and add block execution counts to invokees
            ControlFlowGraph cfg = method.getCode().getControlFlowGraph(false);
            for (CFGNode node : cfg.getGraph().vertexSet()) {
                if (node instanceof InvokeNode) {
                    InvokeNode inv = (InvokeNode) node;
                    long ef = getExecFrequency(method, node);
                    for (MethodInfo invokee : inv.getImplementingMethods()) {
                        addExecCount(invokee, ec * ef);
                    }
                } else if (node instanceof BasicBlockNode) {
                    // check if we have a JVM invoke here (or an invoke not in a dedicated node..)
                    for (InstructionHandle ih : node.getBasicBlock().getInstructions()) {
                        if (!code.isInvokeSite(ih))
                            continue;
                        long ef = getExecFrequency(method, node);
                        for (MethodInfo invokee : method.getAppInfo().findImplementations(code.getInvokeSite(ih))) {
                            addExecCount(invokee, ec * ef);
                        }
                    }
                }
            }
            return true;
        }
    };
    TopologicalTraverser<ExecutionContext, ContextEdge> topOrder = new TopologicalTraverser<ExecutionContext, ContextEdge>(wcetTool.getCallGraph().getGraph(), visitor);
    topOrder.traverse();
}
Also used : CFGNode(com.jopdesign.common.code.ControlFlowGraph.CFGNode) BasicBlockNode(com.jopdesign.common.code.ControlFlowGraph.BasicBlockNode) ContextEdge(com.jopdesign.common.code.CallGraph.ContextEdge) InstructionHandle(org.apache.bcel.generic.InstructionHandle) NodeVisitor(com.jopdesign.common.graphutils.NodeVisitor) ExecutionContext(com.jopdesign.common.code.ExecutionContext) ControlFlowGraph(com.jopdesign.common.code.ControlFlowGraph) InvokeNode(com.jopdesign.common.code.ControlFlowGraph.InvokeNode) TopologicalTraverser(com.jopdesign.common.graphutils.TopologicalTraverser) MethodInfo(com.jopdesign.common.MethodInfo) MethodCode(com.jopdesign.common.MethodCode)

Example 3 with CFGNode

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

the class ExecFrequencyAnalysis method getExecFrequency.

public long getExecFrequency(ExecutionContext context, InstructionHandle ih) {
    MethodInfo method = context.getMethodInfo();
    // By loading the CFG, loopbounds are attached to the blocks if the WCA tool is loaded
    ControlFlowGraph cfg = method.getCode().getControlFlowGraph(false);
    LoopColoring<CFGNode, CFGEdge> lc = cfg.getLoopColoring();
    BasicBlockNode node = cfg.getHandleNode(ih, true);
    if (node == null) {
        // THIS IS UNSAFE! but what can you do ...
        return 1;
    }
    long ef = 1;
    for (CFGNode hol : lc.getLoopColor(node)) {
        LoopBound lb = hol.getLoopBound();
        if (lb != null) {
            if (lb.isDefaultBound() && !analyses.isWCAMethod(method)) {
                ef *= DEFAULT_ACET_LOOP_BOUND;
            } else {
                ef *= lb.getUpperBound(context);
            }
        } else {
            ef *= DEFAULT_ACET_LOOP_BOUND;
        }
    }
    return ef;
}
Also used : CFGNode(com.jopdesign.common.code.ControlFlowGraph.CFGNode) BasicBlockNode(com.jopdesign.common.code.ControlFlowGraph.BasicBlockNode) LoopBound(com.jopdesign.common.code.LoopBound) ControlFlowGraph(com.jopdesign.common.code.ControlFlowGraph) MethodInfo(com.jopdesign.common.MethodInfo) CFGEdge(com.jopdesign.common.code.ControlFlowGraph.CFGEdge)

Example 4 with CFGNode

use of com.jopdesign.common.code.ControlFlowGraph.CFGNode 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 5 with CFGNode

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

the class SuperGraph method incomingEdgesOf.

/**
	 * The incoming edges are generated as follows:
	 * <ul>
	 * <li/>return node: superedge returning to the caller
	 * <li/>entry  node: superedge invoking the node's method
	 * <li/>other:       intraprocedural CFG edge
	 * </ul>
	 * @param node
	 * @return
	 */
public Iterable<SuperGraphEdge> incomingEdgesOf(SuperGraphNode node) {
    CFGNode cfgNode = node.getCFGNode();
    if (cfgNode instanceof ReturnNode) {
        /* return node: incoming edges are callgraph return edges */
        final ReturnNode retNode = (ReturnNode) cfgNode;
        Set<SuperEdge> cgReturnEdges = superGraph.incomingEdgesOf(node.getContextCFG());
        return new Filter<SuperGraphEdge>() {

            @Override
            protected boolean include(SuperGraphEdge e) {
                if (!(e instanceof SuperReturnEdge))
                    return false;
                SuperReturnEdge retEdge = (SuperReturnEdge) e;
                return retEdge.getReturnNode().equals(retNode);
            }
        }.<SuperGraphEdge>filter(cgReturnEdges);
    } else if (cfgNode instanceof VirtualNode && ((VirtualNode) cfgNode).getKind() == VirtualNodeKind.ENTRY) {
        /* entry  node: superedge invoking the node's method */
        Set<SuperEdge> cgInvokeEdges = superGraph.incomingEdgesOf(node.getContextCFG());
        return new Filter<SuperGraphEdge>() {

            @Override
            protected boolean include(SuperGraphEdge e) {
                return (e instanceof SuperInvokeEdge);
            }
        }.<SuperGraphEdge>filter(cgInvokeEdges);
    } else {
        /* standard edges: incoming edges of cfg node */
        return liftCFGEdges(node.getContextCFG(), node.getContextCFG().getCfg().incomingEdgesOf(cfgNode));
    }
}
Also used : ReturnNode(com.jopdesign.common.code.ControlFlowGraph.ReturnNode) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) CFGNode(com.jopdesign.common.code.ControlFlowGraph.CFGNode) Filter(com.jopdesign.common.misc.Filter) VirtualNode(com.jopdesign.common.code.ControlFlowGraph.VirtualNode)

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