start of new file
[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                 writeFlatIRGraph(fm,cd.getSymbol()+"."+md.getSymbol());
45             }
46         }       
47     }
48
49     private void writeFlatIRGraph( FlatMethod fm, String graphname ) throws java.io.IOException {
50         // give every node in the flat IR graph a unique label
51         // so a human being can inspect the graph and verify
52         // correctness
53         flatnodetolabel=new Hashtable<FlatNode, Integer>();
54         visited=new HashSet<FlatNode>();
55         labelindex=0;
56         labelFlatNodes( fm );
57
58         // take symbols out of graphname that cause dot to fail
59         graphname = graphname.replaceAll( "[\\W]", "" );
60
61         flatbw=new BufferedWriter( new FileWriter( graphname+"_flatIRGraph.dot" ) );
62         flatbw.write("digraph "+graphname+" {\n");
63
64         visited=new HashSet<FlatNode>();
65         toVisit=new HashSet<FlatNode>();
66         toVisit.add(fm);
67
68         while( !toVisit.isEmpty() ) {
69             FlatNode fn=(FlatNode)toVisit.iterator().next();
70             toVisit.remove(fn);
71             visited.add(fn);
72
73             if( fn.kind() == FKind.FlatMethod ) {
74                 // FlatMethod does not have toString
75                 flatbw.write( makeDotNodeDec( graphname, flatnodetolabel.get(fn), fn.getClass().getName(), "FlatMethod" ) );
76             } else {
77                 flatbw.write( makeDotNodeDec( graphname, flatnodetolabel.get(fn), fn.getClass().getName(), fn.toString() ) );
78             }
79             
80             for(int i=0;i<fn.numNext();i++) {
81                 FlatNode nn=fn.getNext(i);
82                 flatbw.write( "  node"+flatnodetolabel.get(fn)+" -> node"+flatnodetolabel.get(nn)+";\n" );
83
84                 if( !visited.contains( nn ) ) {
85                     toVisit.add( nn );
86                 }
87             }
88         }
89
90         flatbw.write( "}\n" );
91         flatbw.close();
92     }
93
94     private void labelFlatNodes(FlatNode fn) {
95         visited.add(fn);
96         flatnodetolabel.put(fn,new Integer(labelindex++));
97         for(int i=0;i<fn.numNext();i++) {
98             FlatNode nn=fn.getNext(i);
99             if(!visited.contains(nn)) {
100                 labelFlatNodes(nn);
101             }
102         }
103     }
104
105     private String makeNodeName( String graphname, Integer id, String type ) {
106         String s = String.format( "%05d", id );
107         return "FN"+s+"_"+type;
108     }
109
110     private String makeDotNodeDec( String graphname, Integer id, String type, String details ) {
111         if( details == null ) {
112             return "  node"+id+"[label=\""+makeNodeName(graphname,id,type)+"\"];\n";
113         } else {
114             return "  node"+id+"[label=\""+makeNodeName(graphname,id,type)+"\\n"+details+"\"];\n";
115         }
116     }
117 }