/* * This file is part of JOP, the Java Optimized Processor * see <http://www.jopdesign.com/> * * Copyright (C) 2011, Stefan Hepp (stefan@stefant.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.jopdesign.jcopter.greedy; import com.jopdesign.common.MethodInfo; import com.jopdesign.jcopter.analysis.AnalysisManager; import com.jopdesign.jcopter.analysis.ExecFrequencyProvider; import com.jopdesign.jcopter.analysis.WCAInvoker; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; /** * @author Stefan Hepp (stefan@stefant.org) */ public class WCEPRebateSelector extends RebateSelector { private final GainCalculator gainCalculator; public WCEPRebateSelector(AnalysisManager analyses, GainCalculator gainCalculator, int maxGlobalSize) { super(analyses, maxGlobalSize); this.gainCalculator = gainCalculator; } @Override protected void onRemoveMethodData(MethodData data) { } @Override protected void sortMethodData(ExecFrequencyProvider ecp, MethodData data) { } @Override public void sortCandidates(ExecFrequencyProvider ecp) { } @Override public Collection<Candidate> selectNextCandidates(ExecFrequencyProvider ecp) { WCAInvoker wcaInvoker = analyses.getWCAInvoker(); Set<MethodInfo> visited = new LinkedHashSet<MethodInfo>(); LinkedList<MethodInfo> queue = new LinkedList<MethodInfo>(); // go down all methods in the callgraph which are on the WCET path, find best candidate RebateRatio next = null; queue.addAll(wcaInvoker.getWcaTargets()); visited.addAll(queue); while (!queue.isEmpty()) { MethodInfo method = queue.removeFirst(); MethodData data = methodData.get(method); if (data == null) continue; // skip methods not on the WCET path if (!wcaInvoker.isOnWCETPath(method)) { continue; } // select best candidate from method or use previous method next = selectCandidate(ecp, data, next); // add childs to queue if not already visited for (MethodInfo child : analyses.getTargetCallGraph().getInvokedMethods(method)) { if (visited.add(child)) { queue.add(child); } } } logSelection(ecp, next); return next != null ? next.getCandidates() : null; } @Override public Set<MethodInfo> updateChangeSet(ExecFrequencyProvider ecp, Set<MethodInfo> optimizedMethods, Set<MethodInfo> candidateChanges) { // No need to add anything else, as we search the whole graph anyway.. analyses.getWCAInvoker().updateWCA(optimizedMethods); return candidateChanges; } private RebateRatio selectCandidate(ExecFrequencyProvider ecp, MethodData data, RebateRatio next) { List<Candidate> remove = new ArrayList<Candidate>(); for (Candidate candidate : data.getCandidates()) { if (!checkConstraints(candidate)) { remove.add(candidate); continue; } if (!analyses.getWCAInvoker().isOnLocalWCETPath(candidate.getMethod(), candidate.getEntry())) { continue; } long gain = gainCalculator.calculateGain(ecp, candidate); if (gain <= 0) continue; RebateRatio ratio = createRatio(gainCalculator, ecp, candidate, gain); if (next == null || ratio.getRatio() > next.getRatio()) { next = ratio; } } for (Candidate candidate : remove) { removeCandidate(candidate); } return next; } }