/* * This file is part of JOP, the Java Optimized Processor * see <http://www.jopdesign.com/> * * Copyright (C) 2010, Benedikt Huber (benedikt.huber@gmail.com) * * 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.common.graphutils; import com.jopdesign.common.misc.BadGraphException; import com.jopdesign.common.misc.MiscUtils; import org.jgrapht.DirectedGraph; import org.jgrapht.graph.DefaultEdge; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; /** * Module to compute relative progess measure * Fun fact: While implementing, I suddenly recognized this is a * generalized tree based WCET computation :) */ public class ProgressMeasure<V, E> { public static class RelativeProgress<V> { public RelativeProgress(long staticDiff, Map<V, Long> loopDiff) { this.staticDiff = staticDiff; this.loopDiff = loopDiff; } public final long staticDiff; public final Map<V, Long> loopDiff; public String toString() { StringBuilder sb = new StringBuilder(); sb.append(staticDiff); for (Entry<V, Long> entry : loopDiff.entrySet()) { sb.append(String.format(" - %d * iter(%s)", entry.getValue(), entry.getKey())); } return sb.toString(); } } /* input */ private LoopColoring<V, E> loopColors; private FlowGraph<V, E> cfg; private Map<V, Long> loopBounds; private Map<V, Long> blockMeasure; /* state */ private HashMap<V, Long> pMaxMap = null; private HashMap<V, Long> loopProgress = null; public long getLoopProgress(V target) { getMaxProgress(); return this.loopProgress.get(target); } public ProgressMeasure(FlowGraph<V, E> cfg, LoopColoring<V, E> loopColors, Map<V, Long> loopBounds, Map<V, Long> blockMeasure) { this.cfg = cfg; this.loopBounds = loopBounds; this.loopColors = loopColors; this.blockMeasure = blockMeasure; } /** * The fun algorithm to compute relative progress measures. * * @return */ public Map<V, Long> getMaxProgress() { if (pMaxMap != null) return pMaxMap; /* pmax: maximal progress upto the given node */ pMaxMap = new HashMap<V, Long>(); loopProgress = new HashMap<V, Long>(); /* for all loops in reverse topo order of the loop nest tree */ List<V> reverseTopo = MiscUtils.reverseTopologicalOrder(loopColors.getLoopNestDAG()); for (V hol : reverseTopo) { /* set progress of loop header to 0 */ pMaxMap.put(hol, 0L); /* get linear subgraph */ DirectedGraph<V, E> subGraph = loopColors.getLinearSubgraph(hol); /* update pmax (in topo order of the linear subgraph) */ for (V node : MiscUtils.topologicalOrder(subGraph)) { if (node == hol) continue; updatePMax(subGraph, node, loopColors); } /* update loopProgress */ long loopProgressMax = 0; for (E backEdge : loopColors.getBackEdgesByHOL().get(hol)) { loopProgressMax = Math.max(loopProgressMax, getMaxProgressVia(cfg, backEdge)); } this.loopProgress.put(hol, loopProgressMax); } /* update pmax (linear subgraph of the method) */ DirectedGraph<V, E> subGraph = loopColors.getLinearSubgraph(null); pMaxMap.put(cfg.getEntry(), 0L); for (V node : MiscUtils.topologicalOrder(subGraph)) { if (node == cfg.getEntry()) continue; updatePMax(subGraph, node, loopColors); } return pMaxMap; } public Map<E, RelativeProgress<V>> computeRelativeProgress() { Map<V, Long> maxProgress = getMaxProgress(); Map<E, RelativeProgress<V>> relProgress = new HashMap<E, RelativeProgress<V>>(); for (E e : cfg.edgeSet()) { V src = cfg.getEdgeSource(e); V target = cfg.getEdgeTarget(e); Long pmSrc = maxProgress.get(src); Long pmTarget = maxProgress.get(target); long staticDiff = pmTarget - pmSrc; if (this.loopColors.isBackEdge(e)) staticDiff += getLoopProgress(target); Map<V, Long> loopDiff = new HashMap<V, Long>(); for (V exit : loopColors.getLoopExitSet(e)) { loopDiff.put(exit, getLoopProgress(exit)); } relProgress.put(e, new RelativeProgress<V>(staticDiff, loopDiff)); } return relProgress; } private void updatePMax(DirectedGraph<V, E> subgraph, V node, LoopColoring<V, E> color) { long pMax = 0; for (E incoming : subgraph.incomingEdgesOf(node)) { pMax = Math.max(pMax, getMaxProgressVia(subgraph, incoming)); } pMaxMap.put(node, pMax); } private long getMaxProgressVia(DirectedGraph<V, E> subgraph, E incoming) { V src = subgraph.getEdgeSource(incoming); long pMaxPred = pMaxMap.get(src); for (V exitLoop : loopColors.getLoopExitSet(incoming)) { pMaxPred += loopProgress.get(exitLoop) * loopBounds.get(exitLoop); } return pMaxPred + blockMeasure.get(src); } /* test */ public static void main(String argv[]) { int nodes[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; long blockm[] = {1, 1, 22, 4, 4, 4, 2, 1, 1, 1, 1}; int edges[][] = {{1, 2}, {2, 3}, {2, 4}, {4, 5}, {5, 6}, {6, 7}, {6, 2}, {7, 5}, {7, 10}, {5, 8}, {3, 9}, {8, 9}, {9, 2}, {8, 10}, {9, 11}, {10, 11}}; FlowGraph<Integer, DefaultEdge> testGraph = new DefaultFlowGraph<Integer, DefaultEdge>(DefaultEdge.class, 0, 11); for (int n : nodes) testGraph.addVertex(n); for (int[] e : edges) testGraph.addEdge(e[0], e[1]); Map<Integer, Long> testLoopBounds = new HashMap<Integer, Long>(); testLoopBounds.put(2, 7L); testLoopBounds.put(5, 15L); TopOrder<Integer, DefaultEdge> topo = null; try { topo = new TopOrder<Integer, DefaultEdge>(testGraph, 1); } catch (BadGraphException e1) { e1.printStackTrace(); } LoopColoring<Integer, DefaultEdge> testLoopColors = new LoopColoring<Integer, DefaultEdge>(testGraph, topo, 11); HashMap<Integer, Long> testBlockMeasure = new HashMap<Integer, Long>(); for (int i = 0; i < nodes.length; i++) { testBlockMeasure.put(nodes[i], blockm[i]); } ProgressMeasure<Integer, DefaultEdge> pm = new ProgressMeasure<Integer, DefaultEdge>(testGraph, testLoopColors, testLoopBounds, testBlockMeasure); Map<Integer, Long> maxProgress = pm.getMaxProgress(); MiscUtils.printMap(System.out, new TreeMap<Integer, Long>(maxProgress), 10, 0); /* compute relative updates */ for (Entry<DefaultEdge, RelativeProgress<Integer>> x : pm.computeRelativeProgress().entrySet()) { int src = testGraph.getEdgeSource(x.getKey()); int target = testGraph.getEdgeTarget(x.getKey()); System.out.println(String.format("%2d --> %2d: +%s", src, target, x.getValue())); } } }