switch to spaces only..
[IRC.git] / Robust / src / IR / Flat / FlatMethod.java
1 package IR.Flat;
2 import IR.MethodDescriptor;
3 import IR.TaskDescriptor;
4 import java.util.*;
5
6 public class FlatMethod extends FlatNode {
7   MethodDescriptor method;
8   TaskDescriptor task;
9   Vector parameterTemps;
10   Vector tagTemps;
11   Hashtable tagtointmap;
12   FlatExit flatExit;
13
14   public FlatMethod(MethodDescriptor md, FlatExit fe) {
15     method=md;
16     task=null;
17     parameterTemps=new Vector();
18     tagTemps=new Vector();
19     tagtointmap=new Hashtable();
20     flatExit=fe;
21   }
22
23   FlatMethod(TaskDescriptor td, FlatExit fe) {
24     task=td;
25     method=null;
26     parameterTemps=new Vector();
27     tagTemps=new Vector();
28     tagtointmap=new Hashtable();
29     flatExit=fe;
30   }
31
32   public String toString() {
33     String ret = "FlatMethod_";
34     if( method != null ) {
35       ret += method.toString();
36     } else {
37       ret += task.toString();
38     }
39     ret+="(";
40     boolean first=true;
41     for(int i=0; i<numParameters(); i++) {
42       if (first) {
43         first=false;
44       } else
45         ret+=", ";
46       ret+=getParameter(i);
47     }
48     ret+=")";
49     return ret;
50   }
51
52   public MethodDescriptor getMethod() {
53     return method;
54   }
55
56   public TaskDescriptor getTask() {
57     return task;
58   }
59
60   public int kind() {
61     return FKind.FlatMethod;
62   }
63
64   public void addParameterTemp(TempDescriptor t) {
65     parameterTemps.add(t);
66   }
67
68   public int numParameters() {
69     return parameterTemps.size();
70   }
71
72   public void addTagTemp(TempDescriptor t) {
73     tagtointmap.put(t, new Integer(tagTemps.size()));
74     tagTemps.add(t);
75   }
76
77   public int getTagInt(TempDescriptor t) {
78     return ((Integer)tagtointmap.get(t)).intValue();
79   }
80
81   public int numTags() {
82     return tagTemps.size();
83   }
84
85   public TempDescriptor getTag(int i) {
86     return (TempDescriptor) tagTemps.get(i);
87   }
88
89   public TempDescriptor getParameter(int i) {
90     return (TempDescriptor) parameterTemps.get(i);
91   }
92
93   public FlatExit getFlatExit() {
94     return flatExit;
95   }
96
97   public void check() {
98     Set<FlatNode> set=getNodeSet();
99     for(Iterator<FlatNode> setit=set.iterator(); setit.hasNext(); ) {
100       FlatNode fn=setit.next();
101       for(int i=0; i<fn.numPrev(); i++) {
102         FlatNode fnprev=fn.getPrev(i);
103         if (!set.contains(fnprev)) {
104           System.out.println(fn+" has unreachable parent:"+i+"  "+fnprev);
105           System.out.println(printMethod());
106           throw new Error();
107
108         }
109       }
110     }
111   }
112
113   /** This method returns a set of the nodes in this flat representation */
114
115   public Set<FlatNode> getNodeSet() {
116     HashSet<FlatNode> tovisit=new HashSet<FlatNode>();
117     HashSet<FlatNode> visited=new HashSet<FlatNode>();
118     tovisit.add(this);
119     while(!tovisit.isEmpty()) {
120       FlatNode fn=tovisit.iterator().next();
121       tovisit.remove(fn);
122       visited.add(fn);
123       for(int i=0; i<fn.numNext(); i++) {
124         FlatNode nn=fn.getNext(i);
125         if (nn==null)
126           continue;
127         if (!visited.contains(nn))
128           tovisit.add(nn);
129       }
130     }
131     return visited;
132   }
133
134   public String printMethod() {
135     return printMethod(null);
136   }
137
138   /** This method returns a string that is a human readable
139    * representation of this method. */
140
141   public String printMethod(Map map) {
142     String st=method+" {\n";
143     HashSet tovisit=new HashSet();
144     HashSet visited=new HashSet();
145     int labelindex=0;
146     Hashtable nodetolabel=new Hashtable();
147     tovisit.add(this);
148     FlatNode current_node=null;
149     //Assign labels 1st
150     //Node needs a label if it is
151     while(!tovisit.isEmpty()) {
152       FlatNode fn=(FlatNode)tovisit.iterator().next();
153       tovisit.remove(fn);
154       visited.add(fn);
155
156       for(int i=0; i<fn.numNext(); i++) {
157         FlatNode nn=fn.getNext(i);
158         if(i>0) {
159           //1) Edge >1 of node
160           nodetolabel.put(nn,new Integer(labelindex++));
161         }
162         if (!visited.contains(nn)&&!tovisit.contains(nn)) {
163           tovisit.add(nn);
164         } else {
165           //2) Join point
166           nodetolabel.put(nn,new Integer(labelindex++));
167         }
168       }
169     }
170
171     //Do the actual printing
172     tovisit=new HashSet();
173     visited=new HashSet();
174     tovisit.add(this);
175     while(current_node!=null||!tovisit.isEmpty()) {
176       if (current_node==null) {
177         current_node=(FlatNode)tovisit.iterator().next();
178         tovisit.remove(current_node);
179       } else {
180         if (tovisit.contains(current_node))
181           tovisit.remove(current_node);
182       }
183       visited.add(current_node);
184       if (nodetolabel.containsKey(current_node)) {
185         st+="L"+nodetolabel.get(current_node)+":\n";
186         for(int i=0; i<current_node.numPrev(); i++) {
187           st+="i="+i+" "+current_node.getPrev(i);
188         }
189         st+="\n";
190       }
191       if (current_node.numNext()==0) {
192         if (map==null)
193           st+="   "+current_node.toString()+"\n";
194         else
195           st+="   "+current_node.toString()+"["+map.get(current_node)+"]\n";
196         current_node=null;
197       } else if(current_node.numNext()==1) {
198         if (map==null)
199           st+="   "+current_node.toString()+"\n";
200         else
201           st+="   "+current_node.toString()+"["+map.get(current_node)+"]\n";
202         FlatNode nextnode=current_node.getNext(0);
203         if (visited.contains(nextnode)) {
204           st+="goto L"+nodetolabel.get(nextnode)+"\n";
205           current_node=null;
206         } else
207           current_node=nextnode;
208       } else if (current_node.numNext()==2) {
209         /* Branch */
210         st+="   "+((FlatCondBranch)current_node).toString("L"+nodetolabel.get(current_node.getNext(1)))+"\n";
211         if (!visited.contains(current_node.getNext(1)))
212           tovisit.add(current_node.getNext(1));
213         if (visited.contains(current_node.getNext(0))) {
214           st+="goto L"+nodetolabel.get(current_node.getNext(0))+"\n";
215           current_node=null;
216         } else
217           current_node=current_node.getNext(0);
218       } else throw new Error();
219     }
220     return st+"}\n";
221   }
222
223   public TempDescriptor [] writesTemps() {
224     return (TempDescriptor[])parameterTemps.toArray(new TempDescriptor[ parameterTemps.size()]);
225   }
226 }