use of com.jopdesign.common.MethodInfo 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();
}
use of com.jopdesign.common.MethodInfo 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);
}
}
use of com.jopdesign.common.MethodInfo in project jop by jop-devel.
the class RebateSelector method sortCandidates.
@Override
public void sortCandidates(ExecFrequencyProvider ecp, Set<MethodInfo> changedMethods) {
for (MethodInfo method : changedMethods) {
MethodData data = methodData.get(method);
// changed methods which are not optimized or not reachable anymore are skipped
if (data == null)
continue;
// remove candidates of methods which are no longer reachable
if (!analyses.getTargetCallGraph().containsMethod(method)) {
removeCandidates(method);
continue;
}
sortMethodData(ecp, data);
}
}
use of com.jopdesign.common.MethodInfo in project jop by jop-devel.
the class DFATool method getReceiverMethods.
public Set<MethodInfo> getReceiverMethods(InstructionHandle stmt, CallString cs) {
Set<String> receivers = getReceivers(stmt, cs);
Set<MethodInfo> methods = new LinkedHashSet<MethodInfo>(receivers.size());
for (String rcv : receivers) {
MemberID mID = MemberID.parse(rcv);
methods.add(appInfo.getMethodInfoInherited(mID));
}
return methods;
}
use of com.jopdesign.common.MethodInfo in project jop by jop-devel.
the class DFATool method load.
/**
* Load the methods into the internal DFA structures and initialize the DFA tool for a new analysis.
* You need to call this method before starting the first analysis and before starting an analysis after
* the code has been modified.
*/
public void load() {
// First clear everything ..
statements.clear();
flow.clear();
receivers = null;
prologue = createPrologue();
// Now we need to process all classes (for DFA's internal flow graph)
for (ClassInfo cls : appInfo.getClassInfos()) {
for (MethodInfo mi : cls.getMethods()) {
if (mi.hasCode()) {
loadMethod(mi);
}
}
}
if (cacheDir != null && !appInfo.updateCheckSum(prologue)) {
cacheDir = null;
}
}
Aggregations