Jim told me to do this...
[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   //TODO: Jim! Also give me a list of "inset alloc sites" 
44   //as in for every state, give me starting allocation sites
45   //Useful for determining which allocs within a state need its own case statement
46   //Basically allocs that have transitions TO them. 
47   protected Set<Alloc> startingAllocs;
48
49   // the given effect allows a transition to a
50   // set of new states
51   protected Hashtable< Effect, Set<SMFEState> > e2states;
52
53   // useful for knowing when a state can be inlined during
54   // code gen
55   protected int refCount;
56
57
58   
59   public SMFEState( FlatNode fnWhereDefined ) {
60
61     this.id         = fnWhereDefined.nodeid;
62     this.iHashCode  = fnWhereDefined.hashCode();
63
64     effects         = new HashSet<Effect>();
65     conflicts       = new HashSet<Effect>();
66     e2states        = new Hashtable< Effect, Set<SMFEState> >();
67     refCount        = 0;
68   }
69
70   public void addEffect( Effect e ) {
71     effects.add( e );
72   }
73
74   // the given effect allows the transition to the new state
75   public void addTransition( Effect    effect,
76                              SMFEState stateTo
77                              ) {
78
79     Set<SMFEState> states = e2states.get( effect );
80     if( states == null ) {
81       states = new HashSet<SMFEState>();
82       e2states.put( effect, states );
83     }
84     states.add( stateTo );
85
86     ++stateTo.refCount;
87   }
88
89
90   public int getID() {
91     return id;
92   }
93
94   // once you get your hands on an SMFEState in the
95   // RuntimeConflictResolver side of things, this is how you
96   // find out what effects are possible in this state
97   public Set<Effect> getEffectsAllowed() {
98     return effects;
99   }
100   
101   public Set<Effect> getConflicts() {
102     //TODO JIM! Fix this when have a chance!
103     conflicts.addAll(effects);
104     return this.conflicts;
105   }
106   
107   public Set<Alloc> getStartingAllocs() {
108     return startingAllocs;
109   }
110   
111   public Set<Effect> getTransistionEffects() {
112     return this.e2states.keySet();
113   }
114
115   // some subset of the above effects may transition to
116   // other states
117   public Set<SMFEState> transitionsTo( Effect e ) {
118     Set<SMFEState> statesOut = e2states.get( e );
119     if( statesOut == null ) {
120       statesOut = new HashSet<SMFEState>();
121     }
122     return statesOut;
123   }
124
125   public int getRefCount() {
126     return refCount;
127   }
128
129
130   public boolean equals( Object o ) {
131     if( o == null ) {
132       return false;
133     }
134
135     if( !(o instanceof SMFEState) ) {
136       return false;
137     }
138
139     SMFEState state = (SMFEState) o;
140
141     return id == state.id;
142   }
143
144   public int hashCode() {
145     return iHashCode;
146   }
147
148
149   public String toStringDOT() {
150     
151     // first create the state as a node in DOT graph
152     String s = "  "+id+"[shape=box,label=\"";
153
154     if( effects.size() == 1 ) {
155       s += effects.iterator().next().toString();
156
157     } else if( effects.size() > 1 ) {
158
159       Iterator<Effect> eItr = effects.iterator();
160       while( eItr.hasNext() ) {
161         Effect e = eItr.next();
162         s += e.toString();
163
164         if( eItr.hasNext() ) {
165           s += "\\n";
166         }
167       }
168     }
169
170     s += "\"];";
171
172     // then each transition is an edge
173     Iterator<Effect> eItr = e2states.keySet().iterator();
174     while( eItr.hasNext() ) {
175       Effect         e      = eItr.next();
176       Set<SMFEState> states = e2states.get( e );
177
178       Iterator<SMFEState> sItr = states.iterator();
179       while( sItr.hasNext() ) {
180         SMFEState state = sItr.next();
181
182         s += "\n  "+
183           id+" -> "+state.id+
184           "[label=\""+e+"\"];";
185       }
186     }
187
188     return s;
189   }
190
191 }