public class MLPAnalysis {
// data from the compiler
- private State state;
- private TypeUtil typeUtil;
- private CallGraph callGraph;
+ private State state;
+ private TypeUtil typeUtil;
+ private CallGraph callGraph;
private OwnershipAnalysis ownAnalysis;
- private SESENode rootTree;
- private FlatSESEEnterNode rootSESE;
- private FlatSESEExitNode rootExit;
-
+ private FlatSESEEnterNode rootSESE;
private Set<FlatSESEEnterNode> allSESEs;
private Hashtable< FlatNode, Stack<FlatSESEEnterNode> > seseStacks;
private Hashtable< FlatNode, Set<TempDescriptor> > notAvailableResults;
private Hashtable< FlatNode, CodePlan > codePlans;
- private static final int maxSESEage = 2;
+ private Hashtable<FlatEdge, FlatWriteDynamicVarNode> wdvNodesToSpliceIn;
+
+ public static int maxSESEage = -1;
- // use these methods in BuildCode to have access to analysis results
- public Set<FlatSESEEnterNode> getAllSESEs() {
- return allSESEs;
- }
+ // use these methods in BuildCode to have access to analysis results
public FlatSESEEnterNode getRootSESE() {
return rootSESE;
}
+ public Set<FlatSESEEnterNode> getAllSESEs() {
+ return allSESEs;
+ }
+
public int getMaxSESEage() {
return maxSESEage;
}
+ // may be null
public CodePlan getCodePlan( FlatNode fn ) {
CodePlan cp = codePlans.get( fn );
- assert cp != null;
return cp;
}
this.typeUtil = tu;
this.callGraph = callGraph;
this.ownAnalysis = ownAnalysis;
+ this.maxSESEage = state.MLP_MAXSESEAGE;
// initialize analysis data structures
allSESEs = new HashSet<FlatSESEEnterNode>();
notAvailableResults = new Hashtable< FlatNode, Set<TempDescriptor> >();
codePlans = new Hashtable< FlatNode, CodePlan >();
+ wdvNodesToSpliceIn = new Hashtable<FlatEdge, FlatWriteDynamicVarNode>();
- // build an implicit root SESE to wrap contents of main method
- rootTree = new SESENode( "root" );
- rootSESE = new FlatSESEEnterNode( rootTree );
- rootExit = new FlatSESEExitNode ( rootTree );
- rootSESE.setFlatExit ( rootExit );
- rootExit.setFlatEnter( rootSESE );
FlatMethod fmMain = state.getMethodFlat( tu.getMain() );
+ rootSESE = (FlatSESEEnterNode) fmMain.getNext(0);
+ rootSESE.setfmEnclosing( fmMain );
+ rootSESE.setmdEnclosing( fmMain.getMethod() );
+ rootSESE.setcdEnclosing( fmMain.getMethod().getClassDesc() );
+
+ if( state.MLPDEBUG ) {
+ System.out.println( "" );
+ }
// 1st pass
// run analysis on each method that is actually called
// and organize them into roots and children
buildForestForward( fm );
}
+ if( state.MLPDEBUG ) {
+ //System.out.println( "\nSESE Hierarchy\n--------------\n" ); printSESEHierarchy();
+ }
// 2nd pass, results are saved in FlatSESEEnterNode, so
// 4th pass, compute liveness contribution from
// virtual reads discovered in variable pass
livenessAnalysisBackward( rootSESE, true, null, fmMain.getFlatExit() );
+ if( state.MLPDEBUG ) {
+ //System.out.println( "\nLive-In, SESE View\n-------------\n" ); printSESELiveness();
+ //System.out.println( "\nLive-In, Root View\n------------------\n"+fmMain.printMethod( livenessRootView ) );
+ }
// 5th pass
Descriptor d = methItr.next();
FlatMethod fm = state.getMethodFlat( d );
+ // prune variable results in one traversal
+ // by removing reference variables that are not live
+ pruneVariableResultsWithLiveness( fm );
+ }
+ if( state.MLPDEBUG ) {
+ //System.out.println( "\nVariable Results-Out\n----------------\n"+fmMain.printMethod( variableResults ) );
+ }
+
+
+ // 6th pass
+ methItr = ownAnalysis.descriptorsToAnalyze.iterator();
+ while( methItr.hasNext() ) {
+ Descriptor d = methItr.next();
+ FlatMethod fm = state.getMethodFlat( d );
+
// compute what is not available at every program
// point, in a forward fixed-point pass
notAvailableForward( fm );
}
+ if( state.MLPDEBUG ) {
+ //System.out.println( "\nNot Available Results-Out\n---------------------\n"+fmMain.printMethod( notAvailableResults ) );
+ }
- // 5th pass
+ // 7th pass
methItr = ownAnalysis.descriptorsToAnalyze.iterator();
while( methItr.hasNext() ) {
Descriptor d = methItr.next();
// compute a plan for code injections
computeStallsForward( fm );
}
-
-
- if( state.MLPDEBUG ) {
- System.out.println( "" );
- //System.out.println( "\nSESE Hierarchy\n--------------\n" ); printSESEHierarchy();
- //System.out.println( "\nSESE Liveness\n-------------\n" ); printSESELiveness();
- //System.out.println( "\nLiveness Root View\n------------------\n"+fmMain.printMethod( livenessRootView ) );
- //System.out.println( "\nVariable Results\n----------------\n"+fmMain.printMethod( variableResults ) );
- //System.out.println( "\nNot Available Results\n---------------------\n"+fmMain.printMethod( notAvailableResults ) );
+ if( state.MLPDEBUG ) {
//System.out.println( "\nCode Plans\n----------\n"+fmMain.printMethod( codePlans ) );
}
+ // splice new IR nodes into graph after all
+ // analysis passes are complete
+ Iterator spliceItr = wdvNodesToSpliceIn.entrySet().iterator();
+ while( spliceItr.hasNext() ) {
+ Map.Entry me = (Map.Entry) spliceItr.next();
+ FlatWriteDynamicVarNode fwdvn = (FlatWriteDynamicVarNode) me.getValue();
+ fwdvn.spliceIntoIR();
+ }
+
+ // detailed per-SESE information
+ if( state.MLPDEBUG ) {
+ System.out.println( "\nSESE info\n-------------\n" ); printSESEInfo();
+ }
double timeEndAnalysis = (double) System.nanoTime();
double dt = (timeEndAnalysis - timeStartAnalysis)/(Math.pow( 10.0, 9.0 ) );
Set<FlatNode> visited = new HashSet<FlatNode>();
Stack<FlatSESEEnterNode> seseStackFirst = new Stack<FlatSESEEnterNode>();
- seseStackFirst.push( rootSESE );
seseStacks.put( fm, seseStackFirst );
while( !flatNodesToVisit.isEmpty() ) {
FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
allSESEs.add( fsen );
- fsen.setEnclosingFlatMeth( fm );
+ fsen.setfmEnclosing( fm );
+ fsen.setmdEnclosing( fm.getMethod() );
+ fsen.setcdEnclosing( fm.getMethod().getClassDesc() );
+
+ if( !seseStack.empty() ) {
+ seseStack.peek().addChild( fsen );
+ fsen.setParent( seseStack.peek() );
+ }
- assert !seseStack.empty();
- seseStack.peek().addChild( fsen );
- fsen.setParent( seseStack.peek() );
seseStack.push( fsen );
} break;
case FKind.FlatReturnNode: {
FlatReturnNode frn = (FlatReturnNode) fn;
- if( !seseStack.empty() &&
- !seseStack.peek().equals( rootSESE ) ) {
- throw new Error( "Error: return statement enclosed within "+seseStack.peek() );
+ if( !seseStack.empty() ) {
+ throw new Error( "Error: return statement enclosed within SESE "+
+ seseStack.peek().getPrettyIdentifier() );
}
} break;
u.addAll( s );
}
}
-
+
Set<TempDescriptor> curr = liveness_nodeActions( fn, u, fsen, toplevel, liveout);
// if a new result, schedule backward nodes for analysis
- if(!curr.equals(prev)) {
+ if( !curr.equals( prev ) ) {
livenessResults.put( fn, curr );
// don't flow backwards past current SESE enter
Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
while( childItr.hasNext() ) {
FlatSESEEnterNode fsenChild = childItr.next();
- livenessAnalysisBackward( fsenChild, false, liveout, null);
+ livenessAnalysisBackward( fsenChild, false, liveout, null );
}
}
}
}
+ private void printSESEInfo() {
+ printSESEInfoTree( rootSESE );
+ System.out.println( "" );
+ }
+
+ private void printSESEInfoTree( FlatSESEEnterNode fsen ) {
+
+ System.out.println( "SESE "+fsen.getPrettyIdentifier()+" {" );
+
+ System.out.println( " in-set: "+fsen.getInVarSet() );
+ Iterator<TempDescriptor> tItr = fsen.getInVarSet().iterator();
+ while( tItr.hasNext() ) {
+ TempDescriptor inVar = tItr.next();
+ if( fsen.getReadyInVarSet().contains( inVar ) ) {
+ System.out.println( " (ready) "+inVar );
+ }
+ if( fsen.getStaticInVarSet().contains( inVar ) ) {
+ System.out.println( " (static) "+inVar );
+ }
+ if( fsen.getDynamicInVarSet().contains( inVar ) ) {
+ System.out.println( " (dynamic)"+inVar );
+ }
+ }
+
+ System.out.println( " out-set: "+fsen.getOutVarSet() );
+
+ /*
+ System.out.println( " static names to track:" );
+ tItr = fsen.getOutVarSet().iterator();
+ while( tItr.hasNext() ) {
+ System.out.println( " "+tItr.next() );
+ }
+ */
+
+ System.out.println( "}" );
+
+ Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
+ while( childItr.hasNext() ) {
+ FlatSESEEnterNode fsenChild = childItr.next();
+ printSESEInfoTree( fsenChild );
+ }
+ }
+
private void variableAnalysisForward( FlatMethod fm ) {
VarSrcTokTable prev = variableResults.get( fn );
// merge sets from control flow joins
- VarSrcTokTable inUnion = new VarSrcTokTable();
+ VarSrcTokTable curr = new VarSrcTokTable();
for( int i = 0; i < fn.numPrev(); i++ ) {
FlatNode nn = fn.getPrev( i );
VarSrcTokTable incoming = variableResults.get( nn );
- inUnion.merge( incoming );
+ curr.merge( incoming );
}
- VarSrcTokTable curr = variable_nodeActions( fn, inUnion, seseStack.peek() );
+ if( !seseStack.empty() ) {
+ variable_nodeActions( fn, curr, seseStack.peek() );
+ }
// if a new result, schedule forward nodes for analysis
if( !curr.equals( prev ) ) {
}
}
- private VarSrcTokTable variable_nodeActions( FlatNode fn,
- VarSrcTokTable vstTable,
- FlatSESEEnterNode currentSESE ) {
+ private void variable_nodeActions( FlatNode fn,
+ VarSrcTokTable vstTable,
+ FlatSESEEnterNode currentSESE ) {
switch( fn.kind() ) {
case FKind.FlatSESEEnterNode: {
FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
assert fsen.equals( currentSESE );
+
vstTable.age( currentSESE );
vstTable.assertConsistency();
+
+ vstTable.ownInSet( currentSESE );
+ vstTable.assertConsistency();
} break;
case FKind.FlatSESEExitNode: {
}
livenessVirtualReads.put( fn, virLiveIn );
vstTable.assertConsistency();
+
+ // then all child out-set tokens are guaranteed
+ // to be filled in, so clobber those entries with
+ // the latest, clean sources
+ Iterator<TempDescriptor> outVarItr = fsen.getOutVarSet().iterator();
+ while( outVarItr.hasNext() ) {
+ TempDescriptor outVar = outVarItr.next();
+ HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
+ ts.add( outVar );
+ VariableSourceToken vst = new VariableSourceToken( ts,
+ fsen,
+ new Integer( 0 ),
+ outVar
+ );
+ vstTable.remove( outVar );
+ vstTable.add( vst );
+ }
+ vstTable.assertConsistency();
+
} break;
case FKind.FlatOpNode: {
if( fon.getOp().getOp() == Operation.ASSIGN ) {
TempDescriptor lhs = fon.getDest();
- TempDescriptor rhs = fon.getLeft();
+ TempDescriptor rhs = fon.getLeft();
vstTable.remove( lhs );
HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
ts.add( lhs );
- // if this is from a child, keep the source information
- if( currentSESE.getChildren().contains( vst.getSESE() ) ) {
- forAddition.add( new VariableSourceToken( ts,
- vst.getSESE(),
- vst.getAge(),
- vst.getAddrVar()
- )
- );
-
- // otherwise, it's our or an ancestor's token so we
- // can assume we have everything we need
- } else {
- forAddition.add( new VariableSourceToken( ts,
- currentSESE,
- new Integer( 0 ),
- lhs
- )
- );
- }
+ forAddition.add( new VariableSourceToken( ts,
+ vst.getSESE(),
+ vst.getAge(),
+ vst.getAddrVar()
+ )
+ );
}
vstTable.addAll( forAddition );
} break;
} // end switch
+ }
+
+
+ private void pruneVariableResultsWithLiveness( FlatMethod fm ) {
+
+ // start from flat method top, visit every node in
+ // method exactly once
+ Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
+ flatNodesToVisit.add( fm );
+
+ Set<FlatNode> visited = new HashSet<FlatNode>();
+
+ while( !flatNodesToVisit.isEmpty() ) {
+ Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
+ FlatNode fn = fnItr.next();
+
+ flatNodesToVisit.remove( fn );
+ visited.add( fn );
- return vstTable;
+ Set<TempDescriptor> rootLiveSet = livenessRootView.get( fn );
+ VarSrcTokTable vstTable = variableResults.get( fn );
+
+ // fix later, not working, only wanted it to make tables easier to read
+ //vstTable.pruneByLiveness( rootLiveSet );
+
+ for( int i = 0; i < fn.numNext(); i++ ) {
+ FlatNode nn = fn.getNext( i );
+
+ if( !visited.contains( nn ) ) {
+ flatNodesToVisit.add( nn );
+ }
+ }
+ }
}
Set<TempDescriptor> prev = notAvailableResults.get( fn );
- Set<TempDescriptor> inUnion = new HashSet<TempDescriptor>();
+ Set<TempDescriptor> curr = new HashSet<TempDescriptor>();
for( int i = 0; i < fn.numPrev(); i++ ) {
FlatNode nn = fn.getPrev( i );
Set<TempDescriptor> notAvailIn = notAvailableResults.get( nn );
if( notAvailIn != null ) {
- inUnion.addAll( notAvailIn );
+ curr.addAll( notAvailIn );
}
}
-
- Set<TempDescriptor> curr = notAvailable_nodeActions( fn, inUnion, seseStack.peek() );
+
+ if( !seseStack.empty() ) {
+ notAvailable_nodeActions( fn, curr, seseStack.peek() );
+ }
// if a new result, schedule forward nodes for analysis
if( !curr.equals( prev ) ) {
}
}
- private Set<TempDescriptor> notAvailable_nodeActions( FlatNode fn,
- Set<TempDescriptor> notAvailSet,
- FlatSESEEnterNode currentSESE ) {
+ private void notAvailable_nodeActions( FlatNode fn,
+ Set<TempDescriptor> notAvailSet,
+ FlatSESEEnterNode currentSESE ) {
// any temps that are removed from the not available set
// at this node should be marked in this node's code plan
Set<TempDescriptor> liveTemps = livenessRootView.get( fn );
assert liveTemps != null;
- VarSrcTokTable vstTable = variableResults.get( fn );
- assert vstTable != null;
-
- Set<TempDescriptor> notAvailAtEnter = notAvailableResults.get( fsen );
- assert notAvailAtEnter != null;
-
- Iterator<TempDescriptor> tdItr = liveTemps.iterator();
- while( tdItr.hasNext() ) {
- TempDescriptor td = tdItr.next();
-
- if( vstTable.get( fsen, td ).size() > 0 ) {
- // there is at least one child token for this variable
- notAvailSet.add( td );
- continue;
- }
-
- if( notAvailAtEnter.contains( td ) ) {
- // wasn't available at enter, not available now
- notAvailSet.add( td );
- continue;
- }
- }
+ notAvailSet.addAll( liveTemps );
} break;
case FKind.FlatOpNode: {
TempDescriptor rTemp = readTemps[i];
notAvailSet.remove( rTemp );
- // if this variable has exactly one source, mark everything
- // else from that source as available as well
- VarSrcTokTable table = variableResults.get( fn );
- Set<VariableSourceToken> srcs = table.get( rTemp );
+ // if this variable has exactly one source, potentially
+ // get other things from this source as well
+ VarSrcTokTable vstTable = variableResults.get( fn );
- if( srcs.size() == 1 ) {
- VariableSourceToken vst = srcs.iterator().next();
-
- Iterator<VariableSourceToken> availItr = table.get( vst.getSESE(),
- vst.getAge()
- ).iterator();
+ Integer srcType =
+ vstTable.getRefVarSrcType( rTemp,
+ currentSESE,
+ currentSESE.getParent() );
+
+ if( srcType.equals( VarSrcTokTable.SrcType_STATIC ) ) {
+
+ VariableSourceToken vst = vstTable.get( rTemp ).iterator().next();
+
+ Iterator<VariableSourceToken> availItr = vstTable.get( vst.getSESE(),
+ vst.getAge()
+ ).iterator();
+
+ // look through things that are also available from same source
while( availItr.hasNext() ) {
VariableSourceToken vstAlsoAvail = availItr.next();
- notAvailSet.removeAll( vstAlsoAvail.getRefVars() );
+
+ Iterator<TempDescriptor> refVarItr = vstAlsoAvail.getRefVars().iterator();
+ while( refVarItr.hasNext() ) {
+ TempDescriptor refVarAlso = refVarItr.next();
+
+ // if a variable is available from the same source, AND it ALSO
+ // only comes from one statically known source, mark it available
+ Integer srcTypeAlso =
+ vstTable.getRefVarSrcType( refVarAlso,
+ currentSESE,
+ currentSESE.getParent() );
+ if( srcTypeAlso.equals( VarSrcTokTable.SrcType_STATIC ) ) {
+ notAvailSet.remove( refVarAlso );
+ }
+ }
}
}
}
} break;
} // end switch
-
- return notAvailSet;
}
}
}
- computeStalls_nodeActions( fn, dotSTtable, dotSTnotAvailSet, seseStack.peek() );
+ Set<TempDescriptor> dotSTlive = livenessRootView.get( fn );
+
+ if( !seseStack.empty() ) {
+ computeStalls_nodeActions( fn,
+ dotSTlive,
+ dotSTtable,
+ dotSTnotAvailSet,
+ seseStack.peek()
+ );
+ }
for( int i = 0; i < fn.numNext(); i++ ) {
FlatNode nn = fn.getNext( i );
}
private void computeStalls_nodeActions( FlatNode fn,
- VarSrcTokTable vstTable,
- Set<TempDescriptor> notAvailSet,
+ Set<TempDescriptor> liveSetIn,
+ VarSrcTokTable vstTableIn,
+ Set<TempDescriptor> notAvailSetIn,
FlatSESEEnterNode currentSESE ) {
- CodePlan plan = new CodePlan();
+ CodePlan plan = new CodePlan( currentSESE);
switch( fn.kind() ) {
case FKind.FlatSESEEnterNode: {
FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
- plan.setSESEtoIssue( fsen );
+
+ // track the source types of the in-var set so generated
+ // code at this SESE issue can compute the number of
+ // dependencies properly
+ Iterator<TempDescriptor> inVarItr = fsen.getInVarSet().iterator();
+ while( inVarItr.hasNext() ) {
+ TempDescriptor inVar = inVarItr.next();
+ Integer srcType =
+ vstTableIn.getRefVarSrcType( inVar,
+ fsen,
+ fsen.getParent() );
+
+ // the current SESE needs a local space to track the dynamic
+ // variable and the child needs space in its SESE record
+ if( srcType.equals( VarSrcTokTable.SrcType_DYNAMIC ) ) {
+ fsen.addDynamicInVar( inVar );
+ fsen.getParent().addDynamicVar( inVar );
+
+ } else if( srcType.equals( VarSrcTokTable.SrcType_STATIC ) ) {
+ fsen.addStaticInVar( inVar );
+ VariableSourceToken vst = vstTableIn.get( inVar ).iterator().next();
+ fsen.putStaticInVar2src( inVar, vst );
+ fsen.addStaticInVarSrc( new SESEandAgePair( vst.getSESE(),
+ vst.getAge()
+ )
+ );
+
+ } else {
+ assert srcType.equals( VarSrcTokTable.SrcType_READY );
+ fsen.addReadyInVar( inVar );
+ }
+ }
+
} break;
case FKind.FlatSESEExitNode: {
FlatOpNode fon = (FlatOpNode) fn;
if( fon.getOp().getOp() == Operation.ASSIGN ) {
+ TempDescriptor lhs = fon.getDest();
+ TempDescriptor rhs = fon.getLeft();
+
// if this is an op node, don't stall, copy
// source and delay until we need to use value
+ // but check the source type of rhs variable
+ // and if dynamic, lhs becomes dynamic, too,
+ // and we need to keep dynamic sources during
+ Integer srcType
+ = vstTableIn.getRefVarSrcType( rhs,
+ currentSESE,
+ currentSESE.getParent() );
+
+ if( srcType.equals( VarSrcTokTable.SrcType_DYNAMIC ) ) {
+ plan.addDynAssign( lhs, rhs );
+ currentSESE.addDynamicVar( lhs );
+ currentSESE.addDynamicVar( rhs );
+ }
+
// only break if this is an ASSIGN op node,
// otherwise fall through to default case
break;
// note that FlatOpNode's that aren't ASSIGN
// fall through to this default case
default: {
- // decide if we must stall for variables dereferenced at this node
- Set<VariableSourceToken> stallSet = vstTable.getStallSet( currentSESE );
+
+ // a node with no live set has nothing to stall for
+ if( liveSetIn == null ) {
+ break;
+ }
TempDescriptor[] readarray = fn.readsTemps();
for( int i = 0; i < readarray.length; i++ ) {
// ignore temps that are definitely available
// when considering to stall on it
- if( !notAvailSet.contains( readtmp ) ) {
+ if( !notAvailSetIn.contains( readtmp ) ) {
continue;
}
- Set<VariableSourceToken> readSet = vstTable.get( readtmp );
-
- //Two cases:
-
- //1) Multiple token/age pairs or unknown age: Stall for
- //dynamic name only.
-
+ // check the source type of this variable
+ Integer srcType
+ = vstTableIn.getRefVarSrcType( readtmp,
+ currentSESE,
+ currentSESE.getParent() );
+ if( srcType.equals( VarSrcTokTable.SrcType_DYNAMIC ) ) {
+ // 1) It is not clear statically where this variable will
+ // come from statically, so dynamically we must keep track
+ // along various control paths, and therefore when we stall,
+ // just stall for the exact thing we need and move on
+ plan.addDynamicStall( readtmp );
+ currentSESE.addDynamicVar( readtmp );
- //2) Single token/age pair: Stall for token/age pair, and copy
- //all live variables with same token/age pair at the same
- //time. This is the same stuff that the notavaialable analysis
- //marks as now available.
+ } else if( srcType.equals( VarSrcTokTable.SrcType_STATIC ) ) {
+ // 2) Single token/age pair: Stall for token/age pair, and copy
+ // all live variables with same token/age pair at the same
+ // time. This is the same stuff that the notavaialable analysis
+ // marks as now available.
- //VarSrcTokTable table = variableResults.get( fn );
- //Set<VariableSourceToken> srcs = table.get( rTemp );
+ VariableSourceToken vst = vstTableIn.get( readtmp ).iterator().next();
- //XXXXXXXXXX: Note: We have to generate code to do these
- //copies in the codeplan. Note we should only copy the
- //variables that are live!
+ Iterator<VariableSourceToken> availItr =
+ vstTableIn.get( vst.getSESE(), vst.getAge() ).iterator();
- /*
- if( srcs.size() == 1 ) {
- VariableSourceToken vst = srcs.iterator().next();
-
- Iterator<VariableSourceToken> availItr = table.get( vst.getSESE(),
- vst.getAge()
- ).iterator();
while( availItr.hasNext() ) {
VariableSourceToken vstAlsoAvail = availItr.next();
- notAvailSet.removeAll( vstAlsoAvail.getRefVars() );
- }
- }
- */
+ // only grab additional stuff that is live
+ Set<TempDescriptor> copySet = new HashSet<TempDescriptor>();
- // assert notAvailSet.containsAll( writeSet );
+ Iterator<TempDescriptor> refVarItr = vstAlsoAvail.getRefVars().iterator();
+ while( refVarItr.hasNext() ) {
+ TempDescriptor refVar = refVarItr.next();
+ if( liveSetIn.contains( refVar ) ) {
+ copySet.add( refVar );
+ }
+ }
+
+ if( !copySet.isEmpty() ) {
+ plan.addStall2CopySet( vstAlsoAvail, copySet );
+ }
+ }
+
+ } else {
+ // the other case for srcs is READY from a parent, however
+ // since we are only examining variables that come from
+ // children tokens, this should never occur
+ assert false;
+ }
+
+ // assert that everything being stalled for is in the
+ // "not available" set coming into this flat node and
+ // that every VST identified is in the possible "stall set"
+ // that represents VST's from children SESE's
- /*
- for( Iterator<VariableSourceToken> readit = readSet.iterator();
- readit.hasNext(); ) {
- VariableSourceToken vst = readit.next();
- if( stallSet.contains( vst ) ) {
- if( before == null ) {
- before = "**STALL for:";
- }
- before += "("+vst+" "+readtmp+")";
- }
- }
- */
}
} break;
-
+
} // end switch
- // if any variable at this node has a static source (exactly one sese)
- // but goes to a dynamic source at a next node, write its dynamic addr
- Set<VariableSourceToken> static2dynamicSet = new HashSet<VariableSourceToken>();
- for( int i = 0; i < fn.numNext(); i++ ) {
- FlatNode nn = fn.getNext( i );
- VarSrcTokTable nextVstTable = variableResults.get( nn );
- assert nextVstTable != null;
- static2dynamicSet.addAll( vstTable.getStatic2DynamicSet( nextVstTable ) );
- }
- /*
- Iterator<VariableSourceToken> vstItr = static2dynamicSet.iterator();
+ // identify sese-age pairs that are statically useful
+ // and should have an associated SESE variable in code
+ Set<VariableSourceToken> staticSet = vstTableIn.getStaticSet();
+ Iterator<VariableSourceToken> vstItr = staticSet.iterator();
while( vstItr.hasNext() ) {
VariableSourceToken vst = vstItr.next();
- if( after == null ) {
- after = "** Write dynamic: ";
- }
- after += "("+vst+")";
+ currentSESE.addNeededStaticName(
+ new SESEandAgePair( vst.getSESE(), vst.getAge() )
+ );
+ currentSESE.mustTrackAtLeastAge( vst.getAge() );
}
- */
+
codePlans.put( fn, plan );
+
+
+ // if any variables at this-node-*dot* have a static source (exactly one vst)
+ // but go to a dynamic source at next-node-*dot*, create a new IR graph
+ // node on that edge to track the sources dynamically
+ VarSrcTokTable thisVstTable = variableResults.get( fn );
+ for( int i = 0; i < fn.numNext(); i++ ) {
+ FlatNode nn = fn.getNext( i );
+ VarSrcTokTable nextVstTable = variableResults.get( nn );
+ Set<TempDescriptor> nextLiveIn = livenessRootView.get( nn );
+
+ // the table can be null if it is one of the few IR nodes
+ // completely outside of the root SESE scope
+ if( nextVstTable != null && nextLiveIn != null ) {
+
+ Hashtable<TempDescriptor, VariableSourceToken> static2dynamicSet =
+ thisVstTable.getStatic2DynamicSet( nextVstTable, nextLiveIn );
+
+ if( !static2dynamicSet.isEmpty() ) {
+
+ // either add these results to partial fixed-point result
+ // or make a new one if we haven't made any here yet
+ FlatEdge fe = new FlatEdge( fn, nn );
+ FlatWriteDynamicVarNode fwdvn = wdvNodesToSpliceIn.get( fe );
+
+ if( fwdvn == null ) {
+ fwdvn = new FlatWriteDynamicVarNode( fn,
+ nn,
+ static2dynamicSet,
+ currentSESE
+ );
+ wdvNodesToSpliceIn.put( fe, fwdvn );
+ } else {
+ fwdvn.addMoreVar2Src( static2dynamicSet );
+ }
+ }
+ }
+ }
}
}