From 7de37767e3322c352a7032488c58245c24cb634a Mon Sep 17 00:00:00 2001 From: jjenista Date: Wed, 2 Feb 2011 22:06:41 +0000 Subject: [PATCH] BuildCode, with the monkey of OoOJava off its back --- Robust/src/IR/Flat/BuildCode.java | 1974 +--------------- Robust/src/IR/Flat/BuildOoOJavaCode.java | 2031 +++++++++++++++++ Robust/src/Main/Main.java | 17 +- Robust/src/Makefile | 1 + .../oooJava/conflict-graph-location/makefile | 2 +- 5 files changed, 2131 insertions(+), 1894 deletions(-) create mode 100644 Robust/src/IR/Flat/BuildOoOJavaCode.java diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index e0c99a03..6e877932 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -24,17 +24,6 @@ import Analysis.Locality.DCWrapper; import Analysis.Locality.DelayComputation; import Analysis.Locality.BranchAnalysis; import Analysis.CallGraph.CallGraph; -import Analysis.Disjoint.AllocSite; -import Analysis.Disjoint.Effect; -import Analysis.Disjoint.ReachGraph; -import Analysis.Disjoint.Taint; -import Analysis.OoOJava.OoOJavaAnalysis; -import Analysis.OoOJava.SESEandAgePair; -import Analysis.OoOJava.VariableSourceToken; -import Analysis.OoOJava.CodePlan; -import Analysis.OoOJava.ConflictNode; -import Analysis.OoOJava.SESEWaitingQueue; -import Analysis.OoOJava.VSTWrapper; import Analysis.Prefetch.*; import Analysis.Loops.WriteBarrier; import Analysis.Loops.GlobalFieldType; @@ -72,13 +61,6 @@ public class BuildCode { Hashtable> backuptable; SafetyAnalysis sa; PrefetchAnalysis pa; - OoOJavaAnalysis oooa; - String maxTaskRecSizeStr="__maxTaskRecSize___"; - String mlperrstr = "if(status != 0) { "+ - "sprintf(errmsg, \"MLP error at %s:%d\", __FILE__, __LINE__); "+ - "perror(errmsg); exit(-1); }"; - boolean nonSESEpass=true; - RuntimeConflictResolver rcr = null; WriteBarrier wb; DiscoverConflicts dc; DiscoverConflicts recorddc; @@ -87,21 +69,16 @@ public class BuildCode { public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa) { - this(st, temptovar, typeutil, null, sa, pa, null); + this(st, temptovar, typeutil, null, sa, pa); } - public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa, OoOJavaAnalysis oooa) { - this(st, temptovar, typeutil, null, sa, pa, oooa); + public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, PrefetchAnalysis pa) { + this(st, temptovar, typeutil, locality, null, pa); } - public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, PrefetchAnalysis pa, OoOJavaAnalysis oooa) { - this(st, temptovar, typeutil, locality, null, pa, oooa); - } - - public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, SafetyAnalysis sa, PrefetchAnalysis pa, OoOJavaAnalysis oooa) { + public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, SafetyAnalysis sa, PrefetchAnalysis pa ) { this.sa=sa; this.pa=pa; - this.oooa=oooa; state=st; callgraph=new CallGraph(state); if (state.SINGLETM) @@ -211,22 +188,10 @@ public class BuildCode { outmethodheader.println("#include \"abortreaders.h\""); outmethodheader.println("#include "); } - if (state.OOOJAVA) { - outmethodheader.println("#include "); - outmethodheader.println("#include "); - outmethodheader.println("#include "); - outmethodheader.println("#include \"mlp_runtime.h\""); - outmethodheader.println("#include \"psemaphore.h\""); - outmethodheader.println("#include \"memPool.h\""); - if (state.RCR) { - outmethodheader.println("#include \"rcr_runtime.h\""); - } - // spit out a global to inform all worker threads with - // the maximum size is for any task record - outmethodheader.println("extern int "+maxTaskRecSizeStr+";"); - } + additionalIncludesMethodsHeader( outmethodheader ); + /* Output Structures */ outputStructs(outstructs); @@ -280,56 +245,21 @@ public class BuildCode { outputTaskTypes(outtask); } - if(state.OOOJAVA) { - // have to initialize some SESE compiler data before - // analyzing normal methods, which must happen before - // generating SESE internal code - - Iterator seseit=oooa.getAllSESEs().iterator(); - - //TODO signal the object that will report errors - if(state.RCR) { - try { - rcr = new RuntimeConflictResolver(PREFIX, oooa, oooa.getDisjointAnalysis().getEffectsAnalysis().getAllEffects(), state); - System.out.println("Runtime Conflict Resolver started."); - } catch (FileNotFoundException e) { - System.out.println("Runtime Conflict Resolver could not create output file."); - } - } - - while(seseit.hasNext()){ - FlatSESEEnterNode fsen = seseit.next(); - initializeSESE( fsen ); - } - } - - /* Build the actual methods */ - outputMethods(outmethod); - // Output function prototypes and structures for SESE's and code - if( state.OOOJAVA ) { + // an opportunity for subclasses to do extra + // initialization + preCodeGenInitialization(); - // spit out a global to inform all worker threads with - // the maximum size is for any task record - outmethod.println("int "+maxTaskRecSizeStr+" = 0;"); - // used to differentiate, during code generation, whether we are - // passing over SESE body code, or non-SESE code - nonSESEpass = false; + /* Build the actual methods */ + outputMethods(outmethod); - // first generate code for each sese's internals - Iterator seseit; - seseit=oooa.getAllSESEs().iterator(); - - while(seseit.hasNext()) { - FlatSESEEnterNode fsen = seseit.next(); - generateMethodSESE(fsen, null, outstructs, outmethodheader, outmethod); - } + + // opportunity for subclasses to gen extra code + additionalCodeGen( outmethodheader, + outstructs, + outmethod ); - // then write the invokeSESE switch to decouple scheduler - // from having to do unique details of sese invocation - generateSESEinvocationMethod(outmethodheader, outmethod); - } if (state.TASK) { /* Output code for tasks */ @@ -360,11 +290,13 @@ public class BuildCode { outmethod.close(); outstructs.println("#endif"); outstructs.close(); - if(rcr != null) { - rcr.close(); - System.out.println("Runtime Conflict Resolver Done."); - } + + + + postCodeGenCleanUp(); } + + /* This method goes though the call graph and tag those methods that are * invoked inside static blocks @@ -438,32 +370,9 @@ public class BuildCode { outputStaticBlocks(outmethod); outputClassObjects(outmethod); - if (state.OOOJAVA) { - - // do a calculation to determine which task record - // is the largest, store that as a global value for - // allocating records - Iterator seseit; - seseit=oooa.getAllSESEs().iterator(); - while(seseit.hasNext()){ - FlatSESEEnterNode fsen = seseit.next(); - outmethod.println("if( sizeof( "+fsen.getSESErecordName()+ - " ) > "+maxTaskRecSizeStr+ - " ) { "+maxTaskRecSizeStr+ - " = sizeof( "+fsen.getSESErecordName()+ - " ); }" ); - } - - outmethod.println(" runningSESE = NULL;"); - outmethod.println(" workScheduleInit( "+state.OOO_NUMCORES+", invokeSESEmethod );"); - - //initializes data structures needed for the RCR traverser - if(state.RCR && rcr != null) { - outmethod.println(" initializeStructsRCR();"); - outmethod.println(" createAndFillMasterHashStructureArray();"); - } - } + additionalCodeAtTopOfMain( outmethod ); + if (state.DSM) { if (state.DSMRECOVERYSTATS) { @@ -581,9 +490,9 @@ public class BuildCode { if (state.THREAD||state.SINGLETM) outmethod.println("pthread_exit(NULL);"); - if (state.OOOJAVA) { - outmethod.println(" workScheduleBegin();"); - } + + additionalCodeAtBottomOfMain( outmethod ); + outmethod.println("}"); } @@ -619,11 +528,11 @@ public class BuildCode { outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";"); } + /* This method outputs most of the methods.c file. This includes * some standard includes and then an array with the sizes of * objets and array that stores supertype and then the code for * the Java methods.. */ - protected void outputMethods(PrintWriter outmethod) { outmethod.println("#include \"methodheaders.h\""); outmethod.println("#include \"virtualtable.h\""); @@ -662,19 +571,10 @@ public class BuildCode { if (state.CONSCHECK) { outmethod.println("#include \"checkers.h\""); } - if ( state.OOOJAVA ) { - outmethod.println("#include "); - outmethod.println("#include "); - outmethod.println("#include \"mlp_runtime.h\""); - outmethod.println("#include \"psemaphore.h\""); - - if( state.RCR ) { - outmethod.println("#include \"trqueue.h\""); - outmethod.println("#include \"RuntimeConflictResolver.h\""); - outmethod.println("#include \"rcr_runtime.h\""); - outmethod.println("#include \"hashStructure.h\""); - } - } + + + additionalIncludesMethodsImplementation( outmethod ); + if(state.MGC) { // TODO add version for normal Java later @@ -689,6 +589,10 @@ public class BuildCode { //Store the layout of classes generateLayoutStructs(outmethod); + + additionalCodeAtTopMethodsImplementation( outmethod ); + + /* Generate code for methods */ if (state.DSM||state.SINGLETM) { for(Iterator lbit=locality.getLocalityBindings().iterator(); lbit.hasNext();) { @@ -698,7 +602,6 @@ public class BuildCode { wb.analyze(lb); if (!md.getModifiers().isNative()) { generateFlatMethod(fm, lb, outmethod); - //System.out.println("fm= " + fm + " md= " + md); } } } else { @@ -729,13 +632,9 @@ public class BuildCode { outstructs.println("#define INTPTR int"); outstructs.println("#endif"); outstructs.println("#endif"); - if( state.OOOJAVA ) { - outstructs.println("#include \"mlp_runtime.h\""); - outstructs.println("#include \"psemaphore.h\""); - } - if (state.RCR) { - outstructs.println("#include \"rcr_runtime.h\""); - } + + + additionalIncludesStructsHeader( outstructs ); /* Output #defines that the runtime uses to determine type @@ -827,10 +726,11 @@ public class BuildCode { //Print out definition for array type outclassdefs.println("struct "+arraytype+" {"); outclassdefs.println(" int type;"); - if( state.OOOJAVA ){ - outclassdefs.println(" int oid;"); - outclassdefs.println(" int allocsite;"); - } + + + additionalClassObjectFields( outclassdefs ); + + if (state.EVENTMONITOR) { outclassdefs.println(" int objuid;"); } @@ -864,6 +764,7 @@ public class BuildCode { outclassdefs.println(" int * fses;"); } } + printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs, outglobaldefs); if (state.STMARRAY) { @@ -885,10 +786,11 @@ public class BuildCode { //Print out definition for Class type outclassdefs.println("struct Class {"); outclassdefs.println(" int type;"); - if( state.OOOJAVA ){ - outclassdefs.println(" int oid;"); - outclassdefs.println(" int allocsite;"); - } + + + additionalClassObjectFields( outclassdefs ); + + if (state.EVENTMONITOR) { outclassdefs.println(" int objuid;"); } @@ -1245,10 +1147,7 @@ public class BuildCode { outclassdefs.print("#endif\n"); outclassdefs.print("int numprefetchsites = " + pa.prefetchsiteid + ";\n"); - if( state.OOOJAVA ){ - outclassdefs.print("extern __thread int oid;\n"); - outclassdefs.print("extern int oidIncrement;\n"); - } + Iterator it=state.getClassSymbolTable().getDescriptorsIterator(); cdarray=new ClassDescriptor[state.numClasses()]; @@ -1680,10 +1579,11 @@ public class BuildCode { /* Output class structure */ classdefout.println("struct "+cn.getSafeSymbol()+" {"); classdefout.println(" int type;"); - if( state.OOOJAVA){ - classdefout.println(" int oid;"); - classdefout.println(" int allocsite;"); - } + + + additionalClassObjectFields( classdefout ); + + if (state.EVENTMONITOR) { classdefout.println(" int objuid;"); } @@ -2066,60 +1966,9 @@ public class BuildCode { } - if( state.OOOJAVA ) { - // TODO!!!!!!!!! -// if( fm.getNext(0) instanceof FlatSESEEnterNode ) { -// FlatSESEEnterNode callerSESEplaceholder = (FlatSESEEnterNode) fm.getNext( 0 ); -// if( callerSESEplaceholder != oooa.getMainSESE() ) { -// // declare variables for naming static SESE's -// output.println(" /* static SESE names */"); -// Iterator pItr = callerSESEplaceholder.getNeededStaticNames().iterator(); -// while( pItr.hasNext() ) { -// SESEandAgePair pair = pItr.next(); -// output.println(" void* "+pair+" = NULL;"); -// } -// -// // declare variables for tracking dynamic sources -// output.println(" /* dynamic variable sources */"); -// Iterator dynSrcItr = callerSESEplaceholder.getDynamicVarSet().iterator(); -// while( dynSrcItr.hasNext() ) { -// TempDescriptor dynSrcVar = dynSrcItr.next(); -// output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;"); -// output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;"); -// } -// } -// } -// -// // set up related allocation sites's waiting queues -// // eom -// -// FlatSESEEnterNode callerSESEplaceholder = (FlatSESEEnterNode) fm.getNext( 0 ); -// if(callerSESEplaceholder!= oooa.getMainSESE()){ -// Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(callerSESEplaceholder); -// if (graph != null && graph.hasConflictEdge()) { -// output.println(" // set up waiting queues "); -// output.println(" int numMemoryQueue=0;"); -// output.println(" int memoryQueueItemID=0;"); -// Set lockSet = oooa.getLockMappings(graph); -// System.out.println("#lockSet="+lockSet.hashCode()); -// System.out.println("lockset="+lockSet); -// for (Iterator iterator = lockSet.iterator(); iterator.hasNext();) { -// Analysis.OoOJava.SESELock seseLock = (Analysis.OoOJava.SESELock) iterator.next(); -// System.out.println("id="+seseLock.getID()); -// System.out.println("#="+seseLock); -// } -// System.out.println("size="+lockSet.size()); -// if (lockSet.size() > 0) { -// output.println(" numMemoryQueue=" + lockSet.size() + ";"); -// output.println(" runningSESE->numMemoryQueue=numMemoryQueue;"); -// output.println(" runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);"); -// output.println(); -// } -// } -// } -// -// - } + + additionalCodeAtTopFlatMethodBody( output, fm ); + /* Check to see if we need to do a GC if this is a @@ -2170,505 +2019,6 @@ public class BuildCode { } - protected void initializeSESE( FlatSESEEnterNode fsen ) { - - FlatMethod fm = fsen.getfmEnclosing(); - MethodDescriptor md = fm.getMethod(); - ClassDescriptor cn = md.getClassDesc(); - - - // Creates bogus method descriptor to index into tables - Modifiers modBogus = new Modifiers(); - MethodDescriptor mdBogus = - new MethodDescriptor( modBogus, - new TypeDescriptor( TypeDescriptor.VOID ), - "sese_"+fsen.getPrettyIdentifier()+fsen.getIdentifier() - ); - - mdBogus.setClassDesc( fsen.getcdEnclosing() ); - FlatMethod fmBogus = new FlatMethod( mdBogus, null ); - fsen.setfmBogus( fmBogus ); - fsen.setmdBogus( mdBogus ); - - Set inSetAndOutSet = new HashSet(); - inSetAndOutSet.addAll( fsen.getInVarSet() ); - inSetAndOutSet.addAll( fsen.getOutVarSet() ); - - // Build paramsobj for bogus method descriptor - ParamsObject objectparams = new ParamsObject( mdBogus, tag++ ); - paramstable.put( mdBogus, objectparams ); - - Iterator itr = inSetAndOutSet.iterator(); - while( itr.hasNext() ) { - TempDescriptor temp = itr.next(); - TypeDescriptor type = temp.getType(); - if( type.isPtr() ) { - objectparams.addPtr( temp ); - } else { - objectparams.addPrim( temp ); - } - } - - // Build normal temp object for bogus method descriptor - TempObject objecttemps = new TempObject( objectparams, mdBogus, tag++ ); - tempstable.put( mdBogus, objecttemps ); - - for( Iterator nodeit = fsen.getNodeSet().iterator(); nodeit.hasNext(); ) { - FlatNode fn = (FlatNode)nodeit.next(); - TempDescriptor[] writes = fn.writesTemps(); - - for( int i = 0; i < writes.length; i++ ) { - TempDescriptor temp = writes[i]; - TypeDescriptor type = temp.getType(); - - if( type.isPtr() ) { - objecttemps.addPtr( temp ); - } else { - objecttemps.addPrim( temp ); - } - } - } - } - - // used when generating the specific SESE record struct - // to remember the FIRST field name of sese records - // that the current SESE depends on--we need to know the - // offset to the first one for garbage collection - protected void addingDepRecField( FlatSESEEnterNode fsen, - String field ) { - if( fsen.getFirstDepRecField() == null ) { - fsen.setFirstDepRecField( field ); - } - fsen.incNumDepRecs(); - } - - protected void generateMethodSESE(FlatSESEEnterNode fsen, - LocalityBinding lb, - PrintWriter outputStructs, - PrintWriter outputMethHead, - PrintWriter outputMethods - ) { - - ParamsObject objectparams = (ParamsObject) paramstable.get( fsen.getmdBogus() ); - TempObject objecttemps = (TempObject) tempstable .get( fsen.getmdBogus() ); - - // generate locals structure - outputStructs.println("struct "+ - fsen.getcdEnclosing().getSafeSymbol()+ - fsen.getmdBogus().getSafeSymbol()+"_"+ - fsen.getmdBogus().getSafeMethodDescriptor()+ - "_locals {"); - outputStructs.println(" int size;"); - outputStructs.println(" void * next;"); - for(int i=0; i inSetAndOutSet = new HashSet(); - inSetAndOutSet.addAll( fsen.getInVarSet() ); - inSetAndOutSet.addAll( fsen.getOutVarSet() ); - - Set inSetAndOutSetObjs = new HashSet(); - Set inSetAndOutSetPrims = new HashSet(); - - Iterator itr = inSetAndOutSet.iterator(); - while( itr.hasNext() ) { - TempDescriptor temp = itr.next(); - TypeDescriptor type = temp.getType(); - if( type.isPtr() ) { - inSetAndOutSetObjs.add( temp ); - } else { - inSetAndOutSetPrims.add( temp ); - } - } - - - // generate the SESE record structure - outputStructs.println(fsen.getSESErecordName()+" {"); - - // data common to any SESE, and it must be placed first so - // a module that doesn't know what kind of SESE record this - // is can cast the pointer to a common struct - outputStructs.println(" SESEcommon common;"); - - // then garbage list stuff - outputStructs.println(" /* next is in-set and out-set objects that look like a garbage list */"); - outputStructs.println(" int size;"); - outputStructs.println(" void * next;"); - - // I think that the set of TempDescriptors inSetAndOutSetObjs - // calculated above should match the pointer object params - // used in the following code, but let's just leave the working - // implementation unless there is actually a problem... - - Vector inset=fsen.getInVarsForDynamicCoarseConflictResolution(); - for(int i=0; i itrPrims = inSetAndOutSetPrims.iterator(); - while( itrPrims.hasNext() ) { - TempDescriptor temp = itrPrims.next(); - TypeDescriptor type = temp.getType(); - if(type.isPrimitive()){ - outputStructs.println(" "+temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol()+"; /* in-set or out-set primitive */"); - } - } - - // note that the sese record pointer will be added below, just primitive part of tracking here - Iterator itrDynInVars = fsen.getDynamicInVarSet().iterator(); - while( itrDynInVars.hasNext() ) { - TempDescriptor dynInVar = itrDynInVars.next(); - outputStructs.println(" INTPTR "+dynInVar+"_srcOffset; /* dynamic tracking primitive */"); - } - - - outputStructs.println(" /* everything after this should be pointers to an SESE record */" ); - - // other half of info for dynamic tracking, the SESE record pointer - itrDynInVars = fsen.getDynamicInVarSet().iterator(); - while( itrDynInVars.hasNext() ) { - TempDescriptor dynInVar = itrDynInVars.next(); - String depRecField = dynInVar+"_srcSESE"; - outputStructs.println(" SESEcommon* "+depRecField+";"); - addingDepRecField( fsen, depRecField ); - } - - // statically known sese sources are record pointers, too - Iterator itrStaticInVarSrcs = fsen.getStaticInVarSrcs().iterator(); - while( itrStaticInVarSrcs.hasNext() ) { - SESEandAgePair srcPair = itrStaticInVarSrcs.next(); - outputStructs.println(" "+srcPair.getSESE().getSESErecordName()+"* "+srcPair+";"); - addingDepRecField(fsen, srcPair.toString()); - } - - if (state.RCR) { - if (inset.size()!=0) - outputStructs.println("struct rcrRecord rcrRecords["+inset.size()+"];"); - } - - if( fsen.getFirstDepRecField() != null ) { - outputStructs.println(" /* compiler believes first dependent SESE record field above is: "+ - fsen.getFirstDepRecField()+" */" ); - } - outputStructs.println("};\n"); - - - // write method declaration to header file - outputMethHead.print("void "); - outputMethHead.print(fsen.getSESEmethodName()+"("); - outputMethHead.print(fsen.getSESErecordName()+"* "+paramsprefix); - outputMethHead.println(");\n"); - - - generateFlatMethodSESE( fsen.getfmBogus(), - fsen.getcdEnclosing(), - fsen, - fsen.getFlatExit(), - outputMethods ); - } - - private void generateFlatMethodSESE(FlatMethod fm, - ClassDescriptor cn, - FlatSESEEnterNode fsen, - FlatSESEExitNode seseExit, - PrintWriter output - ) { - - MethodDescriptor md=fm.getMethod(); - - output.print("void "); - output.print(fsen.getSESEmethodName()+"("); - output.print(fsen.getSESErecordName()+"* "+paramsprefix); - output.println("){\n"); - - - TempObject objecttemp=(TempObject) tempstable.get(md); - - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { - output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={"); - output.print(objecttemp.numPointers()+","); - output.print("&(((SESEcommon*)(___params___))[1])"); - for(int j=0; j pItr = fsen.getNeededStaticNames().iterator(); - //while( pItr.hasNext() ) { - // SESEandAgePair pair = pItr.next(); - // output.println(" SESEcommon* "+pair+" = NULL;"); - //} - // - //// declare variables for tracking dynamic sources - //output.println(" /* dynamic variable sources */"); - //Iterator dynSrcItr = fsen.getDynamicVarSet().iterator(); - //while( dynSrcItr.hasNext() ) { - // TempDescriptor dynSrcVar = dynSrcItr.next(); - // output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;"); - // output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;"); - //} - - // declare local temps for in-set primitives, and if it is - // a ready-source variable, get the value from the record - output.println(" /* local temps for in-set primitives */"); - Iterator itrInSet = fsen.getInVarSet().iterator(); - while( itrInSet.hasNext() ) { - TempDescriptor temp = itrInSet.next(); - TypeDescriptor type = temp.getType(); - if( !type.isPtr() ) { - if( fsen.getReadyInVarSet().contains( temp ) ) { - output.println(" "+type+" "+temp+" = "+paramsprefix+"->"+temp+";"); - } else { - output.println(" "+type+" "+temp+";"); - } - } - } - - // declare local temps for out-set primitives if its not already - // in the in-set, and it's value will get written so no problem - output.println(" /* local temp for out-set prim, not already in the in-set */"); - Iterator itrOutSet = fsen.getOutVarSet().iterator(); - while( itrOutSet.hasNext() ) { - TempDescriptor temp = itrOutSet.next(); - TypeDescriptor type = temp.getType(); - if( !type.isPtr() && !fsen.getInVarSet().contains( temp ) ) { - output.println(" "+type+" "+temp+";"); - } - } - - - // initialize thread-local var to a the task's record, which is fused - // with the param list - output.println(" "); - output.println(" // code of this task's body should use this to access the running task record"); - output.println(" runningSESE = &(___params___->common);"); - output.println(" childSESE = 0;"); - output.println(" "); - - // setup memory queue - // eom - if(state.OOOJAVA){ - output.println(" // set up memory queues "); - output.println(" int numMemoryQueue=0;"); - output.println(" int memoryQueueItemID=0;"); - Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(fsen); - if (graph != null && graph.hasConflictEdge()) { - output.println(" {"); - Set lockSet = oooa.getLockMappings(graph); - System.out.println("#lockSet="+lockSet); - if (lockSet.size() > 0) { - output.println(" numMemoryQueue=" + lockSet.size() + ";"); - output.println(" runningSESE->numMemoryQueue=numMemoryQueue;"); - output.println(" runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);"); - output.println(); - } - output.println(" }"); - } - } - - - // set up a task's mem pool to recycle the allocation of children tasks - // don't bother if the task never has children (a leaf task) - output.println( "#ifndef OOO_DISABLE_TASKMEMPOOL" ); - if( !fsen.getIsLeafSESE() ) { - output.println(" runningSESE->taskRecordMemPool = poolcreate( "+ - maxTaskRecSizeStr+", freshTaskRecordInitializer );"); - if (state.RCR && !rcr.hasEmptyTraversers(fsen)) { - output.println(" createTR();"); - output.println(" runningSESE->allHashStructures=TRqueue->allHashStructures;"); - } - } else { - // make it clear we purposefully did not initialize this - output.println(" runningSESE->taskRecordMemPool = (MemPool*)0x7;"); - } - output.println( "#endif // OOO_DISABLE_TASKMEMPOOL" ); - - - // copy in-set into place, ready vars were already - // copied when the SESE was issued - Iterator tempItr; - - // static vars are from a known SESE - output.println(" // copy variables from static sources"); - tempItr = fsen.getStaticInVarSet().iterator(); - while( tempItr.hasNext() ) { - TempDescriptor temp = tempItr.next(); - VariableSourceToken vst = fsen.getStaticInVarSrc( temp ); - SESEandAgePair srcPair = new SESEandAgePair( vst.getSESE(), vst.getAge() ); - output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+ - " = "+paramsprefix+"->"+srcPair+"->"+vst.getAddrVar()+";"); - } - - output.println(" // decrement references to static sources"); - for( Iterator pairItr = fsen.getStaticInVarSrcs().iterator(); pairItr.hasNext(); ) { - SESEandAgePair srcPair = pairItr.next(); - output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); - output.println(" {"); - output.println(" SESEcommon* src = &("+paramsprefix+"->"+srcPair+"->common);"); - output.println(" RELEASE_REFERENCE_TO( src );"); - output.println(" }"); - output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); - } - - - // dynamic vars come from an SESE and src - output.println(" // copy variables from dynamic sources"); - 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 ) {"); - - 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 )+ - " = *(("+typeStr+"*) ((void*)"+ - paramsprefix+"->"+temp+"_srcSESE + "+ - paramsprefix+"->"+temp+"_srcOffset));"); - - output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); - output.println(" SESEcommon* src = "+paramsprefix+"->"+temp+"_srcSESE;"); - output.println(" RELEASE_REFERENCE_TO( src );"); - output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); - - // or if the source was our parent, its already in our record to grab - output.println(" } else {"); - output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+ - " = "+paramsprefix+"->"+temp+";"); - output.println(" }"); - } - - // Check to see if we need to do a GC if this is a - // multi-threaded program... - if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { - output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");"); - //Don't bother if we aren't in recursive methods...The loops case will catch it -// if (callgraph.getAllMethods(md).contains(md)) { -// if(this.state.MULTICOREGC) { -// output.println("if(gcflag) gc("+localsprefixaddr+");"); -// } else { -// output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");"); -// } -// } - } - - if( state.COREPROF ) { - output.println("#ifdef CP_EVENTID_TASKEXECUTE"); - output.println(" CP_LOGEVENT( CP_EVENTID_TASKEXECUTE, CP_EVENTTYPE_BEGIN );"); - output.println("#endif"); - } - - HashSet exitset=new HashSet(); - exitset.add(seseExit); - generateCode(fsen.getNext(0), fm, null, exitset, output, true); - output.println("}\n\n"); - - } - - - // when a new mlp thread is created for an issued SESE, it is started - // by running this method which blocks on a cond variable until - // it is allowed to transition to execute. Then a case statement - // allows it to invoke the method with the proper SESE body, and after - // exiting the SESE method, executes proper SESE exit code before the - // thread can be destroyed - private void generateSESEinvocationMethod(PrintWriter outmethodheader, - PrintWriter outmethod - ) { - - outmethodheader.println("void* invokeSESEmethod( void* seseRecord );"); - outmethod.println( "void* invokeSESEmethod( void* seseRecord ) {"); - outmethod.println( " int status;"); - outmethod.println( " char errmsg[128];"); - - // generate a case for each SESE class that can be invoked - outmethod.println( " switch( ((SESEcommon*)seseRecord)->classID ) {"); - outmethod.println( " "); - Iterator seseit; - seseit=oooa.getAllSESEs().iterator(); - - while(seseit.hasNext()){ - FlatSESEEnterNode fsen = seseit.next(); - - outmethod.println( " /* "+fsen.getPrettyIdentifier()+" */"); - outmethod.println( " case "+fsen.getIdentifier()+":"); - outmethod.println( " "+fsen.getSESEmethodName()+"( seseRecord );"); - - if( fsen.equals( oooa.getMainSESE() ) ) { - outmethod.println( " workScheduleExit();"); - } - - outmethod.println( " break;"); - outmethod.println( ""); - } - - // default case should never be taken, error out - outmethod.println( " default:"); - outmethod.println( " printf(\"Error: unknown SESE class ID in invoke method.\\n\");"); - outmethod.println( " exit(-30);"); - outmethod.println( " break;"); - outmethod.println( " }"); - outmethod.println( " return NULL;"); - outmethod.println( "}\n\n"); - } - protected void generateCode(FlatNode first, FlatMethod fm, @@ -2777,8 +2127,7 @@ public class BuildCode { } else if(current_node.numNext()==1) { FlatNode nextnode; if (state.OOOJAVA && - current_node.kind()==FKind.FlatSESEEnterNode //&& - //!((FlatSESEEnterNode)current_node).getIsCallerSESEplaceholder() + current_node.kind()==FKind.FlatSESEEnterNode ) { FlatSESEEnterNode fsen = (FlatSESEEnterNode)current_node; generateFlatNode(fm, lb, current_node, output); @@ -3059,324 +2408,12 @@ public class BuildCode { } - void stallMEMRCR(FlatMethod fm, FlatNode fn, Set waitingElementSet, PrintWriter output) { - output.println("// stall on parent's stall sites "); - output.println(" {"); - output.println(" REntry* rentry;"); - output.println(" // stallrecord sometimes is used as a task record for instance "); - output.println(" // when you call RELEASE_REFERENCE_TO on a stall record."); - output.println(" // so the parent field must be initialized."); - output.println(" SESEstall * stallrecord=(SESEstall *) poolalloc(runningSESE->taskRecordMemPool);"); - output.println(" stallrecord->common.parent=runningSESE;"); - output.println(" stallrecord->common.unresolvedDependencies=10000;"); - output.println(" stallrecord->common.rcrstatus=1;"); - output.println(" stallrecord->common.offsetToParamRecords=(INTPTR) & (((SESEstall *)0)->rcrRecords);"); - output.println(" stallrecord->common.refCount = 10003;"); - output.println(" int localCount=10000;"); - output.println(" stallrecord->rcrRecords[0].index=0;"); - output.println(" stallrecord->rcrRecords[0].flag=0;"); - output.println(" stallrecord->rcrRecords[0].next=NULL;"); - output.println(" stallrecord->common.parentsStallSem=&runningSESEstallSem;"); - output.println(" psem_reset( &runningSESEstallSem);"); - output.println(" stallrecord->tag=runningSESEstallSem.tag;"); - - TempDescriptor stalltd=null; - for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) { - Analysis.OoOJava.WaitingElement waitingElement =(Analysis.OoOJava.WaitingElement) iterator.next(); - if (waitingElement.getStatus() >= ConflictNode.COARSE) { - output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray[" - + waitingElement.getQueueID() + "]," + waitingElement.getStatus() - + ", (SESEcommon *) stallrecord, 1LL);"); - } else { - throw new Error("Fine-grained conflict: This should not happen in RCR"); - } - output.println(" rentry->queue=runningSESE->memoryQueueArray[" - + waitingElement.getQueueID() + "];"); - output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray[" - + waitingElement.getQueueID() + "],rentry)==NOTREADY) {"); - output.println(" localCount--;"); - output.println(" }"); - output.println("#if defined(RCR)&&!defined(OOO_DISABLE_TASKMEMPOOL)"); - output.println(" else poolfreeinto(runningSESE->memoryQueueArray["+waitingElement.getQueueID()+"]->rentrypool, rentry);"); - output.println("#endif"); - if (stalltd==null) { - stalltd=waitingElement.getTempDesc(); - } else if (stalltd!=waitingElement.getTempDesc()) { - throw new Error("Multiple temp descriptors at stall site"+stalltd+"!="+waitingElement.getTempDesc()); - } - } - - //did all of the course grained stuff - output.println(" if(!atomic_sub_and_test(localCount, &(stallrecord->common.unresolvedDependencies))) {"); - //have to do fine-grained work also - output.println(" stallrecord->___obj___=(struct ___Object___ *)" - + generateTemp(fm, stalltd, null) + ";"); - output.println(" stallrecord->common.classID=-" - + rcr.getTraverserID(stalltd, fn) + ";"); - - output.println(" enqueueTR(TRqueue, (void *)stallrecord);"); - - if (state.COREPROF) { - output.println("#ifdef CP_EVENTID_TASKSTALLMEM"); - output - .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );"); - output.println("#endif"); - } - - output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );"); - - if (state.COREPROF) { - output.println("#ifdef CP_EVENTID_TASKSTALLMEM"); - output - .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );"); - output.println("#endif"); - } - - output.println(" } else {");//exit if condition - //release traversers reference if we didn't use traverser - output.println("#ifndef OOO_DISABLE_TASKMEMPOOL"); - output.println(" RELEASE_REFERENCE_TO((SESEcommon *)stallrecord);"); - output.println("#endif"); - output.println(" }"); - //release our reference to stall record - output.println("#ifndef OOO_DISABLE_TASKMEMPOOL"); - output.println(" RELEASE_REFERENCE_TO((SESEcommon *)stallrecord);"); - output.println("#endif"); - output.println(" }");//exit block - } protected void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) { - // insert pre-node actions from the code plan - if( state.OOOJAVA ) { - - CodePlan cp = oooa.getCodePlan(fn); - - if( cp != null ) { - - FlatSESEEnterNode currentSESE = cp.getCurrentSESE(); - - // for each sese and age pair that this parent statement - // must stall on, take that child's stall semaphore, the - // copying of values comes after the statement - Iterator vstItr = cp.getStallTokens().iterator(); - while( vstItr.hasNext() ) { - VariableSourceToken vst = vstItr.next(); - - SESEandAgePair pair = new SESEandAgePair( vst.getSESE(), vst.getAge() ); - - output.println(" {"); - output.println(" "+pair.getSESE().getSESErecordName()+"* child = ("+ - pair.getSESE().getSESErecordName()+"*) "+pair+";"); - - output.println(" SESEcommon* childCom = (SESEcommon*) "+pair+";"); - - if( state.COREPROF ) { - output.println("#ifdef CP_EVENTID_TASKSTALLVAR"); - output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );"); - output.println("#endif"); - } - output.println(" pthread_mutex_lock( &(childCom->lock) );"); - output.println(" if( childCom->doneExecuting == FALSE ) {"); - output.println(" psem_reset( &runningSESEstallSem );"); - output.println(" childCom->parentsStallSem = &runningSESEstallSem;"); - output.println(" pthread_mutex_unlock( &(childCom->lock) );"); - output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );"); - output.println(" } else {"); - output.println(" pthread_mutex_unlock( &(childCom->lock) );"); - output.println(" }"); - - // copy things we might have stalled for - Iterator tdItr = cp.getCopySet( vst ).iterator(); - while( tdItr.hasNext() ) { - TempDescriptor td = tdItr.next(); - FlatMethod fmContext; - //if( currentSESE.getIsCallerSESEplaceholder() ) { - // fmContext = currentSESE.getfmEnclosing(); - //} else { - fmContext = currentSESE.getfmBogus(); - //} - output.println(" "+generateTemp( fmContext, td, null )+ - " = child->"+vst.getAddrVar().getSafeSymbol()+";"); - } + additionalCodePreNode( fm, lb, fn, output ); - if( state.COREPROF ) { - output.println("#ifdef CP_EVENTID_TASKSTALLVAR"); - output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );"); - output.println("#endif"); - } - - output.println(" }"); - } - - // for each variable with a dynamic source, stall just for that variable - Iterator dynItr = cp.getDynamicStallSet().iterator(); - while( dynItr.hasNext() ) { - TempDescriptor dynVar = dynItr.next(); - - // only stall if the dynamic source is not yourself, denoted by src==NULL - // otherwise the dynamic write nodes will have the local var up-to-date - output.println(" {"); - output.println(" if( "+dynVar+"_srcSESE != NULL ) {"); - - output.println(" SESEcommon* childCom = (SESEcommon*) "+dynVar+"_srcSESE;"); - - if( state.COREPROF ) { - output.println("#ifdef CP_EVENTID_TASKSTALLVAR"); - output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );"); - output.println("#endif"); - } - - output.println(" pthread_mutex_lock( &(childCom->lock) );"); - output.println(" if( childCom->doneExecuting == FALSE ) {"); - output.println(" psem_reset( &runningSESEstallSem );"); - output.println(" childCom->parentsStallSem = &runningSESEstallSem;"); - output.println(" pthread_mutex_unlock( &(childCom->lock) );"); - output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );"); - output.println(" } else {"); - output.println(" pthread_mutex_unlock( &(childCom->lock) );"); - output.println(" }"); - - FlatMethod fmContext; - //if( currentSESE.getIsCallerSESEplaceholder() ) { - // fmContext = currentSESE.getfmEnclosing(); - //} else { - fmContext = currentSESE.getfmBogus(); - //} - - TypeDescriptor type = dynVar.getType(); - String typeStr; - if( type.isNull() ) { - typeStr = "void*"; - } else if( type.isClass() || type.isArray() ) { - typeStr = "struct "+type.getSafeSymbol()+"*"; - } else { - typeStr = type.getSafeSymbol(); - } - - output.println(" "+generateTemp( fmContext, dynVar, null )+ - " = *(("+typeStr+"*) ((void*)"+ - dynVar+"_srcSESE + "+dynVar+"_srcOffset));"); - - if( state.COREPROF ) { - output.println("#ifdef CP_EVENTID_TASKSTALLVAR"); - output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );"); - output.println("#endif"); - } - - output.println(" }"); - output.println(" }"); - } - - // for each assignment of a variable to rhs that has a dynamic source, - // copy the dynamic sources - Iterator dynAssignItr = cp.getDynAssigns().entrySet().iterator(); - while( dynAssignItr.hasNext() ) { - Map.Entry me = (Map.Entry) dynAssignItr.next(); - TempDescriptor lhs = (TempDescriptor) me.getKey(); - TempDescriptor rhs = (TempDescriptor) me.getValue(); - - output.println(" {"); - output.println(" SESEcommon* oldSrc = "+lhs+"_srcSESE;"); - - output.println(" "+lhs+"_srcSESE = "+rhs+"_srcSESE;"); - output.println(" "+lhs+"_srcOffset = "+rhs+"_srcOffset;"); - - // no matter what we did above, track reference count of whatever - // this variable pointed to, do release last in case we're just - // copying the same value in because 1->2->1 is safe but ref count - // 1->0->1 has a window where it looks like it should be free'd - output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); - output.println(" if( "+rhs+"_srcSESE != NULL ) {"); - output.println(" ADD_REFERENCE_TO( "+rhs+"_srcSESE );"); - output.println(" }"); - output.println(" if( oldSrc != NULL ) {"); - output.println(" RELEASE_REFERENCE_TO( oldSrc );"); - output.println(" }"); - output.println(" }"); - output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); - } - - // for each lhs that is dynamic from a non-dynamic source, set the - // dynamic source vars to the current SESE - dynItr = cp.getDynAssignCurr().iterator(); - while( dynItr.hasNext() ) { - TempDescriptor dynVar = dynItr.next(); - - // TODO - //assert currentSESE.getDynamicVarSet().contains( dynVar ); - - // first release a reference to current record - output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); - output.println(" if( "+dynVar+"_srcSESE != NULL ) {"); - output.println(" RELEASE_REFERENCE_TO( oldSrc );"); - output.println(" }"); - output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); - - output.println(" "+dynVar+"_srcSESE = NULL;"); - } - - // eom - // handling stall site - if (state.OOOJAVA) { - Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(currentSESE); - if(graph!=null){ - Set seseLockSet = oooa.getLockMappings(graph); - Set waitingElementSet = graph.getStallSiteWaitingElementSet(fn, seseLockSet); - - if (waitingElementSet.size() > 0) { - if (state.RCR) { - stallMEMRCR(fm, fn, waitingElementSet, output); - } else { - output.println("// stall on parent's stall sites "); - output.println(" {"); - output.println(" REntry* rentry;"); - - for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) { - Analysis.OoOJava.WaitingElement waitingElement = - (Analysis.OoOJava.WaitingElement) iterator.next(); - if (waitingElement.getStatus() >= ConflictNode.COARSE) { - output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray[" - + waitingElement.getQueueID() + "]," + waitingElement.getStatus() - + ", runningSESE);"); - } else { - output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray[" - + waitingElement.getQueueID() + "]," + waitingElement.getStatus() - + ", runningSESE, (void*)&" - + generateTemp(fm, waitingElement.getTempDesc(), lb) + ");"); - } - output.println(" rentry->parentStallSem=&runningSESEstallSem;"); - output.println(" psem_reset( &runningSESEstallSem);"); - output.println(" rentry->tag=runningSESEstallSem.tag;"); - output.println(" rentry->queue=runningSESE->memoryQueueArray[" - + waitingElement.getQueueID() + "];"); - output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray[" - + waitingElement.getQueueID() + "],rentry)==NOTREADY){"); - if (state.COREPROF) { - output.println("#ifdef CP_EVENTID_TASKSTALLMEM"); - output - .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );"); - output.println("#endif"); - } - - output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );"); - - if (state.COREPROF) { - output.println("#ifdef CP_EVENTID_TASKSTALLMEM"); - output - .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );"); - output.println("#endif"); - } - output.println(" } "); - } - output.println(" }"); - } - } - } - } - } - } switch(fn.kind()) { case FKind.FlatAtomicEnterNode: @@ -3504,7 +2541,8 @@ public class BuildCode { throw new Error(); } - // insert post-node actions from the code-plan (none right now...) + + additionalCodePostNode( fm, lb, fn, output ); } public void generateFlatOffsetNode(FlatMethod fm, LocalityBinding lb, FlatOffsetNode fofn, PrintWriter output) { @@ -3884,758 +2922,15 @@ public class BuildCode { FlatSESEEnterNode fsen, PrintWriter output) { // if OOOJAVA flag is off, okay that SESE nodes are in IR graph, - // just skip over them and code generates exactly the same - if( !state.OOOJAVA ) { - return; - } - // there may be an SESE in an unreachable method, skip over - if( !oooa.getAllSESEs().contains(fsen) ) { - return; - } - - // also, if we have encountered a placeholder, just skip it - //if( fsen.getIsCallerSESEplaceholder() ) { - // return; - //} - - output.println(" {"); - - if( state.COREPROF ) { - output.println("#ifdef CP_EVENTID_TASKDISPATCH"); - output.println(" CP_LOGEVENT( CP_EVENTID_TASKDISPATCH, CP_EVENTTYPE_BEGIN );"); - output.println("#endif"); - } - - - // before doing anything, lock your own record and increment the running children - if( fsen != oooa.getMainSESE() ) { - output.println(" childSESE++;"); - } - - // allocate the space for this record - output.println( "#ifndef OOO_DISABLE_TASKMEMPOOL" ); - - output.println( "#ifdef CP_EVENTID_POOLALLOC"); - output.println( " CP_LOGEVENT( CP_EVENTID_POOLALLOC, CP_EVENTTYPE_BEGIN );"); - output.println( "#endif"); - if( fsen != oooa.getMainSESE() ) { - output.println(" "+ - fsen.getSESErecordName()+"* seseToIssue = ("+ - fsen.getSESErecordName()+"*) poolalloc( runningSESE->taskRecordMemPool );"); - output.println(" CHECK_RECORD( seseToIssue );"); - } else { - output.println(" "+ - fsen.getSESErecordName()+"* seseToIssue = ("+ - fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+ - fsen.getSESErecordName()+" ) );"); - } - output.println( "#ifdef CP_EVENTID_POOLALLOC"); - output.println( " CP_LOGEVENT( CP_EVENTID_POOLALLOC, CP_EVENTTYPE_END );"); - output.println( "#endif"); - - output.println( "#else // OOO_DISABLE_TASKMEMPOOL" ); - output.println(" "+ - fsen.getSESErecordName()+"* seseToIssue = ("+ - fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+ - fsen.getSESErecordName()+" ) );"); - output.println( "#endif // OOO_DISABLE_TASKMEMPOOL" ); - - - // set up the SESE in-set and out-set objects, which look - // like a garbage list - output.println(" struct garbagelist * gl= (struct garbagelist *)&(((SESEcommon*)(seseToIssue))[1]);"); - output.println(" gl->size="+calculateSizeOfSESEParamList(fsen)+";"); - output.println(" gl->next = NULL;"); - output.println(" seseToIssue->common.rentryIdx=0;"); - - if(state.RCR) { - //flag the SESE status as 1...it will be reset - output.println(" seseToIssue->common.rcrstatus=1;"); - } - - // there are pointers to SESE records the newly-issued SESE - // will use to get values it depends on them for--how many - // are there, and what is the offset from the total SESE - // record to the first dependent record pointer? - output.println(" seseToIssue->common.numDependentSESErecords="+ - fsen.getNumDepRecs()+";"); - - // we only need this (and it will only compile) when the number of dependent - // SESE records is non-zero - if( fsen.getFirstDepRecField() != null ) { - output.println(" seseToIssue->common.offsetToDepSESErecords=(INTPTR)sizeof("+ - fsen.getSESErecordName()+") - (INTPTR)&((("+ - fsen.getSESErecordName()+"*)0)->"+fsen.getFirstDepRecField()+");" - ); - } - - if (state.RCR&&fsen.getInVarsForDynamicCoarseConflictResolution().size()>0) { - output.println(" seseToIssue->common.offsetToParamRecords=(INTPTR) & ((("+fsen.getSESErecordName()+"*)0)->rcrRecords);"); - } - - // fill in common data - output.println(" int localCount=0;"); - output.println(" seseToIssue->common.classID = "+fsen.getIdentifier()+";"); - output.println(" seseToIssue->common.unresolvedDependencies = 10000;"); - output.println(" seseToIssue->common.parentsStallSem = NULL;"); - output.println(" initQueue(&seseToIssue->common.forwardList);"); - output.println(" seseToIssue->common.doneExecuting = FALSE;"); - output.println(" seseToIssue->common.numRunningChildren = 0;"); - output.println( "#ifdef OOO_DISABLE_TASKMEMPOOL" ); - output.println(" pthread_cond_init( &(seseToIssue->common.runningChildrenCond), NULL );"); - output.println("#endif"); - output.println(" seseToIssue->common.parent = runningSESE;"); - // start with refCount = 2, one being the count that the child itself - // will decrement when it retires, to say it is done using its own - // record, and the other count is for the parent that will remember - // the static name of this new child below - if( state.RCR ) { - // if we're using RCR, ref count is 3 because the traverser has - // a reference, too - if( fsen != oooa.getMainSESE() && fsen.getInVarsForDynamicCoarseConflictResolution().size()>0){ - output.println(" seseToIssue->common.refCount = 10003;"); - } else { - output.println(" seseToIssue->common.refCount = 10002;"); - } - output.println(" int refCount=10000;"); - } else { - output.println(" seseToIssue->common.refCount = 2;"); - } - - // all READY in-vars should be copied now and be done with it - Iterator tempItr = fsen.getReadyInVarSet().iterator(); - while( tempItr.hasNext() ) { - TempDescriptor temp = tempItr.next(); - - // when we are issuing the main SESE or an SESE with placeholder - // caller SESE as parent, generate temp child child's eclosing method, - // otherwise use the parent's enclosing method as the context - boolean useParentContext = false; - - if( fsen != oooa.getMainSESE() ) { - assert fsen.getParents() != null; - //if( !fsen.getParent().getIsCallerSESEplaceholder() ) { - useParentContext = true; - //} - } - - /* - if( useParentContext ) { - output.println(" seseToIssue->"+temp+" = "+ - generateTemp( fsen.getParent().getfmBogus(), temp, null )+";"); - } else { - output.println(" seseToIssue->"+temp+" = "+ - generateTemp( fsen.getfmEnclosing(), temp, null )+";"); - } - */ - } - - // before potentially adding this SESE to other forwarding lists, - // create it's lock - output.println( "#ifdef OOO_DISABLE_TASKMEMPOOL" ); - output.println(" pthread_mutex_init( &(seseToIssue->common.lock), NULL );"); - output.println("#endif"); - - if( fsen != oooa.getMainSESE() ) { - // count up outstanding dependencies, static first, then dynamic - Iterator staticSrcsItr = fsen.getStaticInVarSrcs().iterator(); - while( staticSrcsItr.hasNext() ) { - SESEandAgePair srcPair = staticSrcsItr.next(); - output.println(" {"); - output.println(" SESEcommon* src = (SESEcommon*)"+srcPair+";"); - output.println(" pthread_mutex_lock( &(src->lock) );"); - // FORWARD TODO - output.println(" if( !src->doneExecuting ) {"); - output.println(" addNewItem( &src->forwardList, seseToIssue );"); - output.println(" ++(localCount);"); - output.println(" }"); - output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); - output.println(" ADD_REFERENCE_TO( src );"); - output.println("#endif" ); - output.println(" pthread_mutex_unlock( &(src->lock) );"); - output.println(" }"); - - // whether or not it is an outstanding dependency, make sure - // to pass the static name to the child's record - output.println(" seseToIssue->"+srcPair+" = "+ - "("+srcPair.getSESE().getSESErecordName()+"*)"+ - srcPair+";"); - } - - // dynamic sources might already be accounted for in the static list, - // so only add them to forwarding lists if they're not already there - Iterator dynVarsItr = fsen.getDynamicInVarSet().iterator(); - while( dynVarsItr.hasNext() ) { - TempDescriptor dynInVar = dynVarsItr.next(); - output.println(" {"); - output.println(" SESEcommon* src = (SESEcommon*)"+dynInVar+"_srcSESE;"); - - // the dynamic source is NULL if it comes from your own space--you can't pass - // the address off to the new child, because you're not done executing and - // might change the variable, so copy it right now - output.println(" if( src != NULL ) {"); - output.println(" pthread_mutex_lock( &(src->lock) );"); - - // FORWARD TODO - - output.println(" if( isEmpty( &src->forwardList ) ||"); - output.println(" seseToIssue != peekItem( &src->forwardList ) ) {"); - output.println(" if( !src->doneExecuting ) {"); - output.println(" addNewItem( &src->forwardList, seseToIssue );"); - output.println(" ++(localCount);"); - output.println(" }"); - output.println(" }"); - output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); - output.println(" ADD_REFERENCE_TO( src );"); - output.println("#endif" ); - output.println(" pthread_mutex_unlock( &(src->lock) );"); - output.println(" seseToIssue->"+dynInVar+"_srcOffset = "+dynInVar+"_srcOffset;"); - output.println(" } else {"); - - boolean useParentContext = false; - if( fsen != oooa.getMainSESE() ) { - //assert fsen.getParent() != null; - //if( !fsen.getParent().getIsCallerSESEplaceholder() ) { - useParentContext = true; - //} - } - //if( useParentContext ) { - // output.println(" seseToIssue->"+dynInVar+" = "+ - // generateTemp( fsen.getParent().getfmBogus(), dynInVar, null )+";"); - //} else { - // output.println(" seseToIssue->"+dynInVar+" = "+ - // generateTemp( fsen.getfmEnclosing(), dynInVar, null )+";"); - //} - - output.println(" }"); - output.println(" }"); - - // even if the value is already copied, make sure your NULL source - // gets passed so child knows it already has the dynamic value - output.println(" seseToIssue->"+dynInVar+"_srcSESE = "+dynInVar+"_srcSESE;"); - } - - - - - // maintain pointers for finding dynamic SESE - // instances from static names - // TODO - SESEandAgePair pairNewest = new SESEandAgePair( fsen, 0 ); - SESEandAgePair pairOldest = new SESEandAgePair( fsen, fsen.getOldestAgeToTrack() ); - if( true//fsen.getParent() != null && - //fsen.getParent().getNeededStaticNames().contains( pairNewest ) - ) { - output.println(" {"); - output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); - output.println(" SESEcommon* oldest = "+pairOldest+";"); - output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); - - for( int i = fsen.getOldestAgeToTrack(); i > 0; --i ) { - SESEandAgePair pair1 = new SESEandAgePair( fsen, i ); - SESEandAgePair pair2 = new SESEandAgePair( fsen, i-1 ); - output.println(" "+pair1+" = "+pair2+";"); - } - output.println(" "+pairNewest+" = &(seseToIssue->common);"); - - // no need to add a reference to whatever is the newest record, because - // we initialized seseToIssue->refCount to *2* - // but release a reference to whatever was the oldest BEFORE the shift - output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); - output.println(" if( oldest != NULL ) {"); - output.println(" RELEASE_REFERENCE_TO( oldest );"); - output.println(" }"); - output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); - output.println(" }"); - } - - if( state.COREPROF ) { - output.println("#ifdef CP_EVENTID_PREPAREMEMQ"); - output.println(" CP_LOGEVENT( CP_EVENTID_PREPAREMEMQ, CP_EVENTTYPE_BEGIN );"); - output.println("#endif"); - } - - - //////////////// - // count up memory conflict dependencies, - if(state.RCR) { - dispatchMEMRC(fm, lb, fsen, output); - } else if(state.OOOJAVA){ - // NEED TO FIX IT - // assumes that there is only one parent, but it is possible that - // currentSESE has more than one so we need to generate - // conditional case for each parent case - assert fsen.getParents().size()>0; - FlatSESEEnterNode parent = fsen.getParents().iterator().next(); - Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(parent); - if (graph != null && graph.hasConflictEdge()) { - Set seseLockSet = oooa.getLockMappings(graph); - output.println(); - output.println(" //add memory queue element"); - Analysis.OoOJava.SESEWaitingQueue seseWaitingQueue= - graph.getWaitingElementSetBySESEID(fsen.getIdentifier(), seseLockSet); - if(seseWaitingQueue.getWaitingElementSize()>0) { - output.println(" {"); - output.println(" REntry* rentry=NULL;"); - output.println(" INTPTR* pointer=NULL;"); - output.println(" seseToIssue->common.rentryIdx=0;"); - - Set queueIDSet=seseWaitingQueue.getQueueIDSet(); - for (Iterator iterator = queueIDSet.iterator(); iterator.hasNext();) { - Integer key = (Integer) iterator.next(); - int queueID=key.intValue(); - Set waitingQueueSet = - seseWaitingQueue.getWaitingElementSet(queueID); - int enqueueType=seseWaitingQueue.getType(queueID); - if(enqueueType==SESEWaitingQueue.EXCEPTION) { - output.println(" INITIALIZEBUF(runningSESE->memoryQueueArray[" + queueID+ "]);"); - } - for (Iterator iterator2 = waitingQueueSet.iterator(); iterator2.hasNext();) { - Analysis.OoOJava.WaitingElement waitingElement - = (Analysis.OoOJava.WaitingElement) iterator2.next(); - if (waitingElement.getStatus() >= ConflictNode.COARSE) { - output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["+ queueID+ "]," - + waitingElement.getStatus() - + ", &(seseToIssue->common));"); - } else { - TempDescriptor td = waitingElement.getTempDesc(); - // decide whether waiting element is dynamic or static - if (fsen.getDynamicInVarSet().contains(td)) { - // dynamic in-var case - output.println(" pointer=seseToIssue->" - + waitingElement.getDynID() - + "_srcSESE+seseToIssue->" - + waitingElement.getDynID() - + "_srcOffset;"); - output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "]," - + waitingElement.getStatus() - + ", &(seseToIssue->common), pointer );"); - } else if (fsen.getStaticInVarSet().contains(td)) { - // static in-var case - VariableSourceToken vst = fsen.getStaticInVarSrc(td); - if (vst != null) { - - String srcId = "SESE_" + vst.getSESE().getPrettyIdentifier() - + vst.getSESE().getIdentifier() - + "_" + vst.getAge(); - output.println(" pointer=(void*)&seseToIssue->" - + srcId - + "->" - + waitingElement - .getDynID() - + ";"); - output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "]," - + waitingElement.getStatus() - + ", &(seseToIssue->common), pointer );"); - } - } else { - output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "]," - + waitingElement.getStatus() - + ", &(seseToIssue->common), (void*)&seseToIssue->" - + waitingElement.getDynID() - + ");"); - } - } - output.println(" rentry->queue=runningSESE->memoryQueueArray[" - + waitingElement.getQueueID() - + "];"); - - if(enqueueType==SESEWaitingQueue.NORMAL){ - output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;"); - output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray[" - + waitingElement.getQueueID() - + "],rentry)==NOTREADY) {"); - output.println(" localCount++;"); - output.println(" }"); - } else { - output.println(" ADDRENTRYTOBUF(runningSESE->memoryQueueArray[" + waitingElement.getQueueID() + "],rentry);"); - } - } - if(enqueueType!=SESEWaitingQueue.NORMAL){ - output.println(" localCount+=RESOLVEBUF(runningSESE->memoryQueueArray[" - + queueID+ "],&seseToIssue->common);"); - } - } - output.println(" }"); - } - output.println(); - } - } - } - - if( state.COREPROF ) { - output.println("#ifdef CP_EVENTID_PREPAREMEMQ"); - output.println(" CP_LOGEVENT( CP_EVENTID_PREPAREMEMQ, CP_EVENTTYPE_END );"); - output.println("#endif"); - } - - // Enqueue Task Record - if (state.RCR) { - if( fsen != oooa.getMainSESE() && fsen.getInVarsForDynamicCoarseConflictResolution().size()>0){ - output.println(" enqueueTR(TRqueue, (void *)seseToIssue);"); - } - } - - // if there were no outstanding dependencies, issue here - output.println(" if( atomic_sub_and_test(10000-localCount,&(seseToIssue->common.unresolvedDependencies) ) ) {"); - output.println(" workScheduleSubmit( (void*)seseToIssue );"); - output.println(" }"); - - - - if( state.COREPROF ) { - output.println("#ifdef CP_EVENTID_TASKDISPATCH"); - output.println(" CP_LOGEVENT( CP_EVENTID_TASKDISPATCH, CP_EVENTTYPE_END );"); - output.println("#endif"); - } - - output.println(" }"); - - } - - void dispatchMEMRC(FlatMethod fm, LocalityBinding lb, FlatSESEEnterNode fsen, PrintWriter output) { - // NEED TO FIX IT - // assumes that there is only one parent, but it is possible that - // currentSESE has more than one so we need to generate - // conditional case for each parent case - assert fsen.getParents().size()>0; - FlatSESEEnterNode parent = fsen.getParents().iterator().next(); - Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(parent); - if (graph != null && graph.hasConflictEdge()) { - Set seseLockSet = oooa.getLockMappings(graph); - Analysis.OoOJava.SESEWaitingQueue seseWaitingQueue=graph.getWaitingElementSetBySESEID(fsen.getIdentifier(), seseLockSet); - if(seseWaitingQueue.getWaitingElementSize()>0) { - output.println(" {"); - output.println(" REntry* rentry=NULL;"); - output.println(" INTPTR* pointer=NULL;"); - output.println(" seseToIssue->common.rentryIdx=0;"); - Vector invars=fsen.getInVarsForDynamicCoarseConflictResolution(); - System.out.println(fm.getMethod()+"["+invars+"]"); - - Vector queuetovar=new Vector(); - - for(int i=0;i weset=seseWaitingQueue.getWaitingElementSet(td); - int numqueues=0; - Set queueSet=new HashSet(); - for (Iterator iterator = weset.iterator(); iterator.hasNext();) { - Analysis.OoOJava.WaitingElement we = (Analysis.OoOJava.WaitingElement) iterator.next(); - Integer queueID=new Integer( we.getQueueID()); - if(!queueSet.contains(queueID)){ - numqueues++; - queueSet.add(queueID); - } - } - output.println(" seseToIssue->rcrRecords["+i+"].flag="+numqueues+";"); - output.println(" seseToIssue->rcrRecords["+i+"].index=0;"); - output.println(" seseToIssue->rcrRecords["+i+"].next=NULL;"); - output.println(" int dispCount"+i+"=0;"); - - for (Iterator wtit = weset.iterator(); wtit.hasNext();) { - Analysis.OoOJava.WaitingElement waitingElement = wtit.next(); - int queueID = waitingElement.getQueueID(); - if (queueID >= queuetovar.size()) - queuetovar.setSize(queueID + 1); - Long l = queuetovar.get(queueID); - long val = (l != null) ? l.longValue() : 0; - val = val | (1 << i); - queuetovar.set(queueID, new Long(val)); - } - } - - HashSet generatedqueueentry=new HashSet(); - for(int i=0;i weset=seseWaitingQueue.getWaitingElementSet(td); - for(Iterator wtit=weset.iterator();wtit.hasNext();) { - Analysis.OoOJava.WaitingElement waitingElement=wtit.next(); - int queueID=waitingElement.getQueueID(); - - if(waitingElement.isBogus()){ - continue; - } - - if (generatedqueueentry.contains(queueID)) - continue; - else - generatedqueueentry.add(queueID); - - assert(waitingElement.getStatus()>=ConflictNode.COARSE); - long mask=queuetovar.get(queueID); - output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "]," + waitingElement.getStatus() + ", &(seseToIssue->common), "+mask+"LL);"); - output.println(" rentry->count=2;"); - output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;"); - output.println(" rentry->queue=runningSESE->memoryQueueArray[" + waitingElement.getQueueID()+"];"); - - output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "],rentry)==READY) {"); - for(int j=0;mask!=0;j++) { - if ((mask&1)==1) - output.println(" dispCount"+j+"++;"); - mask=mask>>1; - } - output.println(" } else "); - output.println(" refCount--;"); - - } - - if (fsen.getDynamicInVarSet().contains(td)) { - // dynamic in-var case - //output.println(" pointer=seseToIssue->" + waitingElement.getDynID()+ "_srcSESE+seseToIssue->"+ waitingElement.getDynID()+ "_srcOffset;"); - //output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", &(seseToIssue->common), pointer );"); - } - } - for(int i=0;ircrRecords["+i+"].flag)))"); - output.println(" localCount++;"); - } - output.println(" }"); - } - } - output.println("#ifndef OOO_DISABLE_TASKMEMPOOL"); - output.println(" RELEASE_REFERENCES_TO((SESEcommon *)seseToIssue, refCount);"); - output.println("#endif"); + // just skip over them and code generates exactly the same } public void generateFlatSESEExitNode( FlatMethod fm, LocalityBinding lb, FlatSESEExitNode fsexn, PrintWriter output) { - // if OOOJAVA flag is off, okay that SESE nodes are in IR graph, // just skip over them and code generates exactly the same - if( !state.OOOJAVA ) { - return; - } - - // get the enter node for this exit that has meta data embedded - FlatSESEEnterNode fsen = fsexn.getFlatEnter(); - - // there may be an SESE in an unreachable method, skip over - if( !oooa.getAllSESEs().contains( fsen ) ) { - return; - } - - // also, if we have encountered a placeholder, just jump it - //if( fsen.getIsCallerSESEplaceholder() ) { - // return; - //} - - if( state.COREPROF ) { - output.println("#ifdef CP_EVENTID_TASKEXECUTE"); - output.println(" CP_LOGEVENT( CP_EVENTID_TASKEXECUTE, CP_EVENTTYPE_END );"); - output.println("#endif"); - } - - output.println(" /* SESE exiting */"); - - if( state.COREPROF ) { - output.println("#ifdef CP_EVENTID_TASKRETIRE"); - output.println(" CP_LOGEVENT( CP_EVENTID_TASKRETIRE, CP_EVENTTYPE_BEGIN );"); - output.println("#endif"); - } - - - // this SESE cannot be done until all of its children are done - // so grab your own lock with the condition variable for watching - // that the number of your running children is greater than zero - output.println(" atomic_add(childSESE, &runningSESE->numRunningChildren);"); - output.println(" pthread_mutex_lock( &(runningSESE->lock) );"); - output.println(" if( runningSESE->numRunningChildren > 0 ) {"); - output.println(" stopforgc( (struct garbagelist *)&___locals___ );"); - output.println(" do {"); - output.println(" pthread_cond_wait( &(runningSESE->runningChildrenCond), &(runningSESE->lock) );"); - output.println(" } while( runningSESE->numRunningChildren > 0 );"); - output.println(" restartaftergc();"); - output.println(" }"); - - - // copy out-set from local temps into the sese record - Iterator itr = fsen.getOutVarSet().iterator(); - while( itr.hasNext() ) { - TempDescriptor temp = itr.next(); - - // only have to do this for primitives non-arrays - if( !( - temp.getType().isPrimitive() && !temp.getType().isArray() - ) - ) { - continue; - } - - // have to determine the context enclosing this sese - boolean useParentContext = false; - - if( fsen != oooa.getMainSESE() ) { - assert fsen.getParents() != null; - //if( !fsen.getParent().getIsCallerSESEplaceholder() ) { - useParentContext = true; - //} - } - - String from; - //if( useParentContext ) { - //from = generateTemp( fsen.getParent().getfmBogus(), temp, null ); - //} else { - from = generateTemp( fsen.getfmEnclosing(), temp, null ); - //} - - output.println(" "+paramsprefix+ - "->"+temp.getSafeSymbol()+ - " = "+from+";"); - } - - // mark yourself done, your task data is now read-only - output.println(" runningSESE->doneExecuting = TRUE;"); - - // if parent is stalling on you, let them know you're done - if( fsexn.getFlatEnter() != oooa.getMainSESE() ) { - output.println(" if( runningSESE->parentsStallSem != NULL ) {"); - output.println(" psem_give( runningSESE->parentsStallSem );"); - output.println(" }"); - } - - output.println(" pthread_mutex_unlock( &(runningSESE->lock) );"); - - // decrement dependency count for all SESE's on your forwarding list - - // FORWARD TODO - output.println(" while( !isEmpty( &runningSESE->forwardList ) ) {"); - output.println(" SESEcommon* consumer = (SESEcommon*) getItem( &runningSESE->forwardList );"); - - - if (!state.RCR) { - output.println(" if(consumer->rentryIdx>0){"); - output.println(" // resolved null pointer"); - output.println(" int idx;"); - output.println(" for(idx=0;idxrentryIdx;idx++){"); - output.println(" resolvePointer(consumer->rentryArray[idx]);"); - output.println(" }"); - output.println(" }"); - } - - output.println(" if( atomic_sub_and_test( 1, &(consumer->unresolvedDependencies) ) ){"); - output.println(" workScheduleSubmit( (void*)consumer );"); - output.println(" }"); - output.println(" }"); - - - // clean up its lock element from waiting queue, and decrement dependency count for next SESE block - if( fsen != oooa.getMainSESE() ) { - output.println(); - output.println(" /* check memory dependency*/"); - output.println(" {"); - output.println(" int idx;"); - output.println(" for(idx=0;idx<___params___->common.rentryIdx;idx++){"); - output.println(" REntry* re=___params___->common.rentryArray[idx];"); - output.println(" RETIRERENTRY(re->queue,re);"); - output.println(" }"); - output.println(" }"); - } - - Vector inset=fsen.getInVarsForDynamicCoarseConflictResolution(); - if (state.RCR && inset.size() > 0) { - /* Make sure the running SESE is finished */ - output.println(" if (unlikely(runningSESE->rcrstatus!=0)) {"); - output.println(" if(CAS(&runningSESE->rcrstatus,1,0)==2) {"); - output.println(" while(runningSESE->rcrstatus) {"); - output.println(" BARRIER();"); - output.println(" sched_yield();"); - output.println(" }"); - output.println(" }"); - output.println(" }"); - output.println("{"); - output.println(" int idx,idx2;"); - - output.println(" struct rcrRecord *rec;"); - output - .println(" struct Hashtable_rcr ** hashstruct=runningSESE->parent->allHashStructures;"); - - for (int i = 0; i < inset.size(); i++) { - output.println(" rec=&" + paramsprefix + "->rcrRecords[" + i + "];"); - output.println(" while(rec!=NULL) {"); - output.println(" for(idx2=0;idx2index;idx2++) {"); - - int weaklyConnectedComponentIndex = rcr.getWeakID(inset.get(i), fsen); - - output.println(" rcr_RETIREHASHTABLE(hashstruct[" + weaklyConnectedComponentIndex - + "],&(___params___->common), rec->array[idx2], (BinItem_rcr *) rec->ptrarray[idx2]);"); - - output.println(" }");// exit idx2 for loop - output.println(" rec=rec->next;"); - output.println(" }");// exit rec while loop - } - output.println("}"); - } - - - // a task has variables to track static/dynamic instances - // that serve as sources, release the parent's ref of each - // non-null var of these types - output.println(" // releasing static SESEs"); - output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); - // TODO - //Iterator pItr = fsen.getNeededStaticNames().iterator(); - //while( pItr.hasNext() ) { - // SESEandAgePair pair = pItr.next(); - // output.println(" if( "+pair+" != NULL ) {"); - // output.println(" RELEASE_REFERENCE_TO( "+pair+" );"); - // output.println(" }"); - //} - //output.println(" // releasing dynamic variable sources"); - //Iterator dynSrcItr = fsen.getDynamicVarSet().iterator(); - //while( dynSrcItr.hasNext() ) { - // TempDescriptor dynSrcVar = dynSrcItr.next(); - // output.println(" if( "+dynSrcVar+"_srcSESE != NULL ) {"); - // output.println(" RELEASE_REFERENCE_TO( "+dynSrcVar+"_srcSESE );"); - // output.println(" }"); - //} - // destroy this task's mempool if it is not a leaf task - if( !fsen.getIsLeafSESE() ) { - output.println(" pooldestroy( runningSESE->taskRecordMemPool );"); - if (state.RCR && fsen.getInVarsForDynamicCoarseConflictResolution().size() > 0 ) { - output.println(" returnTR();"); - } - } - output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); - - - output.println("{"); - output.println("SESEcommon *myparent=runningSESE->parent;"); - - // if this is not the Main sese (which has no parent) then return - // THIS task's record to the PARENT'S task record pool, and only if - // the reference count is now zero - if( fsen != oooa.getMainSESE() ) { - output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); - output.println(" RELEASE_REFERENCE_TO( runningSESE );"); - output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); - } else { - // the main task has no parent, just free its record - output.println(" mlpFreeSESErecord( runningSESE );"); - } - - - // last of all, decrement your parent's number of running children - output.println(" if( myparent != NULL ) {"); - output.println(" if( atomic_sub_and_test( 1, &(myparent->numRunningChildren) ) ) {"); - output.println(" pthread_mutex_lock ( &(myparent->lock) );"); - output.println(" pthread_cond_signal ( &(myparent->runningChildrenCond) );"); - output.println(" pthread_mutex_unlock( &(myparent->lock) );"); - output.println(" }"); - output.println(" }"); - - output.println("}"); - - // as this thread is wrapping up the task, make sure the thread-local var - // for the currently running task record references an invalid task - output.println(" runningSESE = (SESEcommon*) 0x1;"); - - if( state.COREPROF ) { - output.println("#ifdef CP_EVENTID_TASKRETIRE"); - output.println(" CP_LOGEVENT( CP_EVENTID_TASKRETIRE, CP_EVENTTYPE_END );"); - output.println("#endif"); - } } public void generateFlatWriteDynamicVarNode( FlatMethod fm, @@ -4648,48 +2943,6 @@ public class BuildCode { // OOOJAVA flag is not set throw new Error("Unexpected presence of FlatWriteDynamicVarNode"); } - - Hashtable writeDynamic = fwdvn.getVar2src(); - - assert writeDynamic != null; - - Iterator wdItr = writeDynamic.entrySet().iterator(); - while( wdItr.hasNext() ) { - Map.Entry me = (Map.Entry) wdItr.next(); - TempDescriptor refVar = (TempDescriptor) me.getKey(); - VSTWrapper vstW = (VSTWrapper) me.getValue(); - VariableSourceToken vst = vstW.vst; - - output.println(" {"); - output.println(" SESEcommon* oldSrc = "+refVar+"_srcSESE;"); - - if( vst == null ) { - // if there is no given source, this variable is ready so - // mark src pointer NULL to signify that the var is up-to-date - output.println(" "+refVar+"_srcSESE = NULL;"); - } else { - // otherwise we track where it will come from - SESEandAgePair instance = new SESEandAgePair( vst.getSESE(), vst.getAge() ); - output.println(" "+refVar+"_srcSESE = "+instance+";"); - output.println(" "+refVar+"_srcOffset = (INTPTR) &((("+ - vst.getSESE().getSESErecordName()+"*)0)->"+vst.getAddrVar()+");"); - } - - // no matter what we did above, track reference count of whatever - // this variable pointed to, do release last in case we're just - // copying the same value in because 1->2->1 is safe but ref count - // 1->0->1 has a window where it looks like it should be free'd - output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); - output.println(" if( "+refVar+"_srcSESE != NULL ) {"); - output.println(" ADD_REFERENCE_TO( "+refVar+"_srcSESE );"); - output.println(" }"); - output.println(" if( oldSrc != NULL ) {"); - output.println(" RELEASE_REFERENCE_TO( oldSrc );"); - output.println(" }"); - output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); - - output.println(" }"); - } } @@ -5342,6 +3595,7 @@ public class BuildCode { } } + protected void generateFlatNew(FlatMethod fm, LocalityBinding lb, FlatNew fn, PrintWriter output) { if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) { //Stash pointer in case of GC @@ -5372,12 +3626,7 @@ public class BuildCode { if (fn.isGlobal()&&(state.DSM||state.SINGLETM)) { output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarrayglobal("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");"); } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { - if(state.OOOJAVA){ - output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray_mlp("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+", oid, "+oooa.getDisjointAnalysis().getAllocationSiteFromFlatNew(fn).getUniqueAllocSiteID()+");"); - output.println(" oid += oidIncrement;"); - }else{ - output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");"); - } + output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");"); } else { output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");"); } @@ -5385,12 +3634,7 @@ public class BuildCode { if (fn.isGlobal()&&(state.DSM||state.SINGLETM)) { output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newglobal("+fn.getType().getClassDesc().getId()+");"); } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { - if (state.OOOJAVA){ - output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new_mlp("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+", oid, "+oooa.getDisjointAnalysis().getAllocationSiteFromFlatNew(fn).getUniqueAllocSiteID()+");"); - output.println(" oid += oidIncrement;"); - } else { - output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");"); - } + output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");"); } else { output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+fn.getType().getClassDesc().getId()+");"); } @@ -6145,72 +4389,26 @@ public class BuildCode { protected void outputTransCode(PrintWriter output) { } - - private int calculateSizeOfSESEParamList(FlatSESEEnterNode fsen){ - - Set tdSet=new HashSet(); - - for (Iterator iterator = fsen.getInVarSet().iterator(); iterator.hasNext();) { - TempDescriptor tempDescriptor = (TempDescriptor) iterator.next(); - if(!tempDescriptor.getType().isPrimitive() || tempDescriptor.getType().isArray()){ - tdSet.add(tempDescriptor); - } - } - - for (Iterator iterator = fsen.getOutVarSet().iterator(); iterator.hasNext();) { - TempDescriptor tempDescriptor = (TempDescriptor) iterator.next(); - if(!tempDescriptor.getType().isPrimitive() || tempDescriptor.getType().isArray()){ - tdSet.add(tempDescriptor); - } - } - - return tdSet.size(); - } - - private String calculateSizeOfSESEParamSize(FlatSESEEnterNode fsen){ - HashMap map=new HashMap(); - HashSet processed=new HashSet(); - String rtr=""; - - // space for all in and out set primitives - Set inSetAndOutSet = new HashSet(); - inSetAndOutSet.addAll( fsen.getInVarSet() ); - inSetAndOutSet.addAll( fsen.getOutVarSet() ); - - Set inSetAndOutSetPrims = new HashSet(); - - Iterator itr = inSetAndOutSet.iterator(); - while( itr.hasNext() ) { - TempDescriptor temp = itr.next(); - TypeDescriptor type = temp.getType(); - if( !type.isPtr() ) { - inSetAndOutSetPrims.add( temp ); - } - } - - Iterator itrPrims = inSetAndOutSetPrims.iterator(); - while( itrPrims.hasNext() ) { - TempDescriptor temp = itrPrims.next(); - TypeDescriptor type = temp.getType(); - if(type.isPrimitive()){ - Integer count=map.get(type.getSymbol()); - if(count==null){ - count=new Integer(1); - map.put(type.getSymbol(), count); - }else{ - map.put(type.getSymbol(), new Integer(count.intValue()+1)); - } - } - } - - Set keySet=map.keySet(); - for (Iterator iterator = keySet.iterator(); iterator.hasNext();) { - String key = (String) iterator.next(); - rtr+="+sizeof("+key+")*"+map.get(key); - } - return rtr; - } + + + // override these methods in a subclass of BuildCode + // to generate code for additional systems + protected void additionalIncludesMethodsHeader( PrintWriter outmethodheader ) {} + protected void preCodeGenInitialization() {} + protected void postCodeGenCleanUp() {} + protected void additionalCodeGen( PrintWriter outmethodheader, + PrintWriter outstructs, + PrintWriter outmethod ) {} + protected void additionalCodeAtTopOfMain( PrintWriter outmethod ) {} + protected void additionalCodeAtBottomOfMain( PrintWriter outmethod ) {} + protected void additionalIncludesMethodsImplementation( PrintWriter outmethod ) {} + protected void additionalIncludesStructsHeader( PrintWriter outstructs ) {} + protected void additionalClassObjectFields( PrintWriter outclassdefs ) {} + protected void additionalCodeAtTopMethodsImplementation( PrintWriter outmethod ) {} + protected void additionalCodeAtTopFlatMethodBody( PrintWriter output, FlatMethod fm ) {} + protected void additionalCodePreNode( FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output ) {} + protected void additionalCodePostNode( FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output ) {} } diff --git a/Robust/src/IR/Flat/BuildOoOJavaCode.java b/Robust/src/IR/Flat/BuildOoOJavaCode.java new file mode 100644 index 00000000..d9dbadda --- /dev/null +++ b/Robust/src/IR/Flat/BuildOoOJavaCode.java @@ -0,0 +1,2031 @@ +package IR.Flat; +import IR.Tree.Modifiers; +import IR.Tree.FlagExpressionNode; +import IR.Tree.DNFFlag; +import IR.Tree.DNFFlagAtom; +import IR.Tree.TagExpressionList; +import IR.Tree.OffsetNode; +import IR.*; + +import java.util.*; +import java.io.*; + +import Util.Relation; +import Analysis.TaskStateAnalysis.FlagState; +import Analysis.TaskStateAnalysis.FlagComparator; +import Analysis.TaskStateAnalysis.OptionalTaskDescriptor; +import Analysis.TaskStateAnalysis.Predicate; +import Analysis.TaskStateAnalysis.SafetyAnalysis; +import Analysis.TaskStateAnalysis.TaskIndex; +import Analysis.Locality.LocalityAnalysis; +import Analysis.Locality.LocalityBinding; +import Analysis.Locality.DiscoverConflicts; +import Analysis.Locality.DCWrapper; +import Analysis.Locality.DelayComputation; +import Analysis.Locality.BranchAnalysis; +import Analysis.CallGraph.CallGraph; +import Analysis.Disjoint.AllocSite; +import Analysis.Disjoint.Effect; +import Analysis.Disjoint.ReachGraph; +import Analysis.Disjoint.Taint; +import Analysis.OoOJava.OoOJavaAnalysis; +import Analysis.OoOJava.SESEandAgePair; +import Analysis.OoOJava.VariableSourceToken; +import Analysis.OoOJava.CodePlan; +import Analysis.OoOJava.ConflictNode; +import Analysis.OoOJava.SESEWaitingQueue; +import Analysis.OoOJava.VSTWrapper; +import Analysis.Prefetch.*; +import Analysis.Loops.WriteBarrier; +import Analysis.Loops.GlobalFieldType; +import Analysis.Locality.TypeAnalysis; +import Util.CodePrinter; + +public class BuildOoOJavaCode extends BuildCode { + + OoOJavaAnalysis oooa; + + String maxTaskRecSizeStr="__maxTaskRecSize___"; + + String mlperrstr = + "if(status != 0) { "+ + "sprintf(errmsg, \"MLP error at %s:%d\", __FILE__, __LINE__); "+ + "perror(errmsg); exit(-1); }"; + + boolean nonSESEpass = true; + + RuntimeConflictResolver rcr = null; + + public BuildOoOJavaCode( State st, + Hashtable temptovar, + TypeUtil typeutil, + SafetyAnalysis sa, + PrefetchAnalysis pa, + OoOJavaAnalysis oooa + ) { + + super( st, temptovar, typeutil, sa, pa ); + + this.oooa = oooa; + } + + + protected void additionalIncludesMethodsHeader( PrintWriter outmethodheader ) { + + outmethodheader.println("#include "); + outmethodheader.println("#include "); + outmethodheader.println("#include "); + outmethodheader.println("#include \"mlp_runtime.h\""); + outmethodheader.println("#include \"psemaphore.h\""); + outmethodheader.println("#include \"memPool.h\""); + + if (state.RCR) { + outmethodheader.println("#include \"rcr_runtime.h\""); + } + + // spit out a global to inform all worker threads with + // the maximum size is for any task record + outmethodheader.println("extern int "+maxTaskRecSizeStr+";"); + } + + + protected void preCodeGenInitialization() { + + // have to initialize some SESE compiler data before + // analyzing normal methods, which must happen before + // generating SESE internal code + + Iterator seseit = oooa.getAllSESEs().iterator(); + + //TODO signal the object that will report errors + if( state.RCR ) { + try { + rcr = new RuntimeConflictResolver( PREFIX, + oooa, + oooa.getDisjointAnalysis().getEffectsAnalysis().getAllEffects(), + state ); + System.out.println("Runtime Conflict Resolver started."); + } catch (FileNotFoundException e) { + System.out.println("Runtime Conflict Resolver could not create output file."); + } + } + + while( seseit.hasNext() ) { + FlatSESEEnterNode fsen = seseit.next(); + initializeSESE( fsen ); + } + } + + + protected void postCodeGenCleanUp() { + if(rcr != null) { + rcr.close(); + System.out.println("Runtime Conflict Resolver Done."); + } + } + + + protected void additionalCodeGen( PrintWriter outmethodheader, + PrintWriter outstructs, + PrintWriter outmethod ) { + + // Output function prototypes and structures for SESE's and code + + // spit out a global to inform all worker threads with + // the maximum size is for any task record + outmethod.println("int "+maxTaskRecSizeStr+" = 0;"); + + // used to differentiate, during code generation, whether we are + // passing over SESE body code, or non-SESE code + nonSESEpass = false; + + // first generate code for each sese's internals + Iterator seseit; + seseit=oooa.getAllSESEs().iterator(); + + while( seseit.hasNext() ) { + FlatSESEEnterNode fsen = seseit.next(); + generateMethodSESE( fsen, null, outstructs, outmethodheader, outmethod ); + } + + // then write the invokeSESE switch to decouple scheduler + // from having to do unique details of sese invocation + generateSESEinvocationMethod( outmethodheader, outmethod ); + } + + + protected void additionalCodeAtTopOfMain( PrintWriter outmethod ) { + + // do a calculation to determine which task record + // is the largest, store that as a global value for + // allocating records + Iterator seseit = oooa.getAllSESEs().iterator(); + while( seseit.hasNext() ) { + FlatSESEEnterNode fsen = seseit.next(); + outmethod.println("if( sizeof( "+fsen.getSESErecordName()+ + " ) > "+maxTaskRecSizeStr+ + " ) { "+maxTaskRecSizeStr+ + " = sizeof( "+fsen.getSESErecordName()+ + " ); }" ); + } + + outmethod.println(" runningSESE = NULL;"); + + outmethod.println(" workScheduleInit( "+state.OOO_NUMCORES+", invokeSESEmethod );"); + + //initializes data structures needed for the RCR traverser + if( state.RCR && rcr != null ) { + outmethod.println(" initializeStructsRCR();"); + outmethod.println(" createAndFillMasterHashStructureArray();"); + } + } + + + protected void additionalCodeAtBottomOfMain( PrintWriter outmethod ) { + outmethod.println(" workScheduleBegin();"); + } + + + protected void additionalIncludesMethodsImplementation( PrintWriter outmethod ) { + outmethod.println("#include "); + outmethod.println("#include "); + outmethod.println("#include \"mlp_runtime.h\""); + outmethod.println("#include \"psemaphore.h\""); + + if( state.RCR ) { + outmethod.println("#include \"trqueue.h\""); + outmethod.println("#include \"RuntimeConflictResolver.h\""); + outmethod.println("#include \"rcr_runtime.h\""); + outmethod.println("#include \"hashStructure.h\""); + } + } + + + protected void additionalIncludesStructsHeader( PrintWriter outstructs ) { + outstructs.println("#include \"mlp_runtime.h\""); + outstructs.println("#include \"psemaphore.h\""); + if( state.RCR ) { + outstructs.println("#include \"rcr_runtime.h\""); + } + } + + + protected void additionalClassObjectFields( PrintWriter outclassdefs ) { + outclassdefs.println(" int oid;"); + outclassdefs.println(" int allocsite;"); + } + + + protected void additionalCodeAtTopMethodsImplementation( PrintWriter outmethod ) { + outmethod.print("extern __thread int oid;\n"); + outmethod.print("extern int oidIncrement;\n"); + } + + + protected void additionalCodeAtTopFlatMethodBody( PrintWriter output, FlatMethod fm ) { + + // TODO!!!!!!!!! + // if( fm.getNext(0) instanceof FlatSESEEnterNode ) { + // FlatSESEEnterNode callerSESEplaceholder = (FlatSESEEnterNode) fm.getNext( 0 ); + // if( callerSESEplaceholder != oooa.getMainSESE() ) { + // // declare variables for naming static SESE's + // output.println(" /* static SESE names */"); + // Iterator pItr = callerSESEplaceholder.getNeededStaticNames().iterator(); + // while( pItr.hasNext() ) { + // SESEandAgePair pair = pItr.next(); + // output.println(" void* "+pair+" = NULL;"); + // } + // + // // declare variables for tracking dynamic sources + // output.println(" /* dynamic variable sources */"); + // Iterator dynSrcItr = callerSESEplaceholder.getDynamicVarSet().iterator(); + // while( dynSrcItr.hasNext() ) { + // TempDescriptor dynSrcVar = dynSrcItr.next(); + // output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;"); + // output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;"); + // } + // } + // } + // + // // set up related allocation sites's waiting queues + // // eom + // + // FlatSESEEnterNode callerSESEplaceholder = (FlatSESEEnterNode) fm.getNext( 0 ); + // if(callerSESEplaceholder!= oooa.getMainSESE()){ + // Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(callerSESEplaceholder); + // if (graph != null && graph.hasConflictEdge()) { + // output.println(" // set up waiting queues "); + // output.println(" int numMemoryQueue=0;"); + // output.println(" int memoryQueueItemID=0;"); + // Set lockSet = oooa.getLockMappings(graph); + // System.out.println("#lockSet="+lockSet.hashCode()); + // System.out.println("lockset="+lockSet); + // for (Iterator iterator = lockSet.iterator(); iterator.hasNext();) { + // Analysis.OoOJava.SESELock seseLock = (Analysis.OoOJava.SESELock) iterator.next(); + // System.out.println("id="+seseLock.getID()); + // System.out.println("#="+seseLock); + // } + // System.out.println("size="+lockSet.size()); + // if (lockSet.size() > 0) { + // output.println(" numMemoryQueue=" + lockSet.size() + ";"); + // output.println(" runningSESE->numMemoryQueue=numMemoryQueue;"); + // output.println(" runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);"); + // output.println(); + // } + // } + // } + // + // + } + + + protected void initializeSESE( FlatSESEEnterNode fsen ) { + + FlatMethod fm = fsen.getfmEnclosing(); + MethodDescriptor md = fm.getMethod(); + ClassDescriptor cn = md.getClassDesc(); + + + // Creates bogus method descriptor to index into tables + Modifiers modBogus = new Modifiers(); + MethodDescriptor mdBogus = + new MethodDescriptor( modBogus, + new TypeDescriptor( TypeDescriptor.VOID ), + "sese_"+fsen.getPrettyIdentifier()+fsen.getIdentifier() + ); + + mdBogus.setClassDesc( fsen.getcdEnclosing() ); + FlatMethod fmBogus = new FlatMethod( mdBogus, null ); + fsen.setfmBogus( fmBogus ); + fsen.setmdBogus( mdBogus ); + + Set inSetAndOutSet = new HashSet(); + inSetAndOutSet.addAll( fsen.getInVarSet() ); + inSetAndOutSet.addAll( fsen.getOutVarSet() ); + + // Build paramsobj for bogus method descriptor + ParamsObject objectparams = new ParamsObject( mdBogus, tag++ ); + paramstable.put( mdBogus, objectparams ); + + Iterator itr = inSetAndOutSet.iterator(); + while( itr.hasNext() ) { + TempDescriptor temp = itr.next(); + TypeDescriptor type = temp.getType(); + if( type.isPtr() ) { + objectparams.addPtr( temp ); + } else { + objectparams.addPrim( temp ); + } + } + + // Build normal temp object for bogus method descriptor + TempObject objecttemps = new TempObject( objectparams, mdBogus, tag++ ); + tempstable.put( mdBogus, objecttemps ); + + for( Iterator nodeit = fsen.getNodeSet().iterator(); nodeit.hasNext(); ) { + FlatNode fn = (FlatNode)nodeit.next(); + TempDescriptor[] writes = fn.writesTemps(); + + for( int i = 0; i < writes.length; i++ ) { + TempDescriptor temp = writes[i]; + TypeDescriptor type = temp.getType(); + + if( type.isPtr() ) { + objecttemps.addPtr( temp ); + } else { + objecttemps.addPrim( temp ); + } + } + } + } + + // used when generating the specific SESE record struct + // to remember the FIRST field name of sese records + // that the current SESE depends on--we need to know the + // offset to the first one for garbage collection + protected void addingDepRecField( FlatSESEEnterNode fsen, + String field ) { + if( fsen.getFirstDepRecField() == null ) { + fsen.setFirstDepRecField( field ); + } + fsen.incNumDepRecs(); + } + + protected void generateMethodSESE(FlatSESEEnterNode fsen, + LocalityBinding lb, + PrintWriter outputStructs, + PrintWriter outputMethHead, + PrintWriter outputMethods + ) { + + ParamsObject objectparams = (ParamsObject) paramstable.get( fsen.getmdBogus() ); + TempObject objecttemps = (TempObject) tempstable .get( fsen.getmdBogus() ); + + // generate locals structure + outputStructs.println("struct "+ + fsen.getcdEnclosing().getSafeSymbol()+ + fsen.getmdBogus().getSafeSymbol()+"_"+ + fsen.getmdBogus().getSafeMethodDescriptor()+ + "_locals {"); + outputStructs.println(" int size;"); + outputStructs.println(" void * next;"); + for(int i=0; i inSetAndOutSet = new HashSet(); + inSetAndOutSet.addAll( fsen.getInVarSet() ); + inSetAndOutSet.addAll( fsen.getOutVarSet() ); + + Set inSetAndOutSetObjs = new HashSet(); + Set inSetAndOutSetPrims = new HashSet(); + + Iterator itr = inSetAndOutSet.iterator(); + while( itr.hasNext() ) { + TempDescriptor temp = itr.next(); + TypeDescriptor type = temp.getType(); + if( type.isPtr() ) { + inSetAndOutSetObjs.add( temp ); + } else { + inSetAndOutSetPrims.add( temp ); + } + } + + + // generate the SESE record structure + outputStructs.println(fsen.getSESErecordName()+" {"); + + // data common to any SESE, and it must be placed first so + // a module that doesn't know what kind of SESE record this + // is can cast the pointer to a common struct + outputStructs.println(" SESEcommon common;"); + + // then garbage list stuff + outputStructs.println(" /* next is in-set and out-set objects that look like a garbage list */"); + outputStructs.println(" int size;"); + outputStructs.println(" void * next;"); + + // I think that the set of TempDescriptors inSetAndOutSetObjs + // calculated above should match the pointer object params + // used in the following code, but let's just leave the working + // implementation unless there is actually a problem... + + Vector inset=fsen.getInVarsForDynamicCoarseConflictResolution(); + for(int i=0; i itrPrims = inSetAndOutSetPrims.iterator(); + while( itrPrims.hasNext() ) { + TempDescriptor temp = itrPrims.next(); + TypeDescriptor type = temp.getType(); + if(type.isPrimitive()){ + outputStructs.println(" "+temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol()+"; /* in-set or out-set primitive */"); + } + } + + // note that the sese record pointer will be added below, just primitive part of tracking here + Iterator itrDynInVars = fsen.getDynamicInVarSet().iterator(); + while( itrDynInVars.hasNext() ) { + TempDescriptor dynInVar = itrDynInVars.next(); + outputStructs.println(" INTPTR "+dynInVar+"_srcOffset; /* dynamic tracking primitive */"); + } + + + outputStructs.println(" /* everything after this should be pointers to an SESE record */" ); + + // other half of info for dynamic tracking, the SESE record pointer + itrDynInVars = fsen.getDynamicInVarSet().iterator(); + while( itrDynInVars.hasNext() ) { + TempDescriptor dynInVar = itrDynInVars.next(); + String depRecField = dynInVar+"_srcSESE"; + outputStructs.println(" SESEcommon* "+depRecField+";"); + addingDepRecField( fsen, depRecField ); + } + + // statically known sese sources are record pointers, too + Iterator itrStaticInVarSrcs = fsen.getStaticInVarSrcs().iterator(); + while( itrStaticInVarSrcs.hasNext() ) { + SESEandAgePair srcPair = itrStaticInVarSrcs.next(); + outputStructs.println(" "+srcPair.getSESE().getSESErecordName()+"* "+srcPair+";"); + addingDepRecField(fsen, srcPair.toString()); + } + + if (state.RCR) { + if (inset.size()!=0) + outputStructs.println("struct rcrRecord rcrRecords["+inset.size()+"];"); + } + + if( fsen.getFirstDepRecField() != null ) { + outputStructs.println(" /* compiler believes first dependent SESE record field above is: "+ + fsen.getFirstDepRecField()+" */" ); + } + outputStructs.println("};\n"); + + + // write method declaration to header file + outputMethHead.print("void "); + outputMethHead.print(fsen.getSESEmethodName()+"("); + outputMethHead.print(fsen.getSESErecordName()+"* "+paramsprefix); + outputMethHead.println(");\n"); + + + generateFlatMethodSESE( fsen.getfmBogus(), + fsen.getcdEnclosing(), + fsen, + fsen.getFlatExit(), + outputMethods ); + } + + private void generateFlatMethodSESE(FlatMethod fm, + ClassDescriptor cn, + FlatSESEEnterNode fsen, + FlatSESEExitNode seseExit, + PrintWriter output + ) { + + MethodDescriptor md=fm.getMethod(); + + output.print("void "); + output.print(fsen.getSESEmethodName()+"("); + output.print(fsen.getSESErecordName()+"* "+paramsprefix); + output.println("){\n"); + + + TempObject objecttemp=(TempObject) tempstable.get(md); + + if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { + output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={"); + output.print(objecttemp.numPointers()+","); + output.print("&(((SESEcommon*)(___params___))[1])"); + for(int j=0; j pItr = fsen.getNeededStaticNames().iterator(); + //while( pItr.hasNext() ) { + // SESEandAgePair pair = pItr.next(); + // output.println(" SESEcommon* "+pair+" = NULL;"); + //} + // + //// declare variables for tracking dynamic sources + //output.println(" /* dynamic variable sources */"); + //Iterator dynSrcItr = fsen.getDynamicVarSet().iterator(); + //while( dynSrcItr.hasNext() ) { + // TempDescriptor dynSrcVar = dynSrcItr.next(); + // output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;"); + // output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;"); + //} + + // declare local temps for in-set primitives, and if it is + // a ready-source variable, get the value from the record + output.println(" /* local temps for in-set primitives */"); + Iterator itrInSet = fsen.getInVarSet().iterator(); + while( itrInSet.hasNext() ) { + TempDescriptor temp = itrInSet.next(); + TypeDescriptor type = temp.getType(); + if( !type.isPtr() ) { + if( fsen.getReadyInVarSet().contains( temp ) ) { + output.println(" "+type+" "+temp+" = "+paramsprefix+"->"+temp+";"); + } else { + output.println(" "+type+" "+temp+";"); + } + } + } + + // declare local temps for out-set primitives if its not already + // in the in-set, and it's value will get written so no problem + output.println(" /* local temp for out-set prim, not already in the in-set */"); + Iterator itrOutSet = fsen.getOutVarSet().iterator(); + while( itrOutSet.hasNext() ) { + TempDescriptor temp = itrOutSet.next(); + TypeDescriptor type = temp.getType(); + if( !type.isPtr() && !fsen.getInVarSet().contains( temp ) ) { + output.println(" "+type+" "+temp+";"); + } + } + + + // initialize thread-local var to a the task's record, which is fused + // with the param list + output.println(" "); + output.println(" // code of this task's body should use this to access the running task record"); + output.println(" runningSESE = &(___params___->common);"); + output.println(" childSESE = 0;"); + output.println(" "); + + // setup memory queue + // eom + if(state.OOOJAVA){ + output.println(" // set up memory queues "); + output.println(" int numMemoryQueue=0;"); + output.println(" int memoryQueueItemID=0;"); + Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(fsen); + if (graph != null && graph.hasConflictEdge()) { + output.println(" {"); + Set lockSet = oooa.getLockMappings(graph); + System.out.println("#lockSet="+lockSet); + if (lockSet.size() > 0) { + output.println(" numMemoryQueue=" + lockSet.size() + ";"); + output.println(" runningSESE->numMemoryQueue=numMemoryQueue;"); + output.println(" runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);"); + output.println(); + } + output.println(" }"); + } + } + + + // set up a task's mem pool to recycle the allocation of children tasks + // don't bother if the task never has children (a leaf task) + output.println( "#ifndef OOO_DISABLE_TASKMEMPOOL" ); + if( !fsen.getIsLeafSESE() ) { + output.println(" runningSESE->taskRecordMemPool = poolcreate( "+ + maxTaskRecSizeStr+", freshTaskRecordInitializer );"); + if (state.RCR && !rcr.hasEmptyTraversers(fsen)) { + output.println(" createTR();"); + output.println(" runningSESE->allHashStructures=TRqueue->allHashStructures;"); + } + } else { + // make it clear we purposefully did not initialize this + output.println(" runningSESE->taskRecordMemPool = (MemPool*)0x7;"); + } + output.println( "#endif // OOO_DISABLE_TASKMEMPOOL" ); + + + // copy in-set into place, ready vars were already + // copied when the SESE was issued + Iterator tempItr; + + // static vars are from a known SESE + output.println(" // copy variables from static sources"); + tempItr = fsen.getStaticInVarSet().iterator(); + while( tempItr.hasNext() ) { + TempDescriptor temp = tempItr.next(); + VariableSourceToken vst = fsen.getStaticInVarSrc( temp ); + SESEandAgePair srcPair = new SESEandAgePair( vst.getSESE(), vst.getAge() ); + output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+ + " = "+paramsprefix+"->"+srcPair+"->"+vst.getAddrVar()+";"); + } + + output.println(" // decrement references to static sources"); + for( Iterator pairItr = fsen.getStaticInVarSrcs().iterator(); pairItr.hasNext(); ) { + SESEandAgePair srcPair = pairItr.next(); + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" {"); + output.println(" SESEcommon* src = &("+paramsprefix+"->"+srcPair+"->common);"); + output.println(" RELEASE_REFERENCE_TO( src );"); + output.println(" }"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + } + + + // dynamic vars come from an SESE and src + output.println(" // copy variables from dynamic sources"); + 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 ) {"); + + 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 )+ + " = *(("+typeStr+"*) ((void*)"+ + paramsprefix+"->"+temp+"_srcSESE + "+ + paramsprefix+"->"+temp+"_srcOffset));"); + + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" SESEcommon* src = "+paramsprefix+"->"+temp+"_srcSESE;"); + output.println(" RELEASE_REFERENCE_TO( src );"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + + // or if the source was our parent, its already in our record to grab + output.println(" } else {"); + output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+ + " = "+paramsprefix+"->"+temp+";"); + output.println(" }"); + } + + // Check to see if we need to do a GC if this is a + // multi-threaded program... + if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { + output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");"); + //Don't bother if we aren't in recursive methods...The loops case will catch it +// if (callgraph.getAllMethods(md).contains(md)) { +// if(this.state.MULTICOREGC) { +// output.println("if(gcflag) gc("+localsprefixaddr+");"); +// } else { +// output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");"); +// } +// } + } + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKEXECUTE"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKEXECUTE, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } + + HashSet exitset=new HashSet(); + exitset.add(seseExit); + generateCode(fsen.getNext(0), fm, null, exitset, output, true); + output.println("}\n\n"); + + } + + + // when a new mlp thread is created for an issued SESE, it is started + // by running this method which blocks on a cond variable until + // it is allowed to transition to execute. Then a case statement + // allows it to invoke the method with the proper SESE body, and after + // exiting the SESE method, executes proper SESE exit code before the + // thread can be destroyed + private void generateSESEinvocationMethod(PrintWriter outmethodheader, + PrintWriter outmethod + ) { + + outmethodheader.println("void* invokeSESEmethod( void* seseRecord );"); + outmethod.println( "void* invokeSESEmethod( void* seseRecord ) {"); + outmethod.println( " int status;"); + outmethod.println( " char errmsg[128];"); + + // generate a case for each SESE class that can be invoked + outmethod.println( " switch( ((SESEcommon*)seseRecord)->classID ) {"); + outmethod.println( " "); + Iterator seseit; + seseit=oooa.getAllSESEs().iterator(); + + while(seseit.hasNext()){ + FlatSESEEnterNode fsen = seseit.next(); + + outmethod.println( " /* "+fsen.getPrettyIdentifier()+" */"); + outmethod.println( " case "+fsen.getIdentifier()+":"); + outmethod.println( " "+fsen.getSESEmethodName()+"( seseRecord );"); + + if( fsen.equals( oooa.getMainSESE() ) ) { + outmethod.println( " workScheduleExit();"); + } + + outmethod.println( " break;"); + outmethod.println( ""); + } + + // default case should never be taken, error out + outmethod.println( " default:"); + outmethod.println( " printf(\"Error: unknown SESE class ID in invoke method.\\n\");"); + outmethod.println( " exit(-30);"); + outmethod.println( " break;"); + outmethod.println( " }"); + outmethod.println( " return NULL;"); + outmethod.println( "}\n\n"); + } + + + + void stallMEMRCR(FlatMethod fm, FlatNode fn, Set waitingElementSet, PrintWriter output) { + output.println("// stall on parent's stall sites "); + output.println(" {"); + output.println(" REntry* rentry;"); + output.println(" // stallrecord sometimes is used as a task record for instance "); + output.println(" // when you call RELEASE_REFERENCE_TO on a stall record."); + output.println(" // so the parent field must be initialized."); + output.println(" SESEstall * stallrecord=(SESEstall *) poolalloc(runningSESE->taskRecordMemPool);"); + output.println(" stallrecord->common.parent=runningSESE;"); + output.println(" stallrecord->common.unresolvedDependencies=10000;"); + output.println(" stallrecord->common.rcrstatus=1;"); + output.println(" stallrecord->common.offsetToParamRecords=(INTPTR) & (((SESEstall *)0)->rcrRecords);"); + output.println(" stallrecord->common.refCount = 10003;"); + output.println(" int localCount=10000;"); + output.println(" stallrecord->rcrRecords[0].index=0;"); + output.println(" stallrecord->rcrRecords[0].flag=0;"); + output.println(" stallrecord->rcrRecords[0].next=NULL;"); + output.println(" stallrecord->common.parentsStallSem=&runningSESEstallSem;"); + output.println(" psem_reset( &runningSESEstallSem);"); + output.println(" stallrecord->tag=runningSESEstallSem.tag;"); + + TempDescriptor stalltd=null; + for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) { + Analysis.OoOJava.WaitingElement waitingElement =(Analysis.OoOJava.WaitingElement) iterator.next(); + if (waitingElement.getStatus() >= ConflictNode.COARSE) { + output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray[" + + waitingElement.getQueueID() + "]," + waitingElement.getStatus() + + ", (SESEcommon *) stallrecord, 1LL);"); + } else { + throw new Error("Fine-grained conflict: This should not happen in RCR"); + } + output.println(" rentry->queue=runningSESE->memoryQueueArray[" + + waitingElement.getQueueID() + "];"); + output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray[" + + waitingElement.getQueueID() + "],rentry)==NOTREADY) {"); + output.println(" localCount--;"); + output.println(" }"); + output.println("#if defined(RCR)&&!defined(OOO_DISABLE_TASKMEMPOOL)"); + output.println(" else poolfreeinto(runningSESE->memoryQueueArray["+waitingElement.getQueueID()+"]->rentrypool, rentry);"); + output.println("#endif"); + if (stalltd==null) { + stalltd=waitingElement.getTempDesc(); + } else if (stalltd!=waitingElement.getTempDesc()) { + throw new Error("Multiple temp descriptors at stall site"+stalltd+"!="+waitingElement.getTempDesc()); + } + } + + //did all of the course grained stuff + output.println(" if(!atomic_sub_and_test(localCount, &(stallrecord->common.unresolvedDependencies))) {"); + //have to do fine-grained work also + output.println(" stallrecord->___obj___=(struct ___Object___ *)" + + generateTemp(fm, stalltd, null) + ";"); + output.println(" stallrecord->common.classID=-" + + rcr.getTraverserID(stalltd, fn) + ";"); + + output.println(" enqueueTR(TRqueue, (void *)stallrecord);"); + + if (state.COREPROF) { + output.println("#ifdef CP_EVENTID_TASKSTALLMEM"); + output + .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } + + output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );"); + + if (state.COREPROF) { + output.println("#ifdef CP_EVENTID_TASKSTALLMEM"); + output + .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );"); + output.println("#endif"); + } + + output.println(" } else {");//exit if condition + //release traversers reference if we didn't use traverser + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL"); + output.println(" RELEASE_REFERENCE_TO((SESEcommon *)stallrecord);"); + output.println("#endif"); + output.println(" }"); + //release our reference to stall record + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL"); + output.println(" RELEASE_REFERENCE_TO((SESEcommon *)stallrecord);"); + output.println("#endif"); + output.println(" }");//exit block + } + + + protected void additionalCodePreNode( FlatMethod fm, + LocalityBinding lb, + FlatNode fn, + PrintWriter output ) { + // insert pre-node actions from the code plan + + CodePlan cp = oooa.getCodePlan(fn); + + if( cp != null ) { + + FlatSESEEnterNode currentSESE = cp.getCurrentSESE(); + + // for each sese and age pair that this parent statement + // must stall on, take that child's stall semaphore, the + // copying of values comes after the statement + Iterator vstItr = cp.getStallTokens().iterator(); + while( vstItr.hasNext() ) { + VariableSourceToken vst = vstItr.next(); + + SESEandAgePair pair = new SESEandAgePair( vst.getSESE(), vst.getAge() ); + + output.println(" {"); + output.println(" "+pair.getSESE().getSESErecordName()+"* child = ("+ + pair.getSESE().getSESErecordName()+"*) "+pair+";"); + + output.println(" SESEcommon* childCom = (SESEcommon*) "+pair+";"); + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKSTALLVAR"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } + + output.println(" pthread_mutex_lock( &(childCom->lock) );"); + output.println(" if( childCom->doneExecuting == FALSE ) {"); + output.println(" psem_reset( &runningSESEstallSem );"); + output.println(" childCom->parentsStallSem = &runningSESEstallSem;"); + output.println(" pthread_mutex_unlock( &(childCom->lock) );"); + output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );"); + output.println(" } else {"); + output.println(" pthread_mutex_unlock( &(childCom->lock) );"); + output.println(" }"); + + // copy things we might have stalled for + Iterator tdItr = cp.getCopySet( vst ).iterator(); + while( tdItr.hasNext() ) { + TempDescriptor td = tdItr.next(); + FlatMethod fmContext; + //if( currentSESE.getIsCallerSESEplaceholder() ) { + // fmContext = currentSESE.getfmEnclosing(); + //} else { + fmContext = currentSESE.getfmBogus(); + //} + output.println(" "+generateTemp( fmContext, td, null )+ + " = child->"+vst.getAddrVar().getSafeSymbol()+";"); + } + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKSTALLVAR"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );"); + output.println("#endif"); + } + + output.println(" }"); + } + + // for each variable with a dynamic source, stall just for that variable + Iterator dynItr = cp.getDynamicStallSet().iterator(); + while( dynItr.hasNext() ) { + TempDescriptor dynVar = dynItr.next(); + + // only stall if the dynamic source is not yourself, denoted by src==NULL + // otherwise the dynamic write nodes will have the local var up-to-date + output.println(" {"); + output.println(" if( "+dynVar+"_srcSESE != NULL ) {"); + + output.println(" SESEcommon* childCom = (SESEcommon*) "+dynVar+"_srcSESE;"); + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKSTALLVAR"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } + + output.println(" pthread_mutex_lock( &(childCom->lock) );"); + output.println(" if( childCom->doneExecuting == FALSE ) {"); + output.println(" psem_reset( &runningSESEstallSem );"); + output.println(" childCom->parentsStallSem = &runningSESEstallSem;"); + output.println(" pthread_mutex_unlock( &(childCom->lock) );"); + output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );"); + output.println(" } else {"); + output.println(" pthread_mutex_unlock( &(childCom->lock) );"); + output.println(" }"); + + FlatMethod fmContext; + //if( currentSESE.getIsCallerSESEplaceholder() ) { + // fmContext = currentSESE.getfmEnclosing(); + //} else { + fmContext = currentSESE.getfmBogus(); + //} + + TypeDescriptor type = dynVar.getType(); + String typeStr; + if( type.isNull() ) { + typeStr = "void*"; + } else if( type.isClass() || type.isArray() ) { + typeStr = "struct "+type.getSafeSymbol()+"*"; + } else { + typeStr = type.getSafeSymbol(); + } + + output.println(" "+generateTemp( fmContext, dynVar, null )+ + " = *(("+typeStr+"*) ((void*)"+ + dynVar+"_srcSESE + "+dynVar+"_srcOffset));"); + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKSTALLVAR"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );"); + output.println("#endif"); + } + + output.println(" }"); + output.println(" }"); + } + + // for each assignment of a variable to rhs that has a dynamic source, + // copy the dynamic sources + Iterator dynAssignItr = cp.getDynAssigns().entrySet().iterator(); + while( dynAssignItr.hasNext() ) { + Map.Entry me = (Map.Entry) dynAssignItr.next(); + TempDescriptor lhs = (TempDescriptor) me.getKey(); + TempDescriptor rhs = (TempDescriptor) me.getValue(); + + output.println(" {"); + output.println(" SESEcommon* oldSrc = "+lhs+"_srcSESE;"); + + output.println(" "+lhs+"_srcSESE = "+rhs+"_srcSESE;"); + output.println(" "+lhs+"_srcOffset = "+rhs+"_srcOffset;"); + + // no matter what we did above, track reference count of whatever + // this variable pointed to, do release last in case we're just + // copying the same value in because 1->2->1 is safe but ref count + // 1->0->1 has a window where it looks like it should be free'd + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" if( "+rhs+"_srcSESE != NULL ) {"); + output.println(" ADD_REFERENCE_TO( "+rhs+"_srcSESE );"); + output.println(" }"); + output.println(" if( oldSrc != NULL ) {"); + output.println(" RELEASE_REFERENCE_TO( oldSrc );"); + output.println(" }"); + output.println(" }"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + } + + // for each lhs that is dynamic from a non-dynamic source, set the + // dynamic source vars to the current SESE + dynItr = cp.getDynAssignCurr().iterator(); + while( dynItr.hasNext() ) { + TempDescriptor dynVar = dynItr.next(); + + // TODO + //assert currentSESE.getDynamicVarSet().contains( dynVar ); + + // first release a reference to current record + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" if( "+dynVar+"_srcSESE != NULL ) {"); + output.println(" RELEASE_REFERENCE_TO( oldSrc );"); + output.println(" }"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + + output.println(" "+dynVar+"_srcSESE = NULL;"); + } + + // eom + // handling stall site + if (state.OOOJAVA) { + Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(currentSESE); + if(graph!=null){ + Set seseLockSet = oooa.getLockMappings(graph); + Set waitingElementSet = graph.getStallSiteWaitingElementSet(fn, seseLockSet); + + if (waitingElementSet.size() > 0) { + if (state.RCR) { + stallMEMRCR(fm, fn, waitingElementSet, output); + } else { + output.println("// stall on parent's stall sites "); + output.println(" {"); + output.println(" REntry* rentry;"); + + for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) { + Analysis.OoOJava.WaitingElement waitingElement = + (Analysis.OoOJava.WaitingElement) iterator.next(); + if (waitingElement.getStatus() >= ConflictNode.COARSE) { + output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray[" + + waitingElement.getQueueID() + "]," + waitingElement.getStatus() + + ", runningSESE);"); + } else { + output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray[" + + waitingElement.getQueueID() + "]," + waitingElement.getStatus() + + ", runningSESE, (void*)&" + + generateTemp(fm, waitingElement.getTempDesc(), lb) + ");"); + } + output.println(" rentry->parentStallSem=&runningSESEstallSem;"); + output.println(" psem_reset( &runningSESEstallSem);"); + output.println(" rentry->tag=runningSESEstallSem.tag;"); + output.println(" rentry->queue=runningSESE->memoryQueueArray[" + + waitingElement.getQueueID() + "];"); + output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray[" + + waitingElement.getQueueID() + "],rentry)==NOTREADY){"); + if (state.COREPROF) { + output.println("#ifdef CP_EVENTID_TASKSTALLMEM"); + output + .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } + + output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );"); + + if (state.COREPROF) { + output.println("#ifdef CP_EVENTID_TASKSTALLMEM"); + output + .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );"); + output.println("#endif"); + } + output.println(" } "); + } + output.println(" }"); + } + } + } + } + } + } + + + protected void additionalCodePostNode( FlatMethod fm, + LocalityBinding lb, + FlatNode fn, + PrintWriter output ) { + + // insert post-node actions from the code-plan (none right now...) + } + + + public void generateFlatSESEEnterNode( FlatMethod fm, + LocalityBinding lb, + FlatSESEEnterNode fsen, + PrintWriter output ) { + + // there may be an SESE in an unreachable method, skip over + if( !oooa.getAllSESEs().contains(fsen) ) { + return; + } + + // also, if we have encountered a placeholder, just skip it + //if( fsen.getIsCallerSESEplaceholder() ) { + // return; + //} + + output.println(" {"); + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKDISPATCH"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKDISPATCH, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } + + + // before doing anything, lock your own record and increment the running children + if( fsen != oooa.getMainSESE() ) { + output.println(" childSESE++;"); + } + + // allocate the space for this record + output.println( "#ifndef OOO_DISABLE_TASKMEMPOOL" ); + + output.println( "#ifdef CP_EVENTID_POOLALLOC"); + output.println( " CP_LOGEVENT( CP_EVENTID_POOLALLOC, CP_EVENTTYPE_BEGIN );"); + output.println( "#endif"); + if( fsen != oooa.getMainSESE() ) { + output.println(" "+ + fsen.getSESErecordName()+"* seseToIssue = ("+ + fsen.getSESErecordName()+"*) poolalloc( runningSESE->taskRecordMemPool );"); + output.println(" CHECK_RECORD( seseToIssue );"); + } else { + output.println(" "+ + fsen.getSESErecordName()+"* seseToIssue = ("+ + fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+ + fsen.getSESErecordName()+" ) );"); + } + output.println( "#ifdef CP_EVENTID_POOLALLOC"); + output.println( " CP_LOGEVENT( CP_EVENTID_POOLALLOC, CP_EVENTTYPE_END );"); + output.println( "#endif"); + + output.println( "#else // OOO_DISABLE_TASKMEMPOOL" ); + output.println(" "+ + fsen.getSESErecordName()+"* seseToIssue = ("+ + fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+ + fsen.getSESErecordName()+" ) );"); + output.println( "#endif // OOO_DISABLE_TASKMEMPOOL" ); + + + // set up the SESE in-set and out-set objects, which look + // like a garbage list + output.println(" struct garbagelist * gl= (struct garbagelist *)&(((SESEcommon*)(seseToIssue))[1]);"); + output.println(" gl->size="+calculateSizeOfSESEParamList(fsen)+";"); + output.println(" gl->next = NULL;"); + output.println(" seseToIssue->common.rentryIdx=0;"); + + if(state.RCR) { + //flag the SESE status as 1...it will be reset + output.println(" seseToIssue->common.rcrstatus=1;"); + } + + // there are pointers to SESE records the newly-issued SESE + // will use to get values it depends on them for--how many + // are there, and what is the offset from the total SESE + // record to the first dependent record pointer? + output.println(" seseToIssue->common.numDependentSESErecords="+ + fsen.getNumDepRecs()+";"); + + // we only need this (and it will only compile) when the number of dependent + // SESE records is non-zero + if( fsen.getFirstDepRecField() != null ) { + output.println(" seseToIssue->common.offsetToDepSESErecords=(INTPTR)sizeof("+ + fsen.getSESErecordName()+") - (INTPTR)&((("+ + fsen.getSESErecordName()+"*)0)->"+fsen.getFirstDepRecField()+");" + ); + } + + if (state.RCR&&fsen.getInVarsForDynamicCoarseConflictResolution().size()>0) { + output.println(" seseToIssue->common.offsetToParamRecords=(INTPTR) & ((("+fsen.getSESErecordName()+"*)0)->rcrRecords);"); + } + + // fill in common data + output.println(" int localCount=0;"); + output.println(" seseToIssue->common.classID = "+fsen.getIdentifier()+";"); + output.println(" seseToIssue->common.unresolvedDependencies = 10000;"); + output.println(" seseToIssue->common.parentsStallSem = NULL;"); + output.println(" initQueue(&seseToIssue->common.forwardList);"); + output.println(" seseToIssue->common.doneExecuting = FALSE;"); + output.println(" seseToIssue->common.numRunningChildren = 0;"); + output.println( "#ifdef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" pthread_cond_init( &(seseToIssue->common.runningChildrenCond), NULL );"); + output.println("#endif"); + output.println(" seseToIssue->common.parent = runningSESE;"); + // start with refCount = 2, one being the count that the child itself + // will decrement when it retires, to say it is done using its own + // record, and the other count is for the parent that will remember + // the static name of this new child below + if( state.RCR ) { + // if we're using RCR, ref count is 3 because the traverser has + // a reference, too + if( fsen != oooa.getMainSESE() && fsen.getInVarsForDynamicCoarseConflictResolution().size()>0){ + output.println(" seseToIssue->common.refCount = 10003;"); + } else { + output.println(" seseToIssue->common.refCount = 10002;"); + } + output.println(" int refCount=10000;"); + } else { + output.println(" seseToIssue->common.refCount = 2;"); + } + + // all READY in-vars should be copied now and be done with it + Iterator tempItr = fsen.getReadyInVarSet().iterator(); + while( tempItr.hasNext() ) { + TempDescriptor temp = tempItr.next(); + + // when we are issuing the main SESE or an SESE with placeholder + // caller SESE as parent, generate temp child child's eclosing method, + // otherwise use the parent's enclosing method as the context + boolean useParentContext = false; + + if( fsen != oooa.getMainSESE() ) { + assert fsen.getParents() != null; + //if( !fsen.getParent().getIsCallerSESEplaceholder() ) { + useParentContext = true; + //} + } + + /* + if( useParentContext ) { + output.println(" seseToIssue->"+temp+" = "+ + generateTemp( fsen.getParent().getfmBogus(), temp, null )+";"); + } else { + output.println(" seseToIssue->"+temp+" = "+ + generateTemp( fsen.getfmEnclosing(), temp, null )+";"); + } + */ + } + + // before potentially adding this SESE to other forwarding lists, + // create it's lock + output.println( "#ifdef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" pthread_mutex_init( &(seseToIssue->common.lock), NULL );"); + output.println("#endif"); + + if( fsen != oooa.getMainSESE() ) { + // count up outstanding dependencies, static first, then dynamic + Iterator staticSrcsItr = fsen.getStaticInVarSrcs().iterator(); + while( staticSrcsItr.hasNext() ) { + SESEandAgePair srcPair = staticSrcsItr.next(); + output.println(" {"); + output.println(" SESEcommon* src = (SESEcommon*)"+srcPair+";"); + output.println(" pthread_mutex_lock( &(src->lock) );"); + // FORWARD TODO + output.println(" if( !src->doneExecuting ) {"); + output.println(" addNewItem( &src->forwardList, seseToIssue );"); + output.println(" ++(localCount);"); + output.println(" }"); + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" ADD_REFERENCE_TO( src );"); + output.println("#endif" ); + output.println(" pthread_mutex_unlock( &(src->lock) );"); + output.println(" }"); + + // whether or not it is an outstanding dependency, make sure + // to pass the static name to the child's record + output.println(" seseToIssue->"+srcPair+" = "+ + "("+srcPair.getSESE().getSESErecordName()+"*)"+ + srcPair+";"); + } + + // dynamic sources might already be accounted for in the static list, + // so only add them to forwarding lists if they're not already there + Iterator dynVarsItr = fsen.getDynamicInVarSet().iterator(); + while( dynVarsItr.hasNext() ) { + TempDescriptor dynInVar = dynVarsItr.next(); + output.println(" {"); + output.println(" SESEcommon* src = (SESEcommon*)"+dynInVar+"_srcSESE;"); + + // the dynamic source is NULL if it comes from your own space--you can't pass + // the address off to the new child, because you're not done executing and + // might change the variable, so copy it right now + output.println(" if( src != NULL ) {"); + output.println(" pthread_mutex_lock( &(src->lock) );"); + + // FORWARD TODO + + output.println(" if( isEmpty( &src->forwardList ) ||"); + output.println(" seseToIssue != peekItem( &src->forwardList ) ) {"); + output.println(" if( !src->doneExecuting ) {"); + output.println(" addNewItem( &src->forwardList, seseToIssue );"); + output.println(" ++(localCount);"); + output.println(" }"); + output.println(" }"); + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" ADD_REFERENCE_TO( src );"); + output.println("#endif" ); + output.println(" pthread_mutex_unlock( &(src->lock) );"); + output.println(" seseToIssue->"+dynInVar+"_srcOffset = "+dynInVar+"_srcOffset;"); + output.println(" } else {"); + + boolean useParentContext = false; + if( fsen != oooa.getMainSESE() ) { + //assert fsen.getParent() != null; + //if( !fsen.getParent().getIsCallerSESEplaceholder() ) { + useParentContext = true; + //} + } + //if( useParentContext ) { + // output.println(" seseToIssue->"+dynInVar+" = "+ + // generateTemp( fsen.getParent().getfmBogus(), dynInVar, null )+";"); + //} else { + // output.println(" seseToIssue->"+dynInVar+" = "+ + // generateTemp( fsen.getfmEnclosing(), dynInVar, null )+";"); + //} + + output.println(" }"); + output.println(" }"); + + // even if the value is already copied, make sure your NULL source + // gets passed so child knows it already has the dynamic value + output.println(" seseToIssue->"+dynInVar+"_srcSESE = "+dynInVar+"_srcSESE;"); + } + + + + + // maintain pointers for finding dynamic SESE + // instances from static names + // TODO + SESEandAgePair pairNewest = new SESEandAgePair( fsen, 0 ); + SESEandAgePair pairOldest = new SESEandAgePair( fsen, fsen.getOldestAgeToTrack() ); + if( true//fsen.getParent() != null && + //fsen.getParent().getNeededStaticNames().contains( pairNewest ) + ) { + output.println(" {"); + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" SESEcommon* oldest = "+pairOldest+";"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + + for( int i = fsen.getOldestAgeToTrack(); i > 0; --i ) { + SESEandAgePair pair1 = new SESEandAgePair( fsen, i ); + SESEandAgePair pair2 = new SESEandAgePair( fsen, i-1 ); + output.println(" "+pair1+" = "+pair2+";"); + } + output.println(" "+pairNewest+" = &(seseToIssue->common);"); + + // no need to add a reference to whatever is the newest record, because + // we initialized seseToIssue->refCount to *2* + // but release a reference to whatever was the oldest BEFORE the shift + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" if( oldest != NULL ) {"); + output.println(" RELEASE_REFERENCE_TO( oldest );"); + output.println(" }"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + output.println(" }"); + } + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_PREPAREMEMQ"); + output.println(" CP_LOGEVENT( CP_EVENTID_PREPAREMEMQ, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } + + + //////////////// + // count up memory conflict dependencies, + if(state.RCR) { + dispatchMEMRC(fm, lb, fsen, output); + } else if(state.OOOJAVA){ + // NEED TO FIX IT + // assumes that there is only one parent, but it is possible that + // currentSESE has more than one so we need to generate + // conditional case for each parent case + assert fsen.getParents().size()>0; + FlatSESEEnterNode parent = fsen.getParents().iterator().next(); + Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(parent); + if (graph != null && graph.hasConflictEdge()) { + Set seseLockSet = oooa.getLockMappings(graph); + output.println(); + output.println(" //add memory queue element"); + Analysis.OoOJava.SESEWaitingQueue seseWaitingQueue= + graph.getWaitingElementSetBySESEID(fsen.getIdentifier(), seseLockSet); + if(seseWaitingQueue.getWaitingElementSize()>0) { + output.println(" {"); + output.println(" REntry* rentry=NULL;"); + output.println(" INTPTR* pointer=NULL;"); + output.println(" seseToIssue->common.rentryIdx=0;"); + + Set queueIDSet=seseWaitingQueue.getQueueIDSet(); + for (Iterator iterator = queueIDSet.iterator(); iterator.hasNext();) { + Integer key = (Integer) iterator.next(); + int queueID=key.intValue(); + Set waitingQueueSet = + seseWaitingQueue.getWaitingElementSet(queueID); + int enqueueType=seseWaitingQueue.getType(queueID); + if(enqueueType==SESEWaitingQueue.EXCEPTION) { + output.println(" INITIALIZEBUF(runningSESE->memoryQueueArray[" + queueID+ "]);"); + } + for (Iterator iterator2 = waitingQueueSet.iterator(); iterator2.hasNext();) { + Analysis.OoOJava.WaitingElement waitingElement + = (Analysis.OoOJava.WaitingElement) iterator2.next(); + if (waitingElement.getStatus() >= ConflictNode.COARSE) { + output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["+ queueID+ "]," + + waitingElement.getStatus() + + ", &(seseToIssue->common));"); + } else { + TempDescriptor td = waitingElement.getTempDesc(); + // decide whether waiting element is dynamic or static + if (fsen.getDynamicInVarSet().contains(td)) { + // dynamic in-var case + output.println(" pointer=seseToIssue->" + + waitingElement.getDynID() + + "_srcSESE+seseToIssue->" + + waitingElement.getDynID() + + "_srcOffset;"); + output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "]," + + waitingElement.getStatus() + + ", &(seseToIssue->common), pointer );"); + } else if (fsen.getStaticInVarSet().contains(td)) { + // static in-var case + VariableSourceToken vst = fsen.getStaticInVarSrc(td); + if (vst != null) { + + String srcId = "SESE_" + vst.getSESE().getPrettyIdentifier() + + vst.getSESE().getIdentifier() + + "_" + vst.getAge(); + output.println(" pointer=(void*)&seseToIssue->" + + srcId + + "->" + + waitingElement + .getDynID() + + ";"); + output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "]," + + waitingElement.getStatus() + + ", &(seseToIssue->common), pointer );"); + } + } else { + output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "]," + + waitingElement.getStatus() + + ", &(seseToIssue->common), (void*)&seseToIssue->" + + waitingElement.getDynID() + + ");"); + } + } + output.println(" rentry->queue=runningSESE->memoryQueueArray[" + + waitingElement.getQueueID() + + "];"); + + if(enqueueType==SESEWaitingQueue.NORMAL){ + output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;"); + output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray[" + + waitingElement.getQueueID() + + "],rentry)==NOTREADY) {"); + output.println(" localCount++;"); + output.println(" }"); + } else { + output.println(" ADDRENTRYTOBUF(runningSESE->memoryQueueArray[" + waitingElement.getQueueID() + "],rentry);"); + } + } + if(enqueueType!=SESEWaitingQueue.NORMAL){ + output.println(" localCount+=RESOLVEBUF(runningSESE->memoryQueueArray[" + + queueID+ "],&seseToIssue->common);"); + } + } + output.println(" }"); + } + output.println(); + } + } + } + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_PREPAREMEMQ"); + output.println(" CP_LOGEVENT( CP_EVENTID_PREPAREMEMQ, CP_EVENTTYPE_END );"); + output.println("#endif"); + } + + // Enqueue Task Record + if (state.RCR) { + if( fsen != oooa.getMainSESE() && fsen.getInVarsForDynamicCoarseConflictResolution().size()>0){ + output.println(" enqueueTR(TRqueue, (void *)seseToIssue);"); + } + } + + // if there were no outstanding dependencies, issue here + output.println(" if( atomic_sub_and_test(10000-localCount,&(seseToIssue->common.unresolvedDependencies) ) ) {"); + output.println(" workScheduleSubmit( (void*)seseToIssue );"); + output.println(" }"); + + + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKDISPATCH"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKDISPATCH, CP_EVENTTYPE_END );"); + output.println("#endif"); + } + + output.println(" }"); + + } + + + void dispatchMEMRC( FlatMethod fm, + LocalityBinding lb, + FlatSESEEnterNode fsen, + PrintWriter output ) { + // NEED TO FIX IT + // assumes that there is only one parent, but it is possible that + // currentSESE has more than one so we need to generate + // conditional case for each parent case + assert fsen.getParents().size()>0; + FlatSESEEnterNode parent = fsen.getParents().iterator().next(); + Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(parent); + if (graph != null && graph.hasConflictEdge()) { + Set seseLockSet = oooa.getLockMappings(graph); + Analysis.OoOJava.SESEWaitingQueue seseWaitingQueue=graph.getWaitingElementSetBySESEID(fsen.getIdentifier(), seseLockSet); + if(seseWaitingQueue.getWaitingElementSize()>0) { + output.println(" {"); + output.println(" REntry* rentry=NULL;"); + output.println(" INTPTR* pointer=NULL;"); + output.println(" seseToIssue->common.rentryIdx=0;"); + Vector invars=fsen.getInVarsForDynamicCoarseConflictResolution(); + System.out.println(fm.getMethod()+"["+invars+"]"); + + Vector queuetovar=new Vector(); + + for(int i=0;i weset=seseWaitingQueue.getWaitingElementSet(td); + int numqueues=0; + Set queueSet=new HashSet(); + for (Iterator iterator = weset.iterator(); iterator.hasNext();) { + Analysis.OoOJava.WaitingElement we = (Analysis.OoOJava.WaitingElement) iterator.next(); + Integer queueID=new Integer( we.getQueueID()); + if(!queueSet.contains(queueID)){ + numqueues++; + queueSet.add(queueID); + } + } + output.println(" seseToIssue->rcrRecords["+i+"].flag="+numqueues+";"); + output.println(" seseToIssue->rcrRecords["+i+"].index=0;"); + output.println(" seseToIssue->rcrRecords["+i+"].next=NULL;"); + output.println(" int dispCount"+i+"=0;"); + + for (Iterator wtit = weset.iterator(); wtit.hasNext();) { + Analysis.OoOJava.WaitingElement waitingElement = wtit.next(); + int queueID = waitingElement.getQueueID(); + if (queueID >= queuetovar.size()) + queuetovar.setSize(queueID + 1); + Long l = queuetovar.get(queueID); + long val = (l != null) ? l.longValue() : 0; + val = val | (1 << i); + queuetovar.set(queueID, new Long(val)); + } + } + + HashSet generatedqueueentry=new HashSet(); + for(int i=0;i weset=seseWaitingQueue.getWaitingElementSet(td); + for(Iterator wtit=weset.iterator();wtit.hasNext();) { + Analysis.OoOJava.WaitingElement waitingElement=wtit.next(); + int queueID=waitingElement.getQueueID(); + + if(waitingElement.isBogus()){ + continue; + } + + if (generatedqueueentry.contains(queueID)) + continue; + else + generatedqueueentry.add(queueID); + + assert(waitingElement.getStatus()>=ConflictNode.COARSE); + long mask=queuetovar.get(queueID); + output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "]," + waitingElement.getStatus() + ", &(seseToIssue->common), "+mask+"LL);"); + output.println(" rentry->count=2;"); + output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;"); + output.println(" rentry->queue=runningSESE->memoryQueueArray[" + waitingElement.getQueueID()+"];"); + + output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "],rentry)==READY) {"); + for(int j=0;mask!=0;j++) { + if ((mask&1)==1) + output.println(" dispCount"+j+"++;"); + mask=mask>>1; + } + output.println(" } else "); + output.println(" refCount--;"); + + } + + if (fsen.getDynamicInVarSet().contains(td)) { + // dynamic in-var case + //output.println(" pointer=seseToIssue->" + waitingElement.getDynID()+ "_srcSESE+seseToIssue->"+ waitingElement.getDynID()+ "_srcOffset;"); + //output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", &(seseToIssue->common), pointer );"); + } + } + for(int i=0;ircrRecords["+i+"].flag)))"); + output.println(" localCount++;"); + } + output.println(" }"); + } + } + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL"); + output.println(" RELEASE_REFERENCES_TO((SESEcommon *)seseToIssue, refCount);"); + output.println("#endif"); + } + + public void generateFlatSESEExitNode( FlatMethod fm, + LocalityBinding lb, + FlatSESEExitNode fsexn, + PrintWriter output ) { + + // get the enter node for this exit that has meta data embedded + FlatSESEEnterNode fsen = fsexn.getFlatEnter(); + + // there may be an SESE in an unreachable method, skip over + if( !oooa.getAllSESEs().contains( fsen ) ) { + return; + } + + // also, if we have encountered a placeholder, just jump it + //if( fsen.getIsCallerSESEplaceholder() ) { + // return; + //} + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKEXECUTE"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKEXECUTE, CP_EVENTTYPE_END );"); + output.println("#endif"); + } + + output.println(" /* SESE exiting */"); + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKRETIRE"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKRETIRE, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } + + + // this SESE cannot be done until all of its children are done + // so grab your own lock with the condition variable for watching + // that the number of your running children is greater than zero + output.println(" atomic_add(childSESE, &runningSESE->numRunningChildren);"); + output.println(" pthread_mutex_lock( &(runningSESE->lock) );"); + output.println(" if( runningSESE->numRunningChildren > 0 ) {"); + output.println(" stopforgc( (struct garbagelist *)&___locals___ );"); + output.println(" do {"); + output.println(" pthread_cond_wait( &(runningSESE->runningChildrenCond), &(runningSESE->lock) );"); + output.println(" } while( runningSESE->numRunningChildren > 0 );"); + output.println(" restartaftergc();"); + output.println(" }"); + + + // copy out-set from local temps into the sese record + Iterator itr = fsen.getOutVarSet().iterator(); + while( itr.hasNext() ) { + TempDescriptor temp = itr.next(); + + // only have to do this for primitives non-arrays + if( !( + temp.getType().isPrimitive() && !temp.getType().isArray() + ) + ) { + continue; + } + + // have to determine the context enclosing this sese + boolean useParentContext = false; + + if( fsen != oooa.getMainSESE() ) { + assert fsen.getParents() != null; + //if( !fsen.getParent().getIsCallerSESEplaceholder() ) { + useParentContext = true; + //} + } + + String from; + //if( useParentContext ) { + //from = generateTemp( fsen.getParent().getfmBogus(), temp, null ); + //} else { + from = generateTemp( fsen.getfmEnclosing(), temp, null ); + //} + + output.println(" "+paramsprefix+ + "->"+temp.getSafeSymbol()+ + " = "+from+";"); + } + + // mark yourself done, your task data is now read-only + output.println(" runningSESE->doneExecuting = TRUE;"); + + // if parent is stalling on you, let them know you're done + if( fsexn.getFlatEnter() != oooa.getMainSESE() ) { + output.println(" if( runningSESE->parentsStallSem != NULL ) {"); + output.println(" psem_give( runningSESE->parentsStallSem );"); + output.println(" }"); + } + + output.println(" pthread_mutex_unlock( &(runningSESE->lock) );"); + + // decrement dependency count for all SESE's on your forwarding list + + // FORWARD TODO + output.println(" while( !isEmpty( &runningSESE->forwardList ) ) {"); + output.println(" SESEcommon* consumer = (SESEcommon*) getItem( &runningSESE->forwardList );"); + + + if (!state.RCR) { + output.println(" if(consumer->rentryIdx>0){"); + output.println(" // resolved null pointer"); + output.println(" int idx;"); + output.println(" for(idx=0;idxrentryIdx;idx++){"); + output.println(" resolvePointer(consumer->rentryArray[idx]);"); + output.println(" }"); + output.println(" }"); + } + + output.println(" if( atomic_sub_and_test( 1, &(consumer->unresolvedDependencies) ) ){"); + output.println(" workScheduleSubmit( (void*)consumer );"); + output.println(" }"); + output.println(" }"); + + + // clean up its lock element from waiting queue, and decrement dependency count for next SESE block + if( fsen != oooa.getMainSESE() ) { + output.println(); + output.println(" /* check memory dependency*/"); + output.println(" {"); + output.println(" int idx;"); + output.println(" for(idx=0;idx<___params___->common.rentryIdx;idx++){"); + output.println(" REntry* re=___params___->common.rentryArray[idx];"); + output.println(" RETIRERENTRY(re->queue,re);"); + output.println(" }"); + output.println(" }"); + } + + Vector inset=fsen.getInVarsForDynamicCoarseConflictResolution(); + if (state.RCR && inset.size() > 0) { + /* Make sure the running SESE is finished */ + output.println(" if (unlikely(runningSESE->rcrstatus!=0)) {"); + output.println(" if(CAS(&runningSESE->rcrstatus,1,0)==2) {"); + output.println(" while(runningSESE->rcrstatus) {"); + output.println(" BARRIER();"); + output.println(" sched_yield();"); + output.println(" }"); + output.println(" }"); + output.println(" }"); + output.println("{"); + output.println(" int idx,idx2;"); + + output.println(" struct rcrRecord *rec;"); + output + .println(" struct Hashtable_rcr ** hashstruct=runningSESE->parent->allHashStructures;"); + + for (int i = 0; i < inset.size(); i++) { + output.println(" rec=&" + paramsprefix + "->rcrRecords[" + i + "];"); + output.println(" while(rec!=NULL) {"); + output.println(" for(idx2=0;idx2index;idx2++) {"); + + int weaklyConnectedComponentIndex = rcr.getWeakID(inset.get(i), fsen); + + output.println(" rcr_RETIREHASHTABLE(hashstruct[" + weaklyConnectedComponentIndex + + "],&(___params___->common), rec->array[idx2], (BinItem_rcr *) rec->ptrarray[idx2]);"); + + output.println(" }");// exit idx2 for loop + output.println(" rec=rec->next;"); + output.println(" }");// exit rec while loop + } + output.println("}"); + } + + + // a task has variables to track static/dynamic instances + // that serve as sources, release the parent's ref of each + // non-null var of these types + output.println(" // releasing static SESEs"); + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + // TODO + //Iterator pItr = fsen.getNeededStaticNames().iterator(); + //while( pItr.hasNext() ) { + // SESEandAgePair pair = pItr.next(); + // output.println(" if( "+pair+" != NULL ) {"); + // output.println(" RELEASE_REFERENCE_TO( "+pair+" );"); + // output.println(" }"); + //} + //output.println(" // releasing dynamic variable sources"); + //Iterator dynSrcItr = fsen.getDynamicVarSet().iterator(); + //while( dynSrcItr.hasNext() ) { + // TempDescriptor dynSrcVar = dynSrcItr.next(); + // output.println(" if( "+dynSrcVar+"_srcSESE != NULL ) {"); + // output.println(" RELEASE_REFERENCE_TO( "+dynSrcVar+"_srcSESE );"); + // output.println(" }"); + //} + // destroy this task's mempool if it is not a leaf task + if( !fsen.getIsLeafSESE() ) { + output.println(" pooldestroy( runningSESE->taskRecordMemPool );"); + if (state.RCR && fsen.getInVarsForDynamicCoarseConflictResolution().size() > 0 ) { + output.println(" returnTR();"); + } + } + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + + + output.println("{"); + output.println("SESEcommon *myparent=runningSESE->parent;"); + + // if this is not the Main sese (which has no parent) then return + // THIS task's record to the PARENT'S task record pool, and only if + // the reference count is now zero + if( fsen != oooa.getMainSESE() ) { + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" RELEASE_REFERENCE_TO( runningSESE );"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + } else { + // the main task has no parent, just free its record + output.println(" mlpFreeSESErecord( runningSESE );"); + } + + + // last of all, decrement your parent's number of running children + output.println(" if( myparent != NULL ) {"); + output.println(" if( atomic_sub_and_test( 1, &(myparent->numRunningChildren) ) ) {"); + output.println(" pthread_mutex_lock ( &(myparent->lock) );"); + output.println(" pthread_cond_signal ( &(myparent->runningChildrenCond) );"); + output.println(" pthread_mutex_unlock( &(myparent->lock) );"); + output.println(" }"); + output.println(" }"); + + output.println("}"); + + // as this thread is wrapping up the task, make sure the thread-local var + // for the currently running task record references an invalid task + output.println(" runningSESE = (SESEcommon*) 0x1;"); + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKRETIRE"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKRETIRE, CP_EVENTTYPE_END );"); + output.println("#endif"); + } + } + + + public void generateFlatWriteDynamicVarNode( FlatMethod fm, + LocalityBinding lb, + FlatWriteDynamicVarNode fwdvn, + PrintWriter output + ) { + + Hashtable writeDynamic = fwdvn.getVar2src(); + + assert writeDynamic != null; + + Iterator wdItr = writeDynamic.entrySet().iterator(); + while( wdItr.hasNext() ) { + Map.Entry me = (Map.Entry) wdItr.next(); + TempDescriptor refVar = (TempDescriptor) me.getKey(); + VSTWrapper vstW = (VSTWrapper) me.getValue(); + VariableSourceToken vst = vstW.vst; + + output.println(" {"); + output.println(" SESEcommon* oldSrc = "+refVar+"_srcSESE;"); + + if( vst == null ) { + // if there is no given source, this variable is ready so + // mark src pointer NULL to signify that the var is up-to-date + output.println(" "+refVar+"_srcSESE = NULL;"); + } else { + // otherwise we track where it will come from + SESEandAgePair instance = new SESEandAgePair( vst.getSESE(), vst.getAge() ); + output.println(" "+refVar+"_srcSESE = "+instance+";"); + output.println(" "+refVar+"_srcOffset = (INTPTR) &((("+ + vst.getSESE().getSESErecordName()+"*)0)->"+vst.getAddrVar()+");"); + } + + // no matter what we did above, track reference count of whatever + // this variable pointed to, do release last in case we're just + // copying the same value in because 1->2->1 is safe but ref count + // 1->0->1 has a window where it looks like it should be free'd + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" if( "+refVar+"_srcSESE != NULL ) {"); + output.println(" ADD_REFERENCE_TO( "+refVar+"_srcSESE );"); + output.println(" }"); + output.println(" if( oldSrc != NULL ) {"); + output.println(" RELEASE_REFERENCE_TO( oldSrc );"); + output.println(" }"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + + output.println(" }"); + } + } + + + protected void generateFlatNew( FlatMethod fm, + LocalityBinding lb, + FlatNew fn, + PrintWriter output ) { + + if( fn.getType().isArray() ) { + int arrayid = state.getArrayNumber( fn.getType() )+state.numClasses(); + + if( GENERATEPRECISEGC ) { + output.println(generateTemp( fm, fn.getDst(), lb )+ + "=allocate_newarray_mlp("+localsprefixaddr+ + ", "+arrayid+", "+generateTemp( fm, fn.getSize(), lb )+ + ", oid, "+ + oooa.getDisjointAnalysis().getAllocationSiteFromFlatNew( fn ).getUniqueAllocSiteID()+ + ");"); + output.println(" oid += oidIncrement;"); + } else { + output.println(generateTemp( fm, fn.getDst(), lb )+ + "=allocate_newarray("+arrayid+ + ", "+generateTemp( fm, fn.getSize(), lb )+ + ");"); + } + + } else { + // not an array + if( GENERATEPRECISEGC ) { + output.println( generateTemp( fm, fn.getDst(), lb )+ + "=allocate_new_mlp("+localsprefixaddr+ + ", "+fn.getType().getClassDesc().getId()+ + ", oid, "+ + oooa.getDisjointAnalysis().getAllocationSiteFromFlatNew( fn ).getUniqueAllocSiteID()+ + ");"); + output.println(" oid += oidIncrement;"); + } else { + output.println( generateTemp( fm, fn.getDst(), lb )+ + "=allocate_new("+fn.getType().getClassDesc().getId()+ + ");"); + } + } + } + + + private int calculateSizeOfSESEParamList(FlatSESEEnterNode fsen){ + + Set tdSet=new HashSet(); + + for (Iterator iterator = fsen.getInVarSet().iterator(); iterator.hasNext();) { + TempDescriptor tempDescriptor = (TempDescriptor) iterator.next(); + if(!tempDescriptor.getType().isPrimitive() || tempDescriptor.getType().isArray()){ + tdSet.add(tempDescriptor); + } + } + + for (Iterator iterator = fsen.getOutVarSet().iterator(); iterator.hasNext();) { + TempDescriptor tempDescriptor = (TempDescriptor) iterator.next(); + if(!tempDescriptor.getType().isPrimitive() || tempDescriptor.getType().isArray()){ + tdSet.add(tempDescriptor); + } + } + + return tdSet.size(); + } + + private String calculateSizeOfSESEParamSize(FlatSESEEnterNode fsen){ + HashMap map=new HashMap(); + HashSet processed=new HashSet(); + String rtr=""; + + // space for all in and out set primitives + Set inSetAndOutSet = new HashSet(); + inSetAndOutSet.addAll( fsen.getInVarSet() ); + inSetAndOutSet.addAll( fsen.getOutVarSet() ); + + Set inSetAndOutSetPrims = new HashSet(); + + Iterator itr = inSetAndOutSet.iterator(); + while( itr.hasNext() ) { + TempDescriptor temp = itr.next(); + TypeDescriptor type = temp.getType(); + if( !type.isPtr() ) { + inSetAndOutSetPrims.add( temp ); + } + } + + Iterator itrPrims = inSetAndOutSetPrims.iterator(); + while( itrPrims.hasNext() ) { + TempDescriptor temp = itrPrims.next(); + TypeDescriptor type = temp.getType(); + if(type.isPrimitive()){ + Integer count=map.get(type.getSymbol()); + if(count==null){ + count=new Integer(1); + map.put(type.getSymbol(), count); + }else{ + map.put(type.getSymbol(), new Integer(count.intValue()+1)); + } + } + } + + Set keySet=map.keySet(); + for (Iterator iterator = keySet.iterator(); iterator.hasNext();) { + String key = (String) iterator.next(); + rtr+="+sizeof("+key+")*"+map.get(key); + } + return rtr; + } + +} + + + + + + diff --git a/Robust/src/Main/Main.java b/Robust/src/Main/Main.java index d9687ab2..b6263c3a 100644 --- a/Robust/src/Main/Main.java +++ b/Robust/src/Main/Main.java @@ -18,6 +18,7 @@ import IR.Flat.BuildCodeMultiCore; import IR.Flat.BuildCodeMGC; import IR.Flat.BuildFlat; import IR.Flat.BuildCode; +import IR.Flat.BuildOoOJavaCode; import IR.Flat.Inliner; import IR.ClassDescriptor; import IR.State; @@ -515,7 +516,7 @@ public class Main { CallGraph cg = new CallGraph(state); Liveness l = new Liveness(); ArrayReferencees ar = new ArrayReferencees(state); - oooa = new OoOJavaAnalysis(state, tu, cg, l, ar); + oooa = new OoOJavaAnalysis(state, tu, cg, l, ar); } @@ -619,6 +620,8 @@ public class Main { } if(!state.MULTICORE) { + BuildCode bc; + if (state.DSM||state.SINGLETM) { CallGraph callgraph=new CallGraph(state); if (state.PREFETCH) { @@ -628,12 +631,16 @@ public class Main { } LocalityAnalysis la=new LocalityAnalysis(state, callgraph, tu); GenerateConversions gc=new GenerateConversions(la, state); - BuildCode bc=new BuildCode(state, bf.getMap(), tu, la, pa, oooa); - bc.buildCode(); + bc=new BuildCode(state, bf.getMap(), tu, la, pa); } else { - BuildCode bc=new BuildCode(state, bf.getMap(), tu, sa, pa, oooa); - bc.buildCode(); + if( state.OOOJAVA ) { + bc=new BuildOoOJavaCode(state, bf.getMap(), tu, sa, pa, oooa); + } else { + bc=new BuildCode(state, bf.getMap(), tu, sa, pa); + } } + + bc.buildCode(); } System.out.println("Lines="+state.lines); diff --git a/Robust/src/Makefile b/Robust/src/Makefile index 7be05e0b..7120e897 100644 --- a/Robust/src/Makefile +++ b/Robust/src/Makefile @@ -15,6 +15,7 @@ IR/State.class IR/SymbolTable.class IR/TagDescriptor.class \ IR/TagVarDescriptor.class IR/TaskDescriptor.class \ IR/TypeDescriptor.class IR/TypeUtil.class IR/VarDescriptor.class \ IR/Virtual.class IR/Flat/BuildCode.class IR/Flat/BuildFlat.class \ +IR/Flat/BuildOoOJavaCode.class \ IR/Flat/FKind.class IR/Flat/FlatAtomicEnterNode.class \ IR/Flat/FlatAtomicExitNode.class IR/Flat/FlatBackEdge.class \ IR/Flat/FlatCall.class IR/Flat/FlatCastNode.class \ diff --git a/Robust/src/Tests/oooJava/conflict-graph-location/makefile b/Robust/src/Tests/oooJava/conflict-graph-location/makefile index f206390a..b1e14c60 100644 --- a/Robust/src/Tests/oooJava/conflict-graph-location/makefile +++ b/Robust/src/Tests/oooJava/conflict-graph-location/makefile @@ -25,7 +25,7 @@ DISJOINT= -disjoint -disjoint-k 1 -enable-assertions #-disjoint-desire-determini USEOOO= -ooojava 24 2 -ooodebug -squeue USERCR= -ooojava 23 2 -rcr -ooodebug -squeue -BSFLAGS= -justanalyze -64bit -mainclass $(PROGRAM) -heapsize-mb 1024 -garbagestats -noloop -joptimize -debug #-ooodebug-disable-task-mem-pool +BSFLAGS= -mainclass $(PROGRAM) -heapsize-mb 1024 -garbagestats -noloop -joptimize -debug #-ooodebug-disable-task-mem-pool -justanalyze -64bit all: ooo -- 2.34.1