/*
* This file is part of JOP, the Java Optimized Processor
* see <http://www.jopdesign.com/>
*
* Copyright (C) 2008-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.wcet;// MS: this is the only class that would like junit
// Shall we add junit to the JOP project?
//package com.jopdesign.wcet.test;
//
//
//import java.io.File;
//import java.io.FileWriter;
//import java.io.IOException;
//import java.text.MessageFormat;
//import java.util.Comparator;
//import java.util.Hashtable;
//import java.util.Map;
//import java.util.Set;
//import java.util.TreeSet;
//import java.util.Vector;
//
//import org.jgrapht.DirectedGraph;
//import org.jgrapht.VertexFactory;
//import org.jgrapht.ext.DOTExporter;
//import org.jgrapht.ext.IntegerNameProvider;
//import org.jgrapht.ext.StringNameProvider;
//import org.jgrapht.graph.DefaultDirectedGraph;
//import org.jgrapht.graph.DefaultEdge;
//import org.junit.Before;
//import org.junit.Test;
//
//import com.jopdesign.wcet.graphutils.AdvancedDOTExporter;
//import com.jopdesign.wcet.graphutils.DefaultFlowGraph;
//import com.jopdesign.wcet.graphutils.DominanceFrontiers;
//import com.jopdesign.wcet.graphutils.Dominators;
//import com.jopdesign.wcet.graphutils.FlowGraph;
//import com.jopdesign.wcet.graphutils.LoopColoring;
//import com.jopdesign.wcet.graphutils.TopOrder;
//import com.jopdesign.wcet.graphutils.AdvancedDOTExporter.DOTLabeller;
//import com.jopdesign.wcet.graphutils.AdvancedDOTExporter.DOTNodeLabeller;
//import com.jopdesign.wcet.graphutils.AdvancedDOTExporter.DefaultNodeLabeller;
//import com.jopdesign.wcet.graphutils.LoopColoring.IterationBranchLabel;
//import com.jopdesign.wcet.graphutils.TopOrder.BadGraphException;
//
//import static junit.framework.Assert.*;
//public class GraphTopologyTest {
// public static class AnalysisNodeLabel extends DefaultNodeLabeller<String> {
// private TopOrder<String, DefaultEdge> to;
// private LoopColoring<String, DefaultEdge> lc;
//
// public AnalysisNodeLabel(DirectedGraph<String, DefaultEdge> g,
// TopOrder<String, DefaultEdge> topOrder,
// LoopColoring<String, DefaultEdge> loopColoring) {
// to = topOrder;
// lc = loopColoring;
// }
//
// public String getLabel(String n) {
// return MessageFormat.format("{0} [ idom: {1}, loops: {2} ]",
// n, to.getDominators().getIDoms().get(n), lc.getLoopColors().get(n));
// }
//
// public boolean setAttributes(String n, Map<String, String> ht) {
// super.setAttributes(n, ht);
// if(lc.getHeadOfLoops().contains(n)) {
// ht.put("peripheries", "2");
// }
// return true;
// }
//
// }
// public static class AnalysisEdgeLabeller implements DOTLabeller<DefaultEdge> {
//
// private LoopColoring<String, DefaultEdge> lc;
//
// public AnalysisEdgeLabeller(
// DirectedGraph<String, DefaultEdge> g,
// LoopColoring<String, DefaultEdge> loopColoring) {
// lc = loopColoring;
// }
//
// public String getLabel(DefaultEdge e) {
// IterationBranchLabel<String> lab = lc.getIterationBranchEdges().get(e);
// if(lab == null) return null;
// return MessageFormat.format("cont: {0}\nexit: {1}",
// lab.getContinues(),lab.getExits());
// }
// public boolean setAttributes(DefaultEdge e, Map<String, String> ht) {
// String lab = getLabel(e);
// if(lab != null) {
// ht.put("label",lab);
// return true;
// } else {
// return false;
// }
// }
//
// }
// private static final Integer ENTRY_VERTEX = 0;
//
// private static class EdgeCmp implements Comparator<DefaultEdge> {
// private DirectedGraph<Integer, DefaultEdge> g;
// public EdgeCmp(DirectedGraph<Integer, DefaultEdge> g) {
// this.g = g;
// }
// public int compare(DefaultEdge o1, DefaultEdge o2) {
// int r1 = g.getEdgeSource(o1).compareTo(g.getEdgeSource(o2));
// if(r1 == 0) return g.getEdgeTarget(o1).compareTo(g.getEdgeTarget(o2));
// else return r1;
// }
// }
// public static DefaultDirectedGraph<Integer,DefaultEdge> mkGraph(int[] vxs, int[][]edges) {
// DefaultDirectedGraph<Integer, DefaultEdge> gr = new DefaultDirectedGraph<Integer, DefaultEdge>(DefaultEdge.class);
// for(int v : vxs) {
// gr.addVertex(v);
// }
// for(int[] e: edges) {
// gr.addEdge(e[0], e[1]);
// }
// return gr;
// }
// public static TreeSet<DefaultEdge> mkEdgeSet(DefaultDirectedGraph<Integer,DefaultEdge> gr,int [][] es) {
// TreeSet<DefaultEdge> v = new TreeSet<DefaultEdge>(new EdgeCmp(gr));
// for(int[] e : es) { v.add(gr.getEdge(e[0], e[1])); }
// return v;
// }
// public static TreeSet<DefaultEdge> mkEdgeSet(DefaultDirectedGraph<Integer,DefaultEdge> gr,
// Vector<DefaultEdge> edges) {
// TreeSet<DefaultEdge> v = new TreeSet<DefaultEdge>(new EdgeCmp(gr));
// v.addAll(edges);
// return v;
// }
//
// public static int[] vxs1 = { 0,1,2,3,4,5,6,7 };
// public static int[][] edges1 = {
// {0,1},
// {1,2},
// {2,3},
// {3,4},{3,5},
// {4,6},{4,2},
// {5,7},{5,1},
// {7,6}
// };
// public static int[][] backEdges1 = {
// {4,2},{5,1}
// };
// public static int[][] toporders1 = {
// {1,2,3,4,5,6,7}, // 0
// {2,3,4,5,6,7}, // 1
// {3,4,5,6,7}, // 2
// {4,5,6,7}, // 3
// {6}, // 4
// {6,7}, // 5
// {}, // 6
// {6} // 7
// };
// public static int[] idoms1 = { 0,0,1,2,3,3,3,5 };
//
// private DefaultDirectedGraph<Integer, DefaultEdge> gr1;
// private TopOrder<Integer, DefaultEdge> to1;
//
// @Before
// public void setUp() throws Exception {
// gr1 = mkGraph(vxs1,edges1);
// to1 = new TopOrder<Integer,DefaultEdge>(gr1,ENTRY_VERTEX);
// }
// @Test
// public void testBackEdges1() {
// assertEquals(mkEdgeSet(gr1,to1.getBackEdges()),mkEdgeSet(gr1, backEdges1));
// }
// @Test
// public void testDominators1() {
// Dominators<Integer, DefaultEdge> doms1 = new Dominators<Integer, DefaultEdge>(gr1,to1.getDFSTraversal());
// Hashtable<Integer, Integer> idoms = doms1.getIDoms();
// for(int i = 0; i < vxs1.length; i++) {
// assertEquals(idoms.get(vxs1[i]).intValue(),idoms1[i]);
// }
// }
//
// // small demo
// static class StringVertexFactory implements VertexFactory<String> {
// private int genId;
// public StringVertexFactory(DirectedGraph<String,DefaultEdge> g) {
// this.genId = g.vertexSet().size() + 1;
// }
// public String createVertex() {
// return ("v"+(genId++));
// }
// }
// public static FlowGraph<String, DefaultEdge> g1() {
// FlowGraph<String, DefaultEdge> g = new DefaultFlowGraph<String, DefaultEdge>(DefaultEdge.class,"Entry","10");
// g.addVertex("Entry");
// g.addVertex("1");g.addVertex("2");g.addVertex("3");
// g.addVertex("4");g.addVertex("5");g.addVertex("6");
// g.addVertex("7");g.addVertex("8");g.addVertex("9");g.addVertex("10");
// g.addEdge("Entry", "1");
// g.addEdge("1", "2");g.addEdge("2", "3");g.addEdge("3", "4");g.addEdge("3", "5");
// g.addEdge("4", "6");g.addEdge("4", "2");g.addEdge("5", "6");g.addEdge("5", "1");
// g.addEdge("1","7");g.addEdge("7","8");g.addEdge("8", "8");g.addEdge("8","9");
// g.addEdge("6", "10");g.addEdge("9", "10");g.addEdge("9", "7");
// return g;
// }
// public static FlowGraph<String, DefaultEdge> g2() {
// FlowGraph <String, DefaultEdge> g =
// new DefaultFlowGraph<String, DefaultEdge>(DefaultEdge.class,"Entry","Exit");
// for(int i = 1; i <= 8; i++) { g.addVertex(""+i); }
// g.addVertex("4a");g.addVertex("4b");
// g.addEdge("Entry","1");
// g.addEdge("1","2");g.addEdge("1","7");
// g.addEdge("2","3");g.addEdge("2","7");
// g.addEdge("3","4");g.addEdge("3","6");
// g.addEdge("4","4a");g.addEdge("4","4b");
// g.addEdge("4a","5");
// g.addEdge("4b","5");
// g.addEdge("5","2");
// g.addEdge("6","1");
// g.addEdge("7","8");
// g.addEdge("8","Exit");
// return g;
// }
// public static void main(String argv[]) {
// FlowGraph<String, DefaultEdge> g = g1();
// System.out.println("Graph: "+g);
// exportDOT("g1-cfg",g);
// TopOrder<String, DefaultEdge> topOrder = null;
// try {
// topOrder = new TopOrder<String,DefaultEdge>(g,"Entry");
// } catch (BadGraphException e) {
// e.printStackTrace();
// System.exit(1);
// }
// System.out.println("DfsOrder: "+topOrder.getDFSTraversal());
// System.out.println("Back-Edges: "+topOrder.getBackEdges());
// System.out.println("Dominators: "+topOrder.getDominators().getIDoms());
// System.out.println("Dominator Tree: "+topOrder.getDominators().getDominatorTree());
// exportDOT("g1-domtree",topOrder.getDominators().getDominatorTree());
// DominanceFrontiers<String, DefaultEdge> domFrontiers =
// new DominanceFrontiers<String, DefaultEdge>(g,g.getEntry(), g.getExit());
// Map<String, Set<String>> df = domFrontiers.getDominanceFrontiers();
// for(String v : g.vertexSet()) {
// System.out.println(String.format("DF(%s) := %s",v,df.get(v)));
// }
// Map<String, Set<DefaultEdge>> cd = domFrontiers.getControlDependencies();
// for(String v : g.vertexSet()) {
// System.out.println(String.format("CD(%s) := %s",v,cd.get(v)));
// }
//// for(Set<String> sese : domFrontiers.getSingleEntrySingleExitSets()) {
//// System.out.println(String.format("Mutual SESE set: %s",sese));
//// }
// LoopColoring<String, DefaultEdge> loopColoring =
// new LoopColoring<String, DefaultEdge>(g,topOrder,"10");
// System.out.println("Loop coloring: "+loopColoring.getLoopColors());
// System.out.println("Iteration branch edges: "+loopColoring.getIterationBranchEdges());
// exportDOT("g1-lnf",loopColoring.getLoopNestDAG());
// System.out.println("Loop nest tree: "+loopColoring.getLoopNestDAG());
// exportDOT("g1-flow-order-graph",loopColoring.getFlowTraversalGraph());
// System.out.println("Flow order: "+loopColoring.getFlowTraversal());
//
// exportDOT("g1-analysis", g,new AnalysisNodeLabel(g,topOrder,loopColoring),
// new AnalysisEdgeLabeller(g,loopColoring));
//
// try {
// FlowGraph<String, DefaultEdge> g2 = g2();
// exportDOT("g2-cfg",g2);
// TopOrder<String, DefaultEdge> top2 = new TopOrder<String, DefaultEdge>(g2,g2.getEntry());
// LoopColoring<String, DefaultEdge> loops2 =
// new LoopColoring<String, DefaultEdge>(g2,top2,g2.getExit());
//
// exportDOT("g2-analysis", g2 ,
// new AnalysisNodeLabel(g2,top2,loops2),
// new AnalysisEdgeLabeller(g2,loops2));
// } catch(Exception e) { e.printStackTrace(); }
//
// StringVertexFactory vf = new StringVertexFactory(g);
// loopColoring.unpeelLoop("8", vf);
// System.out.println("Graph (unpeel 8): "+g);
// exportDOT("g1-up8",g);
// loopColoring.unpeelLoop("7", vf);
// System.out.println("Graph (unpeel 7,8): "+g);
// exportDOT("g1-up7",g);
// loopColoring.unpeelLoop("2", vf);
// loopColoring.unpeelLoop("1", vf);
// System.out.println("Graph (unpeel all): "+g);
// exportDOT("g1-up-all",g);
// }
// private static void exportDOT(String file, DirectedGraph<String, DefaultEdge> g) {
// DOTExporter<String, DefaultEdge> export = new DOTExporter<String, DefaultEdge>(
// new IntegerNameProvider<String>(),
// new StringNameProvider<String>(),
// null
// );
// try {
// File tmpFile = File.createTempFile(file, ".dot");
// System.out.println("Creating .dot file: "+tmpFile);
// FileWriter fw = new FileWriter(tmpFile);
// export.export(fw, g);
// fw.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// private static void exportDOT(String file, DirectedGraph<String, DefaultEdge> g,
// DOTNodeLabeller<String> nl,
// DOTLabeller<DefaultEdge> el) {
// AdvancedDOTExporter<String, DefaultEdge> export =
// new AdvancedDOTExporter<String, DefaultEdge>(nl,el);
// try {
// File tmpFile = File.createTempFile(file, ".dot");
// System.out.println("Creating .dot file: "+tmpFile);
// FileWriter fw = new FileWriter(tmpFile);
// export.exportDOT(fw, g);
// fw.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
//
//}