changes.
[IRC.git] / Robust / src / Analysis / FlatIRGraph / FlatIRGraph.java
1 package Analysis.FlatIRGraph;
2
3 import IR.*;
4 import IR.Flat.*;
5 import java.util.*;
6 import java.io.*;
7
8 public class FlatIRGraph {
9
10   private State state;
11
12   private BufferedWriter flatbw;
13
14   private HashSet<FlatNode> visited;
15   private HashSet<FlatNode> toVisit;
16
17   private int labelindex;
18   private Hashtable<FlatNode, Integer> flatnodetolabel;
19
20   public FlatIRGraph(State state, boolean tasks, boolean usermethods, boolean libmethods) throws java.io.IOException {
21     this.state=state;
22
23     if( tasks )
24       graphTasks();
25
26     if( usermethods || libmethods )
27       graphMethods();
28   }
29
30   private void graphTasks() throws java.io.IOException {
31     for(Iterator it_tasks=state.getTaskSymbolTable().getDescriptorsIterator(); it_tasks.hasNext(); ) {
32       TaskDescriptor td = (TaskDescriptor)it_tasks.next();
33       FlatMethod fm = state.getMethodFlat(td);
34       writeFlatIRGraph(fm,"task"+td.getSymbol());
35     }
36   }
37
38   private void graphMethods() throws java.io.IOException {
39     for(Iterator it_classes=state.getClassSymbolTable().getDescriptorsIterator(); it_classes.hasNext(); ) {
40       ClassDescriptor cd = (ClassDescriptor)it_classes.next();
41       for(Iterator it_methods=cd.getMethods(); it_methods.hasNext(); ) {
42         MethodDescriptor md = (MethodDescriptor)it_methods.next();
43         FlatMethod fm = state.getMethodFlat(md);
44
45         // make sure the graph name reflects the method signature so
46         // overloaded methods don't clobber one another
47         String graphName = cd.getSymbol()+"."+md.getSymbol();        
48         for (int i = 0; i < fm.numParameters(); ++i) {
49           graphName += fm.getParameter(i).getSymbol();
50         }
51         writeFlatIRGraph(fm, graphName);
52       }
53     }
54   }
55   
56   public void writeFlatIRGraph(FlatMethod fm, String graphname) throws java.io.IOException {
57     // give every node in the flat IR graph a unique label
58     // so a human being can inspect the graph and verify
59     // correctness
60     flatnodetolabel=new Hashtable<FlatNode, Integer>();
61     visited=new HashSet<FlatNode>();
62     labelindex=0;
63     labelFlatNodes(fm);
64
65     // take symbols out of graphname that cause dot to fail
66     graphname = graphname.replaceAll("[\\W]", "");
67
68     flatbw=new BufferedWriter(new FileWriter("FLATIR_"+graphname+".dot") );
69     flatbw.write("digraph "+graphname+" {\n");
70
71     visited=new HashSet<FlatNode>();
72     toVisit=new HashSet<FlatNode>();
73     toVisit.add(fm);
74
75     while( !toVisit.isEmpty() ) {
76       FlatNode fn=(FlatNode)toVisit.iterator().next();
77       toVisit.remove(fn);
78       visited.add(fn);
79
80       if( fn.kind() == FKind.FlatMethod ) {
81         // FlatMethod does not have toString
82         flatbw.write(makeDotNodeDec(graphname, flatnodetolabel.get(fn), fn.getClass().getName(), "FlatMethod") );
83       } else {
84         flatbw.write(makeDotNodeDec(graphname, flatnodetolabel.get(fn), fn.getClass().getName(), fn.toString() ) );
85       }
86
87       for(int i=0; i<fn.numNext(); i++) {
88         FlatNode nn=fn.getNext(i);
89         flatbw.write("  node"+flatnodetolabel.get(fn)+" -> node"+flatnodetolabel.get(nn)+";\n");
90
91         if( !visited.contains(nn) ) {
92           toVisit.add(nn);
93         }
94       }
95     }
96
97     flatbw.write("}\n");
98     flatbw.close();
99   }
100
101   private void labelFlatNodes(FlatNode fn) {
102     visited.add(fn);
103     flatnodetolabel.put(fn,new Integer(labelindex++));
104     for(int i=0; i<fn.numNext(); i++) {
105       FlatNode nn=fn.getNext(i);
106       if(!visited.contains(nn)) {
107         labelFlatNodes(nn);
108       }
109     }
110   }
111
112   private String makeNodeName(String graphname, Integer id, String type) {
113     String s = String.format("%05d", id);
114     return "FN"+s+"_"+type;
115   }
116
117   private String makeDotNodeDec(String graphname, Integer id, String type, String details) {
118     if( details == null ) {
119       return "  node"+id+"[label=\""+makeNodeName(graphname,id,type)+"\"];\n";
120     } else {
121       return "  node"+id+"[label=\""+makeNodeName(graphname,id,type)+"\\n"+details+"\"];\n";
122     }
123   }
124 }