switch to spaces only..
[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   protected FlatNode whereDefined;
52
53   public SMFEState(FlatNode fnWhereDefined, int id) {
54     this.id         = id;
55     this.iHashCode  = fnWhereDefined.hashCode();
56     this.whereDefined=fnWhereDefined;
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> getTransitionEffects() {
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,";
156     if (conflicts.size()>0 ) {
157       s+="peripheries=2,";
158     }
159     s+="label=\"";
160
161     if( effects.size() >= 1 ) {
162
163       Iterator<Effect> eItr = effects.iterator();
164       while( eItr.hasNext() ) {
165         Effect e = eItr.next();
166         if (conflicts.contains(e)) {
167           s += "["+e.toString()+"]";
168         } else {
169           s += e.toString();
170         }
171         if( eItr.hasNext() ) {
172           s += "\\n";
173         }
174       }
175     }
176
177     s += "\"];";
178
179     // then each transition is an edge
180     Iterator<Effect> eItr = e2states.keySet().iterator();
181     while( eItr.hasNext() ) {
182       Effect e      = eItr.next();
183       Set<SMFEState> states = e2states.get(e);
184
185       Iterator<SMFEState> sItr = states.iterator();
186       while( sItr.hasNext() ) {
187         SMFEState state = sItr.next();
188
189         s += "\n  "+
190              id+" -> "+state.id+
191              "[label=\""+e+", RC="+refCount+"\"";
192         if (conflicts.contains(e))
193           s+=",style=dashed";
194         s+="];";
195       }
196     }
197
198     return s;
199   }
200
201 }