bug fix
[IRC.git] / Robust / src / Analysis / Disjoint / SMFEState.java
1 package Analysis.Disjoint;
2
3 import java.util.*;
4 import java.io.*;
5
6 import IR.*;
7 import IR.Flat.*;
8
9 //////////////////////////////////////////////
10 //
11 //  SMFEState is part of a 
12 //  (S)tate (M)achine (F)or (E)ffects.
13 //
14 //  StateMachineForEffects describes an intial
15 //  state and the effect transtions a DFJ
16 //  traverser should make from the current state
17 //  when searching for possible runtime conflicts.
18 //
19 //////////////////////////////////////////////
20
21 public class SMFEState {
22
23   //  #####################
24   //  ## NOTE NOTE NOTE!!!!
25   //  #####################
26   //  When every state corresponds to exactly one
27   //  FlatNode (whereDefined attribute) then we can
28   //  use the FlatNode's id as an ID.  BUT BUT BUT, if
29   //  we merge nodes together in the future for
30   //  optimizations and whatnot, we need an alternate
31   //  system of unique IDs
32
33   // uniquely identifies this state  
34   protected int id;
35   protected int iHashCode;
36
37   // all possible effects in this state
38   protected Set<Effect> effects;
39   
40   //TODO Jim! get me the list of conflicts!
41   protected Set<Effect> conflicts;
42
43   // the given effect allows a transition to a
44   // set of new states
45   protected Hashtable< Effect, Set<SMFEState> > e2states;
46
47   // useful for knowing when a state can be inlined during
48   // code gen
49   protected int refCount;
50
51
52   
53   public SMFEState( FlatNode fnWhereDefined, int id ) {
54
55     this.id         = id;
56     this.iHashCode  = fnWhereDefined.hashCode();
57
58     effects         = new HashSet<Effect>();
59     conflicts       = new HashSet<Effect>();
60     e2states        = new Hashtable< Effect, Set<SMFEState> >();
61     refCount        = 0;
62   }
63
64   public void addEffect( Effect e ) {
65     effects.add( e );
66   }
67
68   // the given effect allows the transition to the new state
69   public void addTransition( Effect    effect,
70                              SMFEState stateTo
71                              ) {
72
73     Set<SMFEState> states = e2states.get( effect );
74     if( states == null ) {
75       states = new HashSet<SMFEState>();
76       e2states.put( effect, states );
77     }
78     if (!states.contains(stateTo)) {
79       states.add( stateTo );
80       stateTo.refCount++;
81     }
82   }
83
84
85   public int getID() {
86     return id;
87   }
88
89   // once you get your hands on an SMFEState in the
90   // RuntimeConflictResolver side of things, this is how you
91   // find out what effects are possible in this state
92   public Set<Effect> getEffectsAllowed() {
93     return effects;
94   }
95   
96   public void addConflict(Effect e) {
97     conflicts.add(e);
98   }
99
100   public Set<Effect> getConflicts() {
101     return conflicts;
102   }
103   
104   public Set<Effect> getTransistionEffects() {
105     return this.e2states.keySet();
106   }
107
108   // some subset of the above effects may transition to
109   // other states
110   public Set<SMFEState> transitionsTo( Effect e ) {
111     Set<SMFEState> statesOut = e2states.get( e );
112     if( statesOut == null ) {
113       statesOut = new HashSet<SMFEState>();
114     }
115     return statesOut;
116   }
117
118   // some subset of the above effects may transition to
119   // other states
120   public Set<SMFEState> transitionsTo() {
121     Set<SMFEState> statesOut = new HashSet<SMFEState>();
122     for(Map.Entry<Effect, Set<SMFEState>> entry:e2states.entrySet()) {
123       statesOut.addAll(entry.getValue());
124     }
125     return statesOut;
126   }
127
128   public int getRefCount() {
129     return refCount;
130   }
131
132
133   public boolean equals( Object o ) {
134     if( o == null ) {
135       return false;
136     }
137
138     if( !(o instanceof SMFEState) ) {
139       return false;
140     }
141
142     SMFEState state = (SMFEState) o;
143
144     return id == state.id;
145   }
146
147   public int hashCode() {
148     return iHashCode;
149   }
150
151
152   public String toStringDOT() {
153     
154     // first create the state as a node in DOT graph
155     String s = "  "+id+"[shape=box,label=\"";
156
157     if( effects.size() == 1 ) {
158       s += effects.iterator().next().toString();
159
160     } else if( effects.size() > 1 ) {
161
162       Iterator<Effect> eItr = effects.iterator();
163       while( eItr.hasNext() ) {
164         Effect e = eItr.next();
165         s += e.toString();
166
167         if( eItr.hasNext() ) {
168           s += "\\n";
169         }
170       }
171     }
172
173     s += "\"];";
174
175     // then each transition is an edge
176     Iterator<Effect> eItr = e2states.keySet().iterator();
177     while( eItr.hasNext() ) {
178       Effect         e      = eItr.next();
179       Set<SMFEState> states = e2states.get( e );
180
181       Iterator<SMFEState> sItr = states.iterator();
182       while( sItr.hasNext() ) {
183         SMFEState state = sItr.next();
184
185         s += "\n  "+
186           id+" -> "+state.id+
187           "[label=\""+e+"\"];";
188       }
189     }
190
191     return s;
192   }
193
194 }