Still haven't worked all the bugs out of MLP's support for method calls, but stable...
[IRC.git] / Robust / src / Analysis / MLP / VarSrcTokTable.java
index d3cffae3beaf710233a00f209b185b024dc3e24a..95265618629b61886e97b5773a8f59eff3be6303 100644 (file)
@@ -28,7 +28,11 @@ public class VarSrcTokTable {
   private Hashtable< SVKey,             Set<VariableSourceToken> >   sv2vst;
 
   // maximum age from aging operation
-  private Integer MAX_AGE = new Integer( 2 );
+  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() {
@@ -134,11 +138,11 @@ public class VarSrcTokTable {
     return s;
   }
 
-  public Set<VariableSourceToken> get( TempDescriptor var ) {
-    Set<VariableSourceToken> s = var2vst.get( var );
+  public Set<VariableSourceToken> get( TempDescriptor refVar ) {
+    Set<VariableSourceToken> s = var2vst.get( refVar );
     if( s == null ) {
       s = new HashSet<VariableSourceToken>();
-      var2vst.put( var, s );
+      var2vst.put( refVar, s );
     }
     return s;
   }
@@ -215,10 +219,20 @@ public class VarSrcTokTable {
       TempDescriptor refVar = refVarItr.next();
 
       s = get( refVar );
-      if( s != null ) { s.remove( vst ); }
+      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 != null ) { 
+       s.remove( vst );
+       if( s.isEmpty() ) {
+         sv2vst.remove( new SVKey( vst.getSESE(), refVar ) );
+       }
+      }
     }
   }
 
@@ -281,10 +295,12 @@ public class VarSrcTokTable {
         removePrivate( vst );
       }
 
-      refVars.remove( refVar );
+      sv2vst.remove( new SVKey( vst.getSESE(), refVar ) );
+
+      refVars.remove( refVar );      
     }
 
-    var2vst.remove( refVar );
+    var2vst.remove( refVar );    
   }
 
 
@@ -301,31 +317,71 @@ public class VarSrcTokTable {
   // 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 ) ) {
 
-       Integer newAge = vst.getAge()+1;
-       if( newAge > MAX_AGE ) {
-         newAge = MAX_AGE;
-       }
+       // only age if the token isn't already the maximum age
+       if( vst.getAge() < MAX_AGE ) {
        
-       remove( vst );
-
-        add( new VariableSourceToken( vst.getRefVars(), 
-                                     curr,                                           
-                                     newAge,
-                                     vst.getAddrVar()
-                                     )
-            );
+         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 ) {
@@ -419,7 +475,7 @@ public class VarSrcTokTable {
 
   
   // get the set of VST's that come from a child
-  public Set<VariableSourceToken> getStallSet( FlatSESEEnterNode curr ) {
+  public Set<VariableSourceToken> getChildrenVSTs( FlatSESEEnterNode curr ) {
     
     Set<VariableSourceToken> out = new HashSet<VariableSourceToken>();
     
@@ -457,24 +513,36 @@ public class VarSrcTokTable {
   // 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 Set<VariableSourceToken> getStatic2DynamicSet( VarSrcTokTable next ) {
+  public Hashtable<TempDescriptor, VariableSourceToken> 
+    getStatic2DynamicSet( VarSrcTokTable nextTable,
+                         Set<TempDescriptor> nextLiveIn ) {
     
-    Set<VariableSourceToken> out = new HashSet<VariableSourceToken>();
+    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();      
-    
-      if( s1.size() == 1 ) {
-        // this is a variable with a static source
-        Set<VariableSourceToken> s2 = next.get( var );
-        
-        if( s2.size() > 1 ) {
-          // and in the next table, it is dynamic
-          out.addAll( s1 );
-        }
+
+      // only worth tracking if live
+      if( nextLiveIn.contains( var ) ) {
+
+       // this is a variable with a static source if it
+       // currently has one vst
+       if( s1.size() == 1 ) {
+         Set<VariableSourceToken> s2 = nextTable.get( var );    
+
+         // and if in the next table, it is dynamic, then
+         // this is a transition point, so
+         if( s2.size() > 1 ) {    
+
+           // remember the variable and the only source
+           // it had before crossing the transition
+           out.put( var, s1.iterator().next() );
+         }
+       }
       }
     }
 
@@ -482,6 +550,80 @@ public class VarSrcTokTable {
   }
 
 
+  // 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, or that
+    // source is at the summary age, it must be tracked dynamically
+    if( srcs.size() > 1 || 
+       srcs.iterator().next().getAge() == MLPAnalysis.maxSESEage ) {
+      return SrcType_DYNAMIC;
+    } 
+
+    // if it has one source that comes from the parent, it's ready
+    if( srcs.iterator().next().getSESE() == parent ) {
+      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
@@ -616,7 +758,6 @@ public class VarSrcTokTable {
   }
 
   public String toString() {
-    //return "trueSet ="+trueSet.toString();
     return toStringPretty();
   }