use of com.jopdesign.common.code.CallGraph.ContextEdge in project jop by jop-devel.
the class ExecuteOnceAnalysis method analyze.
private void analyze() {
inLoopSet = new HashMap<ExecutionContext, Set<MethodInfo>>();
/* Top Down the Scope Graph */
TopologicalOrderIterator<ExecutionContext, ContextEdge> iter = project.getCallGraph().topDownIterator();
while (iter.hasNext()) {
ExecutionContext scope = iter.next();
scope = new ExecutionContext(scope.getMethodInfo());
/* Remove call string */
ControlFlowGraph cfg = project.getFlowGraph(scope.getMethodInfo());
Set<MethodInfo> inLoop = new HashSet<MethodInfo>();
for (CFGNode node : cfg.vertexSet()) {
if (!(node instanceof ControlFlowGraph.InvokeNode))
continue;
ControlFlowGraph.InvokeNode iNode = (ControlFlowGraph.InvokeNode) node;
if (!cfg.getLoopColoring().getLoopColor(node).isEmpty()) {
for (MethodInfo impl : iNode.getImplementingMethods()) {
inLoop.add(impl);
inLoop.addAll(project.getCallGraph().getReachableImplementationsSet(impl));
}
}
}
inLoopSet.put(scope, inLoop);
}
}
use of com.jopdesign.common.code.CallGraph.ContextEdge in project jop by jop-devel.
the class WCETAnalysis method exploreCacheAnalysis.
/**
* @param mca
* @param iter
* @throws InvalidFlowFactException
*/
@SuppressWarnings("unused")
private void exploreCacheAnalysis() throws InvalidFlowFactException {
// Segment Cache Analysis: Experiments
MethodCacheAnalysis mca = new MethodCacheAnalysis(wcetTool);
/* iterate top down the scope graph (currently: the call graph) */
TopologicalOrderIterator<ExecutionContext, ContextEdge> iter = wcetTool.getCallGraph().reverseTopologicalOrder();
LpSolveWrapper.resetSolverTime();
long blocks = 0;
long start = System.nanoTime();
while (iter.hasNext()) {
ExecutionContext scope = iter.next();
Segment segment = Segment.methodSegment(scope.getMethodInfo(), scope.getCallString(), wcetTool, wcetTool.getCallstringLength(), wcetTool);
int availBlocks = wcetTool.getWCETProcessorModel().getMethodCache().getNumBlocks();
long total, distinctApprox = -1, distinct = -1;
blocks = total = mca.countDistinctBlocksUsed(segment);
if (total > availBlocks || true) {
try {
blocks = distinctApprox = mca.countDistinctBlocksAccessed(segment, false);
if (blocks > availBlocks && blocks < availBlocks * 2 || true) {
blocks = distinct = mca.countDistinctBlocksAccessed(segment, true);
}
} catch (LpSolveException e) {
System.err.println((distinctApprox >= 0 ? "I" : "Relaxed ") + "LP Problem too difficult, giving up: " + e);
}
}
System.out.println(String.format("block-count < %2d [%2d,%2d,%2d] for %-30s @ %s", blocks, total, distinctApprox, distinct, scope.getMethodInfo().getFQMethodName(), scope.getCallString().toStringVerbose(false)));
}
long stop = System.nanoTime();
reportSpecial("block-count", WcetCost.totalCost(blocks), start, stop, LpSolveWrapper.getSolverTime());
System.out.println("solver-time: " + LpSolveWrapper.getSolverTime());
}
use of com.jopdesign.common.code.CallGraph.ContextEdge in project jop by jop-devel.
the class ExecFrequencyAnalysis method inline.
/**
* Update the execution frequencies after inlining.
* This must be called after the underlying callgraph has been updated!
*
* @param invokeSite the inlined invokesite.
* @param invokee the inlined method.
* @param newInvokeSites the set of new invokesites in the invoker
*/
public void inline(InvokeSite invokeSite, MethodInfo invokee, Set<InvokeSite> newInvokeSites) {
List<ExecutionContext> queue = new ArrayList<ExecutionContext>();
for (ExecutionContext context : callGraph.getNodes(invokeSite.getInvoker())) {
for (ExecutionContext child : callGraph.getChildren(context)) {
if (child.getCallString().isEmpty() && child.getMethodInfo().equals(invokee)) {
// there can be at most one such node in the graph.. remove the total exec count of the
// inlined invokesite
nodeCount.put(child, nodeCount.get(child) - getExecCount(invokeSite, invokee));
} else if (!child.getCallString().isEmpty() && newInvokeSites.contains(child.getCallString().top())) {
// This is a new node, sum up the execution counts of all invokesite instances
addExecCount(child, getExecCount(context, child.getCallString().top().getInstructionHandle()));
queue.add(child);
}
}
}
// update exec frequencies for all new nodes. A node is new if it contains one of the new invoke sites
// We do not need to remove exec frequencies, since all nodes containing the old invokesite are now no
// longer in the callgraph. We could however remove those nodes from our data structures in a
// separate step before the callgraph is updated.
// To do this, we create a temporary subgraph containing all new nodes and no back edges, and then traverse
// it in topological order
// TODO if the callgraph is compressed, we need to look down up to callstringLength for new nodes!
DirectedGraph<ExecutionContext, ContextEdge> dag = GraphUtils.copyGraph(new InlineEdgeProvider(newInvokeSites), callGraph.getEdgeFactory(), queue, false);
updateExecCounts(dag);
// Despite all that is going on, the only *method* for which something changes in total is the inlined invokee
changeSet.add(invokee);
}
use of com.jopdesign.common.code.CallGraph.ContextEdge in project jop by jop-devel.
the class MethodCacheAnalysis method findClassificationChanges.
private Set<MethodInfo> findClassificationChanges(MethodInfo method, final int deltaBlocks, Collection<MethodInfo> removed, final boolean update) {
if (analysisType == AnalysisType.ALWAYS_HIT || analysisType == AnalysisType.ALWAYS_MISS || (deltaBlocks == 0 && removed.isEmpty())) {
return Collections.emptySet();
}
Set<ExecutionContext> roots = callGraph.getNodes(method);
// First, go up and find all nodes where one or more methods need to be removed from the reachable methods set
final Map<ExecutionContext, Set<MethodInfo>> removeMethods = findRemovedMethods(roots, removed);
// next, calculate blocks of removed methods
final Map<MethodInfo, Integer> blocks = new LinkedHashMap<MethodInfo, Integer>(removed.size());
for (MethodInfo m : removed) {
int size = MiscUtils.bytesToWords(getMethodSize(m));
blocks.put(m, cache.requiredNumberOfBlocks(size));
}
// finally, go up all invokers, sum up reachable method set changes and deltaBlocks per node, check all-fit
final Set<MethodInfo> changeSet = new LinkedHashSet<MethodInfo>();
DFSVisitor<ExecutionContext, ContextEdge> visitor = new EmptyDFSVisitor<ExecutionContext, ContextEdge>() {
@Override
public void preorder(ExecutionContext node) {
Set<MethodInfo> remove = removeMethods.get(node);
int oldBlocks = cacheBlocks.get(node);
int newBlocks = oldBlocks;
if (remove != null) {
if (update) {
reachableMethods.get(node).removeAll(remove);
}
for (MethodInfo r : remove) {
newBlocks -= blocks.get(r);
}
}
newBlocks += deltaBlocks;
if (update) {
cacheBlocks.put(node, newBlocks);
}
boolean oldFit = cache.allFit(oldBlocks);
boolean newFit = cache.allFit(newBlocks);
if (oldFit != newFit) {
changeSet.add(node.getMethodInfo());
if (update) {
classifyChanges.add(node.getMethodInfo());
}
}
}
};
DFSTraverser<ExecutionContext, ContextEdge> traverser = new DFSTraverser<ExecutionContext, ContextEdge>(visitor);
traverser.traverse(callGraph.getReversedGraph(), roots);
return changeSet;
}
use of com.jopdesign.common.code.CallGraph.ContextEdge in project jop by jop-devel.
the class WCAInvoker method runAnalysis.
///////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////
private Set<MethodInfo> runAnalysis(DirectedGraph<ExecutionContext, ContextEdge> reversed) {
// Phew. The WCA only runs on acyclic callgraphs, we can therefore assume the
// reversed graph to be a DAG
TopologicalOrderIterator<ExecutionContext, ContextEdge> topOrder = new TopologicalOrderIterator<ExecutionContext, ContextEdge>(reversed);
Set<MethodInfo> changed = new LinkedHashSet<MethodInfo>();
while (topOrder.hasNext()) {
ExecutionContext node = topOrder.next();
// At times like this I really wish Java would have type aliases ..
RecursiveWcetAnalysis<AnalysisContextLocal>.LocalWCETSolution<AnalysisContextLocal> sol = recursiveAnalysis.computeSolution(node.getMethodInfo(), new AnalysisContextLocal(cacheApproximation, node.getCallString()));
wcaNodeFlow.put(node, sol.getNodeFlowVirtual());
// TODO some logging would be nice, keep target-method WCET for comparison of speedup
if (node.getMethodInfo().equals(wcetTool.getTargetMethod())) {
lastWCET = sol.getCost().getCost();
logger.info("WCET: " + lastWCET);
}
changed.add(node.getMethodInfo());
}
return changed;
}
Aggregations