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.
14 public class VarSrcTokTable {
16 // a set of every token in the table
17 private HashSet<VariableSourceToken> trueSet;
19 // these hashtables provide an efficient retreival from the true set
20 private Hashtable< TempDescriptor, Set<VariableSourceToken> > var2vst;
21 private Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> > sese2vst;
22 private Hashtable< SVKey, Set<VariableSourceToken> > sv2vst;
24 // maximum age from aging operation
25 private Integer MAX_AGE = new Integer( 2 );
28 public VarSrcTokTable() {
29 trueSet = new HashSet<VariableSourceToken>();
31 sese2vst = new Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> >();
32 var2vst = new Hashtable< TempDescriptor, Set<VariableSourceToken> >();
33 sv2vst = new Hashtable< SVKey, Set<VariableSourceToken> >();
37 public VarSrcTokTable( VarSrcTokTable in ) {
38 trueSet = (HashSet<VariableSourceToken>) in.trueSet.clone();
42 sese2vst = new Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> >();
43 itr = in.sese2vst.entrySet().iterator();
44 while( itr.hasNext() ) {
45 Map.Entry me = (Map.Entry) itr.next();
46 FlatSESEEnterNode sese = (FlatSESEEnterNode) me.getKey();
47 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
50 (HashSet<VariableSourceToken>) (s1.clone()) );
53 var2vst = new Hashtable< TempDescriptor, Set<VariableSourceToken> >();
54 itr = in.var2vst.entrySet().iterator();
55 while( itr.hasNext() ) {
56 Map.Entry me = (Map.Entry) itr.next();
57 TempDescriptor var = (TempDescriptor) me.getKey();
58 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
61 (HashSet<VariableSourceToken>) (s1.clone()) );
64 sv2vst = new Hashtable< SVKey, Set<VariableSourceToken> >();
65 itr = in.sv2vst.entrySet().iterator();
66 while( itr.hasNext() ) {
67 Map.Entry me = (Map.Entry) itr.next();
68 SVKey key = (SVKey) me.getKey();
69 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
72 (HashSet<VariableSourceToken>) (s1.clone()) );
79 public void add( VariableSourceToken vst ) {
81 // make sure we aren't clobbering anything!
82 assert !trueSet.contains( vst );
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 );
117 public void addAll( Set<VariableSourceToken> s ) {
118 Iterator<VariableSourceToken> itr = s.iterator();
119 while( itr.hasNext() ) {
125 public Set<VariableSourceToken> get() {
129 public Set<VariableSourceToken> get( FlatSESEEnterNode sese ) {
130 Set<VariableSourceToken> s = sese2vst.get( sese );
132 s = new HashSet<VariableSourceToken>();
133 sese2vst.put( sese, s );
138 public Set<VariableSourceToken> get( TempDescriptor var ) {
139 Set<VariableSourceToken> s = var2vst.get( var );
141 s = new HashSet<VariableSourceToken>();
142 var2vst.put( var, s );
147 public Set<VariableSourceToken> get( FlatSESEEnterNode sese,
148 TempDescriptor refVar ) {
149 SVKey key = new SVKey( sese, refVar );
150 Set<VariableSourceToken> s = sv2vst.get( key );
152 s = new HashSet<VariableSourceToken>();
153 sv2vst.put( key, s );
158 public Set<VariableSourceToken> get( FlatSESEEnterNode sese,
160 Set<VariableSourceToken> s = sese2vst.get( sese );
162 s = new HashSet<VariableSourceToken>();
163 sese2vst.put( sese, s );
165 Iterator<VariableSourceToken> sItr = s.iterator();
166 while( sItr.hasNext() ) {
167 VariableSourceToken vst = sItr.next();
168 if( !vst.getAge().equals( age ) ) {
176 public void merge( VarSrcTokTable tableIn ) {
178 if( tableIn == null ) {
182 // make a copy for modification to use in the merge
183 VarSrcTokTable table = new VarSrcTokTable( tableIn );
186 trueSet.addAll( table.trueSet );
191 // merge sese2vst mappings
192 itr = this.sese2vst.entrySet().iterator();
193 while( itr.hasNext() ) {
194 Map.Entry me = (Map.Entry) itr.next();
195 FlatSESEEnterNode sese = (FlatSESEEnterNode) me.getKey();
196 Set<VariableSourceToken> s1 = (Set<VariableSourceToken>) me.getValue();
197 Set<VariableSourceToken> s2 = table.sese2vst.get( sese );
204 itr = table.sese2vst.entrySet().iterator();
205 while( itr.hasNext() ) {
206 Map.Entry me = (Map.Entry) itr.next();
207 FlatSESEEnterNode sese = (FlatSESEEnterNode) me.getKey();
208 Set<VariableSourceToken> s2 = (Set<VariableSourceToken>) me.getValue();
209 Set<VariableSourceToken> s1 = this.sese2vst.get( sese );
213 this.sese2vst.put( sese, s2 );
217 // merge var2vst mappings
218 itr = this.var2vst.entrySet().iterator();
219 while( itr.hasNext() ) {
220 Map.Entry me = (Map.Entry) itr.next();
221 TempDescriptor var = (TempDescriptor) me.getKey();
222 Set<VariableSourceToken> s1 = (Set<VariableSourceToken>) me.getValue();
223 Set<VariableSourceToken> s2 = table.var2vst.get( var );
230 itr = table.var2vst.entrySet().iterator();
231 while( itr.hasNext() ) {
232 Map.Entry me = (Map.Entry) itr.next();
233 TempDescriptor var = (TempDescriptor) me.getKey();
234 Set<VariableSourceToken> s2 = (Set<VariableSourceToken>) me.getValue();
235 Set<VariableSourceToken> s1 = this.var2vst.get( var );
239 this.var2vst.put( var, s2 );
243 // merge sv2vst mappings
244 itr = this.sv2vst.entrySet().iterator();
245 while( itr.hasNext() ) {
246 Map.Entry me = (Map.Entry) itr.next();
247 SVKey key = (SVKey) me.getKey();
248 Set<VariableSourceToken> s1 = (Set<VariableSourceToken>) me.getValue();
249 Set<VariableSourceToken> s2 = table.sv2vst.get( key );
256 itr = table.sv2vst.entrySet().iterator();
257 while( itr.hasNext() ) {
258 Map.Entry me = (Map.Entry) itr.next();
259 SVKey key = (SVKey) me.getKey();
260 Set<VariableSourceToken> s2 = (Set<VariableSourceToken>) me.getValue();
261 Set<VariableSourceToken> s1 = this.sv2vst.get( key );
265 this.sv2vst.put( key, s2 );
273 // remove operations must leave the trueSet
274 // and the hash maps consistent!
275 public void remove( VariableSourceToken vst ) {
276 trueSet.remove( vst );
278 Set<VariableSourceToken> s;
280 s = get( vst.getSESE() );
281 if( s != null ) { s.remove( vst ); }
283 Iterator<TempDescriptor> refVarItr = vst.getRefVars().iterator();
284 while( refVarItr.hasNext() ) {
285 TempDescriptor refVar = refVarItr.next();
288 if( s != null ) { s.remove( vst ); }
290 s = get( vst.getSESE(), refVar );
291 if( s != null ) { s.remove( vst ); }
297 public void remove( FlatSESEEnterNode sese ) {
298 Set<VariableSourceToken> s = sese2vst.get( sese );
303 Iterator<VariableSourceToken> itr = s.iterator();
304 while( itr.hasNext() ) {
305 VariableSourceToken vst = itr.next();
309 sese2vst.remove( sese );
314 public void remove( TempDescriptor refVar ) {
315 Set<VariableSourceToken> s = var2vst.get( refVar );
320 Set<VariableSourceToken> forRemoval = new HashSet<VariableSourceToken>();
322 // iterate over tokens that this temp can reference, make a set
323 // of tokens that need this temp stripped out of them
324 Iterator<VariableSourceToken> itr = s.iterator();
325 while( itr.hasNext() ) {
326 VariableSourceToken vst = itr.next();
327 Set<TempDescriptor> refVars = vst.getRefVars();
328 assert refVars.contains( refVar );
329 forRemoval.add( vst );
332 itr = forRemoval.iterator();
333 while( itr.hasNext() ) {
334 // here's a token marked for removal, take it out as it is
336 VariableSourceToken vst = itr.next();
339 // if there are other references to the token, alter the
340 // token and then readd it to this table, because it has
341 // a new hash value now
342 Set<TempDescriptor> refVars = vst.getRefVars();
343 refVars.remove( refVar );
344 if( refVars.size() > 0 ) {
349 //var2vst.remove( var );
354 public void remove( FlatSESEEnterNode sese,
355 TempDescriptor var ) {
357 SVKey key = new SVKey( sese, var );
358 Set<VariableSourceToken> s = sv2vst.get( key );
363 Iterator<VariableSourceToken> itr = s.iterator();
364 while( itr.hasNext() ) {
365 VariableSourceToken vst = itr.next();
369 sv2vst.remove( key );
376 // return a new table based on this one and
377 // age tokens with respect to SESE curr, where
378 // any curr tokens increase age by 1
379 public VarSrcTokTable age( FlatSESEEnterNode curr ) {
381 // create a table to modify as a copy of this
382 VarSrcTokTable out = new VarSrcTokTable( this );
384 Iterator<VariableSourceToken> itr = trueSet.iterator();
385 while( itr.hasNext() ) {
386 VariableSourceToken vst = itr.next();
388 if( vst.getSESE().equals( curr ) ) {
390 Integer newAge = vst.getAge()+1;
391 if( newAge > MAX_AGE ) {
397 out.add( new VariableSourceToken( vst.getRefVars(),
406 out.assertConsistency();
411 // for the given SESE, change child tokens into this parent
412 public void remapChildTokens( FlatSESEEnterNode curr ) {
414 Iterator<FlatSESEEnterNode> childItr = curr.getChildren().iterator();
415 if( childItr.hasNext() ) {
416 FlatSESEEnterNode child = childItr.next();
418 Iterator<VariableSourceToken> vstItr = get( child ).iterator();
419 while( vstItr.hasNext() ) {
420 VariableSourceToken vst = vstItr.next();
424 add( new VariableSourceToken( vst.getRefVars(),
437 // if we can get a value from the current SESE and the parent
438 // or a sibling, just getting from the current SESE suffices now
439 // return a set of temps that are virtually read
440 public Set<TempDescriptor> removeParentAndSiblingTokens( FlatSESEEnterNode curr,
441 Set<TempDescriptor> liveIn ) {
443 HashSet<TempDescriptor> virtualLiveIn = new HashSet<TempDescriptor>();
445 FlatSESEEnterNode parent = curr.getParent();
446 if( parent == null ) {
447 // have no parent or siblings
448 return virtualLiveIn;
451 remove_A_if_B( parent, curr, liveIn, virtualLiveIn );
453 Iterator<FlatSESEEnterNode> childItr = parent.getChildren().iterator();
454 if( childItr.hasNext() ) {
455 FlatSESEEnterNode child = childItr.next();
457 if( !child.equals( curr ) ) {
458 remove_A_if_B( child, curr, liveIn, virtualLiveIn );
463 return virtualLiveIn;
466 // if B is also a source for some variable, remove all entries
467 // of A as a source for that variable: s is virtual reads
468 protected void remove_A_if_B( FlatSESEEnterNode a,
470 Set<TempDescriptor> liveInCurrentSESE,
471 Set<TempDescriptor> virtualLiveIn ) {
473 Set<VariableSourceToken> forRemoval = new HashSet<VariableSourceToken>();
475 Iterator<VariableSourceToken> vstItr = get( a ).iterator();
476 while( vstItr.hasNext() ) {
477 VariableSourceToken vst = vstItr.next();
478 Iterator<TempDescriptor> refVarItr = vst.getRefVars().iterator();
479 while( refVarItr.hasNext() ) {
480 TempDescriptor refVar = refVarItr.next();
481 Set<VariableSourceToken> bSet = get( b, refVar );
483 if( !bSet.isEmpty() ) {
484 forRemoval.add( vst );
486 // mark this variable as a virtual read as well
487 virtualLiveIn.add( refVar );
492 vstItr = forRemoval.iterator();
493 while( vstItr.hasNext() ) {
494 VariableSourceToken vst = vstItr.next();
500 public Set<VariableSourceToken> getStallSet( FlatSESEEnterNode curr ) {
502 Set<VariableSourceToken> out = new HashSet<VariableSourceToken>();
504 Iterator<FlatSESEEnterNode> cItr = curr.getChildren().iterator();
505 while( cItr.hasNext() ) {
506 FlatSESEEnterNode child = cItr.next();
507 out.addAll( get( child ) );
514 // use as an aid for debugging, where true-set is checked
515 // against the alternate mappings: assert that nothing is
516 // missing or extra in the alternates
517 public void assertConsistency() {
522 Set<VariableSourceToken> trueSetByAlts = new HashSet<VariableSourceToken>();
523 itr = sese2vst.entrySet().iterator();
524 while( itr.hasNext() ) {
525 Map.Entry me = (Map.Entry) itr.next();
526 FlatSESEEnterNode sese = (FlatSESEEnterNode) me.getKey();
527 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
530 // the trueSet should have all entries in s1
531 assert trueSet.containsAll( s1 );
533 // s1 should not have anything that doesn't appear in trueset
534 Set<VariableSourceToken> sInt = (Set<VariableSourceToken>) s1.clone();
535 sInt.removeAll( trueSet );
537 assert sInt.isEmpty();
539 // add s1 to a running union--at the end check if trueSet has extra
540 trueSetByAlts.addAll( s1 );
542 // make sure trueSet isn't too big
543 assert trueSetByAlts.containsAll( trueSet );
546 trueSetByAlts = new HashSet<VariableSourceToken>();
547 itr = var2vst.entrySet().iterator();
548 while( itr.hasNext() ) {
549 Map.Entry me = (Map.Entry) itr.next();
550 TempDescriptor var = (TempDescriptor) me.getKey();
551 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
554 // the trueSet should have all entries in s1
555 assert trueSet.containsAll( s1 );
557 // s1 should not have anything that doesn't appear in trueset
558 Set<VariableSourceToken> sInt = (Set<VariableSourceToken>) s1.clone();
559 sInt.removeAll( trueSet );
561 assert sInt.isEmpty();
563 // add s1 to a running union--at the end check if trueSet has extra
564 trueSetByAlts.addAll( s1 );
566 // make sure trueSet isn't too big
567 assert trueSetByAlts.containsAll( trueSet );
570 trueSetByAlts = new HashSet<VariableSourceToken>();
571 itr = sv2vst.entrySet().iterator();
572 while( itr.hasNext() ) {
573 Map.Entry me = (Map.Entry) itr.next();
574 SVKey key = (SVKey) me.getKey();
575 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
578 // the trueSet should have all entries in s1
579 assert trueSet.containsAll( s1 );
581 // s1 should not have anything that doesn't appear in trueset
582 Set<VariableSourceToken> sInt = (Set<VariableSourceToken>) s1.clone();
583 sInt.removeAll( trueSet );
585 assert sInt.isEmpty();
587 // add s1 to a running union--at the end check if trueSet has extra
588 trueSetByAlts.addAll( s1 );
590 // make sure trueSet isn't too big
591 assert trueSetByAlts.containsAll( trueSet );
594 // also check that the reference var sets are consistent
595 Hashtable<VariableSourceToken, Set<TempDescriptor> > vst2refVars =
596 new Hashtable<VariableSourceToken, Set<TempDescriptor> >();
597 itr = var2vst.entrySet().iterator();
598 while( itr.hasNext() ) {
599 Map.Entry me = (Map.Entry) itr.next();
600 TempDescriptor refVar = (TempDescriptor) me.getKey();
601 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
602 Iterator<VariableSourceToken> vstItr = s1.iterator();
603 while( vstItr.hasNext() ) {
604 VariableSourceToken vst = vstItr.next();
605 assert vst.getRefVars().contains( refVar );
607 Set<TempDescriptor> refVarsPart = vst2refVars.get( vst );
608 if( refVarsPart == null ) {
609 refVarsPart = new HashSet<TempDescriptor>();
611 refVarsPart.add( refVar );
612 vst2refVars.put( vst, refVarsPart );
615 itr = vst2refVars.entrySet().iterator();
616 while( itr.hasNext() ) {
617 Map.Entry me = (Map.Entry) itr.next();
618 VariableSourceToken vst = (VariableSourceToken) me.getKey();
619 Set<TempDescriptor> s1 = (Set<TempDescriptor>) me.getValue();
620 assert vst.getRefVars().equals( s1 );
625 public boolean equals( Object o ) {
630 if( !(o instanceof VarSrcTokTable) ) {
634 VarSrcTokTable table = (VarSrcTokTable) o;
635 return trueSet.equals( table.trueSet );
638 public int hashCode() {
639 return trueSet.hashCode();
642 public Iterator<VariableSourceToken> iterator() {
643 return trueSet.iterator();
646 public String toString() {
647 return "trueSet ="+trueSet.toString();
650 public String toStringVerbose() {
651 return "trueSet ="+trueSet.toString()+"\n"+
652 "sese2vst="+sese2vst.toString()+"\n"+
653 "var2vst ="+var2vst.toString()+"\n"+
654 "sv2vst ="+sv2vst.toString();
657 public String toStringPretty() {
658 String tokHighlighter = "o";
660 String str = "VarSrcTokTable\n";
661 Iterator<VariableSourceToken> vstItr = trueSet.iterator();
662 while( vstItr.hasNext() ) {
663 str += " "+tokHighlighter+" "+vstItr.next()+"\n";
668 public String toStringPrettyVerbose() {
669 String tokHighlighter = "o";
671 String str = "VarSrcTokTable\n";
675 Iterator<VariableSourceToken> vstItr;
678 vstItr = trueSet.iterator();
679 while( vstItr.hasNext() ) {
680 str += " "+tokHighlighter+" "+vstItr.next()+"\n";
683 str += " sese2vst\n";
684 itr = sese2vst.entrySet().iterator();
685 while( itr.hasNext() ) {
686 Map.Entry me = (Map.Entry) itr.next();
687 FlatSESEEnterNode sese = (FlatSESEEnterNode) me.getKey();
688 HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
691 str += " "+sese.getPrettyIdentifier()+" -> \n";
693 vstItr = s1.iterator();
694 while( vstItr.hasNext() ) {
695 str += " "+tokHighlighter+" "+vstItr.next()+"\n";
700 itr = var2vst.entrySet().iterator();
701 while( itr.hasNext() ) {
702 Map.Entry me = (Map.Entry) itr.next();
703 TempDescriptor var = (TempDescriptor) me.getKey();
704 Set<VariableSourceToken> s1 = (Set<VariableSourceToken>) me.getValue();
707 str += " "+var+" -> \n";
709 vstItr = s1.iterator();
710 while( vstItr.hasNext() ) {
711 str += " "+tokHighlighter+" "+vstItr.next()+"\n";
716 itr = sv2vst.entrySet().iterator();
717 while( itr.hasNext() ) {
718 Map.Entry me = (Map.Entry) itr.next();
719 SVKey key = (SVKey) me.getKey();
720 Set<VariableSourceToken> s1 = (Set<VariableSourceToken>) me.getValue();
723 str += " "+key+" -> \n";
725 vstItr = s1.iterator();
726 while( vstItr.hasNext() ) {
727 str += " "+tokHighlighter+" "+vstItr.next()+"\n";