use of com.jopdesign.common.ClassInfo in project jop by jop-devel.
the class TypeGraph method getSupertypeSets.
/**
* Compute, for each type, the set of subtypes, using a single
* top-down traversal
* @return
*/
public Map<ClassInfo, Set<ClassInfo>> getSupertypeSets() {
Map<ClassInfo, Set<ClassInfo>> supertypeMap = new HashMap<ClassInfo, Set<ClassInfo>>();
for (ClassInfo v : topDownTraversal()) {
Set<ClassInfo> supertypes = new HashSet<ClassInfo>();
for (DefaultEdge parentEdge : incomingEdgesOf(v)) {
ClassInfo supertype = getEdgeSource(parentEdge);
supertypes.addAll(supertypeMap.get(supertype));
supertypes.add(supertype);
}
supertypeMap.put(v, supertypes);
}
return supertypeMap;
}
use of com.jopdesign.common.ClassInfo in project jop by jop-devel.
the class TypeGraph method exportDOT.
/**
* Write the type graph in DOT format.
* @param w
* @param classFilter If non-null, only classes matching this prefix will be exported
* @throws IOException
*/
public void exportDOT(Writer w, String classFilter) throws IOException {
Set<ClassInfo> subset = null;
if (classFilter != null) {
subset = new HashSet<ClassInfo>();
subset.add(this.rootNode);
for (ClassInfo ci : this.vertexSet()) {
if (ci.getClassName().startsWith(classFilter)) {
while (ci.getSuperClassInfo() != null) {
subset.add(ci);
ci = ci.getSuperClassInfo();
}
}
}
}
Subgraph<ClassInfo, DefaultEdge, TypeGraph> subgraph = new Subgraph<ClassInfo, DefaultEdge, TypeGraph>(this, subset);
AdvancedDOTExporter<ClassInfo, DefaultEdge> exporter = new AdvancedDOTExporter<ClassInfo, DefaultEdge>(new TgNodeLabeller(), null);
exporter.exportDOTDiGraph(w, subgraph);
}
use of com.jopdesign.common.ClassInfo 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.ClassInfo in project jop by jop-devel.
the class RecursiveWcetAnalysis method updateClassReport.
/**
* Update class report (cost per line number)
*
* @param key
* @param sol FIXME: Currently only reported once per method
*/
private void updateClassReport(CacheKey key, LocalWCETSolution sol) {
MethodInfo m = key.m;
if (costsPerLineReported.contains(m))
return;
costsPerLineReported.add(m);
Map<CFGNode, WcetCost> nodeCosts = sol.getNodeCostMap();
HashMap<CFGNode, String> nodeFlowCostDescrs = new HashMap<CFGNode, String>();
// for autogenerated code
long anonymousCost = 0;
for (Entry<CFGNode, WcetCost> entry : nodeCosts.entrySet()) {
CFGNode n = entry.getKey();
WcetCost cost = entry.getValue();
if (sol.getNodeFlow(n) > 0) {
nodeFlowCostDescrs.put(n, cost.toString());
BasicBlock basicBlock = n.getBasicBlock();
/* prototyping */
if (basicBlock != null) {
Map<ClassInfo, TreeSet<Integer>> lineMap = basicBlock.getSourceLines();
if (lineMap.isEmpty()) {
logger.error("No source code lines associated with basic block " + basicBlock + " in " + m + " ! ");
continue;
}
// we attach to the first class in the map only
ClassInfo cli = lineMap.keySet().iterator().next();
TreeSet<Integer> lineRange = lineMap.get(cli);
ClassReport cr = getWCETTool().getReport().getClassReport(cli);
long newCost = sol.getNodeFlow(n) * nodeCosts.get(n).getCost();
// Autogenerated code, attach to next entry
if (lineRange.isEmpty()) {
anonymousCost += newCost;
continue;
} else {
newCost += anonymousCost;
anonymousCost = 0;
}
Long oldCost = (Long) cr.getLineProperty(lineRange.first(), "cost");
if (oldCost == null)
oldCost = 0L;
if (logger.isTraceEnabled()) {
logger.trace("Attaching cost " + oldCost + " + " + newCost + " to line " + lineRange.first() + " in " + basicBlock.getMethodInfo());
}
cr.addLineProperty(lineRange.first(), "cost", oldCost + newCost);
for (int i : lineRange) {
cr.addLineProperty(i, "color", "red");
}
}
} else {
nodeFlowCostDescrs.put(n, "" + nodeCosts.get(n).getCost());
}
}
}
use of com.jopdesign.common.ClassInfo in project jop by jop-devel.
the class AbstractOptimizer method optimize.
public void optimize() {
initialize();
if (appInfo.hasCallGraph()) {
Collection<MethodInfo> methods = appInfo.getCallGraph().getMethodInfos();
if (iterateSorted) {
// little hack to make the DFA cache hack more deterministic
TreeMap<String, MethodInfo> temp = new TreeMap<String, MethodInfo>();
for (MethodInfo method : methods) {
temp.put(method.getFQMethodName(), method);
}
methods = temp.values();
}
for (MethodInfo method : methods) {
if (appInfo.isHwObject(method.getClassInfo())) {
// Do not optimize Hardware Objects, leave them alone!
continue;
}
if (method.hasCode()) {
optimizeMethod(method);
}
}
} else {
if (iterateSorted) {
TreeMap<String, ClassInfo> temp = new TreeMap<String, ClassInfo>();
for (ClassInfo cls : appInfo.getClassInfos()) {
temp.put(cls.getClassName(), cls);
}
for (ClassInfo cls : temp.values()) {
visitClass(cls);
}
} else {
appInfo.iterate(this);
}
}
printStatistics();
}
Aggregations