use of com.jopdesign.common.code.ExecutionContext 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.ExecutionContext in project jop by jop-devel.
the class WCETEventHandler method loadLoopAnnotations.
/**
* load annotations for the flow graph.
*
* @param cfg the control flow graph of the method
* @throws BadAnnotationException if an annotations is missing
*/
public void loadLoopAnnotations(ControlFlowGraph cfg) throws BadAnnotationException {
SourceAnnotations wcaMap;
MethodInfo method = cfg.getMethodInfo();
MethodCode code = method.getCode();
ExecutionContext eCtx = new ExecutionContext(cfg.getMethodInfo());
for (CFGNode n : cfg.getLoopColoring().getHeadOfLoops()) {
BasicBlockNode headOfLoop = (BasicBlockNode) n;
BasicBlock block = headOfLoop.getBasicBlock();
// check if loopbound has already been loaded
if (block.getLoopBound() != null) {
// or at least check if the source-annotation is tighter than what is currently set?
continue;
}
Set<LoopBound> bounds = new HashSet<LoopBound>(2);
InstructionHandle first = block.getFirstInstruction();
InstructionHandle last = first;
ClassInfo sourceInfo = method.getCode().getSourceClassInfo(block.getFirstInstruction());
for (InstructionHandle ih : block.getInstructions()) {
ClassInfo cls = method.getCode().getSourceClassInfo(ih);
boolean isLast = ih.equals(block.getLastInstruction());
if (!cls.equals(sourceInfo) || isLast) {
try {
wcaMap = getAnnotations(method.getCode().getSourceClassInfo(block.getFirstInstruction()));
} catch (IOException e) {
throw new BadAnnotationException("IO Error reading annotation: " + e.getMessage(), e);
}
if (isLast) {
last = ih;
}
// search for loop annotation in range
int sourceRangeStart = code.getLineNumber(first);
int sourceRangeStop = code.getLineNumber(last);
bounds.addAll(wcaMap.annotationsForLineRange(sourceRangeStart, sourceRangeStop + 1));
first = ih;
}
last = ih;
}
if (bounds.size() > 1) {
String reason = "Ambiguous Annotation [" + bounds + "]";
throw new BadAnnotationException(reason, code, block);
}
LoopBound loopAnnot = null;
if (bounds.size() == 1) {
loopAnnot = bounds.iterator().next();
}
// if we have loop bounds from DFA analysis, use them
loopAnnot = dfaLoopBound(block, eCtx, loopAnnot);
if (loopAnnot == null) {
// Bit of a hack: if we load CFGs before the callgraph is constructed, this will log errors anyway
if (ignoreMissingLoopBounds) {
logger.trace("No loop bound annotation: " + method + ":" + n + " " + getLineRangeText(code, block) + ".\nApproximating with " + DEFAULT_LOOP_BOUND + ", but result is not safe anymore.");
} else if (project.getCallGraph() != null && !project.getCallGraph().containsMethod(method)) {
logger.debug("No loop bound annotation for non-WCET method: " + method + ":" + n + " " + getLineRangeText(code, block) + ".\nApproximating with " + DEFAULT_LOOP_BOUND);
} else {
logger.error("No loop bound annotation: " + method + ":" + n + " " + getLineRangeText(code, block) + ".\nApproximating with " + DEFAULT_LOOP_BOUND + ", but result is not safe anymore.");
}
loopAnnot = LoopBound.defaultBound(DEFAULT_LOOP_BOUND);
}
block.setLoopBound(loopAnnot);
}
}
use of com.jopdesign.common.code.ExecutionContext in project jop by jop-devel.
the class MethodCacheAnalysis method getMissCountChangeSet.
/**
* @param ecp exec count provider
* @return all methods for which the cache costs of the contained invoke sites changed, either due to classification
* changes or due to execution count changes.
*/
public Set<MethodInfo> getMissCountChangeSet(ExecFrequencyProvider ecp) {
if (analysisType == AnalysisType.ALWAYS_HIT)
return Collections.emptySet();
Set<MethodInfo> countChanges = new LinkedHashSet<MethodInfo>(classifyChanges);
// we check the exec analysis for changed exec counts,
// need to update change sets since cache miss counts changed for cache-misses
Set<MethodInfo> methods = ecp.getChangeSet();
if (analysisType == AnalysisType.ALWAYS_MISS) {
countChanges.addAll(methods);
return countChanges;
}
for (MethodInfo method : methods) {
if (!allFit(method)) {
countChanges.add(method);
}
}
if (analysisType == AnalysisType.ALL_FIT_REGIONS) {
for (MethodInfo method : ecp.getChangeSet()) {
if (!classifyChanges.contains(method)) {
continue;
}
// all methods for which the classification changed and for which the exe count changed..
for (ExecutionContext context : callGraph.getNodes(method)) {
// add all reachable methods
countChanges.addAll(reachableMethods.get(context));
}
}
}
return countChanges;
}
use of com.jopdesign.common.code.ExecutionContext 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;
}
use of com.jopdesign.common.code.ExecutionContext in project jop by jop-devel.
the class WCAInvoker method getExecFrequency.
public long getExecFrequency(MethodInfo method, CFGNode block) {
long flow = 0;
for (ExecutionContext node : wcetTool.getCallGraph().getNodes(method)) {
Long value = wcaNodeFlow.get(node).get(block);
flow += value;
}
return flow;
}
Aggregations