private CallGraph callGraph;
private OwnershipAnalysis ownAnalysis;
- private FlatSESEEnterNode rootSESE;
+
+
+ // an implicit SESE is automatically spliced into
+ // the IR graph around the C main before this analysis--it
+ // is nothing special except that we can make assumptions
+ // about it, such as the whole program ends when it ends
+ private FlatSESEEnterNode mainSESE;
+
+ // SESEs that are the root of an SESE tree belong to this
+ // set--the main SESE is always a root, statically SESEs
+ // inside methods are a root because we don't know how they
+ // will fit into the runtime tree of SESEs
+ private Set<FlatSESEEnterNode> rootSESEs;
+
+ // simply a set of every reachable SESE in the program
private Set<FlatSESEEnterNode> allSESEs;
+
+ // A mapping of flat nodes to the stack of SESEs for that node, where
+ // an SESE is the child of the SESE directly below it on the stack.
+ // These stacks do not reflect the heirarchy over methods calls--whenever
+ // there is an empty stack it means all variables are available.
private Hashtable< FlatNode, Stack<FlatSESEEnterNode> > seseStacks;
+
+
private Hashtable< FlatNode, Set<TempDescriptor> > livenessRootView;
private Hashtable< FlatNode, Set<TempDescriptor> > livenessVirtualReads;
private Hashtable< FlatNode, VarSrcTokTable > variableResults;
// use these methods in BuildCode to have access to analysis results
- public FlatSESEEnterNode getRootSESE() {
- return rootSESE;
+ public FlatSESEEnterNode getMainSESE() {
+ return mainSESE;
+ }
+
+ public Set<FlatSESEEnterNode> getRootSESEs() {
+ return rootSESEs;
}
public Set<FlatSESEEnterNode> getAllSESEs() {
this.ownAnalysis = ownAnalysis;
this.maxSESEage = state.MLP_MAXSESEAGE;
- // initialize analysis data structures
- allSESEs = new HashSet<FlatSESEEnterNode>();
+ rootSESEs = new HashSet<FlatSESEEnterNode>();
+ allSESEs = new HashSet<FlatSESEEnterNode>();
- seseStacks = new Hashtable< FlatNode, Stack<FlatSESEEnterNode> >();
+ seseStacks = new Hashtable< FlatNode, Stack<FlatSESEEnterNode> >();
+ livenessRootView = new Hashtable< FlatNode, Set<TempDescriptor> >();
livenessVirtualReads = new Hashtable< FlatNode, Set<TempDescriptor> >();
variableResults = new Hashtable< FlatNode, VarSrcTokTable >();
notAvailableResults = new Hashtable< FlatNode, Set<TempDescriptor> >();
codePlans = new Hashtable< FlatNode, CodePlan >();
-
- wdvNodesToSpliceIn = new Hashtable<FlatEdge, FlatWriteDynamicVarNode>();
+ wdvNodesToSpliceIn = new Hashtable< FlatEdge, FlatWriteDynamicVarNode >();
FlatMethod fmMain = state.getMethodFlat( tu.getMain() );
- rootSESE = (FlatSESEEnterNode) fmMain.getNext(0);
- rootSESE.setfmEnclosing( fmMain );
- rootSESE.setmdEnclosing( fmMain.getMethod() );
- rootSESE.setcdEnclosing( fmMain.getMethod().getClassDesc() );
+ mainSESE = (FlatSESEEnterNode) fmMain.getNext(0);
+ mainSESE.setfmEnclosing( fmMain );
+ mainSESE.setmdEnclosing( fmMain.getMethod() );
+ mainSESE.setcdEnclosing( fmMain.getMethod().getClassDesc() );
+
if( state.MLPDEBUG ) {
System.out.println( "" );
buildForestForward( fm );
}
if( state.MLPDEBUG ) {
- //System.out.println( "\nSESE Hierarchy\n--------------\n" ); printSESEHierarchy();
+ System.out.println( "\nSESE Hierarchy\n--------------\n" ); printSESEHierarchy();
}
// 2nd pass, results are saved in FlatSESEEnterNode, so
// intermediate results, for safety, are discarded
- livenessAnalysisBackward( rootSESE, true, null, fmMain.getFlatExit() );
+ Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
+ while( rootItr.hasNext() ) {
+ FlatSESEEnterNode root = rootItr.next();
+ livenessAnalysisBackward( root,
+ true,
+ null,
+ root.getfmEnclosing().getFlatExit() );
+ }
// 3rd pass
// 4th pass, compute liveness contribution from
// virtual reads discovered in variable pass
- livenessAnalysisBackward( rootSESE, true, null, fmMain.getFlatExit() );
+ rootItr = rootSESEs.iterator();
+ while( rootItr.hasNext() ) {
+ FlatSESEEnterNode root = rootItr.next();
+ livenessAnalysisBackward( root,
+ true,
+ null,
+ root.getfmEnclosing().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 ) );
pruneVariableResultsWithLiveness( fm );
}
if( state.MLPDEBUG ) {
- //System.out.println( "\nVariable Results-Out\n----------------\n"+fmMain.printMethod( variableResults ) );
+ System.out.println( "\nVariable Results-Out\n----------------\n"+fmMain.printMethod( variableResults ) );
}
FlatMethod fm = state.getMethodFlat( d );
// compute a plan for code injections
- computeStallsForward( fm );
+ codePlansForward( fm );
}
if( state.MLPDEBUG ) {
- //System.out.println( "\nCode Plans\n----------\n"+fmMain.printMethod( codePlans ) );
+ System.out.println( "\nCode Plans\n----------\n"+fmMain.printMethod( codePlans ) );
}
// splice new IR nodes into graph after all
fsen.setmdEnclosing( fm.getMethod() );
fsen.setcdEnclosing( fm.getMethod().getClassDesc() );
- if( !seseStack.empty() ) {
+ if( seseStack.empty() ) {
+ rootSESEs.add( fsen );
+ fsen.setParent( null );
+ } else {
seseStack.peek().addChild( fsen );
fsen.setParent( seseStack.peek() );
}
}
private void printSESEHierarchy() {
- // our forest is actually a tree now that
- // there is an implicit root SESE
- printSESEHierarchyTree( rootSESE, 0 );
+ Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
+ while( rootItr.hasNext() ) {
+ FlatSESEEnterNode root = rootItr.next();
+ printSESEHierarchyTree( root, 0 );
+ }
System.out.println( "" );
}
// remember liveness per node from the root view as the
// global liveness of variables for later passes to use
if( toplevel == true ) {
- livenessRootView = livenessResults;
+ livenessRootView.putAll( livenessResults );
}
// post-order traversal, so do children first
}
private void printSESELiveness() {
- // our forest is actually a tree now that
- // there is an implicit root SESE
- printSESELivenessTree( rootSESE );
+ Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
+ while( rootItr.hasNext() ) {
+ FlatSESEEnterNode root = rootItr.next();
+ printSESELivenessTree( root );
+ }
System.out.println( "" );
}
printSESELivenessTree( fsenChild );
}
}
-
+
private void printSESEInfo() {
- printSESEInfoTree( rootSESE );
+ Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
+ while( rootItr.hasNext() ) {
+ FlatSESEEnterNode root = rootItr.next();
+ printSESEInfoTree( root );
+ }
System.out.println( "" );
}
vstTable.age( currentSESE );
vstTable.assertConsistency();
- vstTable.ownInSet( currentSESE );
- vstTable.assertConsistency();
+ //vstTable.ownInSet( currentSESE );
+ //vstTable.assertConsistency();
} break;
case FKind.FlatSESEExitNode: {
FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
FlatSESEEnterNode fsen = fsexn.getFlatEnter();
assert currentSESE.getChildren().contains( fsen );
- vstTable.remapChildTokens( fsen );
+ vstTable.remapChildTokens( fsen );
+
+ // liveness virtual reads are things written by an SESE
+ // that, if not already, should be added to the in-set
Set<TempDescriptor> liveIn = currentSESE.getInVarSet();
Set<TempDescriptor> virLiveIn = vstTable.removeParentAndSiblingTokens( fsen, liveIn );
+ virLiveIn.addAll( fsen.getOutVarSet() );
Set<TempDescriptor> virLiveInOld = livenessVirtualReads.get( fn );
if( virLiveInOld != null ) {
virLiveIn.addAll( virLiveInOld );
}
livenessVirtualReads.put( fn, virLiveIn );
- vstTable.assertConsistency();
+
+ vstTable.assertConsistency();
+
// then all child out-set tokens are guaranteed
// to be filled in, so clobber those entries with
TempDescriptor outVar = outVarItr.next();
HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
ts.add( outVar );
- VariableSourceToken vst = new VariableSourceToken( ts,
- fsen,
- new Integer( 0 ),
- outVar
- );
+ VariableSourceToken vst =
+ new VariableSourceToken( ts,
+ fsen,
+ new Integer( 0 ),
+ outVar
+ );
vstTable.remove( outVar );
vstTable.add( vst );
}
VarSrcTokTable vstTable = variableResults.get( fn );
// fix later, not working, only wanted it to make tables easier to read
- //vstTable.pruneByLiveness( rootLiveSet );
+ vstTable.pruneByLiveness( rootLiveSet );
for( int i = 0; i < fn.numNext(); i++ ) {
FlatNode nn = fn.getNext( i );
}
- private void computeStallsForward( FlatMethod fm ) {
+ private void codePlansForward( FlatMethod fm ) {
// start from flat method top, visit every node in
// method exactly once
Set<TempDescriptor> dotSTlive = livenessRootView.get( fn );
if( !seseStack.empty() ) {
- computeStalls_nodeActions( fn,
- dotSTlive,
- dotSTtable,
- dotSTnotAvailSet,
- seseStack.peek()
- );
+ codePlans_nodeActions( fn,
+ dotSTlive,
+ dotSTtable,
+ dotSTnotAvailSet,
+ seseStack.peek()
+ );
}
for( int i = 0; i < fn.numNext(); i++ ) {
}
}
- private void computeStalls_nodeActions( FlatNode fn,
- Set<TempDescriptor> liveSetIn,
- VarSrcTokTable vstTableIn,
- Set<TempDescriptor> notAvailSetIn,
- FlatSESEEnterNode currentSESE ) {
-
+ private void codePlans_nodeActions( FlatNode fn,
+ Set<TempDescriptor> liveSetIn,
+ VarSrcTokTable vstTableIn,
+ Set<TempDescriptor> notAvailSetIn,
+ FlatSESEEnterNode currentSESE ) {
+
CodePlan plan = new CodePlan( currentSESE);
switch( fn.kind() ) {
// identify sese-age pairs that are statically useful
// and should have an associated SESE variable in code
- Set<VariableSourceToken> staticSet = vstTableIn.getStaticSet();
+ // JUST GET ALL SESE/AGE NAMES FOR NOW, PRUNE LATER,
+ // AND ALWAYS GIVE NAMES TO PARENTS
+ Set<VariableSourceToken> staticSet = vstTableIn.get();
Iterator<VariableSourceToken> vstItr = staticSet.iterator();
while( vstItr.hasNext() ) {
VariableSourceToken vst = vstItr.next();
- currentSESE.addNeededStaticName(
- new SESEandAgePair( vst.getSESE(), vst.getAge() )
- );
- currentSESE.mustTrackAtLeastAge( vst.getAge() );
+
+ FlatSESEEnterNode sese = currentSESE;
+ while( sese != null ) {
+ sese.addNeededStaticName(
+ new SESEandAgePair( vst.getSESE(), vst.getAge() )
+ );
+ sese.mustTrackAtLeastAge( vst.getAge() );
+
+ sese = sese.getParent();
+ }
}
tempItr = fsen.getDynamicInVarSet().iterator();
while( tempItr.hasNext() ) {
TempDescriptor temp = tempItr.next();
-
+ TypeDescriptor type = temp.getType();
+
// go grab it from the SESE source
output.println(" if( "+paramsprefix+"->"+temp+"_srcSESE != NULL ) {");
output.println(" }");
output.println(" pthread_mutex_unlock( &(com->lock) );");
+ String typeStr;
+ if( type.isNull() ) {
+ typeStr = "void*";
+ } else if( type.isClass() || type.isArray() ) {
+ typeStr = "struct "+type.getSafeSymbol()+"*";
+ } else {
+ typeStr = type.getSafeSymbol();
+ }
+
output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+
- " = *(("+temp.getType().toPrettyString()+"*) ("+
- paramsprefix+"->"+temp+"_srcSESE + "+
- paramsprefix+"->"+temp+"_srcOffset));");
+ " = *(("+typeStr+"*) ("+
+ paramsprefix+"->"+temp+"_srcSESE + "+
+ paramsprefix+"->"+temp+"_srcOffset));");
// or if the source was our parent, its in the record to grab
output.println(" } else {");
outmethod.println( " /* "+fsen.getPrettyIdentifier()+" */");
outmethod.println( " case "+fsen.getIdentifier()+":");
outmethod.println( " "+fsen.getSESEmethodName()+"( seseRecord );");
-
- if( fsen.equals( mlpa.getRootSESE() ) ) {
+
+ if( fsen.equals( mlpa.getMainSESE() ) ) {
outmethod.println( " /* work scheduler works forever, explicitly exit */");
outmethod.println( " exit( 0 );");
}
output.println(" {");
// before doing anything, lock your own record and increment the running children
- if( fsen != mlpa.getRootSESE() ) {
+ if( fsen != mlpa.getMainSESE() ) {
output.println(" pthread_mutex_lock( &("+paramsprefix+"->common.lock) );");
output.println(" ++("+paramsprefix+"->common.numRunningChildren);");
output.println(" pthread_mutex_unlock( &("+paramsprefix+"->common.lock) );");
output.println(" pthread_cond_init( &(seseToIssue->common.runningChildrenCond), NULL );");
output.println(" seseToIssue->common.numRunningChildren = 0;");
- if( fsen != mlpa.getRootSESE() ) {
+ if( fsen != mlpa.getMainSESE() ) {
output.println(" seseToIssue->common.parent = (SESEcommon*) "+paramsprefix+";");
} else {
output.println(" seseToIssue->common.parent = NULL;");
Iterator<TempDescriptor> tempItr = fsen.getReadyInVarSet().iterator();
while( tempItr.hasNext() ) {
TempDescriptor temp = tempItr.next();
- if( fsen != mlpa.getRootSESE() ) {
+ if( fsen != mlpa.getMainSESE() ) {
output.println(" seseToIssue->"+temp+" = "+
generateTemp( fsen.getParent().getfmBogus(), temp, null )+";");
} else {
output.println(" seseToIssue->"+temp+" = "+
- paramsprefix+"->"+temp+";");
+ generateTemp( state.getMethodFlat( typeutil.getMain() ), temp, null )+";");
}
}
output.println(" pthread_mutex_init( &(seseToIssue->common.lock), NULL );");
output.println(" pthread_mutex_lock( &(seseToIssue->common.lock) );");
- if( fsen != mlpa.getRootSESE() ) {
+ if( fsen != mlpa.getMainSESE() ) {
// count up outstanding dependencies, static first, then dynamic
Iterator<SESEandAgePair> staticSrcsItr = fsen.getStaticInVarSrcs().iterator();
while( staticSrcsItr.hasNext() ) {
output.println(" pthread_mutex_unlock( &(src->lock) );");
output.println(" seseToIssue->"+dynInVar+"_srcOffset = "+dynInVar+"_srcOffset;");
output.println(" } else {");
- output.println(" seseToIssue->"+dynInVar+" = "+dynInVar+";");
+ output.println(" seseToIssue->"+dynInVar+" = "+
+ generateTemp( fsen.getParent().getfmBogus(), dynInVar, null )+";");
output.println(" }");
output.println(" }");
// maintain pointers for for finding dynamic SESE
// instances from static names
- for( int i = fsen.getOldestAgeToTrack(); i > 0; --i ) {
- SESEandAgePair p1 = new SESEandAgePair( fsen, i );
- SESEandAgePair p2 = new SESEandAgePair( fsen, i-1 );
- output.println(" "+p1+" = "+p2+";");
- }
SESEandAgePair p = new SESEandAgePair( fsen, 0 );
- output.println(" "+p+" = seseToIssue;");
+ if( fsen.getParent().getNeededStaticNames().contains( p ) ) {
+ for( int i = fsen.getOldestAgeToTrack(); i > 0; --i ) {
+ SESEandAgePair p1 = new SESEandAgePair( fsen, i );
+ SESEandAgePair p2 = new SESEandAgePair( fsen, i-1 );
+ output.println(" "+p1+" = "+p2+";");
+ }
+ output.println(" "+p+" = seseToIssue;");
+ }
}
// if there were no outstanding dependencies, issue here
output.println(" }");
// if parent is stalling on you, let them know you're done
- if( fsexn.getFlatEnter() != mlpa.getRootSESE() ) {
+ if( fsexn.getFlatEnter() != mlpa.getMainSESE() ) {
output.println(" psem_give( &("+paramsprefix+"->common.stallSem) );");
}