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() {
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;
}
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 ) );
+ }
+ }
}
}
removePrivate( vst );
}
- refVars.remove( refVar );
+ sv2vst.remove( new SVKey( vst.getSESE(), refVar ) );
+
+ refVars.remove( refVar );
}
- var2vst.remove( refVar );
+ var2vst.remove( refVar );
}
// 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 ) {
// 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>();
// 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() );
+ }
+ }
}
}
}
+ // 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
}
public String toString() {
- //return "trueSet ="+trueSet.toString();
return toStringPretty();
}