at task exit, a task should acquire any out-set variables that arent already it the...
[IRC.git] / Robust / src / Analysis / OoOJava / VarSrcTokTable.java
1 package Analysis.OoOJava;
2
3 import IR.*;
4 import IR.Flat.*;
5 import java.util.*;
6 import java.io.*;
7 import Analysis.Pointer.MySet;
8
9 // This class formerly had lazy consistency properties, but
10 // it is being changed so that the full set and the extra
11 // hash tables to access the full set efficiently by different
12 // elements will be consistent after EVERY operation.  Also,
13 // a consistent assert method allows a debugger to ask whether
14 // an operation has produced an inconsistent VarSrcTokTable.
15
16 // in an effort to make sure operations keep the table consistent,
17 // all public methods that are also used by other methods for
18 // intermediate results (add and remove are used in other methods)
19 // there should be a public version that calls the private version
20 // so consistency is checked after public ops, but not private ops
21 public class VarSrcTokTable {
22
23   // a set of every token in the table
24   private MySet<VariableSourceToken> trueSet;
25
26   // these hashtables provide an efficient retreival from the true set
27   private Hashtable< TempDescriptor,    Set<VariableSourceToken> >  var2vst;
28   private Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> > sese2vst;
29   private Hashtable< SVKey,             Set<VariableSourceToken> >   sv2vst;
30
31   // maximum age from aging operation
32   private static final Integer MAX_AGE = new Integer( 2 );
33   
34   public static final Integer SrcType_READY   = new Integer( 34 );
35   public static final Integer SrcType_STATIC  = new Integer( 35 );
36   public static final Integer SrcType_DYNAMIC = new Integer( 36 );
37
38   public static RBlockRelationAnalysis rblockRel;
39
40
41
42   public VarSrcTokTable() {
43     trueSet  = new MySet<VariableSourceToken>();
44
45     sese2vst = new Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> >();
46     var2vst  = new Hashtable< TempDescriptor,    Set<VariableSourceToken> >();
47     sv2vst   = new Hashtable< SVKey,             Set<VariableSourceToken> >();
48
49     assertConsistency();
50   }
51
52
53   // make a deep copy of the in table
54   public VarSrcTokTable( VarSrcTokTable in ) {
55     this();
56     merge( in );
57     assertConsistency();
58   }
59
60
61   public void add( VariableSourceToken vst ) {
62     addPrivate( vst );
63     assertConsistency();
64   }
65
66   private void addPrivate( VariableSourceToken vst ) {
67
68     // make sure we aren't clobbering anything!
69     if( trueSet.contains( vst ) ) {
70       // if something with the same hashcode is in the true set, they might
71       // have different reference variable sets because that set is not considered
72       // in a token's equality, so make sure we smooth that out right here
73
74       VariableSourceToken vstAlready = trueSet.get(vst);
75       if (vstAlready!=null) {
76         removePrivate( vstAlready );
77         HashSet<TempDescriptor> toAddSet=new HashSet<TempDescriptor>();
78         toAddSet.addAll(vstAlready.getRefVars());
79         toAddSet.addAll(vst.getRefVars());
80         vst.setRefVars(toAddSet);
81       }
82     }
83
84     trueSet.add( vst );
85
86     Set<VariableSourceToken> s = sese2vst.get( vst.getSESE() );
87     if( s == null ) {
88       s = new HashSet<VariableSourceToken>();
89       sese2vst.put( vst.getSESE(), s );
90     }
91     s.add( vst );
92
93     Iterator<TempDescriptor> refVarItr = vst.getRefVars().iterator();
94     while( refVarItr.hasNext() ) {
95       TempDescriptor refVar = refVarItr.next();
96       s = var2vst.get( refVar );
97       if( s == null ) {
98         s = new HashSet<VariableSourceToken>();
99         var2vst.put( refVar, s );
100       }
101       s.add( vst );
102
103       SVKey key = new SVKey( vst.getSESE(), refVar );
104       s = sv2vst.get( key );
105       if( s == null ) {
106         s = new HashSet<VariableSourceToken>();
107         sv2vst.put( key, s );
108       }
109       s.add( vst );
110     }
111   }
112
113   public void addAll( Set<VariableSourceToken> s ) {
114     Iterator<VariableSourceToken> itr = s.iterator();
115     while( itr.hasNext() ) {
116       addPrivate( itr.next() );
117     }
118     assertConsistency();
119   }
120
121
122   public Set<VariableSourceToken> get() {
123     return trueSet;
124   }
125
126   public Set<VariableSourceToken> get( FlatSESEEnterNode sese ) {
127     Set<VariableSourceToken> s = sese2vst.get( sese );
128     if( s == null ) {
129       s = new HashSet<VariableSourceToken>();      
130       sese2vst.put( sese, s );
131     }
132     return s;
133   }
134
135   public Set<VariableSourceToken> get( TempDescriptor refVar ) {
136     Set<VariableSourceToken> s = var2vst.get( refVar );
137     if( s == null ) {
138       s = new HashSet<VariableSourceToken>();
139       var2vst.put( refVar, s );
140     }
141     return s;
142   }
143
144   public Set<VariableSourceToken> get( FlatSESEEnterNode sese,
145                                        TempDescriptor    refVar ) {
146     SVKey key = new SVKey( sese, refVar );
147     Set<VariableSourceToken> s = sv2vst.get( key );
148     if( s == null ) {
149       s = new HashSet<VariableSourceToken>();
150       sv2vst.put( key, s );
151     }
152     return s;
153   }
154
155   public Set<VariableSourceToken> get( FlatSESEEnterNode sese,
156                                        Integer           age ) {
157
158     HashSet<VariableSourceToken> s0 = (HashSet<VariableSourceToken>) sese2vst.get( sese );
159     if( s0 == null ) {
160       s0 = new HashSet<VariableSourceToken>();      
161       sese2vst.put( sese, s0 );
162     }
163
164     Set<VariableSourceToken> s = (Set<VariableSourceToken>) s0.clone();
165     Iterator<VariableSourceToken> sItr = s.iterator();
166     while( sItr.hasNext() ) {
167       VariableSourceToken vst = sItr.next();
168       if( !vst.getAge().equals( age ) ) {
169         s.remove( vst );
170       }
171     }
172
173     return s;
174   }
175
176
177   // merge now makes a deep copy of incoming stuff because tokens may
178   // be modified (reference var sets) by later ops that change more
179   // than one table, causing inconsistency
180   public void merge( VarSrcTokTable in ) {
181
182     if( in == null ) {
183       return;
184     }
185
186     Iterator<VariableSourceToken> vstItr = in.trueSet.iterator();
187     while( vstItr.hasNext() ) {
188       VariableSourceToken vst = vstItr.next();
189       this.addPrivate( vst.copy() );
190     }
191
192     assertConsistency();
193   }
194
195
196   // remove operations must leave the trueSet 
197   // and the hash maps consistent
198   public void remove( VariableSourceToken vst ) {
199     removePrivate( vst );
200     assertConsistency();
201   }
202
203   private void removePrivate( VariableSourceToken vst ) {
204     trueSet.remove( vst );
205     
206     Set<VariableSourceToken> s;
207
208     s = get( vst.getSESE() );
209     if( s != null ) { s.remove( vst ); }
210
211     Iterator<TempDescriptor> refVarItr = vst.getRefVars().iterator();
212     while( refVarItr.hasNext() ) {
213       TempDescriptor refVar = refVarItr.next();
214
215       s = get( refVar );
216       if( s != null ) { 
217         s.remove( vst );
218         if( s.isEmpty() ) {
219           var2vst.remove( refVar );
220         }
221       }
222       
223       s = get( vst.getSESE(), refVar );
224       if( s != null ) { 
225         s.remove( vst );
226         if( s.isEmpty() ) {
227           sv2vst.remove( new SVKey( vst.getSESE(), refVar ) );
228         }
229       }
230     }
231   }
232
233
234   public void remove( FlatSESEEnterNode sese ) {
235     removePrivate( sese );
236     assertConsistency();
237   }
238
239   public void removePrivate( FlatSESEEnterNode sese ) {
240     Set<VariableSourceToken> s = sese2vst.get( sese );
241     if( s == null ) {
242       return;
243     }
244
245     Iterator<VariableSourceToken> itr = s.iterator();
246     while( itr.hasNext() ) {
247       VariableSourceToken vst = itr.next();
248       removePrivate( vst );
249     }
250
251     sese2vst.remove( sese );
252   }
253
254
255   public void remove( TempDescriptor refVar ) {
256     removePrivate( refVar );
257     assertConsistency();
258   }
259
260   private void removePrivate( TempDescriptor refVar ) {
261     Set<VariableSourceToken> s = var2vst.get( refVar );
262     if( s == null ) {
263       return;
264     }
265     
266     Set<VariableSourceToken> forRemoval = new HashSet<VariableSourceToken>();
267
268     // iterate over tokens that this temp can reference, make a set
269     // of tokens that need this temp stripped out of them
270     Iterator<VariableSourceToken> itr = s.iterator();
271     while( itr.hasNext() ) {
272       VariableSourceToken vst = itr.next();
273       Set<TempDescriptor> refVars = vst.getRefVars();
274       assert refVars.contains( refVar );
275       forRemoval.add( vst );
276     }
277
278     itr = forRemoval.iterator();
279     while( itr.hasNext() ) {
280
281       // here's a token marked for removal
282       VariableSourceToken vst = itr.next();
283       Set<TempDescriptor> refVars = vst.getRefVars();
284
285       // if there was only one one variable
286       // referencing this token, just take it
287       // out of the table all together
288       if( refVars.size() == 1 ) {
289         removePrivate( vst );
290       }
291
292       sv2vst.remove( new SVKey( vst.getSESE(), refVar ) );
293
294       HashSet<TempDescriptor> newset=new HashSet<TempDescriptor>();
295       newset.addAll(vst.getRefVars());
296       newset.remove(refVar);
297       vst.setRefVars(newset);
298     }
299
300
301     var2vst.remove( refVar );    
302   }
303
304
305   public void remove( FlatSESEEnterNode sese,
306                       TempDescriptor    var  ) {
307
308     // don't seem to need this, don't bother maintaining
309     // until its clear we need it
310     assert false;
311   }
312
313
314   // age tokens with respect to SESE curr, where
315   // any curr tokens increase age by 1
316   public void age( FlatSESEEnterNode curr ) {
317
318     Set<VariableSourceToken> forRemoval =
319       new HashSet<VariableSourceToken>();
320
321     Set<VariableSourceToken> forAddition =
322       new HashSet<VariableSourceToken>();
323
324     Iterator<VariableSourceToken> itr = trueSet.iterator();
325     while( itr.hasNext() ) {
326       VariableSourceToken vst = itr.next();
327
328       if( vst.getSESE().equals( curr ) ) {
329
330         // only age if the token isn't already the maximum age
331         if( vst.getAge() < MAX_AGE ) {
332         
333           forRemoval.add( vst );
334
335           forAddition.add( new VariableSourceToken( vst.getRefVars(), 
336                                                     curr,                                           
337                                                     vst.getAge() + 1,
338                                                     vst.getAddrVar()
339                                                     )
340                            );
341         }
342       } 
343     }
344     
345     itr = forRemoval.iterator();
346     while( itr.hasNext() ) {
347       VariableSourceToken vst = itr.next();
348       remove( vst );
349     }
350     
351     itr = forRemoval.iterator();
352     while( itr.hasNext() ) {
353       VariableSourceToken vst = itr.next();
354       add( vst );
355     }
356
357     assertConsistency();
358   }
359
360
361   // at an SESE enter node, all ref vars in the SESE's in-set will
362   // be copied into the SESE's local scope, change source to itself
363   public void ownInSet( FlatSESEEnterNode curr ) {
364     Iterator<TempDescriptor> inVarItr = curr.getInVarSet().iterator();
365     while( inVarItr.hasNext() ) {
366       TempDescriptor inVar = inVarItr.next();
367
368       remove( inVar );
369       assertConsistency();
370
371       Set<TempDescriptor> refVars = new HashSet<TempDescriptor>();
372       refVars.add( inVar );
373       add( new VariableSourceToken( refVars,
374                                     curr,
375                                     new Integer( 0 ),
376                                     inVar
377                                     )
378            );
379       assertConsistency();
380     }
381   }
382
383   
384   // for the given SESE, change child tokens into this parent
385   public void remapChildTokens( FlatSESEEnterNode curr ) {
386
387     Iterator<FlatSESEEnterNode> childItr = curr.getLocalChildren().iterator();
388     while( childItr.hasNext() ) {
389       FlatSESEEnterNode child = childItr.next();
390       
391       // set of VSTs for removal
392       HashSet<VariableSourceToken> removalSet=new HashSet<VariableSourceToken>();
393       // set of VSTs for additon
394       HashSet<VariableSourceToken> additionSet=new HashSet<VariableSourceToken>();
395      
396       Iterator<VariableSourceToken> vstItr = get( child ).iterator();
397       while( vstItr.hasNext() ) {
398         VariableSourceToken vst = vstItr.next();
399         removalSet.add(vst);
400
401         additionSet.add( new VariableSourceToken( vst.getRefVars(),
402                                                   curr,
403                                                   new Integer( 0 ),
404                                                   vst.getAddrVar()
405                                                   )
406                          );
407       }
408       
409       // remove( eah item in forremoval )
410       vstItr = removalSet.iterator();
411       while( vstItr.hasNext() ) {
412         VariableSourceToken vst = vstItr.next();
413         remove( vst );
414       }
415       // add( each  ite inm for additon _
416       vstItr = additionSet.iterator();
417       while( vstItr.hasNext() ) {
418         VariableSourceToken vst = vstItr.next();
419         add( vst );
420       }
421     }
422
423     assertConsistency();
424   }   
425   
426
427   // this method is called at the SESE exit of SESE 'curr'
428   // if the sources for a variable written by curr can also
429   // come from curr's parent or curr's siblings then we're not
430   // sure that curr will actually modify the variable.  There are
431   // many ways to handle this, but for now, mark the variable as
432   // virtually read so curr insists on having ownership of it
433   // whether it ends up writing to it or not.  It will always, then,
434   // appear in curr's out-set.
435   public Set<TempDescriptor>
436     calcVirtReadsAndPruneParentAndSiblingTokens( FlatSESEEnterNode   exiter,
437                                                  Set<TempDescriptor> liveVars ) {
438
439     Set<TempDescriptor> virtReadSet = new HashSet<TempDescriptor>();
440
441     // this calculation is unneeded for the main task, just return an
442     // empty set of virtual reads
443     if( rblockRel.getMainSESE() == exiter ) {
444       return virtReadSet;
445     }
446
447     // who are the parent and siblings?
448     Set<FlatSESEEnterNode> alternateSESEs = new HashSet<FlatSESEEnterNode>();
449     Iterator<FlatSESEEnterNode> childItr;
450
451     FlatSESEEnterNode parent = exiter.getLocalParent();
452
453     if( parent == null ) {
454       // when some caller task is the exiter's parent, the siblings
455       // of the exiter are other local root tasks
456       parent = rblockRel.getCallerProxySESE();      
457       childItr = rblockRel.getLocalRootSESEs( exiter.getfmEnclosing() ).iterator();
458       
459     } else {
460       // otherwise, the siblings are locally-defined
461       childItr = parent.getLocalChildren().iterator();
462     }
463
464     alternateSESEs.add( parent );
465     while( childItr.hasNext() ) {
466       FlatSESEEnterNode sibling = childItr.next();      
467       if( !sibling.equals( exiter ) ) {
468         alternateSESEs.add( sibling );
469       }
470     }
471     
472     // VSTs to remove if they are alternate sources for exiter VSTs
473     // whose variables will become virtual reads
474     Set<VariableSourceToken> forRemoval = new HashSet<VariableSourceToken>();
475
476     // look at all of this SESE's VSTs at exit...
477     Iterator<VariableSourceToken> vstItr = get( exiter ).iterator();
478     while( vstItr.hasNext() ) {
479       VariableSourceToken vstExiterSrc = vstItr.next();
480
481       // only interested in tokens that come from our current instance
482       if( vstExiterSrc.getAge() != 0 ) {
483         continue;
484       }
485
486       // for each variable that might come from those sources...
487       Iterator<TempDescriptor> refVarItr = vstExiterSrc.getRefVars().iterator();
488       while( refVarItr.hasNext() ) {
489         TempDescriptor refVar = refVarItr.next();
490
491         // only matters for live variables at SESE exit program point
492         if( !liveVars.contains( refVar ) ) {
493           continue;
494         }
495
496         // examine other sources for a variable...
497         Iterator<VariableSourceToken> srcItr = get( refVar ).iterator();
498         while( srcItr.hasNext() ) {
499           VariableSourceToken vstPossibleOtherSrc = srcItr.next();
500
501           if( vstPossibleOtherSrc.getSESE().equals( exiter ) &&
502               vstPossibleOtherSrc.getAge() > 0 
503             ) {
504             // this is an alternate source if its 
505             // an older instance of this SESE               
506             virtReadSet.add( refVar );
507             forRemoval.add( vstPossibleOtherSrc );
508             
509           } else if( alternateSESEs.contains( vstPossibleOtherSrc.getSESE() ) ) {
510             // this is an alternate source from parent or sibling
511             virtReadSet.add( refVar );
512             forRemoval.add( vstPossibleOtherSrc );  
513
514           } else {
515             if( !(vstPossibleOtherSrc.getSESE().equals( exiter ) &&
516                   vstPossibleOtherSrc.getAge().equals( 0 )
517                  )
518                 ) {
519               System.out.println( "For refVar="+refVar+" at exit of "+exiter+
520                                   ", unexpected possible variable source "+vstPossibleOtherSrc );
521               assert false;
522             }
523           }
524         }
525       }
526     }
527
528     vstItr = forRemoval.iterator();
529     while( vstItr.hasNext() ) {
530       VariableSourceToken vst = vstItr.next();
531       remove( vst );
532     }
533     assertConsistency();
534     
535     return virtReadSet;
536   }
537   
538
539   // given a table from a subsequent program point, decide
540   // which variables are going from a non-dynamic to a
541   // dynamic source and return them
542   public Hashtable<TempDescriptor, VSTWrapper> 
543     getReadyOrStatic2DynamicSet( VarSrcTokTable nextTable,
544                                  Set<TempDescriptor> nextLiveIn,
545                                  FlatSESEEnterNode current
546                                  ) {
547     
548     Hashtable<TempDescriptor, VSTWrapper> out = 
549       new Hashtable<TempDescriptor, VSTWrapper>();
550     
551     Iterator itr = var2vst.entrySet().iterator();
552     while( itr.hasNext() ) {
553       Map.Entry                    me  = (Map.Entry)                    itr.next();
554       TempDescriptor               var = (TempDescriptor)               me.getKey();
555       HashSet<VariableSourceToken> s1  = (HashSet<VariableSourceToken>) me.getValue();      
556
557       // only worth tracking if live
558       if( nextLiveIn.contains( var ) ) {
559         
560         VSTWrapper vstIfStaticBefore = new VSTWrapper();
561         VSTWrapper vstIfStaticAfter  = new VSTWrapper();
562
563         Integer srcTypeBefore =      this.getRefVarSrcType( var, current, vstIfStaticBefore );
564         Integer srcTypeAfter  = nextTable.getRefVarSrcType( var, current, vstIfStaticAfter  );
565
566         if( !srcTypeBefore.equals( SrcType_DYNAMIC ) &&
567               srcTypeAfter.equals( SrcType_DYNAMIC )       
568           ) {
569           // remember the variable and a source
570           // it had before crossing the transition
571           // 1) if it was ready, vstIfStatic.vst is null
572           // 2) if is was static, use vstIfStatic.vst
573           out.put( var, vstIfStaticBefore );
574         }
575       }
576     }
577
578     return out;
579   }
580
581
582   // for some reference variable, return the type of source
583   // it might have in this table, which might be:
584   // 1. Ready -- this variable is
585   //      definitely available when you are issued.
586   // 2. Static -- there is definitely one child SESE with
587   //      a known age that will produce the value
588   // 3. Dynamic -- we don't know where the value will come
589   //      from statically, so we'll track it dynamically
590   public Integer getRefVarSrcType( TempDescriptor    refVar,
591                                    FlatSESEEnterNode currentSESE,
592                                    VSTWrapper        vstIfStatic ) {
593     assert refVar      != null;
594     assert vstIfStatic != null;
595
596     vstIfStatic.vst = null;
597    
598     // when the current SESE is null, that simply means it is
599     // an unknown placeholder, in which case the system will
600     // ensure that any variables are READY
601     if( currentSESE == null ) {
602       return SrcType_READY;
603     }
604
605     // if there appear to be no sources, it means this variable
606     // comes from outside of any statically-known SESE scope,
607     // which means the system guarantees its READY, so jump over
608     // while loop
609     Set<VariableSourceToken>      srcs    = get( refVar );
610     Iterator<VariableSourceToken> itrSrcs = srcs.iterator();
611     while( itrSrcs.hasNext() ) {
612       VariableSourceToken vst = itrSrcs.next();
613
614       // to make the refVar non-READY we have to find at least
615       // one child token, there are two cases
616       //  1. if the current task invoked the local method context,
617       //     its children are the locally-defined root tasks
618       boolean case1 = 
619         currentSESE.getIsCallerProxySESE() &&
620         rblockRel.getLocalRootSESEs().contains( vst.getSESE() );
621
622       //  2. if the child task is a locally-defined child of the current task
623       boolean case2 = currentSESE.getLocalChildren().contains( vst.getSESE() );
624             
625       if( case1 || case2 ) {
626       
627         // if we ever have at least one child source with an
628         // unknown age, have to treat var as dynamic
629         if( vst.getAge().equals( OoOJavaAnalysis.maxSESEage ) ) {
630           return SrcType_DYNAMIC;
631         }
632
633         // if we have a known-age child source, this var is
634         // either static or dynamic now: it's static if this
635         // source is the only source, otherwise dynamic
636         if( srcs.size() > 1 ) {
637           return SrcType_DYNAMIC;
638         }
639         
640         vstIfStatic.vst = vst;
641         return SrcType_STATIC;
642       }
643     }
644
645     // if we never found a child source, all other
646     // sources must be READY before we could even
647     // begin executing!
648     return SrcType_READY;
649   }
650
651
652   // any reference variables that are not live can be pruned
653   // from the table, and if any VSTs are then no longer 
654   // referenced, they can be dropped as well
655   // THIS CAUSES INCONSISTENCY, FIX LATER, NOT REQUIRED
656   public void pruneByLiveness( Set<TempDescriptor> rootLiveSet ) {
657     
658     // the set of reference variables in the table minus the
659     // live set gives the set of reference variables to remove
660     Set<TempDescriptor> deadRefVars = new HashSet<TempDescriptor>();
661     deadRefVars.addAll( var2vst.keySet() );
662
663     if( rootLiveSet != null ) {
664       deadRefVars.removeAll( rootLiveSet );
665     }
666
667     // just use the remove operation to prune the table now
668     Iterator<TempDescriptor> deadItr = deadRefVars.iterator();
669     while( deadItr.hasNext() ) {
670       TempDescriptor dead = deadItr.next();
671       removePrivate( dead );
672     }
673
674     assertConsistency();
675   }
676  
677
678
679   // use as an aid for debugging, where true-set is checked
680   // against the alternate mappings: assert that nothing is
681   // missing or extra in the alternates
682
683   public void assertConsistency() {
684   }
685   /*  public void assertConsistency() {
686
687     Iterator itr; 
688     Set s;
689
690     Set<VariableSourceToken> trueSetByAlts = new HashSet<VariableSourceToken>();
691     itr = sese2vst.entrySet().iterator();
692     while( itr.hasNext() ) {
693       Map.Entry                    me   = (Map.Entry)                    itr.next();
694       FlatSESEEnterNode            sese = (FlatSESEEnterNode)            me.getKey();
695       HashSet<VariableSourceToken> s1   = (HashSet<VariableSourceToken>) me.getValue();      
696       assert s1 != null;
697       
698       // the trueSet should have all entries in s1
699       assert trueSet.containsAll( s1 );
700
701       // s1 should not have anything that doesn't appear in trueset
702       Set<VariableSourceToken> sInt = (Set<VariableSourceToken>) s1.clone();
703       sInt.removeAll( trueSet );
704
705       assert sInt.isEmpty();
706
707       // add s1 to a running union--at the end check if trueSet has extra
708       trueSetByAlts.addAll( s1 );
709     }
710     // make sure trueSet isn't too big
711     assert trueSetByAlts.containsAll( trueSet );
712
713
714     trueSetByAlts = new HashSet<VariableSourceToken>();
715     itr = var2vst.entrySet().iterator();
716     while( itr.hasNext() ) {
717       Map.Entry                    me   = (Map.Entry)                    itr.next();
718       TempDescriptor               var  = (TempDescriptor)               me.getKey();
719       HashSet<VariableSourceToken> s1   = (HashSet<VariableSourceToken>) me.getValue();      
720       assert s1 != null;
721       
722       // the trueSet should have all entries in s1
723       assert trueSet.containsAll( s1 );
724
725       // s1 should not have anything that doesn't appear in trueset
726       Set<VariableSourceToken> sInt = (Set<VariableSourceToken>) s1.clone();
727       sInt.removeAll( trueSet );
728
729       assert sInt.isEmpty();
730
731       // add s1 to a running union--at the end check if trueSet has extra
732       trueSetByAlts.addAll( s1 );
733     }
734     // make sure trueSet isn't too big
735     assert trueSetByAlts.containsAll( trueSet );
736
737
738     trueSetByAlts = new HashSet<VariableSourceToken>();
739     itr = sv2vst.entrySet().iterator();
740     while( itr.hasNext() ) {
741       Map.Entry                    me   = (Map.Entry)                    itr.next();
742       SVKey                        key  = (SVKey)                        me.getKey();
743       HashSet<VariableSourceToken> s1   = (HashSet<VariableSourceToken>) me.getValue();      
744       assert s1 != null;
745       
746       // the trueSet should have all entries in s1
747       assert trueSet.containsAll( s1 );
748
749       // s1 should not have anything that doesn't appear in trueset
750       Set<VariableSourceToken> sInt = (Set<VariableSourceToken>) s1.clone();
751       sInt.removeAll( trueSet );
752
753       assert sInt.isEmpty();
754
755       // add s1 to a running union--at the end check if trueSet has extra
756       trueSetByAlts.addAll( s1 );
757     }
758     // make sure trueSet isn't too big
759     assert trueSetByAlts.containsAll( trueSet );
760
761
762     // also check that the reference var sets are consistent
763     Hashtable<VariableSourceToken, Set<TempDescriptor> > vst2refVars =
764       new Hashtable<VariableSourceToken, Set<TempDescriptor> >();
765     itr = var2vst.entrySet().iterator();
766     while( itr.hasNext() ) {
767       Map.Entry                     me     = (Map.Entry)                    itr.next();
768       TempDescriptor                refVar = (TempDescriptor)               me.getKey();
769       HashSet<VariableSourceToken>  s1     = (HashSet<VariableSourceToken>) me.getValue();      
770       Iterator<VariableSourceToken> vstItr = s1.iterator();
771       while( vstItr.hasNext() ) {
772         VariableSourceToken vst = vstItr.next();
773         assert vst.getRefVars().contains( refVar );
774
775         Set<TempDescriptor> refVarsPart = vst2refVars.get( vst );
776         if( refVarsPart == null ) {
777           refVarsPart = new HashSet<TempDescriptor>();
778         }
779         refVarsPart.add( refVar );
780         vst2refVars.put( vst, refVarsPart );
781       }
782     }
783     itr = vst2refVars.entrySet().iterator();
784     while( itr.hasNext() ) {
785       Map.Entry           me  = (Map.Entry)           itr.next();
786       VariableSourceToken vst = (VariableSourceToken) me.getKey();
787       Set<TempDescriptor> s1  = (Set<TempDescriptor>) me.getValue();
788
789       assert vst.getRefVars().equals( s1 );
790     }    
791     }*/
792
793
794   public boolean equals( Object o ) {
795     if( o == null ) {
796       return false;
797     }
798
799     if( !(o instanceof VarSrcTokTable) ) {
800       return false;
801     }
802
803     VarSrcTokTable table = (VarSrcTokTable) o;
804     return trueSet.equals( table.trueSet );
805   }
806
807   public int hashCode() {
808     return trueSet.hashCode();
809   }
810
811   public Iterator<VariableSourceToken> iterator() {
812     return trueSet.iterator();
813   }
814
815   public String toString() {
816     return toStringPretty();
817   }
818
819   public String toStringVerbose() {
820     return "trueSet ="+trueSet.toString()+"\n"+
821            "sese2vst="+sese2vst.toString()+"\n"+
822            "var2vst ="+var2vst.toString()+"\n"+
823            "sv2vst  ="+sv2vst.toString();
824   }
825
826   public String toStringPretty() {
827     String tokHighlighter = "o";
828
829     String str = "VarSrcTokTable\n";
830     Iterator<VariableSourceToken> vstItr = trueSet.iterator();    
831     while( vstItr.hasNext() ) {
832       str += "   "+tokHighlighter+" "+vstItr.next()+"\n";
833     }
834     return str;
835   }
836
837   public String toStringPrettyVerbose() {
838     String tokHighlighter = "o";
839
840     String str = "VarSrcTokTable\n";
841
842     Set s;
843     Iterator itr; 
844     Iterator<VariableSourceToken> vstItr;
845
846     str += "  trueSet\n";
847     vstItr = trueSet.iterator();    
848     while( vstItr.hasNext() ) {
849       str += "     "+tokHighlighter+" "+vstItr.next()+"\n";
850     }
851
852     str += "  sese2vst\n";
853     itr = sese2vst.entrySet().iterator();
854     while( itr.hasNext() ) {
855       Map.Entry                    me   = (Map.Entry)                    itr.next();
856       FlatSESEEnterNode            sese = (FlatSESEEnterNode)            me.getKey();
857       HashSet<VariableSourceToken> s1   = (HashSet<VariableSourceToken>) me.getValue();      
858       assert s1 != null;
859
860       str += "    "+sese.getPrettyIdentifier()+" -> \n";
861
862       vstItr = s1.iterator();
863       while( vstItr.hasNext() ) {
864         str += "       "+tokHighlighter+" "+vstItr.next()+"\n";
865       }
866     }
867
868     str += "  var2vst\n";
869     itr = var2vst.entrySet().iterator();
870     while( itr.hasNext() ) {
871       Map.Entry                me  = (Map.Entry)                itr.next();
872       TempDescriptor           var = (TempDescriptor)           me.getKey();
873       Set<VariableSourceToken> s1  = (Set<VariableSourceToken>) me.getValue();
874       assert s1 != null;
875
876       str += "    "+var+" -> \n";
877
878       vstItr = s1.iterator();
879       while( vstItr.hasNext() ) {
880         str += "       "+tokHighlighter+" "+vstItr.next()+"\n";
881       }
882     }
883
884     str += "  sv2vst\n";
885     itr = sv2vst.entrySet().iterator();
886     while( itr.hasNext() ) {
887       Map.Entry                me  = (Map.Entry)                itr.next();
888       SVKey                    key = (SVKey)                    me.getKey();
889       Set<VariableSourceToken> s1  = (Set<VariableSourceToken>) me.getValue();
890       assert s1 != null;
891
892       str += "    "+key+" -> \n";
893
894       vstItr = s1.iterator();
895       while( vstItr.hasNext() ) {
896         str += "       "+tokHighlighter+" "+vstItr.next()+"\n";
897       }
898     }
899
900     return str;
901   }
902 }