8 // This class formerly had lazy consistency properties, but
9 // it is being changed so that the full set and the extra
10 // hash tables to access the full set efficiently by different
11 // elements will be consistent after EVERY operation. Also,
12 // a consistent assert method allows a debugger to ask whether
13 // an operation has produced an inconsistent VarSrcTokTable.
15 // in an effort to make sure operations keep the table consistent,
16 // all public methods that are also used by other methods for
17 // intermediate results (add and remove are used in other methods)
18 // there should be a public version that calls the private version
19 // so consistency is checked after public ops, but not private ops
20 public class VarSrcTokTable {
22 // a set of every token in the table
23 private HashSet<VariableSourceToken> trueSet;
25 // these hashtables provide an efficient retreival from the true set
26 private Hashtable< TempDescriptor, Set<VariableSourceToken> > var2vst;
27 private Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> > sese2vst;
28 private Hashtable< SVKey, Set<VariableSourceToken> > sv2vst;
30 // maximum age from aging operation
31 private Integer MAX_AGE = new Integer( 2 );
34 public VarSrcTokTable() {
35 trueSet = new HashSet<VariableSourceToken>();
37 sese2vst = new Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> >();
38 var2vst = new Hashtable< TempDescriptor, Set<VariableSourceToken> >();
39 sv2vst = new Hashtable< SVKey, Set<VariableSourceToken> >();
45 // make a deep copy of the in table
46 public VarSrcTokTable( VarSrcTokTable in ) {
53 public void add( VariableSourceToken vst ) {
58 private void addPrivate( VariableSourceToken vst ) {
60 // make sure we aren't clobbering anything!
61 if( trueSet.contains( vst ) ) {
62 // if something with the same hashcode is in the true set, they might
63 // have different reference variable sets because that set is not considered
64 // in a token's equality, so make sure we smooth that out right here
65 Iterator<VariableSourceToken> vstItr = trueSet.iterator();
66 while( vstItr.hasNext() ) {
67 VariableSourceToken vstAlready = vstItr.next();
69 if( vstAlready.equals( vst ) ) {
71 // take out the one that is in (we dont' want collisions in
72 // any of the other hash map sets either)
73 removePrivate( vstAlready );
75 // combine reference variable sets
76 vst.getRefVars().addAll( vstAlready.getRefVars() );
78 // now jump back as we are adding in a brand new token
86 Set<VariableSourceToken> s;
88 s = sese2vst.get( vst.getSESE() );
90 s = new HashSet<VariableSourceToken>();
93 sese2vst.put( vst.getSESE(), s );
95 Iterator<TempDescriptor> refVarItr = vst.getRefVars().iterator();
96 while( refVarItr.hasNext() ) {
97 TempDescriptor refVar = refVarItr.next();
98 s = var2vst.get( refVar );
100 s = new HashSet<VariableSourceToken>();
103 var2vst.put( refVar, s );
105 SVKey key = new SVKey( vst.getSESE(), refVar );
106 s = sv2vst.get( key );
108 s = new HashSet<VariableSourceToken>();
111 sv2vst.put( key, s );
115 public void addAll( Set<VariableSourceToken> s ) {
116 Iterator<VariableSourceToken> itr = s.iterator();
117 while( itr.hasNext() ) {
118 addPrivate( itr.next() );
124 public Set<VariableSourceToken> get() {
128 public Set<VariableSourceToken> get( FlatSESEEnterNode sese ) {
129 Set<VariableSourceToken> s = sese2vst.get( sese );
131 s = new HashSet<VariableSourceToken>();
132 sese2vst.put( sese, s );
137 public Set<VariableSourceToken> get( TempDescriptor var ) {
138 Set<VariableSourceToken> s = var2vst.get( var );
140 s = new HashSet<VariableSourceToken>();
141 var2vst.put( var, s );
146 public Set<VariableSourceToken> get( FlatSESEEnterNode sese,
147 TempDescriptor refVar ) {
148 SVKey key = new SVKey( sese, refVar );
149 Set<VariableSourceToken> s = sv2vst.get( key );
151 s = new HashSet<VariableSourceToken>();
152 sv2vst.put( key, s );
157 public Set<VariableSourceToken> get( FlatSESEEnterNode sese,
160 HashSet<VariableSourceToken> s0 = (HashSet<VariableSourceToken>) sese2vst.get( sese );
162 s0 = new HashSet<VariableSourceToken>();
163 sese2vst.put( sese, s0 );
166 Set<VariableSourceToken> s = (Set<VariableSourceToken>) s0.clone();
167 Iterator<VariableSourceToken> sItr = s.iterator();
168 while( sItr.hasNext() ) {
169 VariableSourceToken vst = sItr.next();
170 if( !vst.getAge().equals( age ) ) {
179 // merge now makes a deep copy of incoming stuff because tokens may
180 // be modified (reference var sets) by later ops that change more
181 // than one table, causing inconsistency
182 public void merge( VarSrcTokTable in ) {
188 Iterator<VariableSourceToken> vstItr = in.trueSet.iterator();
189 while( vstItr.hasNext() ) {
190 VariableSourceToken vst = vstItr.next();
191 this.addPrivate( vst.copy() );
198 // remove operations must leave the trueSet
199 // and the hash maps consistent
200 public void remove( VariableSourceToken vst ) {
201 removePrivate( vst );
205 private void removePrivate( VariableSourceToken vst ) {
206 trueSet.remove( vst );
208 Set<VariableSourceToken> s;
210 s = get( vst.getSESE() );
211 if( s != null ) { s.remove( vst ); }
213 Iterator<TempDescriptor> refVarItr = vst.getRefVars().iterator();
214 while( refVarItr.hasNext() ) {
215 TempDescriptor refVar = refVarItr.next();
218 if( s != null ) { s.remove( vst ); }
220 s = get( vst.getSESE(), refVar );
221 if( s != null ) { s.remove( vst ); }
226 public void remove( FlatSESEEnterNode sese ) {
227 removePrivate( sese );
231 public void removePrivate( FlatSESEEnterNode sese ) {
232 Set<VariableSourceToken> s = sese2vst.get( sese );
237 Iterator<VariableSourceToken> itr = s.iterator();
238 while( itr.hasNext() ) {
239 VariableSourceToken vst = itr.next();
240 removePrivate( vst );
243 sese2vst.remove( sese );
247 public void remove( TempDescriptor refVar ) {
248 removePrivate( refVar );
252 private void removePrivate( TempDescriptor refVar ) {
253 Set<VariableSourceToken> s = var2vst.get( refVar );
258 Set<VariableSourceToken> forRemoval = new HashSet<VariableSourceToken>();
260 // iterate over tokens that this temp can reference, make a set
261 // of tokens that need this temp stripped out of them
262 Iterator<VariableSourceToken> itr = s.iterator();
263 while( itr.hasNext() ) {
264 VariableSourceToken vst = itr.next();
265 Set<TempDescriptor> refVars = vst.getRefVars();
266 assert refVars.contains( refVar );
267 forRemoval.add( vst );
270 itr = forRemoval.iterator();
271 while( itr.hasNext() ) {
273 // here's a token marked for removal
274 VariableSourceToken vst = itr.next();
275 Set<TempDescriptor> refVars = vst.getRefVars();
277 // if there was only one one variable
278 // referencing this token, just take it
279 // out of the table all together
280 if( refVars.size() == 1 ) {
281 removePrivate( vst );
284 refVars.remove( refVar );
287 var2vst.remove( refVar );
291 public void remove( FlatSESEEnterNode sese,
292 TempDescriptor var ) {
294 // don't seem to need this, don't bother maintaining
295 // until its clear we need it
300 // age tokens with respect to SESE curr, where
301 // any curr tokens increase age by 1
302 public void age( FlatSESEEnterNode curr ) {
304 Iterator<VariableSourceToken> itr = trueSet.iterator();
305 while( itr.hasNext() ) {
306 VariableSourceToken vst = itr.next();
308 if( vst.getSESE().equals( curr ) ) {
310 Integer newAge = vst.getAge()+1;
311 if( newAge > MAX_AGE ) {
317 add( new VariableSourceToken( vst.getRefVars(),
330 // for the given SESE, change child tokens into this parent
331 public void remapChildTokens( FlatSESEEnterNode curr ) {
333 Iterator<FlatSESEEnterNode> childItr = curr.getChildren().iterator();
334 if( childItr.hasNext() ) {
335 FlatSESEEnterNode child = childItr.next();
337 Iterator<VariableSourceToken> vstItr = get( child ).iterator();
338 while( vstItr.hasNext() ) {
339 VariableSourceToken vst = vstItr.next();
343 add( new VariableSourceToken( vst.getRefVars(),
356 // if we can get a value from the current SESE and the parent
357 // or a sibling, just getting from the current SESE suffices now
358 // return a set of temps that are virtually read
359 public Set<TempDescriptor> removeParentAndSiblingTokens( FlatSESEEnterNode curr,
360 Set<TempDescriptor> liveIn ) {
362 HashSet<TempDescriptor> virtualLiveIn = new HashSet<TempDescriptor>();
364 FlatSESEEnterNode parent = curr.getParent();
365 if( parent == null ) {
366 // have no parent or siblings
367 return virtualLiveIn;
370 remove_A_if_B( parent, curr, liveIn, virtualLiveIn );
372 Iterator<FlatSESEEnterNode> childItr = parent.getChildren().iterator();
373 if( childItr.hasNext() ) {
374 FlatSESEEnterNode child = childItr.next();
376 if( !child.equals( curr ) ) {
377 remove_A_if_B( child, curr, liveIn, virtualLiveIn );
382 return virtualLiveIn;
385 // if B is also a source for some variable, remove all entries
386 // of A as a source for that variable: s is virtual reads
387 protected void remove_A_if_B( FlatSESEEnterNode a,
389 Set<TempDescriptor> liveInCurrentSESE,
390 Set<TempDescriptor> virtualLiveIn ) {
392 Set<VariableSourceToken> forRemoval = new HashSet<VariableSourceToken>();
394 Iterator<VariableSourceToken> vstItr = get( a ).iterator();
395 while( vstItr.hasNext() ) {
396 VariableSourceToken vst = vstItr.next();
397 Iterator<TempDescriptor> refVarItr = vst.getRefVars().iterator();
398 while( refVarItr.hasNext() ) {
399 TempDescriptor refVar = refVarItr.next();
400 Set<VariableSourceToken> bSet = get( b, refVar );
402 if( !bSet.isEmpty() ) {
403 forRemoval.add( vst );
405 // mark this variable as a virtual read as well
406 virtualLiveIn.add( refVar );
411 vstItr = forRemoval.iterator();
412 while( vstItr.hasNext() ) {
413 VariableSourceToken vst = vstItr.next();
421 // get the set of VST's that come from a child
422 public Set<VariableSourceToken> getChildrenVSTs( FlatSESEEnterNode curr ) {
424 Set<VariableSourceToken> out = new HashSet<VariableSourceToken>();
426 Iterator<FlatSESEEnterNode> cItr = curr.getChildren().iterator();
427 while( cItr.hasNext() ) {
428 FlatSESEEnterNode child = cItr.next();
429 out.addAll( get( child ) );
436 // get the set of variables that have exactly one source
437 // from the static perspective
438 public Set<VariableSourceToken> getStaticSet() {
440 Set<VariableSourceToken> out = new HashSet<VariableSourceToken>();
442 Iterator itr = var2vst.entrySet().iterator();
443 while( itr.hasNext() ) {
444 Map.Entry me = (Map.Entry) itr.next();
445 TempDescriptor var = (TempDescriptor) me.getKey();
446 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
448 if( s1.size() == 1 ) {
457 // given a table from a subsequent program point, decide
458 // which variables are going from a static source to a
459 // dynamic source and return them
460 public Set<VariableSourceToken> getStatic2DynamicSet( VarSrcTokTable next ) {
462 Set<VariableSourceToken> out = new HashSet<VariableSourceToken>();
464 Iterator itr = var2vst.entrySet().iterator();
465 while( itr.hasNext() ) {
466 Map.Entry me = (Map.Entry) itr.next();
467 TempDescriptor var = (TempDescriptor) me.getKey();
468 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
470 if( s1.size() == 1 ) {
471 // this is a variable with a static source
472 Set<VariableSourceToken> s2 = next.get( var );
474 if( s2.size() > 1 ) {
475 // and in the next table, it is dynamic
485 // use as an aid for debugging, where true-set is checked
486 // against the alternate mappings: assert that nothing is
487 // missing or extra in the alternates
488 public void assertConsistency() {
493 Set<VariableSourceToken> trueSetByAlts = new HashSet<VariableSourceToken>();
494 itr = sese2vst.entrySet().iterator();
495 while( itr.hasNext() ) {
496 Map.Entry me = (Map.Entry) itr.next();
497 FlatSESEEnterNode sese = (FlatSESEEnterNode) me.getKey();
498 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
501 // the trueSet should have all entries in s1
502 assert trueSet.containsAll( s1 );
504 // s1 should not have anything that doesn't appear in trueset
505 Set<VariableSourceToken> sInt = (Set<VariableSourceToken>) s1.clone();
506 sInt.removeAll( trueSet );
508 assert sInt.isEmpty();
510 // add s1 to a running union--at the end check if trueSet has extra
511 trueSetByAlts.addAll( s1 );
513 // make sure trueSet isn't too big
514 assert trueSetByAlts.containsAll( trueSet );
517 trueSetByAlts = new HashSet<VariableSourceToken>();
518 itr = var2vst.entrySet().iterator();
519 while( itr.hasNext() ) {
520 Map.Entry me = (Map.Entry) itr.next();
521 TempDescriptor var = (TempDescriptor) me.getKey();
522 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
525 // the trueSet should have all entries in s1
526 assert trueSet.containsAll( s1 );
528 // s1 should not have anything that doesn't appear in trueset
529 Set<VariableSourceToken> sInt = (Set<VariableSourceToken>) s1.clone();
530 sInt.removeAll( trueSet );
532 assert sInt.isEmpty();
534 // add s1 to a running union--at the end check if trueSet has extra
535 trueSetByAlts.addAll( s1 );
537 // make sure trueSet isn't too big
538 assert trueSetByAlts.containsAll( trueSet );
541 trueSetByAlts = new HashSet<VariableSourceToken>();
542 itr = sv2vst.entrySet().iterator();
543 while( itr.hasNext() ) {
544 Map.Entry me = (Map.Entry) itr.next();
545 SVKey key = (SVKey) me.getKey();
546 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
549 // the trueSet should have all entries in s1
550 assert trueSet.containsAll( s1 );
552 // s1 should not have anything that doesn't appear in trueset
553 Set<VariableSourceToken> sInt = (Set<VariableSourceToken>) s1.clone();
554 sInt.removeAll( trueSet );
556 assert sInt.isEmpty();
558 // add s1 to a running union--at the end check if trueSet has extra
559 trueSetByAlts.addAll( s1 );
561 // make sure trueSet isn't too big
562 assert trueSetByAlts.containsAll( trueSet );
565 // also check that the reference var sets are consistent
566 Hashtable<VariableSourceToken, Set<TempDescriptor> > vst2refVars =
567 new Hashtable<VariableSourceToken, Set<TempDescriptor> >();
568 itr = var2vst.entrySet().iterator();
569 while( itr.hasNext() ) {
570 Map.Entry me = (Map.Entry) itr.next();
571 TempDescriptor refVar = (TempDescriptor) me.getKey();
572 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
573 Iterator<VariableSourceToken> vstItr = s1.iterator();
574 while( vstItr.hasNext() ) {
575 VariableSourceToken vst = vstItr.next();
576 assert vst.getRefVars().contains( refVar );
578 Set<TempDescriptor> refVarsPart = vst2refVars.get( vst );
579 if( refVarsPart == null ) {
580 refVarsPart = new HashSet<TempDescriptor>();
582 refVarsPart.add( refVar );
583 vst2refVars.put( vst, refVarsPart );
586 itr = vst2refVars.entrySet().iterator();
587 while( itr.hasNext() ) {
588 Map.Entry me = (Map.Entry) itr.next();
589 VariableSourceToken vst = (VariableSourceToken) me.getKey();
590 Set<TempDescriptor> s1 = (Set<TempDescriptor>) me.getValue();
592 assert vst.getRefVars().equals( s1 );
597 public boolean equals( Object o ) {
602 if( !(o instanceof VarSrcTokTable) ) {
606 VarSrcTokTable table = (VarSrcTokTable) o;
607 return trueSet.equals( table.trueSet );
610 public int hashCode() {
611 return trueSet.hashCode();
614 public Iterator<VariableSourceToken> iterator() {
615 return trueSet.iterator();
618 public String toString() {
619 //return "trueSet ="+trueSet.toString();
620 return toStringPretty();
623 public String toStringVerbose() {
624 return "trueSet ="+trueSet.toString()+"\n"+
625 "sese2vst="+sese2vst.toString()+"\n"+
626 "var2vst ="+var2vst.toString()+"\n"+
627 "sv2vst ="+sv2vst.toString();
630 public String toStringPretty() {
631 String tokHighlighter = "o";
633 String str = "VarSrcTokTable\n";
634 Iterator<VariableSourceToken> vstItr = trueSet.iterator();
635 while( vstItr.hasNext() ) {
636 str += " "+tokHighlighter+" "+vstItr.next()+"\n";
641 public String toStringPrettyVerbose() {
642 String tokHighlighter = "o";
644 String str = "VarSrcTokTable\n";
648 Iterator<VariableSourceToken> vstItr;
651 vstItr = trueSet.iterator();
652 while( vstItr.hasNext() ) {
653 str += " "+tokHighlighter+" "+vstItr.next()+"\n";
656 str += " sese2vst\n";
657 itr = sese2vst.entrySet().iterator();
658 while( itr.hasNext() ) {
659 Map.Entry me = (Map.Entry) itr.next();
660 FlatSESEEnterNode sese = (FlatSESEEnterNode) me.getKey();
661 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
664 str += " "+sese.getPrettyIdentifier()+" -> \n";
666 vstItr = s1.iterator();
667 while( vstItr.hasNext() ) {
668 str += " "+tokHighlighter+" "+vstItr.next()+"\n";
673 itr = var2vst.entrySet().iterator();
674 while( itr.hasNext() ) {
675 Map.Entry me = (Map.Entry) itr.next();
676 TempDescriptor var = (TempDescriptor) me.getKey();
677 Set<VariableSourceToken> s1 = (Set<VariableSourceToken>) me.getValue();
680 str += " "+var+" -> \n";
682 vstItr = s1.iterator();
683 while( vstItr.hasNext() ) {
684 str += " "+tokHighlighter+" "+vstItr.next()+"\n";
689 itr = sv2vst.entrySet().iterator();
690 while( itr.hasNext() ) {
691 Map.Entry me = (Map.Entry) itr.next();
692 SVKey key = (SVKey) me.getKey();
693 Set<VariableSourceToken> s1 = (Set<VariableSourceToken>) me.getValue();
696 str += " "+key+" -> \n";
698 vstItr = s1.iterator();
699 while( vstItr.hasNext() ) {
700 str += " "+tokHighlighter+" "+vstItr.next()+"\n";