bug fixed in taskanalysis. we missed self edges if the task just returned w/o settin...
[IRC.git] / Robust / src / Analysis / TaskStateAnalysis / FlagState.java
1 package Analysis.TaskStateAnalysis;
2 import Analysis.TaskStateAnalysis.*;
3 import IR.*;
4 import IR.Tree.*;
5 import IR.Flat.*;
6 import java.util.*;
7 import java.io.*;
8 import Util.GraphNode;
9
10 /** This class is used to hold the flag states that a class in the Bristlecone 
11  *  program can exist in, during runtime.
12  */
13 public class FlagState extends GraphNode {
14     public static final int ONETAG=1;
15     public static final int NOTAGS=0;
16     public static final int MULTITAGS=-1;
17     
18     private int uid;
19     private static int nodeid=0;
20
21     private final HashSet flagstate;
22     private final ClassDescriptor cd;
23     private final Hashtable<TagDescriptor,Integer> tags;
24     private boolean issourcenode;
25
26     /** Class constructor
27      *  Creates a new flagstate with all flags set to false.
28      *  @param cd ClassDescriptor
29      */
30     public FlagState(ClassDescriptor cd) {
31         this.flagstate=new HashSet();
32         this.cd=cd;
33         this.tags=new Hashtable<TagDescriptor,Integer>();
34         this.uid=FlagState.nodeid++;
35         this.issourcenode=false;
36     }
37
38     /** Class constructor
39      *  Creates a new flagstate with flags set according to the HashSet.
40      *  If the flag exists in the hashset, it's set to true else set to false.
41      *  @param cd ClassDescriptor
42      *  @param flagstate a <CODE>HashSet</CODE> containing FlagDescriptors
43      */
44     private FlagState(HashSet flagstate, ClassDescriptor cd,Hashtable<TagDescriptor,Integer> tags) {
45         this.flagstate=flagstate;
46         this.cd=cd;
47         this.tags=tags;
48         this.uid=FlagState.nodeid++;
49         this.issourcenode=false;
50         
51     }
52     
53     /** Accessor method
54       *  @param fd FlagDescriptor
55       *  @return true if the flagstate contains fd else false.
56       */
57     public boolean get(FlagDescriptor fd) {
58         return flagstate.contains(fd);
59     }
60     
61     /** Checks if the flagstate is a source node. 
62      *  @return true if the flagstate is a sourcenode(i.e. Is the product of an allocation site).
63      */
64       
65     public boolean isSourceNode(){
66             return issourcenode;
67         }
68         
69         /**  Sets the flagstate as a source node. 
70      */
71         public void setAsSourceNode(){
72                 issourcenode=true;
73         }
74
75     
76     public String toString() {
77         return cd.toString()+getTextLabel();
78     }
79
80     /** @return Iterator over the flags in the flagstate.
81      */
82      
83     public Iterator getFlags() {
84         return flagstate.iterator();
85     }
86     
87     public FlagState setTag(TagDescriptor tag){
88            
89             HashSet newset=(HashSet)flagstate.clone();
90             Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
91             
92             if (newtags.containsKey(tag)){
93                    switch (newtags.get(tag).intValue()){
94                            case ONETAG:
95                                         newtags.put(tag,new Integer(MULTITAGS));
96                                         break;
97                            case MULTITAGS:
98                                         newtags.put(tag,new Integer(MULTITAGS));
99                                         break;
100                         }
101                 }
102                 else{
103                         newtags.put(tag,new Integer(ONETAG));
104                 }
105                 
106                 return new FlagState(newset,cd,newtags);
107                                 
108     }
109
110     public int getTagCount(String tagtype){
111                 for (Enumeration en=getTags();en.hasMoreElements();){
112                         TagDescriptor td=(TagDescriptor)en.nextElement();
113                         if (tagtype.equals(td.getSymbol()))
114                                 return tags.get(td).intValue();   //returns either ONETAG or MULTITAG
115                 }
116                 return NOTAGS;
117                 
118     }
119     
120     public FlagState[] clearTag(TagDescriptor tag){
121             FlagState[] retstates;
122             
123             if (tags.containsKey(tag)){
124             switch(tags.get(tag).intValue()){
125                     case ONETAG:
126                         HashSet newset=(HashSet)flagstate.clone();
127                         Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
128                         newtags.remove(tag);
129                         retstates=new FlagState[]{new FlagState(newset,cd,newtags)};
130                         return retstates;
131                         
132                     case MULTITAGS:
133                         //when tagcount is more than 2, COUNT stays at MULTITAGS
134                         retstates=new FlagState[2];
135                         HashSet newset1=(HashSet)flagstate.clone();
136                         Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
137                         retstates[1]=new FlagState(newset1,cd,newtags1);
138                         //when tagcount is 2, COUNT changes to ONETAG
139                         HashSet newset2=(HashSet)flagstate.clone();
140                         Hashtable<TagDescriptor,Integer> newtags2=(Hashtable<TagDescriptor,Integer>)tags.clone();
141                         newtags1.put(tag,new Integer(ONETAG));
142                         retstates[1]=new FlagState(newset2,cd,newtags2);
143                         return retstates;
144                 default:
145                         return null;                    
146         }
147                 }else{
148                         throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
149                         
150                 }
151                 
152     }
153     
154     /** Creates a string description of the flagstate
155      *  e.g.  a flagstate with five flags could look like 01001
156      *  @param flags an array of flagdescriptors.
157      *  @return string representation of the flagstate.
158      */
159         public String toString(FlagDescriptor[] flags)
160         {
161                 StringBuffer sb = new StringBuffer(flagstate.size());
162                 for(int i=0;i < flags.length; i++)
163                 {
164                         if (get(flags[i]))
165                                 sb.append(1);
166                         else
167                                 sb.append(0);
168                 }
169                         
170                 return new String(sb);
171         }
172
173         /** Accessor method
174          *  @return returns the classdescriptor of the flagstate.
175          */
176          
177     public ClassDescriptor getClassDescriptor(){
178         return cd;
179     }
180
181         /** Sets the status of a specific flag in a flagstate after cloning it.
182          *  @param      fd FlagDescriptor of the flag whose status is being set.
183          *  @param  status boolean value
184          *  @return the new flagstate with <CODE>fd</CODE> set to <CODE>status</CODE>.
185          */
186          
187     public FlagState setFlag(FlagDescriptor fd, boolean status) {
188         HashSet newset=(HashSet) flagstate.clone();
189         Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
190         if (status)
191             newset.add(fd);
192         else if (newset.contains(fd)){
193             newset.remove(fd);
194         }
195         
196         return new FlagState(newset, cd,newtags);
197     }
198     
199     /** Tests for equality of two flagstate objects.
200     */
201     
202     public boolean equals(Object o) {
203         if (o instanceof FlagState) {
204             FlagState fs=(FlagState)o;
205             if (fs.cd!=cd)
206                 return false;
207             return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
208         }
209         return false;
210     }
211
212     public int hashCode() {
213         return cd.hashCode()^flagstate.hashCode()^tags.hashCode();
214     }
215
216     public String getLabel() {
217         return "N"+uid;
218     }
219
220     public String getTextLabel() {
221         String label=null;
222         for(Iterator it=getFlags();it.hasNext();) {
223             FlagDescriptor fd=(FlagDescriptor) it.next();
224             if (label==null)
225                 label=fd.toString();
226             else
227                 label+=", "+fd.toString();
228         }
229         for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
230                 TagDescriptor td=(TagDescriptor)en_tags.nextElement();
231                 switch (tags.get(td).intValue()){
232                 case ONETAG:
233                     if (label==null)
234                         label=td.toString()+"(1)";
235                     else
236                         label+=", "+td.toString()+"(1)";
237                     break;
238                 case MULTITAGS:
239                     if (label==null)
240                         label=td.toString()+"(n)";
241                     else
242                         label+=", "+td.toString()+"(n)";
243                     break;
244                 default:
245                     break;
246                 }
247         }
248         if (label==null)
249             return " ";
250         return label;
251     }
252     
253     public Enumeration getTags(){
254             return tags.keys();
255     }
256 }