Search in sources :

Example 1 with ExecutionContext

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

the class MethodBuilder method visitInvokeNode.

public void visitInvokeNode(ControlFlowGraph.InvokeNode n) {
    ExecutionContext ctx = new ExecutionContext(n.getBasicBlock().getMethodInfo());
    MethodCacheAnalysis mca = new MethodCacheAnalysis(jTrans.getProject());
    WCETProcessorModel proc = jTrans.getProject().getWCETProcessorModel();
    SubAutomaton invokeAuto;
    long staticWCET = proc.basicBlockWCET(ctx, n.getBasicBlock());
    if (jTrans.getCacheSim().isAlwaysMiss()) {
        staticWCET += mca.getInvokeReturnMissCost(n.getInvokeSite(), CallString.EMPTY);
    }
    invokeAuto = invokeBuilder.translateInvoke(this, n, staticWCET);
    this.nodeTemplates.put(n, invokeAuto);
}
Also used : ExecutionContext(com.jopdesign.common.code.ExecutionContext) WCETProcessorModel(com.jopdesign.wcet.WCETProcessorModel) MethodCacheAnalysis(com.jopdesign.wcet.analysis.cache.MethodCacheAnalysis)

Example 2 with ExecutionContext

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

the class RebateSelector method initialize.

@Override
public void initialize(GreedyConfig config, boolean dumpStats) {
    // calculate current global codesize
    globalCodesize = 0;
    if (usesCodeRemover) {
        for (MethodInfo method : AppInfo.getSingleton().getCallGraph().getMethodInfos()) {
            if (!method.hasCode())
                continue;
            globalCodesize += method.getCode().getNumberOfBytes();
        }
    } else {
        for (ClassInfo cls : AppInfo.getSingleton().getClassInfos()) {
            for (MethodInfo method : cls.getMethods()) {
                if (!method.hasCode())
                    continue;
                globalCodesize += method.getCode().getNumberOfBytes();
            }
        }
    }
    // we need a tie-breaker for the candidate selection, and to make the results deterministic
    // so we use a topological order of the (initial) callgraph
    DFSVisitor<ExecutionContext, ContextEdge> visitor = new EmptyDFSVisitor<ExecutionContext, ContextEdge>() {

        private int counter = 1;

        @Override
        public void postorder(ExecutionContext node) {
            depthMap.put(node.getMethodInfo(), counter++);
        }
    };
    DirectedGraph<ExecutionContext, ContextEdge> graph = analyses.getTargetCallGraph().getReversedGraph();
    DFSTraverser<ExecutionContext, ContextEdge> traverser = new DFSTraverser<ExecutionContext, ContextEdge>(visitor);
    traverser.traverse(graph);
    logger.info("Initial codesize: " + globalCodesize + " bytes");
    if (config.doDumpStats() && dumpStats) {
        try {
            File statsFile = config.getStatsFile();
            dump = new PrintWriter(statsFile);
            dump.print("total codesize, ");
            if (analyses.useWCAInvoker())
                dump.print("WCET, ");
            dump.println("candidate, ratio, gain, local gain, cache, local cache, delta codesize, frequency");
        } catch (FileNotFoundException e) {
            throw new AppInfoError("Could not initialize dump file", e);
        }
    }
}
Also used : FileNotFoundException(java.io.FileNotFoundException) EmptyDFSVisitor(com.jopdesign.common.graphutils.DFSTraverser.EmptyDFSVisitor) ContextEdge(com.jopdesign.common.code.CallGraph.ContextEdge) AppInfoError(com.jopdesign.common.misc.AppInfoError) DFSTraverser(com.jopdesign.common.graphutils.DFSTraverser) ExecutionContext(com.jopdesign.common.code.ExecutionContext) MethodInfo(com.jopdesign.common.MethodInfo) File(java.io.File) ClassInfo(com.jopdesign.common.ClassInfo) PrintWriter(java.io.PrintWriter)

Example 3 with ExecutionContext

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

the class MethodCacheAnalysis method findRemovedMethods.

private Map<ExecutionContext, Set<MethodInfo>> findRemovedMethods(Set<ExecutionContext> roots, Collection<MethodInfo> removed) {
    Map<ExecutionContext, Set<MethodInfo>> removeMethods = new LinkedHashMap<ExecutionContext, Set<MethodInfo>>();
    LinkedHashSet<ExecutionContext> queue = new LinkedHashSet<ExecutionContext>(roots);
    while (!queue.isEmpty()) {
        ExecutionContext node = queue.iterator().next();
        queue.remove(node);
        boolean changed = false;
        boolean isRoot = roots.contains(node);
        boolean isNew = false;
        // we initialize (lazily) by assuming that all removed methods are no longer reachable in any node,
        // and then removing entries from the set if they are found to be still reachable.
        // This ensures that the size of the sets only decreases and we eventually reach a fixpoint
        Set<MethodInfo> set = removeMethods.get(node);
        if (set == null) {
            set = new LinkedHashSet<MethodInfo>(removed.size());
            removeMethods.put(node, set);
            for (MethodInfo m : removed) {
                // initially add method to remove set if it is reachable from this node
                if (reachableMethods.get(node).contains(m)) {
                    set.add(m);
                }
            }
            changed = true;
            isNew = true;
        }
        // be removed from this node
        for (MethodInfo r : removed) {
            // already removed
            if (!set.contains(r))
                continue;
            for (ExecutionContext child : callGraph.getChildren(node)) {
                // we ignore native methods in the cache analysis
                if (child.getMethodInfo().isNative())
                    continue;
                // skip childs which will be removed
                if (isRoot && removed.contains(child.getMethodInfo()))
                    continue;
                // TODO this is incorrect for cyclic call graphs.. need to fix this!
                if (reachableMethods.get(child).contains(r)) {
                    set.remove(r);
                    changed = true;
                }
            }
        }
        if (isNew && set.isEmpty()) {
            // we did not remove anything here and we did not visit the parents yet, so nothing changes
            changed = false;
        }
        if (changed) {
            // we have found more methods, need to update parents
            queue.addAll(callGraph.getParents(node));
        }
    }
    return removeMethods;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ExecutionContext(com.jopdesign.common.code.ExecutionContext) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) MethodInfo(com.jopdesign.common.MethodInfo) LinkedHashMap(java.util.LinkedHashMap)

