-package Analysis.MLP;\r
-\r
-import IR.*;\r
-import IR.Flat.*;\r
-import java.util.*;\r
-import java.io.*;\r
-\r
-public class VarSrcTokTable {\r
- \r
- // the true set represents the set of (sese, variable, age)\r
- // triples that are truly in the table\r
- private HashSet<VariableSourceToken> trueSet;\r
-\r
- // these hashtables provide an efficient retreival from the\r
- // true set. Note that a particular triple from the quick\r
- // look up must be checked against the true set--remove ops\r
- // can cause the hashtables to be inconsistent to each other\r
- private Hashtable< TempDescriptor, Set<VariableSourceToken> > var2vst;\r
- private Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> > sese2vst;\r
- private Hashtable< SVKey, Set<VariableSourceToken> > sv2vst;\r
-\r
- // maximum age from aging operation\r
- private Integer MAX_AGE = new Integer( 2 );\r
-\r
-\r
- public VarSrcTokTable() {\r
- trueSet = new HashSet<VariableSourceToken>();\r
-\r
- sese2vst = new Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> >();\r
- var2vst = new Hashtable< TempDescriptor, Set<VariableSourceToken> >();\r
- sv2vst = new Hashtable< SVKey, Set<VariableSourceToken> >();\r
- }\r
-\r
- \r
- public VarSrcTokTable( VarSrcTokTable in ) {\r
- trueSet = (HashSet<VariableSourceToken>) in.trueSet.clone();\r
-\r
- Iterator itr; Set s;\r
-\r
- sese2vst = new Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> >();\r
- itr = sese2vst.entrySet().iterator();\r
- while( itr.hasNext() ) {\r
- Map.Entry me = (Map.Entry) itr.next();\r
- FlatSESEEnterNode sese = (FlatSESEEnterNode) me.getKey();\r
- HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue(); \r
- assert s1 != null;\r
- sese2vst.put( sese, \r
- (HashSet<VariableSourceToken>) (s1.clone()) );\r
- }\r
-\r
- var2vst = new Hashtable< TempDescriptor, Set<VariableSourceToken> >();\r
- itr = var2vst.entrySet().iterator();\r
- while( itr.hasNext() ) {\r
- Map.Entry me = (Map.Entry) itr.next();\r
- TempDescriptor var = (TempDescriptor) me.getKey();\r
- HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue(); \r
- assert s1 != null;\r
- var2vst.put( var, \r
- (HashSet<VariableSourceToken>) (s1.clone()) );\r
- }\r
-\r
- sv2vst = new Hashtable< SVKey, Set<VariableSourceToken> >();\r
- itr = sv2vst.entrySet().iterator();\r
- while( itr.hasNext() ) {\r
- Map.Entry me = (Map.Entry) itr.next();\r
- SVKey key = (SVKey) me.getKey();\r
- HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue(); \r
- assert s1 != null;\r
- sv2vst.put( key, \r
- (HashSet<VariableSourceToken>) (s1.clone()) );\r
- }\r
- }\r
-\r
-\r
- public void add( VariableSourceToken vst ) {\r
- trueSet.add( vst );\r
-\r
- Set<VariableSourceToken> s;\r
-\r
- s = sese2vst.get( vst.getSESE() );\r
- if( s == null ) {\r
- s = new HashSet<VariableSourceToken>();\r
- }\r
- s.add( vst );\r
- sese2vst.put( vst.getSESE(), s );\r
-\r
- s = var2vst.get( vst.getVarLive() );\r
- if( s == null ) {\r
- s = new HashSet<VariableSourceToken>();\r
- }\r
- s.add( vst );\r
- var2vst.put( vst.getVarLive(), s );\r
-\r
- SVKey key = new SVKey( vst.getSESE(), vst.getVarLive() );\r
- s = sv2vst.get( key );\r
- if( s == null ) {\r
- s = new HashSet<VariableSourceToken>();\r
- }\r
- s.add( vst );\r
- sv2vst.put( key, s );\r
- }\r
-\r
- public void addAll( Set<VariableSourceToken> s ) {\r
- Iterator<VariableSourceToken> itr = s.iterator();\r
- while( itr.hasNext() ) {\r
- add( itr.next() );\r
- }\r
- }\r
-\r
-\r
- public Set<VariableSourceToken> get() {\r
- return trueSet;\r
- }\r
-\r
- public Set<VariableSourceToken> get( FlatSESEEnterNode sese ) {\r
- Set<VariableSourceToken> s = sese2vst.get( sese );\r
- if( s == null ) {\r
- s = new HashSet<VariableSourceToken>(); \r
- sese2vst.put( sese, s );\r
- }\r
- s.retainAll( trueSet );\r
- return s;\r
- }\r
-\r
- public Set<VariableSourceToken> get( TempDescriptor var ) {\r
- Set<VariableSourceToken> s = var2vst.get( var );\r
- if( s == null ) {\r
- s = new HashSet<VariableSourceToken>();\r
- var2vst.put( var, s );\r
- }\r
- s.retainAll( trueSet );\r
- return s;\r
- }\r
-\r
- public Set<VariableSourceToken> get( SVKey key ) {\r
- Set<VariableSourceToken> s = sv2vst.get( key );\r
- if( s == null ) {\r
- s = new HashSet<VariableSourceToken>();\r
- sv2vst.put( key, s );\r
- }\r
- s.retainAll( trueSet );\r
- return s;\r
- }\r
-\r
-\r
- public void merge( VarSrcTokTable table ) {\r
-\r
- if( table == null ) {\r
- return;\r
- }\r
-\r
- trueSet.addAll( table.trueSet );\r
-\r
- Iterator itr; \r
- Set s;\r
-\r
- itr = sese2vst.entrySet().iterator();\r
- while( itr.hasNext() ) {\r
- Map.Entry me = (Map.Entry) itr.next();\r
- FlatSESEEnterNode sese = (FlatSESEEnterNode) me.getKey();\r
- Set<VariableSourceToken> s1 = (Set<VariableSourceToken>) me.getValue();\r
- Set<VariableSourceToken> s2 = table.sese2vst.get( sese );\r
- \r
- assert s1 != null;\r
-\r
- if( s2 != null ) {\r
- s1.addAll( s2 );\r
- } \r
- }\r
- s = table.sese2vst.entrySet();\r
- s.removeAll( sese2vst.entrySet() );\r
- sese2vst.putAll( table.sese2vst );\r
-\r
- itr = var2vst.entrySet().iterator();\r
- while( itr.hasNext() ) {\r
- Map.Entry me = (Map.Entry) itr.next();\r
- TempDescriptor var = (TempDescriptor) me.getKey();\r
- Set<VariableSourceToken> s1 = (Set<VariableSourceToken>) me.getValue();\r
- Set<VariableSourceToken> s2 = table.var2vst.get( var );\r
- \r
- assert s1 != null;\r
-\r
- if( s2 != null ) {\r
- s1.addAll( s2 );\r
- } \r
- }\r
- s = table.var2vst.entrySet();\r
- s.removeAll( var2vst.entrySet() );\r
- var2vst.putAll( table.var2vst );\r
-\r
- itr = sv2vst.entrySet().iterator();\r
- while( itr.hasNext() ) {\r
- Map.Entry me = (Map.Entry) itr.next();\r
- SVKey key = (SVKey) me.getKey();\r
- Set<VariableSourceToken> s1 = (Set<VariableSourceToken>) me.getValue();\r
- Set<VariableSourceToken> s2 = table.sv2vst.get( key );\r
- \r
- assert s1 != null;\r
-\r
- if( s2 != null ) {\r
- s1.addAll( s2 );\r
- } \r
- }\r
- s = table.sv2vst.entrySet();\r
- s.removeAll( sv2vst.entrySet() );\r
- sv2vst.putAll( table.sv2vst );\r
- }\r
-\r
-\r
- public void remove( FlatSESEEnterNode sese ) {\r
- Set<VariableSourceToken> s = sese2vst.get( sese );\r
- if( s == null ) {\r
- return;\r
- }\r
- \r
- trueSet.removeAll( s ); \r
- sese2vst.remove( sese );\r
- }\r
-\r
- public void remove( TempDescriptor var ) {\r
- Set<VariableSourceToken> s = var2vst.get( var );\r
- if( s == null ) {\r
- return;\r
- }\r
- \r
- trueSet.removeAll( s ); \r
- var2vst.remove( var );\r
- }\r
-\r
- public void remove( FlatSESEEnterNode sese,\r
- TempDescriptor var ) {\r
-\r
- SVKey key = new SVKey( sese, var );\r
- Set<VariableSourceToken> s = sv2vst.get( key );\r
- if( s == null ) {\r
- return;\r
- }\r
- \r
- trueSet.removeAll( s );\r
- sv2vst.remove( key );\r
- }\r
-\r
- public void remove( VariableSourceToken vst ) {\r
- trueSet.remove( vst );\r
- }\r
-\r
-\r
- // return a new table based on this one and\r
- // age tokens with respect to SESE curr, where\r
- // any child becomes curr with age 0, and any\r
- // curr tokens increase age by 1\r
- public VarSrcTokTable age( FlatSESEEnterNode curr ) {\r
-\r
- VarSrcTokTable out = new VarSrcTokTable();\r
-\r
- Iterator<VariableSourceToken> itr = trueSet.iterator();\r
- while( itr.hasNext() ) {\r
- VariableSourceToken vst = itr.next();\r
- if( vst.getSESE().equals( curr ) ) {\r
- Integer newAge = vst.getAge()+1;\r
- if( newAge > MAX_AGE ) {\r
- newAge = MAX_AGE;\r
- }\r
- out.add( new VariableSourceToken( vst.getVarLive(), \r
- curr, \r
- newAge,\r
- vst.getVarSrc() \r
- )\r
- );\r
- } \r
- }\r
-\r
- return out;\r
- }\r
-\r
- \r
- // for the given SESE, change child tokens into this parent\r
- public VarSrcTokTable remapChildTokens( FlatSESEEnterNode curr ) {\r
-\r
- // create a table to modify as a copy of this\r
- VarSrcTokTable out = new VarSrcTokTable( this );\r
-\r
- Iterator<FlatSESEEnterNode> childItr = curr.getChildren().iterator();\r
- if( childItr.hasNext() ) {\r
- FlatSESEEnterNode child = childItr.next();\r
-\r
- Iterator<VariableSourceToken> vstItr = get( child ).iterator();\r
- while( vstItr.hasNext() ) {\r
- VariableSourceToken vst = vstItr.next();\r
- out.remove( vst );\r
- out.add( new VariableSourceToken( vst.getVarLive(),\r
- curr,\r
- new Integer( 0 ),\r
- vst.getVarLive() ) );\r
- }\r
- }\r
-\r
- return out; \r
- } \r
-\r
-\r
- // if we can get a value from the current SESE and the parent\r
- // or a sibling, just getting from the current SESE suffices now\r
- public VarSrcTokTable removeParentAndSiblingTokens( FlatSESEEnterNode curr ) {\r
-\r
- // create a table to modify as a copy of this\r
- VarSrcTokTable out = new VarSrcTokTable( this );\r
-\r
- FlatSESEEnterNode parent = curr.getParent();\r
- if( parent == null ) {\r
- // have no parent or siblings\r
- return out;\r
- } \r
-\r
- out.remove_A_if_B( parent, curr );\r
-\r
- Iterator<FlatSESEEnterNode> childItr = parent.getChildren().iterator();\r
- if( childItr.hasNext() ) {\r
- FlatSESEEnterNode child = childItr.next();\r
-\r
- if( !child.equals( curr ) ) {\r
- out.remove_A_if_B( child, curr );\r
- }\r
- }\r
-\r
- return out; \r
- }\r
-\r
- // if B is also a source for some variable, remove all entries\r
- // of A as a source for that variable\r
- protected void remove_A_if_B( FlatSESEEnterNode a, FlatSESEEnterNode b ) {\r
-\r
- Iterator<VariableSourceToken> vstItr = get( a ).iterator();\r
- while( vstItr.hasNext() ) {\r
- VariableSourceToken vst = vstItr.next();\r
-\r
- Set<VariableSourceToken> bSet = get( new SVKey( b, vst.getVarLive() ) );\r
- if( !bSet.isEmpty() ) {\r
- remove( vst );\r
-\r
- // mark this variable as a virtual read as well\r
- }\r
- }\r
- }\r
-\r
-\r
- public Set<VariableSourceToken> getStallSet( FlatSESEEnterNode curr/*,\r
- TempDescriptor varLive*/ ) {\r
-\r
- Set<VariableSourceToken> out = new HashSet<VariableSourceToken>();\r
-\r
- Iterator<FlatSESEEnterNode> cItr = curr.getChildren().iterator();\r
- while( cItr.hasNext() ) {\r
- FlatSESEEnterNode child = cItr.next();\r
- //out.addAll( get( new SVKey( child, varLive ) ) );\r
- out.addAll( get( child ) );\r
- }\r
-\r
- return out;\r
- }\r
-\r
-\r
- public boolean equals( Object o ) {\r
- if( o == null ) {\r
- return false;\r
- }\r
-\r
- if( !(o instanceof VarSrcTokTable) ) {\r
- return false;\r
- }\r
-\r
- VarSrcTokTable table = (VarSrcTokTable) o;\r
- return trueSet.equals( table.trueSet );\r
- }\r
-\r
- public int hashCode() {\r
- return trueSet.hashCode();\r
- }\r
-\r
- public Iterator<VariableSourceToken> iterator() {\r
- return trueSet.iterator();\r
- }\r
-\r
- public String toString() {\r
- return "trueSet ="+trueSet.toString()+"\n"+\r
- "sese2vst="+sese2vst.toString()+"\n"+\r
- "var2vst ="+var2vst.toString()+"\n"+\r
- "sv2vst ="+sv2vst.toString();\r
- }\r
-}\r
+package Analysis.MLP;
+
+import IR.*;
+import IR.Flat.*;
+import java.util.*;
+import java.io.*;
+
+// This class formerly had lazy consistency properties, but
+// it is being changed so that the full set and the extra
+// hash tables to access the full set efficiently by different
+// elements will be consistent after EVERY operation. Also,
+// a consistent assert method allows a debugger to ask whether
+// an operation has produced an inconsistent VarSrcTokTable.
+
+// in an effort to make sure operations keep the table consistent,
+// all public methods that are also used by other methods for
+// intermediate results (add and remove are used in other methods)
+// there should be a public version that calls the private version
+// so consistency is checked after public ops, but not private ops
+public class VarSrcTokTable {
+
+ // a set of every token in the table
+ private HashSet<VariableSourceToken> trueSet;
+
+ // these hashtables provide an efficient retreival from the true set
+ private Hashtable< TempDescriptor, Set<VariableSourceToken> > var2vst;
+ private Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> > sese2vst;
+ private Hashtable< SVKey, Set<VariableSourceToken> > sv2vst;
+
+ // maximum age from aging operation
+ private static final Integer MAX_AGE = new Integer( 2 );
+
+ public static final Integer SrcType_READY = new Integer( 34 );
+ public static final Integer SrcType_STATIC = new Integer( 35 );
+ public static final Integer SrcType_DYNAMIC = new Integer( 36 );
+
+
+ public VarSrcTokTable() {
+ trueSet = new HashSet<VariableSourceToken>();
+
+ sese2vst = new Hashtable< FlatSESEEnterNode, Set<VariableSourceToken> >();
+ var2vst = new Hashtable< TempDescriptor, Set<VariableSourceToken> >();
+ sv2vst = new Hashtable< SVKey, Set<VariableSourceToken> >();
+
+ assertConsistency();
+ }
+
+
+ // make a deep copy of the in table
+ public VarSrcTokTable( VarSrcTokTable in ) {
+ this();
+ merge( in );
+ assertConsistency();
+ }
+
+
+ public void add( VariableSourceToken vst ) {
+ addPrivate( vst );
+ assertConsistency();
+ }
+
+ private void addPrivate( VariableSourceToken vst ) {
+
+ // make sure we aren't clobbering anything!
+ if( trueSet.contains( vst ) ) {
+ // if something with the same hashcode is in the true set, they might
+ // have different reference variable sets because that set is not considered
+ // in a token's equality, so make sure we smooth that out right here
+ Iterator<VariableSourceToken> vstItr = trueSet.iterator();
+ while( vstItr.hasNext() ) {
+ VariableSourceToken vstAlready = vstItr.next();
+
+ if( vstAlready.equals( vst ) ) {
+
+ // take out the one that is in (we dont' want collisions in
+ // any of the other hash map sets either)
+ removePrivate( vstAlready );
+
+ // combine reference variable sets
+ vst.getRefVars().addAll( vstAlready.getRefVars() );
+
+ // now jump back as we are adding in a brand new token
+ break;
+ }
+ }
+ }
+
+ trueSet.add( vst );
+
+ Set<VariableSourceToken> s;
+
+ s = sese2vst.get( vst.getSESE() );
+ if( s == null ) {
+ s = new HashSet<VariableSourceToken>();
+ }
+ s.add( vst );
+ sese2vst.put( vst.getSESE(), s );
+
+ Iterator<TempDescriptor> refVarItr = vst.getRefVars().iterator();
+ while( refVarItr.hasNext() ) {
+ TempDescriptor refVar = refVarItr.next();
+ s = var2vst.get( refVar );
+ if( s == null ) {
+ s = new HashSet<VariableSourceToken>();
+ }
+ s.add( vst );
+ var2vst.put( refVar, s );
+
+ SVKey key = new SVKey( vst.getSESE(), refVar );
+ s = sv2vst.get( key );
+ if( s == null ) {
+ s = new HashSet<VariableSourceToken>();
+ }
+ s.add( vst );
+ sv2vst.put( key, s );
+ }
+ }
+
+ public void addAll( Set<VariableSourceToken> s ) {
+ Iterator<VariableSourceToken> itr = s.iterator();
+ while( itr.hasNext() ) {
+ addPrivate( itr.next() );
+ }
+ assertConsistency();
+ }
+
+
+ public Set<VariableSourceToken> get() {
+ return trueSet;
+ }
+
+ public Set<VariableSourceToken> get( FlatSESEEnterNode sese ) {
+ Set<VariableSourceToken> s = sese2vst.get( sese );
+ if( s == null ) {
+ s = new HashSet<VariableSourceToken>();
+ sese2vst.put( sese, s );
+ }
+ return s;
+ }
+
+ public Set<VariableSourceToken> get( TempDescriptor refVar ) {
+ Set<VariableSourceToken> s = var2vst.get( refVar );
+ if( s == null ) {
+ s = new HashSet<VariableSourceToken>();
+ var2vst.put( refVar, s );
+ }
+ return s;
+ }
+
+ public Set<VariableSourceToken> get( FlatSESEEnterNode sese,
+ TempDescriptor refVar ) {
+ SVKey key = new SVKey( sese, refVar );
+ Set<VariableSourceToken> s = sv2vst.get( key );
+ if( s == null ) {
+ s = new HashSet<VariableSourceToken>();
+ sv2vst.put( key, s );
+ }
+ return s;
+ }
+
+ public Set<VariableSourceToken> get( FlatSESEEnterNode sese,
+ Integer age ) {
+
+ HashSet<VariableSourceToken> s0 = (HashSet<VariableSourceToken>) sese2vst.get( sese );
+ if( s0 == null ) {
+ s0 = new HashSet<VariableSourceToken>();
+ sese2vst.put( sese, s0 );
+ }
+
+ Set<VariableSourceToken> s = (Set<VariableSourceToken>) s0.clone();
+ Iterator<VariableSourceToken> sItr = s.iterator();
+ while( sItr.hasNext() ) {
+ VariableSourceToken vst = sItr.next();
+ if( !vst.getAge().equals( age ) ) {
+ s.remove( vst );
+ }
+ }
+
+ return s;
+ }
+
+
+ // merge now makes a deep copy of incoming stuff because tokens may
+ // be modified (reference var sets) by later ops that change more
+ // than one table, causing inconsistency
+ public void merge( VarSrcTokTable in ) {
+
+ if( in == null ) {
+ return;
+ }
+
+ Iterator<VariableSourceToken> vstItr = in.trueSet.iterator();
+ while( vstItr.hasNext() ) {
+ VariableSourceToken vst = vstItr.next();
+ this.addPrivate( vst.copy() );
+ }
+
+ assertConsistency();
+ }
+
+
+ // remove operations must leave the trueSet
+ // and the hash maps consistent
+ public void remove( VariableSourceToken vst ) {
+ removePrivate( vst );
+ assertConsistency();
+ }
+
+ private void removePrivate( VariableSourceToken vst ) {
+ trueSet.remove( vst );
+
+ Set<VariableSourceToken> s;
+
+ s = get( vst.getSESE() );
+ if( s != null ) { s.remove( vst ); }
+
+ Iterator<TempDescriptor> refVarItr = vst.getRefVars().iterator();
+ while( refVarItr.hasNext() ) {
+ TempDescriptor refVar = refVarItr.next();
+
+ s = get( refVar );
+ if( s != null ) {
+ s.remove( vst );
+ if( s.isEmpty() ) {
+ var2vst.remove( refVar );
+ }
+ }
+
+ s = get( vst.getSESE(), refVar );
+ if( s != null ) {
+ s.remove( vst );
+ if( s.isEmpty() ) {
+ sv2vst.remove( new SVKey( vst.getSESE(), refVar ) );
+ }
+ }
+ }
+ }
+
+
+ public void remove( FlatSESEEnterNode sese ) {
+ removePrivate( sese );
+ assertConsistency();
+ }
+
+ public void removePrivate( FlatSESEEnterNode sese ) {
+ Set<VariableSourceToken> s = sese2vst.get( sese );
+ if( s == null ) {
+ return;
+ }
+
+ Iterator<VariableSourceToken> itr = s.iterator();
+ while( itr.hasNext() ) {
+ VariableSourceToken vst = itr.next();
+ removePrivate( vst );
+ }
+
+ sese2vst.remove( sese );
+ }
+
+
+ public void remove( TempDescriptor refVar ) {
+ removePrivate( refVar );
+ assertConsistency();
+ }
+
+ private void removePrivate( TempDescriptor refVar ) {
+ Set<VariableSourceToken> s = var2vst.get( refVar );
+ if( s == null ) {
+ return;
+ }
+
+ Set<VariableSourceToken> forRemoval = new HashSet<VariableSourceToken>();
+
+ // iterate over tokens that this temp can reference, make a set
+ // of tokens that need this temp stripped out of them
+ Iterator<VariableSourceToken> itr = s.iterator();
+ while( itr.hasNext() ) {
+ VariableSourceToken vst = itr.next();
+ Set<TempDescriptor> refVars = vst.getRefVars();
+ assert refVars.contains( refVar );
+ forRemoval.add( vst );
+ }
+
+ itr = forRemoval.iterator();
+ while( itr.hasNext() ) {
+
+ // here's a token marked for removal
+ VariableSourceToken vst = itr.next();
+ Set<TempDescriptor> refVars = vst.getRefVars();
+
+ // if there was only one one variable
+ // referencing this token, just take it
+ // out of the table all together
+ if( refVars.size() == 1 ) {
+ removePrivate( vst );
+ }
+
+ sv2vst.remove( new SVKey( vst.getSESE(), refVar ) );
+
+ refVars.remove( refVar );
+ }
+
+ var2vst.remove( refVar );
+ }
+
+
+ public void remove( FlatSESEEnterNode sese,
+ TempDescriptor var ) {
+
+ // don't seem to need this, don't bother maintaining
+ // until its clear we need it
+ assert false;
+ }
+
+
+ // age tokens with respect to SESE curr, where
+ // any curr tokens increase age by 1
+ public void age( FlatSESEEnterNode curr ) {
+
+ Set<VariableSourceToken> forRemoval =
+ new HashSet<VariableSourceToken>();
+
+ Set<VariableSourceToken> forAddition =
+ new HashSet<VariableSourceToken>();
+
+ Iterator<VariableSourceToken> itr = trueSet.iterator();
+ while( itr.hasNext() ) {
+ VariableSourceToken vst = itr.next();
+
+ if( vst.getSESE().equals( curr ) ) {
+
+ // only age if the token isn't already the maximum age
+ if( vst.getAge() < MAX_AGE ) {
+
+ forRemoval.add( vst );
+
+ forAddition.add( new VariableSourceToken( vst.getRefVars(),
+ curr,
+ vst.getAge() + 1,
+ vst.getAddrVar()
+ )
+ );
+ }
+ }
+ }
+
+ itr = forRemoval.iterator();
+ while( itr.hasNext() ) {
+ VariableSourceToken vst = itr.next();
+ remove( vst );
+ }
+
+ itr = forRemoval.iterator();
+ while( itr.hasNext() ) {
+ VariableSourceToken vst = itr.next();
+ add( vst );
+ }
+
+ assertConsistency();
+ }
+
+
+ // at an SESE enter node, all ref vars in the SESE's in-set will
+ // be copied into the SESE's local scope, change source to itself
+ public void ownInSet( FlatSESEEnterNode curr ) {
+ Iterator<TempDescriptor> inVarItr = curr.getInVarSet().iterator();
+ while( inVarItr.hasNext() ) {
+ TempDescriptor inVar = inVarItr.next();
+
+ remove( inVar );
+ assertConsistency();
+
+ Set<TempDescriptor> refVars = new HashSet<TempDescriptor>();
+ refVars.add( inVar );
+ add( new VariableSourceToken( refVars,
+ curr,
+ new Integer( 0 ),
+ inVar
+ )
+ );
+ assertConsistency();
+ }
+ }
+
+
+ // for the given SESE, change child tokens into this parent
+ public void remapChildTokens( FlatSESEEnterNode curr ) {
+
+ Iterator<FlatSESEEnterNode> childItr = curr.getChildren().iterator();
+ if( childItr.hasNext() ) {
+ FlatSESEEnterNode child = childItr.next();
+
+ // set of VSTs for removal
+ HashSet<VariableSourceToken> removalSet=new HashSet<VariableSourceToken>();
+ // set of VSTs for additon
+ HashSet<VariableSourceToken> additionSet=new HashSet<VariableSourceToken>();
+
+ Iterator<VariableSourceToken> vstItr = get( child ).iterator();
+ while( vstItr.hasNext() ) {
+ VariableSourceToken vst = vstItr.next();
+ removalSet.add(vst);
+ additionSet.add(new VariableSourceToken( vst.getRefVars(),
+ curr,
+ new Integer( 0 ),
+ vst.getAddrVar()
+ ));
+ }
+
+ // remove( eah item in forremoval )
+ vstItr = removalSet.iterator();
+ while( vstItr.hasNext() ) {
+ VariableSourceToken vst = vstItr.next();
+ remove( vst );
+ }
+ // add( each ite inm for additon _
+ vstItr = additionSet.iterator();
+ while( vstItr.hasNext() ) {
+ VariableSourceToken vst = vstItr.next();
+ add( vst );
+ }
+ }
+
+ assertConsistency();
+ }
+
+
+ // this method is called at the SESE exit of SESE 'curr'
+ // if the sources for a variable written by curr can also
+ // come from curr's parent or curr's siblings then we're not
+ // sure that curr will actually modify the variable. There are
+ // many ways to handle this, but for now, mark the variable as
+ // virtually read so curr insists on having ownership of it
+ // whether it ends up writing to it or not. It will always, then,
+ // appear in curr's out-set.
+ public Set<TempDescriptor>
+ calcVirtReadsAndPruneParentAndSiblingTokens( FlatSESEEnterNode exiter,
+ Set<TempDescriptor> liveVars ) {
+
+ Set<TempDescriptor> virtReadSet = new HashSet<TempDescriptor>();
+
+ FlatSESEEnterNode parent = exiter.getParent();
+ if( parent == null ) {
+ // having no parent means no siblings, too
+ return virtReadSet;
+ }
+
+ Set<FlatSESEEnterNode> alternateSESEs = new HashSet<FlatSESEEnterNode>();
+ alternateSESEs.add( parent );
+ Iterator<FlatSESEEnterNode> childItr = parent.getChildren().iterator();
+ while( childItr.hasNext() ) {
+ FlatSESEEnterNode sibling = childItr.next();
+ if( !sibling.equals( exiter ) ) {
+ alternateSESEs.add( sibling );
+ }
+ }
+
+ // VSTs to remove if they are alternate sources for exiter VSTs
+ // whose variables will become virtual reads
+ Set<VariableSourceToken> forRemoval = new HashSet<VariableSourceToken>();
+
+ // look at all of this SESE's VSTs at exit...
+ Iterator<VariableSourceToken> vstItr = get( exiter ).iterator();
+ while( vstItr.hasNext() ) {
+ VariableSourceToken vstExiterSrc = vstItr.next();
+
+ // only interested in tokens that come from our current instance
+ if( vstExiterSrc.getAge() != 0 ) {
+ continue;
+ }
+
+ // for each variable that might come from those sources...
+ Iterator<TempDescriptor> refVarItr = vstExiterSrc.getRefVars().iterator();
+ while( refVarItr.hasNext() ) {
+ TempDescriptor refVar = refVarItr.next();
+
+ // only matters for live variables at SESE exit program point
+ if( !liveVars.contains( refVar ) ) {
+ continue;
+ }
+
+ // examine other sources for a variable...
+ Iterator<VariableSourceToken> srcItr = get( refVar ).iterator();
+ while( srcItr.hasNext() ) {
+ VariableSourceToken vstPossibleOtherSrc = srcItr.next();
+
+ if( vstPossibleOtherSrc.getSESE().equals( exiter ) &&
+ vstPossibleOtherSrc.getAge() > 0
+ ) {
+ // this is an alternate source if its
+ // an older instance of this SESE
+ virtReadSet.add( refVar );
+ forRemoval.add( vstPossibleOtherSrc );
+
+ } else if( alternateSESEs.contains( vstPossibleOtherSrc.getSESE() ) ) {
+ // this is an alternate source from parent or sibling
+ virtReadSet.add( refVar );
+ forRemoval.add( vstPossibleOtherSrc );
+
+ } else {
+ assert vstPossibleOtherSrc.getSESE().equals( exiter );
+ assert vstPossibleOtherSrc.getAge().equals( 0 );
+ }
+ }
+ }
+ }
+
+ vstItr = forRemoval.iterator();
+ while( vstItr.hasNext() ) {
+ VariableSourceToken vst = vstItr.next();
+ remove( vst );
+ }
+ assertConsistency();
+
+ return virtReadSet;
+ }
+
+
+ // get the set of VST's that come from a child
+ public Set<VariableSourceToken> getChildrenVSTs( FlatSESEEnterNode curr ) {
+
+ Set<VariableSourceToken> out = new HashSet<VariableSourceToken>();
+
+ Iterator<FlatSESEEnterNode> cItr = curr.getChildren().iterator();
+ while( cItr.hasNext() ) {
+ FlatSESEEnterNode child = cItr.next();
+ out.addAll( get( child ) );
+ }
+
+ return out;
+ }
+
+
+ // get a sufficient set of VariableSourceTokens to cover all static sources
+ public Set<VariableSourceToken> getStaticSet( FlatSESEEnterNode current,
+ FlatSESEEnterNode parent
+ ) {
+
+ Set<VariableSourceToken> out = new HashSet<VariableSourceToken>();
+
+ Iterator itr = var2vst.entrySet().iterator();
+ while( itr.hasNext() ) {
+ Map.Entry me = (Map.Entry) itr.next();
+ TempDescriptor var = (TempDescriptor) me.getKey();
+ HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
+
+ if( getRefVarSrcType( var, current, parent ) == SrcType_STATIC ) {
+ out.add( s1.iterator().next() );
+ }
+ }
+
+ return out;
+ }
+
+
+ // given a table from a subsequent program point, decide
+ // which variables are going from a static source to a
+ // dynamic source and return them
+ public Hashtable<TempDescriptor, VariableSourceToken>
+ getStatic2DynamicSet( VarSrcTokTable nextTable,
+ Set<TempDescriptor> nextLiveIn,
+ FlatSESEEnterNode current,
+ FlatSESEEnterNode parent
+ ) {
+
+ Hashtable<TempDescriptor, VariableSourceToken> out =
+ new Hashtable<TempDescriptor, VariableSourceToken>();
+
+ Iterator itr = var2vst.entrySet().iterator();
+ while( itr.hasNext() ) {
+ Map.Entry me = (Map.Entry) itr.next();
+ TempDescriptor var = (TempDescriptor) me.getKey();
+ HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
+
+ // only worth tracking if live
+ if( nextLiveIn.contains( var ) ) {
+
+ if( this.getRefVarSrcType( var, current, parent ) == SrcType_STATIC &&
+ nextTable.getRefVarSrcType( var, current, parent ) == SrcType_DYNAMIC
+ ) {
+ // remember the variable and a static source
+ // it had before crossing the transition
+ out.put( var, s1.iterator().next() );
+ }
+ }
+ }
+
+ return out;
+ }
+
+
+ // for some reference variable, return the type of source
+ // it might have in this table, which might be:
+ // 1. Ready -- this variable comes from your parent and is
+ // definitely available when you are issued.
+ // 2. Static -- there is definitely one SESE that will
+ // produce the value for this variable
+ // 3. Dynamic -- we don't know where the value will come
+ // from, so we'll track it dynamically
+ public Integer getRefVarSrcType( TempDescriptor refVar,
+ FlatSESEEnterNode current,
+ FlatSESEEnterNode parent ) {
+ assert refVar != null;
+
+ // if you have no parent (root) and the variable in
+ // question is in your in-set, it's a command line
+ // argument and it is definitely available
+ if( parent == null &&
+ current.getInVarSet().contains( refVar ) ) {
+ return SrcType_READY;
+ }
+
+ // if there appear to be no sources, it means this variable
+ // comes from outside of any statically-known SESE scope,
+ // which means the system guarantees its READY
+ Set<VariableSourceToken> srcs = get( refVar );
+ if( srcs.isEmpty() ) {
+ return SrcType_READY;
+ }
+
+ // if the variable may have more than one source it might be
+ // dynamic, unless all sources are from a placeholder
+ if( srcs.size() > 1 ) {
+ Iterator<VariableSourceToken> itrSrcs = srcs.iterator();
+ VariableSourceToken oneSrc = itrSrcs.next();
+ while( itrSrcs.hasNext() ) {
+ VariableSourceToken anotherSrc = itrSrcs.next();
+ if( !oneSrc.getSESE().equals( anotherSrc.getSESE() ) ||
+ !oneSrc.getAge( ).equals( anotherSrc.getAge( ) )
+ ) {
+ return SrcType_DYNAMIC;
+ }
+ }
+
+ // all sources were same SESE and age, BUT, make sure it's
+ // not a placeholder SESE, who's vars are always ready
+ if( oneSrc.getSESE().getIsCallerSESEplaceholder() ) {
+ return SrcType_READY;
+ }
+
+ return SrcType_DYNAMIC;
+ }
+
+ VariableSourceToken singleSrc = srcs.iterator().next();
+ // if the one source is max age, track it dynamically
+ if( singleSrc.getAge() == MLPAnalysis.maxSESEage ) {
+ return SrcType_DYNAMIC;
+ }
+
+ // if it has one source that comes from the parent, it's ready
+ if( singleSrc.getSESE() == parent ) {
+ return SrcType_READY;
+ }
+
+ // if the one source is a placeholder SESE then it's ready
+ if( singleSrc.getSESE().getIsCallerSESEplaceholder() ) {
+ return SrcType_READY;
+ }
+
+ // otherwise it comes from one source not the parent (sibling)
+ // and we know exactly which static SESE/age it will come from
+ return SrcType_STATIC;
+ }
+
+
+ // any reference variables that are not live can be pruned
+ // from the table, and if any VSTs are then no longer
+ // referenced, they can be dropped as well
+ // THIS CAUSES INCONSISTENCY, FIX LATER, NOT REQUIRED
+ public void pruneByLiveness( Set<TempDescriptor> rootLiveSet ) {
+
+ // the set of reference variables in the table minus the
+ // live set gives the set of reference variables to remove
+ Set<TempDescriptor> deadRefVars = new HashSet<TempDescriptor>();
+ deadRefVars.addAll( var2vst.keySet() );
+
+ if( rootLiveSet != null ) {
+ deadRefVars.removeAll( rootLiveSet );
+ }
+
+ // just use the remove operation to prune the table now
+ Iterator<TempDescriptor> deadItr = deadRefVars.iterator();
+ while( deadItr.hasNext() ) {
+ TempDescriptor dead = deadItr.next();
+ removePrivate( dead );
+ }
+
+ assertConsistency();
+ }
+
+
+
+ // use as an aid for debugging, where true-set is checked
+ // against the alternate mappings: assert that nothing is
+ // missing or extra in the alternates
+ public void assertConsistency() {
+
+ Iterator itr;
+ Set s;
+
+ Set<VariableSourceToken> trueSetByAlts = new HashSet<VariableSourceToken>();
+ itr = sese2vst.entrySet().iterator();
+ while( itr.hasNext() ) {
+ Map.Entry me = (Map.Entry) itr.next();
+ FlatSESEEnterNode sese = (FlatSESEEnterNode) me.getKey();
+ HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
+ assert s1 != null;
+
+ // the trueSet should have all entries in s1
+ assert trueSet.containsAll( s1 );
+
+ // s1 should not have anything that doesn't appear in trueset
+ Set<VariableSourceToken> sInt = (Set<VariableSourceToken>) s1.clone();
+ sInt.removeAll( trueSet );
+
+ assert sInt.isEmpty();
+
+ // add s1 to a running union--at the end check if trueSet has extra
+ trueSetByAlts.addAll( s1 );
+ }
+ // make sure trueSet isn't too big
+ assert trueSetByAlts.containsAll( trueSet );
+
+
+ trueSetByAlts = new HashSet<VariableSourceToken>();
+ itr = var2vst.entrySet().iterator();
+ while( itr.hasNext() ) {
+ Map.Entry me = (Map.Entry) itr.next();
+ TempDescriptor var = (TempDescriptor) me.getKey();
+ HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
+ assert s1 != null;
+
+ // the trueSet should have all entries in s1
+ assert trueSet.containsAll( s1 );
+
+ // s1 should not have anything that doesn't appear in trueset
+ Set<VariableSourceToken> sInt = (Set<VariableSourceToken>) s1.clone();
+ sInt.removeAll( trueSet );
+
+ assert sInt.isEmpty();
+
+ // add s1 to a running union--at the end check if trueSet has extra
+ trueSetByAlts.addAll( s1 );
+ }
+ // make sure trueSet isn't too big
+ assert trueSetByAlts.containsAll( trueSet );
+
+
+ trueSetByAlts = new HashSet<VariableSourceToken>();
+ itr = sv2vst.entrySet().iterator();
+ while( itr.hasNext() ) {
+ Map.Entry me = (Map.Entry) itr.next();
+ SVKey key = (SVKey) me.getKey();
+ HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
+ assert s1 != null;
+
+ // the trueSet should have all entries in s1
+ assert trueSet.containsAll( s1 );
+
+ // s1 should not have anything that doesn't appear in trueset
+ Set<VariableSourceToken> sInt = (Set<VariableSourceToken>) s1.clone();
+ sInt.removeAll( trueSet );
+
+ assert sInt.isEmpty();
+
+ // add s1 to a running union--at the end check if trueSet has extra
+ trueSetByAlts.addAll( s1 );
+ }
+ // make sure trueSet isn't too big
+ assert trueSetByAlts.containsAll( trueSet );
+
+
+ // also check that the reference var sets are consistent
+ Hashtable<VariableSourceToken, Set<TempDescriptor> > vst2refVars =
+ new Hashtable<VariableSourceToken, Set<TempDescriptor> >();
+ itr = var2vst.entrySet().iterator();
+ while( itr.hasNext() ) {
+ Map.Entry me = (Map.Entry) itr.next();
+ TempDescriptor refVar = (TempDescriptor) me.getKey();
+ HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
+ Iterator<VariableSourceToken> vstItr = s1.iterator();
+ while( vstItr.hasNext() ) {
+ VariableSourceToken vst = vstItr.next();
+ assert vst.getRefVars().contains( refVar );
+
+ Set<TempDescriptor> refVarsPart = vst2refVars.get( vst );
+ if( refVarsPart == null ) {
+ refVarsPart = new HashSet<TempDescriptor>();
+ }
+ refVarsPart.add( refVar );
+ vst2refVars.put( vst, refVarsPart );
+ }
+ }
+ itr = vst2refVars.entrySet().iterator();
+ while( itr.hasNext() ) {
+ Map.Entry me = (Map.Entry) itr.next();
+ VariableSourceToken vst = (VariableSourceToken) me.getKey();
+ Set<TempDescriptor> s1 = (Set<TempDescriptor>) me.getValue();
+
+ assert vst.getRefVars().equals( s1 );
+ }
+ }
+
+
+ public boolean equals( Object o ) {
+ if( o == null ) {
+ return false;
+ }
+
+ if( !(o instanceof VarSrcTokTable) ) {
+ return false;
+ }
+
+ VarSrcTokTable table = (VarSrcTokTable) o;
+ return trueSet.equals( table.trueSet );
+ }
+
+ public int hashCode() {
+ return trueSet.hashCode();
+ }
+
+ public Iterator<VariableSourceToken> iterator() {
+ return trueSet.iterator();
+ }
+
+ public String toString() {
+ return toStringPretty();
+ }
+
+ public String toStringVerbose() {
+ return "trueSet ="+trueSet.toString()+"\n"+
+ "sese2vst="+sese2vst.toString()+"\n"+
+ "var2vst ="+var2vst.toString()+"\n"+
+ "sv2vst ="+sv2vst.toString();
+ }
+
+ public String toStringPretty() {
+ String tokHighlighter = "o";
+
+ String str = "VarSrcTokTable\n";
+ Iterator<VariableSourceToken> vstItr = trueSet.iterator();
+ while( vstItr.hasNext() ) {
+ str += " "+tokHighlighter+" "+vstItr.next()+"\n";
+ }
+ return str;
+ }
+
+ public String toStringPrettyVerbose() {
+ String tokHighlighter = "o";
+
+ String str = "VarSrcTokTable\n";
+
+ Set s;
+ Iterator itr;
+ Iterator<VariableSourceToken> vstItr;
+
+ str += " trueSet\n";
+ vstItr = trueSet.iterator();
+ while( vstItr.hasNext() ) {
+ str += " "+tokHighlighter+" "+vstItr.next()+"\n";
+ }
+
+ str += " sese2vst\n";
+ itr = sese2vst.entrySet().iterator();
+ while( itr.hasNext() ) {
+ Map.Entry me = (Map.Entry) itr.next();
+ FlatSESEEnterNode sese = (FlatSESEEnterNode) me.getKey();
+ HashSet<VariableSourceToken> s1 = (HashSet<VariableSourceToken>) me.getValue();
+ assert s1 != null;
+
+ str += " "+sese.getPrettyIdentifier()+" -> \n";
+
+ vstItr = s1.iterator();
+ while( vstItr.hasNext() ) {
+ str += " "+tokHighlighter+" "+vstItr.next()+"\n";
+ }
+ }
+
+ str += " var2vst\n";
+ itr = var2vst.entrySet().iterator();
+ while( itr.hasNext() ) {
+ Map.Entry me = (Map.Entry) itr.next();
+ TempDescriptor var = (TempDescriptor) me.getKey();
+ Set<VariableSourceToken> s1 = (Set<VariableSourceToken>) me.getValue();
+ assert s1 != null;
+
+ str += " "+var+" -> \n";
+
+ vstItr = s1.iterator();
+ while( vstItr.hasNext() ) {
+ str += " "+tokHighlighter+" "+vstItr.next()+"\n";
+ }
+ }
+
+ str += " sv2vst\n";
+ itr = sv2vst.entrySet().iterator();
+ while( itr.hasNext() ) {
+ Map.Entry me = (Map.Entry) itr.next();
+ SVKey key = (SVKey) me.getKey();
+ Set<VariableSourceToken> s1 = (Set<VariableSourceToken>) me.getValue();
+ assert s1 != null;
+
+ str += " "+key+" -> \n";
+
+ vstItr = s1.iterator();
+ while( vstItr.hasNext() ) {
+ str += " "+tokHighlighter+" "+vstItr.next()+"\n";
+ }
+ }
+
+ return str;
+ }
+}