we took DFJ and broke its arm, and we'll reset the bones in an upcoming patch
[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
38   // all possible effects in this state
39   protected Set<Effect> effects;
40
41   // the given effect allows a transition to a
42   // set of new states
43   protected Hashtable< Effect, Set<SMFEState> > e2states;
44
45   // useful for knowing when a state can be inlined during
46   // code gen
47   protected int refCount;
48
49
50   
51   public SMFEState( FlatNode fnWhereDefined ) {
52
53     this.id        = fnWhereDefined.nodeid;
54     this.iHashCode = fnWhereDefined.hashCode();
55
56     effects  = new HashSet<Effect>();
57     e2states = new Hashtable< Effect, Set<SMFEState> >();
58     refCount = 0;
59   }
60
61   public void addEffect( Effect e ) {
62     effects.add( e );
63   }
64
65   // the given effect allows the transition to the new state
66   public void addTransition( Effect    effect,
67                              SMFEState stateTo
68                              ) {
69
70     Set<SMFEState> states = e2states.get( effect );
71     if( states == null ) {
72       states = new HashSet<SMFEState>();
73       e2states.put( effect, states );
74     }
75     states.add( stateTo );
76
77     ++stateTo.refCount;
78   }
79
80
81   public int getID() {
82     return id;
83   }
84
85   // once you get your hands on an SMFEState in the
86   // RuntimeConflictResolver side of things, this is how you
87   // find out what effects are possible in this state
88   public Set<Effect> getEffectsAllowed() {
89     return effects;
90   }
91
92   // some subset of the above effects may transition to
93   // other states
94   public Set<SMFEState> transitionsTo( Effect e ) {
95     Set<SMFEState> statesOut = e2states.get( e );
96     if( statesOut == null ) {
97       statesOut = new HashSet<SMFEState>();
98     }
99     return statesOut;
100   }
101
102   public int getRefCount() {
103     return refCount;
104   }
105
106
107   public boolean equals( Object o ) {
108     if( o == null ) {
109       return false;
110     }
111
112     if( !(o instanceof SMFEState) ) {
113       return false;
114     }
115
116     SMFEState state = (SMFEState) o;
117
118     return id == state.id;
119   }
120
121   public int hashCode() {
122     return iHashCode;
123   }
124
125
126   public String toStringDOT() {
127     
128     // first create the state as a node in DOT graph
129     String s = "  "+id+"[shape=box,label=\"";
130
131     if( effects.size() == 1 ) {
132       s += effects.iterator().next().toString();
133
134     } else if( effects.size() > 1 ) {
135
136       Iterator<Effect> eItr = effects.iterator();
137       while( eItr.hasNext() ) {
138         Effect e = eItr.next();
139         s += e.toString();
140
141         if( eItr.hasNext() ) {
142           s += "\\n";
143         }
144       }
145     }
146
147     s += "\"];";
148
149     // then each transition is an edge
150     Iterator<Effect> eItr = e2states.keySet().iterator();
151     while( eItr.hasNext() ) {
152       Effect         e      = eItr.next();
153       Set<SMFEState> states = e2states.get( e );
154
155       Iterator<SMFEState> sItr = states.iterator();
156       while( sItr.hasNext() ) {
157         SMFEState state = sItr.next();
158
159         s += "\n  "+
160           id+" -> "+state.id+
161           "[label=\""+e+"\"];";
162       }
163     }
164
165     return s;
166   }
167
168 }