use of com.jopdesign.jcopter.analysis.StacksizeAnalysis in project jop by jop-devel.
the class GreedyOptimizer method optimizeMethods.
private void optimizeMethods(AnalysisManager analyses, ExecFrequencyProvider ecp, CandidateSelector selector, Set<MethodInfo> methods) {
Map<MethodInfo, MethodData> methodData = new LinkedHashMap<MethodInfo, MethodData>(methods.size());
selector.clear();
if (maxSteps > 0 && countOptimized >= maxSteps) {
return;
}
// first find and initialize all candidates
for (MethodInfo method : methods) {
if (method.isNative())
continue;
// to update maxLocals
method.getCode().compile();
StacksizeAnalysis stacksize = analyses.getStacksizeAnalysis(method);
int locals = method.getCode().getMaxLocals();
for (CodeOptimizer optimizer : optimizers) {
Collection<Candidate> found;
found = optimizer.findCandidates(method, analyses, stacksize, locals);
selector.addCandidates(method, found);
countCandidates += found.size();
}
methodData.put(method, new MethodData(locals));
}
// now use the RebateSelector to order the candidates
selector.sortCandidates(ecp);
Set<MethodInfo> optimizedMethods = new LinkedHashSet<MethodInfo>();
Set<MethodInfo> candidateChanges = new LinkedHashSet<MethodInfo>();
Collection<Candidate> candidates = selector.selectNextCandidates(ecp);
while (candidates != null) {
optimizedMethods.clear();
candidateChanges.clear();
analyses.clearChangeSets();
// perform optimization
for (Candidate c : candidates) {
MethodInfo method = c.getMethod();
StacksizeAnalysis stacksize = analyses.getStacksizeAnalysis(method);
logger.info("Optimizing " + c.toString());
if (!c.optimize(analyses, stacksize))
continue;
countOptimized++;
if (maxSteps > 0 && countOptimized >= maxSteps) {
return;
}
// to update maxStack and positions
method.getCode().compile();
// Now we need to update the stackAnalysis and find new candidates in the optimized code
List<Candidate> newCandidates = new ArrayList<Candidate>();
if (c.getStart() != null) {
stacksize.analyze(c.getStart(), c.getEnd());
int locals = c.getMaxLocalsInRegion();
// find new candidates in optimized code
for (CodeOptimizer optimizer : optimizers) {
Collection<Candidate> found;
found = optimizer.findCandidates(method, analyses, stacksize, locals, c.getStart(), c.getEnd());
newCandidates.addAll(found);
}
countCandidates += newCandidates.size();
}
// Notify selector to update codesize, remove unreachable methods and to replace
// old candidates with new ones
selector.onSuccessfulOptimize(c, newCandidates);
optimizedMethods.add(method);
}
// Now we need to find out for which methods we need to recalculate the candidates..
// First we add all optimized methods since we added new candidates and changed the codesize
candidateChanges.addAll(optimizedMethods);
// small shortcut if we optimize one method at a time. In this case we only have one method to update anyway
if (methods.size() > 1) {
// invokeSites, but well..
for (MethodInfo method : optimizedMethods) {
candidateChanges.addAll(appInfo.getCallGraph().getDirectInvokers(method));
}
// No need to add exec count changes, since candidates calculate values only per single execution,
// or is there? (cache miss count changes due to exec frequency changes are handled by the cache analysis)
// We need to find out for which invokeSites the cache-miss-*counts* (as used by
// Candidate#getDeltaCacheMissCosts()) of invoke and return changed, add to the changeset
candidateChanges.addAll(analyses.getMethodCacheAnalysis().getClassificationChangeSet());
}
// Now let the selector update its analyses and find out which additional methods need sorting
Set<MethodInfo> changeSet = selector.updateChangeSet(ecp, optimizedMethods, candidateChanges);
// but only for methods which we optimize.
for (MethodInfo method : candidateChanges) {
// skip methods in changeset which are not being optimized
if (!methodData.containsKey(method))
continue;
selector.updateCandidates(method, ecp, analyses.getStacksizeAnalysis(method));
}
// Finally use the set of methods for which something changed, and re-sort all candidates of those methods
if (methods.size() == 1) {
selector.sortCandidates(ecp, methods);
} else {
if (logger.isTraceEnabled()) {
logger.trace("Sort changes " + changeSet.size());
}
selector.sortCandidates(ecp, changeSet);
}
// Finally, select the next candidates
candidates = selector.selectNextCandidates(ecp);
}
}
Aggregations