Example 4 with ExecutionContext

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

the class MethodCacheAnalysis method updateNodes.

private void updateNodes(SimpleDirectedGraph<ExecutionContext, ContextEdge> closure, Set<ExecutionContext> nodes, boolean reuseResults) {
    for (ExecutionContext node : nodes) {
        if (node.getMethodInfo().isNative())
            continue;
        // We could make this more memory efficient, because in many cases we do not need a
        // separate set for each node, but this would be more complicated to calculate
        Set<MethodInfo> reachable = new LinkedHashSet<MethodInfo>();
        reachable.add(node.getMethodInfo());
        // we only need to add all children to the set, no need to go down the graph
        for (ContextEdge edge : closure.outgoingEdgesOf(node)) {
            ExecutionContext target = edge.getTarget();
            if (target.getMethodInfo().isNative())
                continue;
            if (reuseResults && !nodes.contains(target)) {
                reachable.addAll(reachableMethods.get(target));
            } else {
                reachable.add(target.getMethodInfo());
            }
        }
        reachableMethods.put(node, reachable);
    }
    MethodCache cache = jcopter.getMethodCache();
    // now we can sum up the cache blocks for all nodes in the graph
    for (ExecutionContext node : nodes) {
        if (node.getMethodInfo().isNative())
            continue;
        Set<MethodInfo> reachable = reachableMethods.get(node);
        int blocks = 0;
        for (MethodInfo method : reachable) {
            int size = MiscUtils.bytesToWords(getMethodSize(method));
            blocks += cache.requiredNumberOfBlocks(size);
        }
        cacheBlocks.put(node, blocks);
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ExecutionContext(com.jopdesign.common.code.ExecutionContext) MethodCache(com.jopdesign.wcet.jop.MethodCache) MethodInfo(com.jopdesign.common.MethodInfo) ContextEdge(com.jopdesign.common.code.CallGraph.ContextEdge)

Example 5 with ExecutionContext

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

the class MethodCacheAnalysis method inline.

public void inline(CodeModification modification, InvokeSite invokeSite, MethodInfo invokee) {
    if (analysisType == AnalysisType.ALWAYS_HIT || analysisType == AnalysisType.ALWAYS_MISS)
        return;
    Set<ExecutionContext> nodes = new LinkedHashSet<ExecutionContext>();
    // We need to go down first, find all new nodes
    MethodInfo invoker = invokeSite.getInvoker();
    LinkedList<ExecutionContext> queue = new LinkedList<ExecutionContext>(callGraph.getNodes(invoker));
    // TODO if the callgraph is compressed, we need to go down all callstring-length long paths
    while (!queue.isEmpty()) {
        ExecutionContext node = queue.remove();
        for (ExecutionContext child : callGraph.getChildren(node)) {
            if (!cacheBlocks.containsKey(child) && !nodes.contains(child)) {
                nodes.add(child);
                queue.add(child);
            }
        }
    }
    // update reachable set and codesize for all new nodes
    updateNewNodes(nodes);
    // To get the old size, use any execution node ..
    ExecutionContext node = callGraph.getNodes(invoker).iterator().next();
    // this includes all reachable methods, so we need to subtract them
    int oldBlocks = cacheBlocks.get(node);
    for (MethodInfo m : reachableMethods.get(node)) {
        int size = MiscUtils.bytesToWords(getMethodSize(m));
        oldBlocks -= cache.requiredNumberOfBlocks(size);
    }
    int size = MiscUtils.bytesToWords(getMethodSize(invoker));
    int newBlocks = cache.requiredNumberOfBlocks(size);
    // not using CodeModification codesize delta because it might be an estimation
    int deltaBlocks = newBlocks - oldBlocks;
    // now go up from the modified method, remove invokee from reachable sets if last invoke was inlined
    // and update block counts
    findClassificationChanges(invoker, deltaBlocks, modification.getRemovedInvokees(), true);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ExecutionContext(com.jopdesign.common.code.ExecutionContext) MethodInfo(com.jopdesign.common.MethodInfo) LinkedList(java.util.LinkedList)

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