From e7760a0bea3789b766c70bf6382f92d31ab79155 Mon Sep 17 00:00:00 2001 From: jjenista Date: Thu, 18 Jun 2009 17:47:59 +0000 Subject: [PATCH] getting close to mlp running a limited program --- Robust/src/Analysis/MLP/MLPAnalysis.java | 11 ++ Robust/src/Analysis/MLP/SESEandAgePair.java | 50 ++++++ Robust/src/Analysis/MLP/VarSrcTokTable.java | 21 +++ Robust/src/IR/Flat/BuildCode.java | 166 +++++++++++--------- Robust/src/IR/Flat/FlatSESEEnterNode.java | 42 ++++- Robust/src/Runtime/mlp_runtime.c | 56 +++---- Robust/src/Runtime/mlp_runtime.h | 33 ++-- Robust/src/buildscript | 2 + 8 files changed, 255 insertions(+), 126 deletions(-) create mode 100644 Robust/src/Analysis/MLP/SESEandAgePair.java diff --git a/Robust/src/Analysis/MLP/MLPAnalysis.java b/Robust/src/Analysis/MLP/MLPAnalysis.java index 54f47a52..a60feb29 100644 --- a/Robust/src/Analysis/MLP/MLPAnalysis.java +++ b/Robust/src/Analysis/MLP/MLPAnalysis.java @@ -855,6 +855,17 @@ public class MLPAnalysis { } // end switch + // identify sese-age pairs that are statically useful + // and should have an associated SESE variable in code + Set staticSet = vstTable.getStaticSet(); + Iterator vstItr = staticSet.iterator(); + while( vstItr.hasNext() ) { + VariableSourceToken vst = vstItr.next(); + currentSESE.addNeededStaticName( + new SESEandAgePair( vst.getSESE(), vst.getAge() ) + ); + } + // 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 static2dynamicSet = new HashSet(); diff --git a/Robust/src/Analysis/MLP/SESEandAgePair.java b/Robust/src/Analysis/MLP/SESEandAgePair.java new file mode 100644 index 00000000..bbeca275 --- /dev/null +++ b/Robust/src/Analysis/MLP/SESEandAgePair.java @@ -0,0 +1,50 @@ +package Analysis.MLP; + +import IR.*; +import IR.Flat.*; +import java.util.*; +import java.io.*; + +public class SESEandAgePair { + + private FlatSESEEnterNode sese; + private Integer age; + + public SESEandAgePair( FlatSESEEnterNode sese, + Integer age ) { + this.sese = sese; + this.age = age; + } + + public FlatSESEEnterNode getSESE() { + return sese; + } + + public Integer getAge() { + return age; + } + + public boolean equals( Object o ) { + if( o == null ) { + return false; + } + + if( !(o instanceof SESEandAgePair) ) { + return false; + } + + SESEandAgePair p = (SESEandAgePair) o; + + return age.equals( p.age ) && + sese.equals( p.sese ); + } + + public int hashCode() { + return (sese.hashCode() << 2)*(age.hashCode() << 5); + } + + + public String toString() { + return "SESE_"+sese.getPrettyIdentifier()+"_"+age; + } +} diff --git a/Robust/src/Analysis/MLP/VarSrcTokTable.java b/Robust/src/Analysis/MLP/VarSrcTokTable.java index d2270c41..a7b275c5 100644 --- a/Robust/src/Analysis/MLP/VarSrcTokTable.java +++ b/Robust/src/Analysis/MLP/VarSrcTokTable.java @@ -432,6 +432,27 @@ public class VarSrcTokTable { } + // get the set of variables that have exactly one source + // from the static perspective + public Set getStaticSet() { + + Set out = new HashSet(); + + Iterator itr = var2vst.entrySet().iterator(); + while( itr.hasNext() ) { + Map.Entry me = (Map.Entry) itr.next(); + TempDescriptor var = (TempDescriptor) me.getKey(); + HashSet s1 = (HashSet) me.getValue(); + + if( s1.size() == 1 ) { + out.addAll( s1 ); + } + } + + 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 diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index f7148dd5..fee4d32d 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -28,6 +28,7 @@ import Analysis.Locality.TypeAnalysis; import Analysis.MLP.MLPAnalysis; import Analysis.MLP.VariableSourceToken; import Analysis.MLP.CodePlan; +import Analysis.MLP.SESEandAgePair; public class BuildCode { State state; @@ -1547,12 +1548,13 @@ public class BuildCode { PrintWriter outmethod ) { - outmethodheader.println("void* invokeSESEmethod( void* vargs );"); - outmethod.println( "void* invokeSESEmethod( void* vargs ) {"); + outmethodheader.println("void invokeSESEmethod( void* vargs );"); + outmethod.println( "void invokeSESEmethod( void* vargs ) {"); outmethod.println( " int status;"); outmethod.println( " char errmsg[128];"); outmethod.println( " invokeSESEargs* args = (invokeSESEargs*) vargs;"); + /* // wait on a condition variable that dispatcher will signal // then this SESE instance's dependencies are resolved outmethod.println( " status = pthread_mutex_lock( args->invokee->startCondVarLock );"); @@ -1561,6 +1563,7 @@ public class BuildCode { outmethod.println( " status = pthread_cond_wait( args->invokee->startCondVar, args->invokee->startCondVarLock );"); outmethod.println( " "+mlperrstr); outmethod.println( " }"); + */ // generate a case for each SESE class that can be invoked outmethod.println( " switch( args->classID ) {"); @@ -1600,10 +1603,7 @@ public class BuildCode { // then invoke the sese's method output.print(" "+cn.getSafeSymbol()+bogusmd.getSafeSymbol()+"_"+bogusmd.getSafeMethodDescriptor()); - output.print("("); - - // why doesn't this work? - //output.print("("+cn.getSafeSymbol()+bogusmd.getSafeSymbol()+"_"+bogusmd.getSafeMethodDescriptor()+paramsprefix+")"); + output.print("( args->invokee, "); // first argument is parameter structure output.print("(struct "+cn.getSafeSymbol()+bogusmd.getSafeSymbol()+"__params*)"); @@ -1614,62 +1614,13 @@ public class BuildCode { TempDescriptor td=objectparams.getPrimitive(i); TypeDescriptor type=td.getType(); assert type.isPrimitive(); - output.print(", args->invokee->vars["+i+"].sesetype_"+type.toString()); + output.print( ", (("+fsen.namespaceStructNameString()+ + "*)args->invokee->namespace)->"+td ); } output.println(");"); } - private void generateFlatMethodSESE(FlatMethod fm, - ClassDescriptor cn, - FlatSESEEnterNode seseEnter, - FlatSESEExitNode seseExit, - PrintWriter output - ) { - - MethodDescriptor md=fm.getMethod(); - ParamsObject objectparams=(ParamsObject)paramstable.get(md); - generateHeader(fm, null, md, output); - TempObject objecttemp=(TempObject) tempstable.get(md); - - - if (GENERATEPRECISEGC) { - output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={"); - output.print(objecttemp.numPointers()+","); - output.print(paramsprefix); - for(int j=0; j pItr = seseEnter.getNeededStaticNames().iterator(); + while( pItr.hasNext() ) { + SESEandAgePair p = pItr.next(); + output.println(" SESErecord* "+p+";"); + } + + + // Check to see if we need to do a GC if this is a + // multi-threaded program... + if (GENERATEPRECISEGC) { + //Don't bother if we aren't in recursive methods...The loops case will catch it + if (callgraph.getAllMethods(md).contains(md)) { + output.println("if (needtocollect) checkcollect(&"+localsprefix+");"); + } + } + + + generateCode(seseEnter.getNext(0), fm, null, seseExit, output); + + + output.println("}\n\n"); + } protected void generateCode(FlatNode first, FlatMethod fm, @@ -1782,12 +1793,12 @@ public class BuildCode { // of that method, whether it be a user-defined method // or a method representing the body of an SESE // TODO: only do this if we know the method actually - // contains an SESE issue, not currently an annotation + // contains an SESE issue, not currently an annotation if( state.MLP ) { output.println(" SESErecord* tempSESE;"); - output.println(" SESErecord* tempParentSESE;"); output.println(" invokeSESEargs* tempSESEargs;"); - } + } + /* Assign labels to FlatNode's if necessary.*/ Hashtable nodetolabel=assignLabels(first, stop); @@ -2341,27 +2352,29 @@ public class BuildCode { output.println("\n /* SESE "+fsen.getPrettyIdentifier()+" issue */"); output.println(" tempSESE = mlpCreateSESErecord( "+ fsen.getIdentifier()+", "+ - "0, "+ - "mlpGetCurrent(), "+ - fsen.numParameters()+", "+ + "malloc( sizeof( "+fsen.namespaceStructNameString()+") ), "+ "NULL );"); for( int i = 0; i < fsen.numParameters(); ++i ) { - TempDescriptor td = fsen.getParameter( i ); - TypeDescriptor type = td.getType(); - output.println(" tempSESE->vars["+i+"].sesetype_"+type.toString()+" = "+td+";"); + TempDescriptor td = fsen.getParameter( i ); + output.println(" (("+fsen.namespaceStructNameString()+ + "*)tempSESE->namespace)->"+td+" = "+td+";"); } output.println(" mlpIssue( tempSESE );"); - output.println(" tempSESE = mlpSchedule();"); - output.println(" tempParentSESE = mlpGetCurrent();"); + output.println(" tempSESE = mlpSchedule();"); // do a pthread_create wit invokeSESE as the argument // and pack all args into a single void* - output.println(" tempSESEargs = (invokeSESEargs*) malloc( sizeof( invokeSESEargs ) );"); + output.println(" tempSESEargs = malloc( sizeof( invokeSESEargs ) );"); output.println(" tempSESEargs->classID = "+fsen.getIdentifier()+";"); - output.println(" tempSESEargs->invokee = tempSESE;"); - output.println(" tempSESEargs->parent = tempParentSESE;"); + output.println(" tempSESEargs->invokee = mlpSchedule();"); + + if( fsen.getParent() == null ) { + output.println(" tempSESEargs->parent = NULL;"); + } else { + output.println(" tempSESEargs->parent = currentSESE;"); + } output.println(" invokeSESEmethod( (void*) tempSESEargs );"); output.println("\n"); @@ -3007,8 +3020,11 @@ public class BuildCode { /** This method generates header information for the method or * task referenced by the Descriptor des. */ - private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) { + generateHeader(fm, lb, des, output, false); + } + + private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output, boolean addSESErecord) { /* Print header */ ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : des); MethodDescriptor md=null; @@ -3036,6 +3052,10 @@ public class BuildCode { } else output.print(task.getSafeSymbol()+"("); + if (addSESErecord) { + output.print("SESErecord* currentSESE, "); + } + boolean printcomma=false; if (GENERATEPRECISEGC) { if (md!=null) { diff --git a/Robust/src/IR/Flat/FlatSESEEnterNode.java b/Robust/src/IR/Flat/FlatSESEEnterNode.java index 524ea973..55869529 100644 --- a/Robust/src/IR/Flat/FlatSESEEnterNode.java +++ b/Robust/src/IR/Flat/FlatSESEEnterNode.java @@ -1,5 +1,7 @@ package IR.Flat; import Analysis.MLP.VariableSourceToken; +import Analysis.MLP.SESEandAgePair; +import IR.TypeDescriptor; import IR.Tree.SESENode; import java.util.*; @@ -16,14 +18,17 @@ public class FlatSESEEnterNode extends FlatNode { protected Set children; protected Set inVars; protected Set outVars; + protected Set needStaticNameInCode; protected FlatMethod enclosing; public FlatSESEEnterNode( SESENode sn ) { - this.id = identifier++; - treeNode = sn; - children = new HashSet(); - inVars = new HashSet(); - outVars = new HashSet(); + this.id = identifier++; + treeNode = sn; + parent = null; + children = new HashSet(); + inVars = new HashSet(); + outVars = new HashSet(); + needStaticNameInCode = new HashSet(); } public void rewriteUse() { @@ -91,6 +96,25 @@ public class FlatSESEEnterNode extends FlatNode { return vecinVars.size(); } + public String namespaceStructNameString() { + return "struct SESE_"+getPrettyIdentifier()+"_namespace"; + } + + public String namespaceStructDeclarationString() { + String s = "struct SESE_"+getPrettyIdentifier()+"_namespace {\n"; + for( int i = 0; i < numParameters(); ++i ) { + TempDescriptor td = getParameter( i ); + TypeDescriptor type = td.getType(); + s += " "+type.toString()+" "+td+";\n"; + } + s += "};\n"; + return s; + } + + public String namespaceStructAccessString( TempDescriptor td ) { + return "SESE_"+getPrettyIdentifier()+"_namespace."+td; + } + public Set getNodeSet() { HashSet tovisit=new HashSet(); HashSet visited=new HashSet(); @@ -115,6 +139,14 @@ public class FlatSESEEnterNode extends FlatNode { return outVars; } + public void addNeededStaticName( SESEandAgePair p ) { + needStaticNameInCode.add( p ); + } + + public Set getNeededStaticNames() { + return needStaticNameInCode; + } + public void setEnclosingFlatMeth( FlatMethod fm ) { enclosing = fm; } diff --git a/Robust/src/Runtime/mlp_runtime.c b/Robust/src/Runtime/mlp_runtime.c index a737d12a..6c724216 100644 --- a/Robust/src/Runtime/mlp_runtime.c +++ b/Robust/src/Runtime/mlp_runtime.c @@ -14,7 +14,7 @@ // the root sese is accessible globally so // buildcode can generate references to it -SESErecord* rootsese; +//SESErecord* rootsese; // the issuedQ, in this simple version, spits @@ -22,44 +22,33 @@ SESErecord* rootsese; static struct Queue* issuedQ; -// the class_age2instance maps an SESE class id and -// age value to a particular SESErecord instance -static SESErecord** class_age2instance; - -// each core/pthread should have a current SESE -static SESErecord* current; - - -SESErecord* mlpCreateSESErecord( int classID, - int instanceID, - SESErecord* parent, - int numVars, - void* paramStruct - ) { +SESErecord* mlpCreateSESErecord( int classID, + void* namespace, + void* paramStruct + ) { SESErecord* newrec = malloc( sizeof( SESErecord ) ); + //newrec->parent = parent; + //newrec->childrenList = createQueue(); + //newrec->vars = malloc( sizeof( SESEvar ) * numVars ); + newrec->classID = classID; - //newrec->instanceID = instanceID; - //newrec->childInstanceIDs = 0; - newrec->parent = parent; - newrec->childrenList = createQueue(); - newrec->vars = (SESEvar*) malloc( sizeof( SESEvar ) * - numVars - ); + newrec->namespace = namespace; newrec->paramStruct = paramStruct; + newrec->forwardList = createQueue(); newrec->doneExecuting = FALSE; - newrec->startedExecuting = FALSE; + //newrec->startedExecuting = FALSE; - newrec->startCondVar = (pthread_cond_t*) malloc( sizeof( pthread_cond_t ) ); - newrec->startCondVarLock = (pthread_mutex_t*) malloc( sizeof( pthread_mutex_t ) ); - newrec->forwardListLock = (pthread_mutex_t*) malloc( sizeof( pthread_mutex_t ) ); + psem_init ( &(newrec->stallSem) ); + /* pthread_cond_init ( newrec->startCondVar, NULL ); pthread_mutex_init( newrec->startCondVarLock, NULL ); pthread_mutex_init( newrec->forwardListLock, NULL ); + */ return newrec; } @@ -67,17 +56,21 @@ SESErecord* mlpCreateSESErecord( int classID, void mlpDestroySESErecord( SESErecord* sese ) { + /* pthread_cond_destroy ( sese->startCondVar ); pthread_mutex_destroy( sese->startCondVarLock ); pthread_mutex_destroy( sese->forwardListLock ); + */ + /* free ( sese->startCondVar ); free ( sese->startCondVarLock ); free ( sese->forwardListLock ); - freeQueue( sese->forwardList ); - freeQueue( sese->childrenList ); + //freeQueue( sese->childrenList ); free ( sese->vars ); + */ + free ( sese->namespace ); free ( sese ); } @@ -86,19 +79,22 @@ void mlpInit( int totalNumSESEs, int maxSESEage ) { issuedQ = createQueue(); + /* class_age2instance = (SESErecord**) malloc( sizeof( SESErecord* ) * maxSESEage * totalNumSESEs ); + */ //current = rootsese; - current = NULL; + //current = NULL; } +/* SESErecord* mlpGetCurrent() { return current; } - +*/ void mlpIssue( SESErecord* sese ) { addNewItem( issuedQ, (void*) sese ); diff --git a/Robust/src/Runtime/mlp_runtime.h b/Robust/src/Runtime/mlp_runtime.h index 990500ac..4d12faeb 100644 --- a/Robust/src/Runtime/mlp_runtime.h +++ b/Robust/src/Runtime/mlp_runtime.h @@ -4,6 +4,7 @@ #include #include "Queue.h" +#include "psemaphore.h" // forward delcarations @@ -34,17 +35,8 @@ typedef struct SESErecord_t { // are instances of one particular static code block int classID; - // pointers to SESEs directly above or below - // in the heirarchy - //struct SESErecord_t* parent; - //struct Queue* childrenList; - // IMPLEMENT THIS LIKE STALLS--EVERY PARENTS EXIT MUST - // "STALL" on COMPLETETION OF ALL ISSUED CHILDREN, SO - // ALWAYS GIVE A CHILD A SEMAPHORE THAT IS ON YOUR LIST - // OF THINGS TO BLOCK ON AT EXIT - // for state of vars after issue - SESEvar* vars; + void* namespace; // when this sese is ready to be invoked, // allocate and fill in this structure, and @@ -52,17 +44,24 @@ typedef struct SESErecord_t { // above var array at the call site void* paramStruct; + /* // for signaling transition from issue // to execute pthread_cond_t* startCondVar; pthread_mutex_t* startCondVarLock; int startedExecuting; + */ + + // this will not be generally sufficient, but + // use a semaphore to let a child resume this + // parent when stall dependency is satisfied + psemaphore stallSem; // use a list of SESErecords and a lock to let // consumers tell this SESE who wants values // forwarded to it - pthread_mutex_t* forwardListLock; - struct Queue* forwardList; + pthread_mutex_t forwardListLock; + struct Queue* forwardList; int doneExecuting; } SESErecord; @@ -77,11 +76,9 @@ typedef struct invokeSESEargs_t { // simple mechanical allocation and deallocation // of SESE records -SESErecord* mlpCreateSESErecord( int classID, - int instanceID, - SESErecord* parent, - int numVars, - void* paramStruct +SESErecord* mlpCreateSESErecord( int classID, + void* namespace, + void* paramStruct ); void mlpDestroySESErecord( SESErecord* sese ); @@ -90,7 +87,7 @@ void mlpDestroySESErecord( SESErecord* sese ); // main library functions void mlpInit(); -SESErecord* mlpGetCurrent(); +//SESErecord* mlpGetCurrent(); SESErecord* mlpSchedule(); void mlpIssue ( SESErecord* sese ); diff --git a/Robust/src/buildscript b/Robust/src/buildscript index 7429feaf..0b827e40 100755 --- a/Robust/src/buildscript +++ b/Robust/src/buildscript @@ -621,6 +621,8 @@ fi if $MLP then FILES="$FILES $ROBUSTROOT/Runtime/mlp_runtime.c" +FILES="$FILES $ROBUSTROOT/Runtime/psemaphore.c" +FILES="$FILES $ROBUSTROOT/Runtime/workschedule.c" fi if $RECOVERFLAG -- 2.34.1