stable capture, bug fixes--a problem: using an SESEs liveIn set liberally, some cases...
[IRC.git] / Robust / src / Analysis / MLP / VarSrcTokTable.java
1 package Analysis.MLP;\r
2 \r
3 import IR.*;\r
4 import IR.Flat.*;\r
5 import java.util.*;\r
6 import java.io.*;\r
7 \r
8 // This class formerly had lazy consistency properties, but\r
9 // it is being changed so that the full set and the extra\r
10 // hash tables to access the full set efficiently by different\r
11 // elements will be consistent after EVERY operation.  Also,\r
12 // a consistent assert method allows a debugger to ask whether\r
13 // an operation has produced an inconsistent VarSrcTokTable.\r
14 public class VarSrcTokTable {\r
15 \r
16   // a set of every token in the table\r
17   private HashSet<VariableSourceToken> trueSet;\r
18 \r
19   // these hashtables provide an efficient retreival from the true set\r
20   private Hashtable< TempDescriptor,    Set<VariableSourceToken> >  var2vst;\r
21   private Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> > sese2vst;\r
22   private Hashtable< SVKey,             Set<VariableSourceToken> >   sv2vst;\r
23 \r
24   // maximum age from aging operation\r
25   private Integer MAX_AGE = new Integer( 2 );\r
26 \r
27 \r
28   public VarSrcTokTable() {\r
29     trueSet = new HashSet<VariableSourceToken>();\r
30 \r
31     sese2vst = new Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> >();\r
32     var2vst  = new Hashtable< TempDescriptor,    Set<VariableSourceToken> >();\r
33     sv2vst   = new Hashtable< SVKey,             Set<VariableSourceToken> >();\r
34   }\r
35 \r
36   \r
37   public VarSrcTokTable( VarSrcTokTable in ) {\r
38     trueSet = (HashSet<VariableSourceToken>) in.trueSet.clone();\r
39 \r
40     Iterator itr; Set s;\r
41 \r
42     sese2vst = new Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> >();\r
43     itr = in.sese2vst.entrySet().iterator();\r
44     while( itr.hasNext() ) {\r
45       Map.Entry                    me   = (Map.Entry)                    itr.next();\r
46       FlatSESEEnterNode            sese = (FlatSESEEnterNode)            me.getKey();\r
47       HashSet<VariableSourceToken> s1   = (HashSet<VariableSourceToken>) me.getValue();      \r
48       assert s1 != null;\r
49       sese2vst.put( sese, \r
50                     (HashSet<VariableSourceToken>) (s1.clone()) );\r
51     }\r
52 \r
53     var2vst = new Hashtable< TempDescriptor, Set<VariableSourceToken> >();\r
54     itr = in.var2vst.entrySet().iterator();\r
55     while( itr.hasNext() ) {\r
56       Map.Entry                    me  = (Map.Entry)                    itr.next();\r
57       TempDescriptor               var = (TempDescriptor)               me.getKey();\r
58       HashSet<VariableSourceToken> s1  = (HashSet<VariableSourceToken>) me.getValue();      \r
59       assert s1 != null;\r
60       var2vst.put( var, \r
61                    (HashSet<VariableSourceToken>) (s1.clone()) );\r
62     }\r
63 \r
64     sv2vst = new Hashtable< SVKey, Set<VariableSourceToken> >();\r
65     itr = in.sv2vst.entrySet().iterator();\r
66     while( itr.hasNext() ) {\r
67       Map.Entry                    me  = (Map.Entry)                    itr.next();\r
68       SVKey                        key = (SVKey)                        me.getKey();\r
69       HashSet<VariableSourceToken> s1  = (HashSet<VariableSourceToken>) me.getValue();      \r
70       assert s1 != null;\r
71       sv2vst.put( key, \r
72                   (HashSet<VariableSourceToken>) (s1.clone()) );\r
73     }\r
74   }\r
75 \r
76 \r
77   public void add( VariableSourceToken vst ) {\r
78     trueSet.add( vst );\r
79 \r
80     Set<VariableSourceToken> s;\r
81 \r
82     s = sese2vst.get( vst.getSESE() );\r
83     if( s == null ) {\r
84       s = new HashSet<VariableSourceToken>();\r
85     }\r
86     s.add( vst );\r
87     sese2vst.put( vst.getSESE(), s );\r
88 \r
89     s = var2vst.get( vst.getVarLive() );\r
90     if( s == null ) {\r
91       s = new HashSet<VariableSourceToken>();\r
92     }\r
93     s.add( vst );\r
94     var2vst.put( vst.getVarLive(), s );\r
95 \r
96     SVKey key = new SVKey( vst.getSESE(), vst.getVarLive() );\r
97     s = sv2vst.get( key );\r
98     if( s == null ) {\r
99       s = new HashSet<VariableSourceToken>();\r
100     }\r
101     s.add( vst );\r
102     sv2vst.put( key, s );\r
103   }\r
104 \r
105   public void addAll( Set<VariableSourceToken> s ) {\r
106     Iterator<VariableSourceToken> itr = s.iterator();\r
107     while( itr.hasNext() ) {\r
108       add( itr.next() );\r
109     }\r
110   }\r
111 \r
112 \r
113   public Set<VariableSourceToken> get() {\r
114     return trueSet;\r
115   }\r
116 \r
117   public Set<VariableSourceToken> get( FlatSESEEnterNode sese ) {\r
118     Set<VariableSourceToken> s = sese2vst.get( sese );\r
119     if( s == null ) {\r
120       s = new HashSet<VariableSourceToken>();      \r
121       sese2vst.put( sese, s );\r
122     }\r
123     return s;\r
124   }\r
125 \r
126   public Set<VariableSourceToken> get( TempDescriptor var ) {\r
127     Set<VariableSourceToken> s = var2vst.get( var );\r
128     if( s == null ) {\r
129       s = new HashSet<VariableSourceToken>();\r
130       var2vst.put( var, s );\r
131     }\r
132     return s;\r
133   }\r
134 \r
135   public Set<VariableSourceToken> get( SVKey key ) {\r
136     Set<VariableSourceToken> s = sv2vst.get( key );\r
137     if( s == null ) {\r
138       s = new HashSet<VariableSourceToken>();\r
139       sv2vst.put( key, s );\r
140     }\r
141     return s;\r
142   }\r
143 \r
144 \r
145   public void merge( VarSrcTokTable tableIn ) {\r
146 \r
147     if( tableIn == null ) {\r
148       return;\r
149     }\r
150 \r
151     // make a copy for modification to use in the merge\r
152     VarSrcTokTable table = new VarSrcTokTable( tableIn );\r
153 \r
154 \r
155     trueSet.addAll( table.trueSet );\r
156 \r
157 \r
158     Iterator itr; \r
159 \r
160     // merge sese2vst mappings\r
161     itr = this.sese2vst.entrySet().iterator();\r
162     while( itr.hasNext() ) {\r
163       Map.Entry                me   = (Map.Entry)                itr.next();\r
164       FlatSESEEnterNode        sese = (FlatSESEEnterNode)        me.getKey();\r
165       Set<VariableSourceToken> s1   = (Set<VariableSourceToken>) me.getValue();\r
166       Set<VariableSourceToken> s2   = table.sese2vst.get( sese );     \r
167       assert s1 != null;\r
168 \r
169       if( s2 != null ) {\r
170         s1.addAll( s2 );\r
171       }\r
172     }\r
173     itr = table.sese2vst.entrySet().iterator();\r
174     while( itr.hasNext() ) {\r
175       Map.Entry                me   = (Map.Entry)                itr.next();\r
176       FlatSESEEnterNode        sese = (FlatSESEEnterNode)        me.getKey();\r
177       Set<VariableSourceToken> s2   = (Set<VariableSourceToken>) me.getValue();\r
178       Set<VariableSourceToken> s1   = this.sese2vst.get( sese );\r
179       assert s2 != null;\r
180 \r
181       if( s1 == null ) {\r
182         this.sese2vst.put( sese, s2 );\r
183       }      \r
184     }\r
185 \r
186     // merge var2vst mappings\r
187     itr = this.var2vst.entrySet().iterator();\r
188     while( itr.hasNext() ) {\r
189       Map.Entry                me  = (Map.Entry)                itr.next();\r
190       TempDescriptor           var = (TempDescriptor)           me.getKey();\r
191       Set<VariableSourceToken> s1  = (Set<VariableSourceToken>) me.getValue();\r
192       Set<VariableSourceToken> s2  = table.var2vst.get( var );      \r
193       assert s1 != null;\r
194 \r
195       if( s2 != null ) {\r
196         s1.addAll( s2 );\r
197       }           \r
198     }\r
199     itr = table.var2vst.entrySet().iterator();\r
200     while( itr.hasNext() ) {\r
201       Map.Entry                me   = (Map.Entry)                itr.next();\r
202       TempDescriptor           var  = (TempDescriptor)           me.getKey();\r
203       Set<VariableSourceToken> s2   = (Set<VariableSourceToken>) me.getValue();\r
204       Set<VariableSourceToken> s1   = this.var2vst.get( var );\r
205       assert s2 != null;\r
206 \r
207       if( s1 == null ) {\r
208         this.var2vst.put( var, s2 );\r
209       }      \r
210     }\r
211 \r
212     // merge sv2vst mappings\r
213     itr = this.sv2vst.entrySet().iterator();\r
214     while( itr.hasNext() ) {\r
215       Map.Entry                me  = (Map.Entry)                itr.next();\r
216       SVKey                    key = (SVKey)                    me.getKey();\r
217       Set<VariableSourceToken> s1  = (Set<VariableSourceToken>) me.getValue();\r
218       Set<VariableSourceToken> s2  = table.sv2vst.get( key );      \r
219       assert s1 != null;\r
220 \r
221       if( s2 != null ) {\r
222         s1.addAll( s2 );\r
223       }           \r
224     }\r
225     itr = table.sv2vst.entrySet().iterator();\r
226     while( itr.hasNext() ) {\r
227       Map.Entry                me   = (Map.Entry)                itr.next();\r
228       SVKey                    key  = (SVKey)                    me.getKey();\r
229       Set<VariableSourceToken> s2   = (Set<VariableSourceToken>) me.getValue();\r
230       Set<VariableSourceToken> s1   = this.sv2vst.get( key );\r
231       assert s2 != null;\r
232 \r
233       if( s1 == null ) {\r
234         this.sv2vst.put( key, s2 );\r
235       }      \r
236     }\r
237   }\r
238 \r
239 \r
240   // remove operations must leave the trueSet \r
241   // and the hash maps consistent!\r
242   public void remove( VariableSourceToken vst ) {\r
243     trueSet.remove( vst );\r
244     \r
245     Set<VariableSourceToken> s;\r
246 \r
247     s = get( vst.getSESE() );\r
248     if( s != null ) { s.remove( vst ); }\r
249 \r
250     s = get( vst.getVarLive() );\r
251     if( s != null ) { s.remove( vst ); }\r
252 \r
253     s = get( new SVKey( vst.getSESE(), vst.getVarLive() ) );\r
254     if( s != null ) { s.remove( vst ); }\r
255   }\r
256 \r
257   public void remove( FlatSESEEnterNode sese ) {\r
258     Set<VariableSourceToken> s = sese2vst.get( sese );\r
259     if( s == null ) {\r
260       return;\r
261     }\r
262     \r
263     trueSet.removeAll( s );\r
264     sese2vst.remove( sese );\r
265 \r
266     Iterator<VariableSourceToken> itr = s.iterator();\r
267     while( itr.hasNext() ) {\r
268       VariableSourceToken vst = itr.next();\r
269       remove( vst );\r
270     }\r
271   }\r
272 \r
273   public void remove( TempDescriptor var ) {\r
274     Set<VariableSourceToken> s = var2vst.get( var );\r
275     if( s == null ) {\r
276       return;\r
277     }\r
278     \r
279     trueSet.removeAll( s );        \r
280     var2vst.remove( var );\r
281 \r
282     Iterator<VariableSourceToken> itr = s.iterator();\r
283     while( itr.hasNext() ) {\r
284       VariableSourceToken vst = itr.next();\r
285       remove( vst );\r
286     }\r
287   }\r
288 \r
289   public void remove( FlatSESEEnterNode sese,\r
290                       TempDescriptor    var  ) {\r
291 \r
292     SVKey key = new SVKey( sese, var );\r
293     Set<VariableSourceToken> s = sv2vst.get( key );\r
294     if( s == null ) {\r
295       return;\r
296     }\r
297     \r
298     trueSet.removeAll( s );\r
299     sv2vst.remove( key );\r
300 \r
301     Iterator<VariableSourceToken> itr = s.iterator();\r
302     while( itr.hasNext() ) {\r
303       VariableSourceToken vst = itr.next();\r
304       remove( vst );\r
305     }\r
306   }\r
307 \r
308 \r
309 \r
310   // return a new table based on this one and\r
311   // age tokens with respect to SESE curr, where\r
312   // any curr tokens increase age by 1\r
313   public VarSrcTokTable age( FlatSESEEnterNode curr ) {\r
314 \r
315     // create a table to modify as a copy of this\r
316     VarSrcTokTable out = new VarSrcTokTable( this );\r
317 \r
318     Iterator<VariableSourceToken> itr = trueSet.iterator();\r
319     while( itr.hasNext() ) {\r
320       VariableSourceToken vst = itr.next();\r
321 \r
322       if( vst.getSESE().equals( curr ) ) {\r
323 \r
324         Integer newAge = vst.getAge()+1;\r
325         if( newAge > MAX_AGE ) {\r
326           newAge = MAX_AGE;\r
327         }\r
328 \r
329         out.remove( vst );\r
330 \r
331         out.add( new VariableSourceToken( vst.getVarLive(), \r
332                                           curr,                                           \r
333                                           newAge,\r
334                                           vst.getVarSrc() \r
335                                           )\r
336                  );\r
337       } \r
338     }\r
339 \r
340     return out;\r
341   }\r
342 \r
343   \r
344   // for the given SESE, change child tokens into this parent\r
345   public void remapChildTokens( FlatSESEEnterNode curr ) {\r
346 \r
347     Iterator<FlatSESEEnterNode> childItr = curr.getChildren().iterator();\r
348     if( childItr.hasNext() ) {\r
349       FlatSESEEnterNode child = childItr.next();\r
350       \r
351       Iterator<VariableSourceToken> vstItr = get( child ).iterator();\r
352       while( vstItr.hasNext() ) {\r
353         VariableSourceToken vst = vstItr.next();\r
354 \r
355         remove( vst );\r
356 \r
357         add( new VariableSourceToken( vst.getVarLive(),\r
358                                       curr,\r
359                                       new Integer( 0 ),\r
360                                       vst.getVarLive() ) );\r
361       }\r
362     }\r
363   }   \r
364 \r
365 \r
366   // if we can get a value from the current SESE and the parent\r
367   // or a sibling, just getting from the current SESE suffices now\r
368   // return a set of temps that are virtually read\r
369   public Set<TempDescriptor> removeParentAndSiblingTokens( FlatSESEEnterNode curr,\r
370                                                            Set<TempDescriptor> liveIn ) {\r
371 \r
372     HashSet<TempDescriptor> virtualLiveIn = new HashSet<TempDescriptor>();\r
373 \r
374     FlatSESEEnterNode parent = curr.getParent();\r
375     if( parent == null ) {\r
376       // have no parent or siblings\r
377       return virtualLiveIn;\r
378     }      \r
379 \r
380     remove_A_if_B( parent, curr, liveIn, virtualLiveIn );\r
381 \r
382     Iterator<FlatSESEEnterNode> childItr = parent.getChildren().iterator();\r
383     if( childItr.hasNext() ) {\r
384       FlatSESEEnterNode child = childItr.next();\r
385 \r
386       if( !child.equals( curr ) ) {\r
387         remove_A_if_B( child, curr, liveIn, virtualLiveIn );\r
388       }\r
389     }\r
390     \r
391     return virtualLiveIn;\r
392   }\r
393   \r
394   // if B is also a source for some variable, remove all entries\r
395   // of A as a source for that variable: s is virtual reads\r
396   protected void remove_A_if_B( FlatSESEEnterNode a, \r
397                                 FlatSESEEnterNode b,\r
398                                 Set<TempDescriptor> liveInCurrentSESE,\r
399                                 Set<TempDescriptor> virtualLiveIn ) {\r
400 \r
401     Set<VariableSourceToken> forRemoval = new HashSet<VariableSourceToken>();\r
402 \r
403     Iterator<VariableSourceToken> vstItr = get( a ).iterator();\r
404     while( vstItr.hasNext() ) {\r
405       VariableSourceToken      vst     = vstItr.next();\r
406       TempDescriptor           varLive = vst.getVarLive();\r
407       Set<VariableSourceToken> bSet    = get( new SVKey( b, varLive ) );\r
408       \r
409       if( !bSet.isEmpty() ) {\r
410         forRemoval.add( vst );\r
411 \r
412         // mark this variable as a virtual read as well\r
413         //if( liveInCurrentSESE.contains( varLive ) ) { ???????????\r
414         virtualLiveIn.add( varLive );\r
415         //}\r
416       }\r
417     }\r
418 \r
419     /*\r
420     System.out.println( "remove "+a.getPrettyIdentifier()+" if "+b.getPrettyIdentifier() );\r
421     System.out.println( "THIS "+toStringPretty() );\r
422     System.out.println( "for removal="+forRemoval );\r
423     */\r
424 \r
425     vstItr = forRemoval.iterator();\r
426     while( vstItr.hasNext() ) {\r
427       VariableSourceToken vst = vstItr.next();\r
428       remove( vst );\r
429     }\r
430   }\r
431 \r
432 \r
433   public Set<VariableSourceToken> getStallSet( FlatSESEEnterNode curr ) {\r
434 \r
435     Set<VariableSourceToken> out = new HashSet<VariableSourceToken>();\r
436 \r
437     Iterator<FlatSESEEnterNode> cItr = curr.getChildren().iterator();\r
438     while( cItr.hasNext() ) {\r
439       FlatSESEEnterNode child = cItr.next();\r
440       out.addAll( get( child ) );\r
441     }\r
442 \r
443     return out;\r
444   }\r
445 \r
446 \r
447   // use as an aid for debugging, where true-set is checked\r
448   // against the alternate mappings: assert that nothing is\r
449   // missing or extra in the alternates\r
450   public void assertConsistency() {\r
451 \r
452     Iterator itr; \r
453     Set s;\r
454 \r
455     Set<VariableSourceToken> trueSetByAlts = new HashSet<VariableSourceToken>();\r
456 \r
457     itr = sese2vst.entrySet().iterator();\r
458     while( itr.hasNext() ) {\r
459       Map.Entry                    me   = (Map.Entry)                    itr.next();\r
460       FlatSESEEnterNode            sese = (FlatSESEEnterNode)            me.getKey();\r
461       HashSet<VariableSourceToken> s1   = (HashSet<VariableSourceToken>) me.getValue();      \r
462       assert s1 != null;\r
463       \r
464       // the trueSet should have all entries in s1\r
465       assert trueSet.containsAll( s1 );\r
466 \r
467       // s1 should not have anything that doesn't appear in trueset\r
468       Set<VariableSourceToken> sInt = (Set<VariableSourceToken>) s1.clone();\r
469       sInt.removeAll( trueSet );\r
470 \r
471       assert sInt.isEmpty();\r
472 \r
473       // add s1 to a running union--at the end check if trueSet has extra\r
474       trueSetByAlts.addAll( s1 );\r
475     }\r
476 \r
477     // make sure trueSet isn't too big\r
478     assert trueSetByAlts.containsAll( trueSet );\r
479   }\r
480 \r
481 \r
482   public boolean equals( Object o ) {\r
483     if( o == null ) {\r
484       return false;\r
485     }\r
486 \r
487     if( !(o instanceof VarSrcTokTable) ) {\r
488       return false;\r
489     }\r
490 \r
491     VarSrcTokTable table = (VarSrcTokTable) o;\r
492     return trueSet.equals( table.trueSet );\r
493   }\r
494 \r
495   public int hashCode() {\r
496     return trueSet.hashCode();\r
497   }\r
498 \r
499   public Iterator<VariableSourceToken> iterator() {\r
500     return trueSet.iterator();\r
501   }\r
502 \r
503   public String toString() {\r
504     return "trueSet ="+trueSet.toString();\r
505   }\r
506 \r
507   public String toStringVerbose() {\r
508     return "trueSet ="+trueSet.toString()+"\n"+\r
509            "sese2vst="+sese2vst.toString()+"\n"+\r
510            "var2vst ="+var2vst.toString()+"\n"+\r
511            "sv2vst  ="+sv2vst.toString();\r
512   }\r
513 \r
514   public String toStringPretty() {\r
515     String tokHighlighter = "o";\r
516 \r
517     String str = "VarSrcTokTable\n";\r
518     Iterator<VariableSourceToken> vstItr = trueSet.iterator();    \r
519     while( vstItr.hasNext() ) {\r
520       str += "   "+tokHighlighter+" "+vstItr.next()+"\n";\r
521     }\r
522     return str;\r
523   }\r
524 \r
525   public String toStringPrettyVerbose() {\r
526     String tokHighlighter = "o";\r
527 \r
528     String str = "VarSrcTokTable\n";\r
529 \r
530     Set s;\r
531     Iterator itr; \r
532     Iterator<VariableSourceToken> vstItr;\r
533 \r
534     str += "  trueSet\n";\r
535     vstItr = trueSet.iterator();    \r
536     while( vstItr.hasNext() ) {\r
537       str += "     "+tokHighlighter+" "+vstItr.next()+"\n";\r
538     }\r
539 \r
540     str += "  sese2vst\n";\r
541     itr = sese2vst.entrySet().iterator();\r
542     while( itr.hasNext() ) {\r
543       Map.Entry                    me   = (Map.Entry)                    itr.next();\r
544       FlatSESEEnterNode            sese = (FlatSESEEnterNode)            me.getKey();\r
545       HashSet<VariableSourceToken> s1   = (HashSet<VariableSourceToken>) me.getValue();      \r
546       assert s1 != null;\r
547 \r
548       str += "    "+sese.getPrettyIdentifier()+" -> \n";\r
549 \r
550       vstItr = s1.iterator();\r
551       while( vstItr.hasNext() ) {\r
552         str += "       "+tokHighlighter+" "+vstItr.next()+"\n";\r
553       }\r
554     }\r
555 \r
556     str += "  var2vst\n";\r
557     itr = var2vst.entrySet().iterator();\r
558     while( itr.hasNext() ) {\r
559       Map.Entry                me  = (Map.Entry)                itr.next();\r
560       TempDescriptor           var = (TempDescriptor)           me.getKey();\r
561       Set<VariableSourceToken> s1  = (Set<VariableSourceToken>) me.getValue();\r
562       assert s1 != null;\r
563 \r
564       str += "    "+var+" -> \n";\r
565 \r
566       vstItr = s1.iterator();\r
567       while( vstItr.hasNext() ) {\r
568         str += "       "+tokHighlighter+" "+vstItr.next()+"\n";\r
569       }\r
570     }\r
571 \r
572     str += "  sv2vst\n";\r
573     itr = sv2vst.entrySet().iterator();\r
574     while( itr.hasNext() ) {\r
575       Map.Entry                me  = (Map.Entry)                itr.next();\r
576       SVKey                    key = (SVKey)                    me.getKey();\r
577       Set<VariableSourceToken> s1  = (Set<VariableSourceToken>) me.getValue();\r
578       assert s1 != null;\r
579 \r
580       str += "    "+key+" -> \n";\r
581 \r
582       vstItr = s1.iterator();\r
583       while( vstItr.hasNext() ) {\r
584         str += "       "+tokHighlighter+" "+vstItr.next()+"\n";\r
585       }\r
586     }\r
587 \r
588     return str;\r
589   }\r
590 }\r