2 import IR.Tree.Modifiers;
3 import IR.Tree.FlagExpressionNode;
4 import IR.Tree.DNFFlag;
5 import IR.Tree.DNFFlagAtom;
6 import IR.Tree.TagExpressionList;
7 import IR.Tree.OffsetNode;
14 import Analysis.TaskStateAnalysis.FlagState;
15 import Analysis.TaskStateAnalysis.FlagComparator;
16 import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
17 import Analysis.TaskStateAnalysis.Predicate;
18 import Analysis.TaskStateAnalysis.SafetyAnalysis;
19 import Analysis.TaskStateAnalysis.TaskIndex;
20 import Analysis.Locality.LocalityAnalysis;
21 import Analysis.Locality.LocalityBinding;
22 import Analysis.Locality.DiscoverConflicts;
23 import Analysis.Locality.DCWrapper;
24 import Analysis.Locality.DelayComputation;
25 import Analysis.Locality.BranchAnalysis;
26 import Analysis.CallGraph.CallGraph;
27 import Analysis.Disjoint.AllocSite;
28 import Analysis.Disjoint.Effect;
29 import Analysis.Disjoint.ReachGraph;
30 import Analysis.Disjoint.Taint;
31 import Analysis.OoOJava.OoOJavaAnalysis;
32 import Analysis.OoOJava.SESEandAgePair;
33 import Analysis.OoOJava.VariableSourceToken;
34 import Analysis.OoOJava.CodePlan;
35 import Analysis.OoOJava.ConflictNode;
36 import Analysis.OoOJava.SESEWaitingQueue;
37 import Analysis.OoOJava.VSTWrapper;
38 import Analysis.Prefetch.*;
39 import Analysis.Loops.WriteBarrier;
40 import Analysis.Loops.GlobalFieldType;
41 import Analysis.Locality.TypeAnalysis;
42 import Util.CodePrinter;
44 public class BuildOoOJavaCode extends BuildCode {
48 String maxTaskRecSizeStr="__maxTaskRecSize___";
52 "sprintf(errmsg, \"MLP error at %s:%d\", __FILE__, __LINE__); "+
53 "perror(errmsg); exit(-1); }";
55 boolean nonSESEpass = true;
57 RuntimeConflictResolver rcr = null;
59 public BuildOoOJavaCode( State st,
67 super( st, temptovar, typeutil, sa, pa );
73 protected void additionalIncludesMethodsHeader( PrintWriter outmethodheader ) {
75 outmethodheader.println("#include <stdlib.h>");
76 outmethodheader.println("#include <stdio.h>");
77 outmethodheader.println("#include <string.h>");
78 outmethodheader.println("#include \"mlp_runtime.h\"");
79 outmethodheader.println("#include \"psemaphore.h\"");
80 outmethodheader.println("#include \"memPool.h\"");
83 outmethodheader.println("#include \"rcr_runtime.h\"");
86 // spit out a global to inform all worker threads with
87 // the maximum size is for any task record
88 outmethodheader.println("extern int "+maxTaskRecSizeStr+";");
92 protected void preCodeGenInitialization() {
94 // have to initialize some SESE compiler data before
95 // analyzing normal methods, which must happen before
96 // generating SESE internal code
98 Iterator<FlatSESEEnterNode> seseit = oooa.getAllSESEs().iterator();
100 //TODO signal the object that will report errors
103 rcr = new RuntimeConflictResolver( PREFIX,
105 oooa.getDisjointAnalysis().getEffectsAnalysis().getAllEffects(),
107 System.out.println("Runtime Conflict Resolver started.");
108 } catch (FileNotFoundException e) {
109 System.out.println("Runtime Conflict Resolver could not create output file.");
113 while( seseit.hasNext() ) {
114 FlatSESEEnterNode fsen = seseit.next();
115 initializeSESE( fsen );
120 protected void postCodeGenCleanUp() {
123 System.out.println("Runtime Conflict Resolver Done.");
128 protected void additionalCodeGen( PrintWriter outmethodheader,
129 PrintWriter outstructs,
130 PrintWriter outmethod ) {
132 // Output function prototypes and structures for SESE's and code
134 // spit out a global to inform all worker threads with
135 // the maximum size is for any task record
136 outmethod.println("int "+maxTaskRecSizeStr+" = 0;");
138 // used to differentiate, during code generation, whether we are
139 // passing over SESE body code, or non-SESE code
142 // first generate code for each sese's internals
143 Iterator<FlatSESEEnterNode> seseit;
144 seseit=oooa.getAllSESEs().iterator();
146 while( seseit.hasNext() ) {
147 FlatSESEEnterNode fsen = seseit.next();
148 generateMethodSESE( fsen, null, outstructs, outmethodheader, outmethod );
151 // then write the invokeSESE switch to decouple scheduler
152 // from having to do unique details of sese invocation
153 generateSESEinvocationMethod( outmethodheader, outmethod );
157 protected void additionalCodeAtTopOfMain( PrintWriter outmethod ) {
159 // do a calculation to determine which task record
160 // is the largest, store that as a global value for
161 // allocating records
162 Iterator<FlatSESEEnterNode> seseit = oooa.getAllSESEs().iterator();
163 while( seseit.hasNext() ) {
164 FlatSESEEnterNode fsen = seseit.next();
165 outmethod.println("if( sizeof( "+fsen.getSESErecordName()+
166 " ) > "+maxTaskRecSizeStr+
167 " ) { "+maxTaskRecSizeStr+
168 " = sizeof( "+fsen.getSESErecordName()+
172 outmethod.println(" runningSESE = NULL;");
174 outmethod.println(" workScheduleInit( "+state.OOO_NUMCORES+", invokeSESEmethod );");
176 //initializes data structures needed for the RCR traverser
177 if( state.RCR && rcr != null ) {
178 outmethod.println(" initializeStructsRCR();");
179 outmethod.println(" createAndFillMasterHashStructureArray();");
184 protected void additionalCodeAtBottomOfMain( PrintWriter outmethod ) {
185 outmethod.println(" workScheduleBegin();");
189 protected void additionalIncludesMethodsImplementation( PrintWriter outmethod ) {
190 outmethod.println("#include <stdlib.h>");
191 outmethod.println("#include <stdio.h>");
192 outmethod.println("#include \"mlp_runtime.h\"");
193 outmethod.println("#include \"psemaphore.h\"");
196 outmethod.println("#include \"trqueue.h\"");
197 outmethod.println("#include \"RuntimeConflictResolver.h\"");
198 outmethod.println("#include \"rcr_runtime.h\"");
199 outmethod.println("#include \"hashStructure.h\"");
204 protected void additionalIncludesStructsHeader( PrintWriter outstructs ) {
205 outstructs.println("#include \"mlp_runtime.h\"");
206 outstructs.println("#include \"psemaphore.h\"");
208 outstructs.println("#include \"rcr_runtime.h\"");
213 protected void additionalClassObjectFields( PrintWriter outclassdefs ) {
214 outclassdefs.println(" int oid;");
215 outclassdefs.println(" int allocsite;");
219 protected void additionalCodeAtTopMethodsImplementation( PrintWriter outmethod ) {
220 outmethod.print("extern __thread int oid;\n");
221 outmethod.print("extern int oidIncrement;\n");
225 protected void additionalCodeAtTopFlatMethodBody( PrintWriter output, FlatMethod fm ) {
228 // if( fm.getNext(0) instanceof FlatSESEEnterNode ) {
229 // FlatSESEEnterNode callerSESEplaceholder = (FlatSESEEnterNode) fm.getNext( 0 );
230 // if( callerSESEplaceholder != oooa.getMainSESE() ) {
231 // // declare variables for naming static SESE's
232 // output.println(" /* static SESE names */");
233 // Iterator<SESEandAgePair> pItr = callerSESEplaceholder.getNeededStaticNames().iterator();
234 // while( pItr.hasNext() ) {
235 // SESEandAgePair pair = pItr.next();
236 // output.println(" void* "+pair+" = NULL;");
239 // // declare variables for tracking dynamic sources
240 // output.println(" /* dynamic variable sources */");
241 // Iterator<TempDescriptor> dynSrcItr = callerSESEplaceholder.getDynamicVarSet().iterator();
242 // while( dynSrcItr.hasNext() ) {
243 // TempDescriptor dynSrcVar = dynSrcItr.next();
244 // output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;");
245 // output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;");
250 // // set up related allocation sites's waiting queues
253 // FlatSESEEnterNode callerSESEplaceholder = (FlatSESEEnterNode) fm.getNext( 0 );
254 // if(callerSESEplaceholder!= oooa.getMainSESE()){
255 // Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(callerSESEplaceholder);
256 // if (graph != null && graph.hasConflictEdge()) {
257 // output.println(" // set up waiting queues ");
258 // output.println(" int numMemoryQueue=0;");
259 // output.println(" int memoryQueueItemID=0;");
260 // Set<Analysis.OoOJava.SESELock> lockSet = oooa.getLockMappings(graph);
261 // System.out.println("#lockSet="+lockSet.hashCode());
262 // System.out.println("lockset="+lockSet);
263 // for (Iterator iterator = lockSet.iterator(); iterator.hasNext();) {
264 // Analysis.OoOJava.SESELock seseLock = (Analysis.OoOJava.SESELock) iterator.next();
265 // System.out.println("id="+seseLock.getID());
266 // System.out.println("#="+seseLock);
268 // System.out.println("size="+lockSet.size());
269 // if (lockSet.size() > 0) {
270 // output.println(" numMemoryQueue=" + lockSet.size() + ";");
271 // output.println(" runningSESE->numMemoryQueue=numMemoryQueue;");
272 // output.println(" runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);");
282 protected void initializeSESE( FlatSESEEnterNode fsen ) {
284 FlatMethod fm = fsen.getfmEnclosing();
285 MethodDescriptor md = fm.getMethod();
286 ClassDescriptor cn = md.getClassDesc();
289 // Creates bogus method descriptor to index into tables
290 Modifiers modBogus = new Modifiers();
291 MethodDescriptor mdBogus =
292 new MethodDescriptor( modBogus,
293 new TypeDescriptor( TypeDescriptor.VOID ),
294 "sese_"+fsen.getPrettyIdentifier()+fsen.getIdentifier()
297 mdBogus.setClassDesc( fsen.getcdEnclosing() );
298 FlatMethod fmBogus = new FlatMethod( mdBogus, null );
299 fsen.setfmBogus( fmBogus );
300 fsen.setmdBogus( mdBogus );
302 Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
303 inSetAndOutSet.addAll( fsen.getInVarSet() );
304 inSetAndOutSet.addAll( fsen.getOutVarSet() );
306 // Build paramsobj for bogus method descriptor
307 ParamsObject objectparams = new ParamsObject( mdBogus, tag++ );
308 paramstable.put( mdBogus, objectparams );
310 Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
311 while( itr.hasNext() ) {
312 TempDescriptor temp = itr.next();
313 TypeDescriptor type = temp.getType();
315 objectparams.addPtr( temp );
317 objectparams.addPrim( temp );
321 // Build normal temp object for bogus method descriptor
322 TempObject objecttemps = new TempObject( objectparams, mdBogus, tag++ );
323 tempstable.put( mdBogus, objecttemps );
325 for( Iterator nodeit = fsen.getNodeSet().iterator(); nodeit.hasNext(); ) {
326 FlatNode fn = (FlatNode)nodeit.next();
327 TempDescriptor[] writes = fn.writesTemps();
329 for( int i = 0; i < writes.length; i++ ) {
330 TempDescriptor temp = writes[i];
331 TypeDescriptor type = temp.getType();
334 objecttemps.addPtr( temp );
336 objecttemps.addPrim( temp );
342 // used when generating the specific SESE record struct
343 // to remember the FIRST field name of sese records
344 // that the current SESE depends on--we need to know the
345 // offset to the first one for garbage collection
346 protected void addingDepRecField( FlatSESEEnterNode fsen,
348 if( fsen.getFirstDepRecField() == null ) {
349 fsen.setFirstDepRecField( field );
351 fsen.incNumDepRecs();
354 protected void generateMethodSESE(FlatSESEEnterNode fsen,
356 PrintWriter outputStructs,
357 PrintWriter outputMethHead,
358 PrintWriter outputMethods
361 ParamsObject objectparams = (ParamsObject) paramstable.get( fsen.getmdBogus() );
362 TempObject objecttemps = (TempObject) tempstable .get( fsen.getmdBogus() );
364 // generate locals structure
365 outputStructs.println("struct "+
366 fsen.getcdEnclosing().getSafeSymbol()+
367 fsen.getmdBogus().getSafeSymbol()+"_"+
368 fsen.getmdBogus().getSafeMethodDescriptor()+
370 outputStructs.println(" int size;");
371 outputStructs.println(" void * next;");
372 for(int i=0; i<objecttemps.numPointers(); i++) {
373 TempDescriptor temp=objecttemps.getPointer(i);
375 if (temp.getType().isNull())
376 outputStructs.println(" void * "+temp.getSafeSymbol()+";");
378 outputStructs.println(" struct "+
379 temp.getType().getSafeSymbol()+" * "+
380 temp.getSafeSymbol()+";");
382 outputStructs.println("};\n");
385 // divide in-set and out-set into objects and primitives to prep
386 // for the record generation just below
387 Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
388 inSetAndOutSet.addAll( fsen.getInVarSet() );
389 inSetAndOutSet.addAll( fsen.getOutVarSet() );
391 Set<TempDescriptor> inSetAndOutSetObjs = new HashSet<TempDescriptor>();
392 Set<TempDescriptor> inSetAndOutSetPrims = new HashSet<TempDescriptor>();
394 Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
395 while( itr.hasNext() ) {
396 TempDescriptor temp = itr.next();
397 TypeDescriptor type = temp.getType();
399 inSetAndOutSetObjs.add( temp );
401 inSetAndOutSetPrims.add( temp );
406 // generate the SESE record structure
407 outputStructs.println(fsen.getSESErecordName()+" {");
409 // data common to any SESE, and it must be placed first so
410 // a module that doesn't know what kind of SESE record this
411 // is can cast the pointer to a common struct
412 outputStructs.println(" SESEcommon common;");
414 // then garbage list stuff
415 outputStructs.println(" /* next is in-set and out-set objects that look like a garbage list */");
416 outputStructs.println(" int size;");
417 outputStructs.println(" void * next;");
419 // I think that the set of TempDescriptors inSetAndOutSetObjs
420 // calculated above should match the pointer object params
421 // used in the following code, but let's just leave the working
422 // implementation unless there is actually a problem...
424 Vector<TempDescriptor> inset=fsen.getInVarsForDynamicCoarseConflictResolution();
425 for(int i=0; i<inset.size();i++) {
426 TempDescriptor temp=inset.get(i);
427 if (temp.getType().isNull())
428 outputStructs.println(" void * "+temp.getSafeSymbol()+
429 "; /* in-or-out-set obj in gl */");
431 outputStructs.println(" struct "+temp.getType().getSafeSymbol()+" * "+
432 temp.getSafeSymbol()+"; /* in-or-out-set obj in gl */");
435 for(int i=0; i<objectparams.numPointers(); i++) {
436 TempDescriptor temp=objectparams.getPointer(i);
437 if (!inset.contains(temp)) {
438 if (temp.getType().isNull())
439 outputStructs.println(" void * "+temp.getSafeSymbol()+
440 "; /* in-or-out-set obj in gl */");
442 outputStructs.println(" struct "+temp.getType().getSafeSymbol()+" * "+
443 temp.getSafeSymbol()+"; /* in-or-out-set obj in gl */");
447 outputStructs.println(" /* next is primitives for in-set and out-set and dynamic tracking */");
449 Iterator<TempDescriptor> itrPrims = inSetAndOutSetPrims.iterator();
450 while( itrPrims.hasNext() ) {
451 TempDescriptor temp = itrPrims.next();
452 TypeDescriptor type = temp.getType();
453 if(type.isPrimitive()){
454 outputStructs.println(" "+temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol()+"; /* in-set or out-set primitive */");
458 // note that the sese record pointer will be added below, just primitive part of tracking here
459 Iterator<TempDescriptor> itrDynInVars = fsen.getDynamicInVarSet().iterator();
460 while( itrDynInVars.hasNext() ) {
461 TempDescriptor dynInVar = itrDynInVars.next();
462 outputStructs.println(" INTPTR "+dynInVar+"_srcOffset; /* dynamic tracking primitive */");
466 outputStructs.println(" /* everything after this should be pointers to an SESE record */" );
468 // other half of info for dynamic tracking, the SESE record pointer
469 itrDynInVars = fsen.getDynamicInVarSet().iterator();
470 while( itrDynInVars.hasNext() ) {
471 TempDescriptor dynInVar = itrDynInVars.next();
472 String depRecField = dynInVar+"_srcSESE";
473 outputStructs.println(" SESEcommon* "+depRecField+";");
474 addingDepRecField( fsen, depRecField );
477 // statically known sese sources are record pointers, too
478 Iterator<SESEandAgePair> itrStaticInVarSrcs = fsen.getStaticInVarSrcs().iterator();
479 while( itrStaticInVarSrcs.hasNext() ) {
480 SESEandAgePair srcPair = itrStaticInVarSrcs.next();
481 outputStructs.println(" "+srcPair.getSESE().getSESErecordName()+"* "+srcPair+";");
482 addingDepRecField(fsen, srcPair.toString());
487 outputStructs.println("struct rcrRecord rcrRecords["+inset.size()+"];");
490 if( fsen.getFirstDepRecField() != null ) {
491 outputStructs.println(" /* compiler believes first dependent SESE record field above is: "+
492 fsen.getFirstDepRecField()+" */" );
494 outputStructs.println("};\n");
497 // write method declaration to header file
498 outputMethHead.print("void ");
499 outputMethHead.print(fsen.getSESEmethodName()+"(");
500 outputMethHead.print(fsen.getSESErecordName()+"* "+paramsprefix);
501 outputMethHead.println(");\n");
504 generateFlatMethodSESE( fsen.getfmBogus(),
505 fsen.getcdEnclosing(),
511 private void generateFlatMethodSESE(FlatMethod fm,
513 FlatSESEEnterNode fsen,
514 FlatSESEExitNode seseExit,
518 MethodDescriptor md=fm.getMethod();
520 output.print("void ");
521 output.print(fsen.getSESEmethodName()+"(");
522 output.print(fsen.getSESErecordName()+"* "+paramsprefix);
523 output.println("){\n");
526 TempObject objecttemp=(TempObject) tempstable.get(md);
528 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
529 output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
530 output.print(objecttemp.numPointers()+",");
531 output.print("&(((SESEcommon*)(___params___))[1])");
532 for(int j=0; j<objecttemp.numPointers(); j++)
533 output.print(", NULL");
534 output.println("};");
537 output.println(" /* regular local primitives */");
538 for(int i=0; i<objecttemp.numPrimitives(); i++) {
539 TempDescriptor td=objecttemp.getPrimitive(i);
540 TypeDescriptor type=td.getType();
542 output.println(" void * "+td.getSafeSymbol()+";");
543 else if (type.isClass()||type.isArray())
544 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
546 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
550 // declare variables for naming static SESE's
552 //output.println(" /* static SESE names */");
553 //Iterator<SESEandAgePair> pItr = fsen.getNeededStaticNames().iterator();
554 //while( pItr.hasNext() ) {
555 // SESEandAgePair pair = pItr.next();
556 // output.println(" SESEcommon* "+pair+" = NULL;");
559 //// declare variables for tracking dynamic sources
560 //output.println(" /* dynamic variable sources */");
561 //Iterator<TempDescriptor> dynSrcItr = fsen.getDynamicVarSet().iterator();
562 //while( dynSrcItr.hasNext() ) {
563 // TempDescriptor dynSrcVar = dynSrcItr.next();
564 // output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;");
565 // output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;");
568 // declare local temps for in-set primitives, and if it is
569 // a ready-source variable, get the value from the record
570 output.println(" /* local temps for in-set primitives */");
571 Iterator<TempDescriptor> itrInSet = fsen.getInVarSet().iterator();
572 while( itrInSet.hasNext() ) {
573 TempDescriptor temp = itrInSet.next();
574 TypeDescriptor type = temp.getType();
575 if( !type.isPtr() ) {
576 if( fsen.getReadyInVarSet().contains( temp ) ) {
577 output.println(" "+type+" "+temp+" = "+paramsprefix+"->"+temp+";");
579 output.println(" "+type+" "+temp+";");
584 // declare local temps for out-set primitives if its not already
585 // in the in-set, and it's value will get written so no problem
586 output.println(" /* local temp for out-set prim, not already in the in-set */");
587 Iterator<TempDescriptor> itrOutSet = fsen.getOutVarSet().iterator();
588 while( itrOutSet.hasNext() ) {
589 TempDescriptor temp = itrOutSet.next();
590 TypeDescriptor type = temp.getType();
591 if( !type.isPtr() && !fsen.getInVarSet().contains( temp ) ) {
592 output.println(" "+type+" "+temp+";");
597 // initialize thread-local var to a the task's record, which is fused
598 // with the param list
600 output.println(" // code of this task's body should use this to access the running task record");
601 output.println(" runningSESE = &(___params___->common);");
602 output.println(" childSESE = 0;");
605 // setup memory queue
608 output.println(" // set up memory queues ");
609 output.println(" int numMemoryQueue=0;");
610 output.println(" int memoryQueueItemID=0;");
611 Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(fsen);
612 if (graph != null && graph.hasConflictEdge()) {
613 output.println(" {");
614 Set<Analysis.OoOJava.SESELock> lockSet = oooa.getLockMappings(graph);
615 System.out.println("#lockSet="+lockSet);
616 if (lockSet.size() > 0) {
617 output.println(" numMemoryQueue=" + lockSet.size() + ";");
618 output.println(" runningSESE->numMemoryQueue=numMemoryQueue;");
619 output.println(" runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);");
622 output.println(" }");
627 // set up a task's mem pool to recycle the allocation of children tasks
628 // don't bother if the task never has children (a leaf task)
629 output.println( "#ifndef OOO_DISABLE_TASKMEMPOOL" );
630 if( !fsen.getIsLeafSESE() ) {
631 output.println(" runningSESE->taskRecordMemPool = poolcreate( "+
632 maxTaskRecSizeStr+", freshTaskRecordInitializer );");
633 if (state.RCR && !rcr.hasEmptyTraversers(fsen)) {
634 output.println(" createTR();");
635 output.println(" runningSESE->allHashStructures=TRqueue->allHashStructures;");
638 // make it clear we purposefully did not initialize this
639 output.println(" runningSESE->taskRecordMemPool = (MemPool*)0x7;");
641 output.println( "#endif // OOO_DISABLE_TASKMEMPOOL" );
644 // copy in-set into place, ready vars were already
645 // copied when the SESE was issued
646 Iterator<TempDescriptor> tempItr;
648 // static vars are from a known SESE
649 output.println(" // copy variables from static sources");
650 tempItr = fsen.getStaticInVarSet().iterator();
651 while( tempItr.hasNext() ) {
652 TempDescriptor temp = tempItr.next();
653 VariableSourceToken vst = fsen.getStaticInVarSrc( temp );
654 SESEandAgePair srcPair = new SESEandAgePair( vst.getSESE(), vst.getAge() );
655 output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+
656 " = "+paramsprefix+"->"+srcPair+"->"+vst.getAddrVar()+";");
659 output.println(" // decrement references to static sources");
660 for( Iterator<SESEandAgePair> pairItr = fsen.getStaticInVarSrcs().iterator(); pairItr.hasNext(); ) {
661 SESEandAgePair srcPair = pairItr.next();
662 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
663 output.println(" {");
664 output.println(" SESEcommon* src = &("+paramsprefix+"->"+srcPair+"->common);");
665 output.println(" RELEASE_REFERENCE_TO( src );");
666 output.println(" }");
667 output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
671 // dynamic vars come from an SESE and src
672 output.println(" // copy variables from dynamic sources");
673 tempItr = fsen.getDynamicInVarSet().iterator();
674 while( tempItr.hasNext() ) {
675 TempDescriptor temp = tempItr.next();
676 TypeDescriptor type = temp.getType();
678 // go grab it from the SESE source
679 output.println(" if( "+paramsprefix+"->"+temp+"_srcSESE != NULL ) {");
682 if( type.isNull() ) {
684 } else if( type.isClass() || type.isArray() ) {
685 typeStr = "struct "+type.getSafeSymbol()+"*";
687 typeStr = type.getSafeSymbol();
690 output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+
691 " = *(("+typeStr+"*) ((void*)"+
692 paramsprefix+"->"+temp+"_srcSESE + "+
693 paramsprefix+"->"+temp+"_srcOffset));");
695 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
696 output.println(" SESEcommon* src = "+paramsprefix+"->"+temp+"_srcSESE;");
697 output.println(" RELEASE_REFERENCE_TO( src );");
698 output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
700 // or if the source was our parent, its already in our record to grab
701 output.println(" } else {");
702 output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+
703 " = "+paramsprefix+"->"+temp+";");
704 output.println(" }");
707 // Check to see if we need to do a GC if this is a
708 // multi-threaded program...
709 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
710 output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
711 //Don't bother if we aren't in recursive methods...The loops case will catch it
712 // if (callgraph.getAllMethods(md).contains(md)) {
713 // if(this.state.MULTICOREGC) {
714 // output.println("if(gcflag) gc("+localsprefixaddr+");");
716 // output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
721 if( state.COREPROF ) {
722 output.println("#ifdef CP_EVENTID_TASKEXECUTE");
723 output.println(" CP_LOGEVENT( CP_EVENTID_TASKEXECUTE, CP_EVENTTYPE_BEGIN );");
724 output.println("#endif");
727 HashSet<FlatNode> exitset=new HashSet<FlatNode>();
728 exitset.add(seseExit);
729 generateCode(fsen.getNext(0), fm, null, exitset, output, true);
730 output.println("}\n\n");
735 // when a new mlp thread is created for an issued SESE, it is started
736 // by running this method which blocks on a cond variable until
737 // it is allowed to transition to execute. Then a case statement
738 // allows it to invoke the method with the proper SESE body, and after
739 // exiting the SESE method, executes proper SESE exit code before the
740 // thread can be destroyed
741 private void generateSESEinvocationMethod(PrintWriter outmethodheader,
742 PrintWriter outmethod
745 outmethodheader.println("void* invokeSESEmethod( void* seseRecord );");
746 outmethod.println( "void* invokeSESEmethod( void* seseRecord ) {");
747 outmethod.println( " int status;");
748 outmethod.println( " char errmsg[128];");
750 // generate a case for each SESE class that can be invoked
751 outmethod.println( " switch( ((SESEcommon*)seseRecord)->classID ) {");
752 outmethod.println( " ");
753 Iterator<FlatSESEEnterNode> seseit;
754 seseit=oooa.getAllSESEs().iterator();
756 while(seseit.hasNext()){
757 FlatSESEEnterNode fsen = seseit.next();
759 outmethod.println( " /* "+fsen.getPrettyIdentifier()+" */");
760 outmethod.println( " case "+fsen.getIdentifier()+":");
761 outmethod.println( " "+fsen.getSESEmethodName()+"( seseRecord );");
763 if( fsen.equals( oooa.getMainSESE() ) ) {
764 outmethod.println( " workScheduleExit();");
767 outmethod.println( " break;");
768 outmethod.println( "");
771 // default case should never be taken, error out
772 outmethod.println( " default:");
773 outmethod.println( " printf(\"Error: unknown SESE class ID in invoke method.\\n\");");
774 outmethod.println( " exit(-30);");
775 outmethod.println( " break;");
776 outmethod.println( " }");
777 outmethod.println( " return NULL;");
778 outmethod.println( "}\n\n");
783 void stallMEMRCR(FlatMethod fm, FlatNode fn, Set<Analysis.OoOJava.WaitingElement> waitingElementSet, PrintWriter output) {
784 output.println("// stall on parent's stall sites ");
785 output.println(" {");
786 output.println(" REntry* rentry;");
787 output.println(" // stallrecord sometimes is used as a task record for instance ");
788 output.println(" // when you call RELEASE_REFERENCE_TO on a stall record.");
789 output.println(" // so the parent field must be initialized.");
790 output.println(" SESEstall * stallrecord=(SESEstall *) poolalloc(runningSESE->taskRecordMemPool);");
791 output.println(" stallrecord->common.parent=runningSESE;");
792 output.println(" stallrecord->common.unresolvedDependencies=10000;");
793 output.println(" stallrecord->common.rcrstatus=1;");
794 output.println(" stallrecord->common.offsetToParamRecords=(INTPTR) & (((SESEstall *)0)->rcrRecords);");
795 output.println(" stallrecord->common.refCount = 10003;");
796 output.println(" int localCount=10000;");
797 output.println(" stallrecord->rcrRecords[0].index=0;");
798 output.println(" stallrecord->rcrRecords[0].flag=0;");
799 output.println(" stallrecord->rcrRecords[0].next=NULL;");
800 output.println(" stallrecord->common.parentsStallSem=&runningSESEstallSem;");
801 output.println(" psem_reset( &runningSESEstallSem);");
802 output.println(" stallrecord->tag=runningSESEstallSem.tag;");
804 TempDescriptor stalltd=null;
805 for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) {
806 Analysis.OoOJava.WaitingElement waitingElement =(Analysis.OoOJava.WaitingElement) iterator.next();
807 if (waitingElement.getStatus() >= ConflictNode.COARSE) {
808 output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["
809 + waitingElement.getQueueID() + "]," + waitingElement.getStatus()
810 + ", (SESEcommon *) stallrecord, 1LL);");
812 throw new Error("Fine-grained conflict: This should not happen in RCR");
814 output.println(" rentry->queue=runningSESE->memoryQueueArray["
815 + waitingElement.getQueueID() + "];");
816 output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["
817 + waitingElement.getQueueID() + "],rentry)==NOTREADY) {");
818 output.println(" localCount--;");
819 output.println(" }");
820 output.println("#if defined(RCR)&&!defined(OOO_DISABLE_TASKMEMPOOL)");
821 output.println(" else poolfreeinto(runningSESE->memoryQueueArray["+waitingElement.getQueueID()+"]->rentrypool, rentry);");
822 output.println("#endif");
824 stalltd=waitingElement.getTempDesc();
825 } else if (stalltd!=waitingElement.getTempDesc()) {
826 throw new Error("Multiple temp descriptors at stall site"+stalltd+"!="+waitingElement.getTempDesc());
830 //did all of the course grained stuff
831 output.println(" if(!atomic_sub_and_test(localCount, &(stallrecord->common.unresolvedDependencies))) {");
832 //have to do fine-grained work also
833 output.println(" stallrecord->___obj___=(struct ___Object___ *)"
834 + generateTemp(fm, stalltd, null) + ";");
835 output.println(" stallrecord->common.classID=-"
836 + rcr.getTraverserID(stalltd, fn) + ";");
838 output.println(" enqueueTR(TRqueue, (void *)stallrecord);");
840 if (state.COREPROF) {
841 output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
843 .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );");
844 output.println("#endif");
847 output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
849 if (state.COREPROF) {
850 output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
852 .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );");
853 output.println("#endif");
856 output.println(" } else {");//exit if condition
857 //release traversers reference if we didn't use traverser
858 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
859 output.println(" RELEASE_REFERENCE_TO((SESEcommon *)stallrecord);");
860 output.println("#endif");
861 output.println(" }");
862 //release our reference to stall record
863 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
864 output.println(" RELEASE_REFERENCE_TO((SESEcommon *)stallrecord);");
865 output.println("#endif");
866 output.println(" }");//exit block
870 protected void additionalCodePreNode( FlatMethod fm,
873 PrintWriter output ) {
874 // insert pre-node actions from the code plan
876 CodePlan cp = oooa.getCodePlan(fn);
880 FlatSESEEnterNode currentSESE = cp.getCurrentSESE();
882 // for each sese and age pair that this parent statement
883 // must stall on, take that child's stall semaphore, the
884 // copying of values comes after the statement
885 Iterator<VariableSourceToken> vstItr = cp.getStallTokens().iterator();
886 while( vstItr.hasNext() ) {
887 VariableSourceToken vst = vstItr.next();
889 SESEandAgePair pair = new SESEandAgePair( vst.getSESE(), vst.getAge() );
891 output.println(" {");
892 output.println(" "+pair.getSESE().getSESErecordName()+"* child = ("+
893 pair.getSESE().getSESErecordName()+"*) "+pair+";");
895 output.println(" SESEcommon* childCom = (SESEcommon*) "+pair+";");
897 if( state.COREPROF ) {
898 output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
899 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );");
900 output.println("#endif");
903 output.println(" pthread_mutex_lock( &(childCom->lock) );");
904 output.println(" if( childCom->doneExecuting == FALSE ) {");
905 output.println(" psem_reset( &runningSESEstallSem );");
906 output.println(" childCom->parentsStallSem = &runningSESEstallSem;");
907 output.println(" pthread_mutex_unlock( &(childCom->lock) );");
908 output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
909 output.println(" } else {");
910 output.println(" pthread_mutex_unlock( &(childCom->lock) );");
911 output.println(" }");
913 // copy things we might have stalled for
914 Iterator<TempDescriptor> tdItr = cp.getCopySet( vst ).iterator();
915 while( tdItr.hasNext() ) {
916 TempDescriptor td = tdItr.next();
917 FlatMethod fmContext;
918 //if( currentSESE.getIsCallerSESEplaceholder() ) {
919 // fmContext = currentSESE.getfmEnclosing();
921 fmContext = currentSESE.getfmBogus();
923 output.println(" "+generateTemp( fmContext, td, null )+
924 " = child->"+vst.getAddrVar().getSafeSymbol()+";");
927 if( state.COREPROF ) {
928 output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
929 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );");
930 output.println("#endif");
933 output.println(" }");
936 // for each variable with a dynamic source, stall just for that variable
937 Iterator<TempDescriptor> dynItr = cp.getDynamicStallSet().iterator();
938 while( dynItr.hasNext() ) {
939 TempDescriptor dynVar = dynItr.next();
941 // only stall if the dynamic source is not yourself, denoted by src==NULL
942 // otherwise the dynamic write nodes will have the local var up-to-date
943 output.println(" {");
944 output.println(" if( "+dynVar+"_srcSESE != NULL ) {");
946 output.println(" SESEcommon* childCom = (SESEcommon*) "+dynVar+"_srcSESE;");
948 if( state.COREPROF ) {
949 output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
950 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );");
951 output.println("#endif");
954 output.println(" pthread_mutex_lock( &(childCom->lock) );");
955 output.println(" if( childCom->doneExecuting == FALSE ) {");
956 output.println(" psem_reset( &runningSESEstallSem );");
957 output.println(" childCom->parentsStallSem = &runningSESEstallSem;");
958 output.println(" pthread_mutex_unlock( &(childCom->lock) );");
959 output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
960 output.println(" } else {");
961 output.println(" pthread_mutex_unlock( &(childCom->lock) );");
962 output.println(" }");
964 FlatMethod fmContext;
965 //if( currentSESE.getIsCallerSESEplaceholder() ) {
966 // fmContext = currentSESE.getfmEnclosing();
968 fmContext = currentSESE.getfmBogus();
971 TypeDescriptor type = dynVar.getType();
973 if( type.isNull() ) {
975 } else if( type.isClass() || type.isArray() ) {
976 typeStr = "struct "+type.getSafeSymbol()+"*";
978 typeStr = type.getSafeSymbol();
981 output.println(" "+generateTemp( fmContext, dynVar, null )+
982 " = *(("+typeStr+"*) ((void*)"+
983 dynVar+"_srcSESE + "+dynVar+"_srcOffset));");
985 if( state.COREPROF ) {
986 output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
987 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );");
988 output.println("#endif");
991 output.println(" }");
992 output.println(" }");
995 // for each assignment of a variable to rhs that has a dynamic source,
996 // copy the dynamic sources
997 Iterator dynAssignItr = cp.getDynAssigns().entrySet().iterator();
998 while( dynAssignItr.hasNext() ) {
999 Map.Entry me = (Map.Entry) dynAssignItr.next();
1000 TempDescriptor lhs = (TempDescriptor) me.getKey();
1001 TempDescriptor rhs = (TempDescriptor) me.getValue();
1003 output.println(" {");
1004 output.println(" SESEcommon* oldSrc = "+lhs+"_srcSESE;");
1006 output.println(" "+lhs+"_srcSESE = "+rhs+"_srcSESE;");
1007 output.println(" "+lhs+"_srcOffset = "+rhs+"_srcOffset;");
1009 // no matter what we did above, track reference count of whatever
1010 // this variable pointed to, do release last in case we're just
1011 // copying the same value in because 1->2->1 is safe but ref count
1012 // 1->0->1 has a window where it looks like it should be free'd
1013 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1014 output.println(" if( "+rhs+"_srcSESE != NULL ) {");
1015 output.println(" ADD_REFERENCE_TO( "+rhs+"_srcSESE );");
1016 output.println(" }");
1017 output.println(" if( oldSrc != NULL ) {");
1018 output.println(" RELEASE_REFERENCE_TO( oldSrc );");
1019 output.println(" }");
1020 output.println(" }");
1021 output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1024 // for each lhs that is dynamic from a non-dynamic source, set the
1025 // dynamic source vars to the current SESE
1026 dynItr = cp.getDynAssignCurr().iterator();
1027 while( dynItr.hasNext() ) {
1028 TempDescriptor dynVar = dynItr.next();
1031 //assert currentSESE.getDynamicVarSet().contains( dynVar );
1033 // first release a reference to current record
1034 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1035 output.println(" if( "+dynVar+"_srcSESE != NULL ) {");
1036 output.println(" RELEASE_REFERENCE_TO( oldSrc );");
1037 output.println(" }");
1038 output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1040 output.println(" "+dynVar+"_srcSESE = NULL;");
1044 // handling stall site
1045 if (state.OOOJAVA) {
1046 Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(currentSESE);
1048 Set<Analysis.OoOJava.SESELock> seseLockSet = oooa.getLockMappings(graph);
1049 Set<Analysis.OoOJava.WaitingElement> waitingElementSet = graph.getStallSiteWaitingElementSet(fn, seseLockSet);
1051 if (waitingElementSet.size() > 0) {
1053 stallMEMRCR(fm, fn, waitingElementSet, output);
1055 output.println("// stall on parent's stall sites ");
1056 output.println(" {");
1057 output.println(" REntry* rentry;");
1059 for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) {
1060 Analysis.OoOJava.WaitingElement waitingElement =
1061 (Analysis.OoOJava.WaitingElement) iterator.next();
1062 if (waitingElement.getStatus() >= ConflictNode.COARSE) {
1063 output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["
1064 + waitingElement.getQueueID() + "]," + waitingElement.getStatus()
1065 + ", runningSESE);");
1067 output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["
1068 + waitingElement.getQueueID() + "]," + waitingElement.getStatus()
1069 + ", runningSESE, (void*)&"
1070 + generateTemp(fm, waitingElement.getTempDesc(), lb) + ");");
1072 output.println(" rentry->parentStallSem=&runningSESEstallSem;");
1073 output.println(" psem_reset( &runningSESEstallSem);");
1074 output.println(" rentry->tag=runningSESEstallSem.tag;");
1075 output.println(" rentry->queue=runningSESE->memoryQueueArray["
1076 + waitingElement.getQueueID() + "];");
1077 output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["
1078 + waitingElement.getQueueID() + "],rentry)==NOTREADY){");
1079 if (state.COREPROF) {
1080 output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
1082 .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );");
1083 output.println("#endif");
1086 output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
1088 if (state.COREPROF) {
1089 output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
1091 .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );");
1092 output.println("#endif");
1094 output.println(" } ");
1096 output.println(" }");
1105 protected void additionalCodePostNode( FlatMethod fm,
1108 PrintWriter output ) {
1110 // insert post-node actions from the code-plan (none right now...)
1114 public void generateFlatSESEEnterNode( FlatMethod fm,
1116 FlatSESEEnterNode fsen,
1117 PrintWriter output ) {
1119 // there may be an SESE in an unreachable method, skip over
1120 if( !oooa.getAllSESEs().contains(fsen) ) {
1124 // also, if we have encountered a placeholder, just skip it
1125 //if( fsen.getIsCallerSESEplaceholder() ) {
1129 output.println(" {");
1131 if( state.COREPROF ) {
1132 output.println("#ifdef CP_EVENTID_TASKDISPATCH");
1133 output.println(" CP_LOGEVENT( CP_EVENTID_TASKDISPATCH, CP_EVENTTYPE_BEGIN );");
1134 output.println("#endif");
1138 // before doing anything, lock your own record and increment the running children
1139 if( fsen != oooa.getMainSESE() ) {
1140 output.println(" childSESE++;");
1143 // allocate the space for this record
1144 output.println( "#ifndef OOO_DISABLE_TASKMEMPOOL" );
1146 output.println( "#ifdef CP_EVENTID_POOLALLOC");
1147 output.println( " CP_LOGEVENT( CP_EVENTID_POOLALLOC, CP_EVENTTYPE_BEGIN );");
1148 output.println( "#endif");
1149 if( fsen != oooa.getMainSESE() ) {
1151 fsen.getSESErecordName()+"* seseToIssue = ("+
1152 fsen.getSESErecordName()+"*) poolalloc( runningSESE->taskRecordMemPool );");
1153 output.println(" CHECK_RECORD( seseToIssue );");
1156 fsen.getSESErecordName()+"* seseToIssue = ("+
1157 fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+
1158 fsen.getSESErecordName()+" ) );");
1160 output.println( "#ifdef CP_EVENTID_POOLALLOC");
1161 output.println( " CP_LOGEVENT( CP_EVENTID_POOLALLOC, CP_EVENTTYPE_END );");
1162 output.println( "#endif");
1164 output.println( "#else // OOO_DISABLE_TASKMEMPOOL" );
1166 fsen.getSESErecordName()+"* seseToIssue = ("+
1167 fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+
1168 fsen.getSESErecordName()+" ) );");
1169 output.println( "#endif // OOO_DISABLE_TASKMEMPOOL" );
1172 // set up the SESE in-set and out-set objects, which look
1173 // like a garbage list
1174 output.println(" struct garbagelist * gl= (struct garbagelist *)&(((SESEcommon*)(seseToIssue))[1]);");
1175 output.println(" gl->size="+calculateSizeOfSESEParamList(fsen)+";");
1176 output.println(" gl->next = NULL;");
1177 output.println(" seseToIssue->common.rentryIdx=0;");
1180 //flag the SESE status as 1...it will be reset
1181 output.println(" seseToIssue->common.rcrstatus=1;");
1184 // there are pointers to SESE records the newly-issued SESE
1185 // will use to get values it depends on them for--how many
1186 // are there, and what is the offset from the total SESE
1187 // record to the first dependent record pointer?
1188 output.println(" seseToIssue->common.numDependentSESErecords="+
1189 fsen.getNumDepRecs()+";");
1191 // we only need this (and it will only compile) when the number of dependent
1192 // SESE records is non-zero
1193 if( fsen.getFirstDepRecField() != null ) {
1194 output.println(" seseToIssue->common.offsetToDepSESErecords=(INTPTR)sizeof("+
1195 fsen.getSESErecordName()+") - (INTPTR)&((("+
1196 fsen.getSESErecordName()+"*)0)->"+fsen.getFirstDepRecField()+");"
1200 if (state.RCR&&fsen.getInVarsForDynamicCoarseConflictResolution().size()>0) {
1201 output.println(" seseToIssue->common.offsetToParamRecords=(INTPTR) & ((("+fsen.getSESErecordName()+"*)0)->rcrRecords);");
1204 // fill in common data
1205 output.println(" int localCount=0;");
1206 output.println(" seseToIssue->common.classID = "+fsen.getIdentifier()+";");
1207 output.println(" seseToIssue->common.unresolvedDependencies = 10000;");
1208 output.println(" seseToIssue->common.parentsStallSem = NULL;");
1209 output.println(" initQueue(&seseToIssue->common.forwardList);");
1210 output.println(" seseToIssue->common.doneExecuting = FALSE;");
1211 output.println(" seseToIssue->common.numRunningChildren = 0;");
1212 output.println( "#ifdef OOO_DISABLE_TASKMEMPOOL" );
1213 output.println(" pthread_cond_init( &(seseToIssue->common.runningChildrenCond), NULL );");
1214 output.println("#endif");
1215 output.println(" seseToIssue->common.parent = runningSESE;");
1216 // start with refCount = 2, one being the count that the child itself
1217 // will decrement when it retires, to say it is done using its own
1218 // record, and the other count is for the parent that will remember
1219 // the static name of this new child below
1221 // if we're using RCR, ref count is 3 because the traverser has
1223 if( fsen != oooa.getMainSESE() && fsen.getInVarsForDynamicCoarseConflictResolution().size()>0){
1224 output.println(" seseToIssue->common.refCount = 10003;");
1226 output.println(" seseToIssue->common.refCount = 10002;");
1228 output.println(" int refCount=10000;");
1230 output.println(" seseToIssue->common.refCount = 2;");
1233 // all READY in-vars should be copied now and be done with it
1234 Iterator<TempDescriptor> tempItr = fsen.getReadyInVarSet().iterator();
1235 while( tempItr.hasNext() ) {
1236 TempDescriptor temp = tempItr.next();
1238 // when we are issuing the main SESE or an SESE with placeholder
1239 // caller SESE as parent, generate temp child child's eclosing method,
1240 // otherwise use the parent's enclosing method as the context
1241 boolean useParentContext = false;
1243 if( fsen != oooa.getMainSESE() ) {
1244 assert fsen.getParents() != null;
1245 //if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
1246 useParentContext = true;
1251 if( useParentContext ) {
1252 output.println(" seseToIssue->"+temp+" = "+
1253 generateTemp( fsen.getParent().getfmBogus(), temp, null )+";");
1255 output.println(" seseToIssue->"+temp+" = "+
1256 generateTemp( fsen.getfmEnclosing(), temp, null )+";");
1261 // before potentially adding this SESE to other forwarding lists,
1263 output.println( "#ifdef OOO_DISABLE_TASKMEMPOOL" );
1264 output.println(" pthread_mutex_init( &(seseToIssue->common.lock), NULL );");
1265 output.println("#endif");
1267 if( fsen != oooa.getMainSESE() ) {
1268 // count up outstanding dependencies, static first, then dynamic
1269 Iterator<SESEandAgePair> staticSrcsItr = fsen.getStaticInVarSrcs().iterator();
1270 while( staticSrcsItr.hasNext() ) {
1271 SESEandAgePair srcPair = staticSrcsItr.next();
1272 output.println(" {");
1273 output.println(" SESEcommon* src = (SESEcommon*)"+srcPair+";");
1274 output.println(" pthread_mutex_lock( &(src->lock) );");
1276 output.println(" if( !src->doneExecuting ) {");
1277 output.println(" addNewItem( &src->forwardList, seseToIssue );");
1278 output.println(" ++(localCount);");
1279 output.println(" }");
1280 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1281 output.println(" ADD_REFERENCE_TO( src );");
1282 output.println("#endif" );
1283 output.println(" pthread_mutex_unlock( &(src->lock) );");
1284 output.println(" }");
1286 // whether or not it is an outstanding dependency, make sure
1287 // to pass the static name to the child's record
1288 output.println(" seseToIssue->"+srcPair+" = "+
1289 "("+srcPair.getSESE().getSESErecordName()+"*)"+
1293 // dynamic sources might already be accounted for in the static list,
1294 // so only add them to forwarding lists if they're not already there
1295 Iterator<TempDescriptor> dynVarsItr = fsen.getDynamicInVarSet().iterator();
1296 while( dynVarsItr.hasNext() ) {
1297 TempDescriptor dynInVar = dynVarsItr.next();
1298 output.println(" {");
1299 output.println(" SESEcommon* src = (SESEcommon*)"+dynInVar+"_srcSESE;");
1301 // the dynamic source is NULL if it comes from your own space--you can't pass
1302 // the address off to the new child, because you're not done executing and
1303 // might change the variable, so copy it right now
1304 output.println(" if( src != NULL ) {");
1305 output.println(" pthread_mutex_lock( &(src->lock) );");
1309 output.println(" if( isEmpty( &src->forwardList ) ||");
1310 output.println(" seseToIssue != peekItem( &src->forwardList ) ) {");
1311 output.println(" if( !src->doneExecuting ) {");
1312 output.println(" addNewItem( &src->forwardList, seseToIssue );");
1313 output.println(" ++(localCount);");
1314 output.println(" }");
1315 output.println(" }");
1316 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1317 output.println(" ADD_REFERENCE_TO( src );");
1318 output.println("#endif" );
1319 output.println(" pthread_mutex_unlock( &(src->lock) );");
1320 output.println(" seseToIssue->"+dynInVar+"_srcOffset = "+dynInVar+"_srcOffset;");
1321 output.println(" } else {");
1323 boolean useParentContext = false;
1324 if( fsen != oooa.getMainSESE() ) {
1325 //assert fsen.getParent() != null;
1326 //if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
1327 useParentContext = true;
1330 //if( useParentContext ) {
1331 // output.println(" seseToIssue->"+dynInVar+" = "+
1332 // generateTemp( fsen.getParent().getfmBogus(), dynInVar, null )+";");
1334 // output.println(" seseToIssue->"+dynInVar+" = "+
1335 // generateTemp( fsen.getfmEnclosing(), dynInVar, null )+";");
1338 output.println(" }");
1339 output.println(" }");
1341 // even if the value is already copied, make sure your NULL source
1342 // gets passed so child knows it already has the dynamic value
1343 output.println(" seseToIssue->"+dynInVar+"_srcSESE = "+dynInVar+"_srcSESE;");
1349 // maintain pointers for finding dynamic SESE
1350 // instances from static names
1352 SESEandAgePair pairNewest = new SESEandAgePair( fsen, 0 );
1353 SESEandAgePair pairOldest = new SESEandAgePair( fsen, fsen.getOldestAgeToTrack() );
1354 if( true//fsen.getParent() != null &&
1355 //fsen.getParent().getNeededStaticNames().contains( pairNewest )
1357 output.println(" {");
1358 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1359 output.println(" SESEcommon* oldest = "+pairOldest+";");
1360 output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1362 for( int i = fsen.getOldestAgeToTrack(); i > 0; --i ) {
1363 SESEandAgePair pair1 = new SESEandAgePair( fsen, i );
1364 SESEandAgePair pair2 = new SESEandAgePair( fsen, i-1 );
1365 output.println(" "+pair1+" = "+pair2+";");
1367 output.println(" "+pairNewest+" = &(seseToIssue->common);");
1369 // no need to add a reference to whatever is the newest record, because
1370 // we initialized seseToIssue->refCount to *2*
1371 // but release a reference to whatever was the oldest BEFORE the shift
1372 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1373 output.println(" if( oldest != NULL ) {");
1374 output.println(" RELEASE_REFERENCE_TO( oldest );");
1375 output.println(" }");
1376 output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1377 output.println(" }");
1380 if( state.COREPROF ) {
1381 output.println("#ifdef CP_EVENTID_PREPAREMEMQ");
1382 output.println(" CP_LOGEVENT( CP_EVENTID_PREPAREMEMQ, CP_EVENTTYPE_BEGIN );");
1383 output.println("#endif");
1388 // count up memory conflict dependencies,
1390 dispatchMEMRC(fm, lb, fsen, output);
1391 } else if(state.OOOJAVA){
1393 // assumes that there is only one parent, but it is possible that
1394 // currentSESE has more than one so we need to generate
1395 // conditional case for each parent case
1396 assert fsen.getParents().size()>0;
1397 FlatSESEEnterNode parent = fsen.getParents().iterator().next();
1398 Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(parent);
1399 if (graph != null && graph.hasConflictEdge()) {
1400 Set<Analysis.OoOJava.SESELock> seseLockSet = oooa.getLockMappings(graph);
1402 output.println(" //add memory queue element");
1403 Analysis.OoOJava.SESEWaitingQueue seseWaitingQueue=
1404 graph.getWaitingElementSetBySESEID(fsen.getIdentifier(), seseLockSet);
1405 if(seseWaitingQueue.getWaitingElementSize()>0) {
1406 output.println(" {");
1407 output.println(" REntry* rentry=NULL;");
1408 output.println(" INTPTR* pointer=NULL;");
1409 output.println(" seseToIssue->common.rentryIdx=0;");
1411 Set<Integer> queueIDSet=seseWaitingQueue.getQueueIDSet();
1412 for (Iterator iterator = queueIDSet.iterator(); iterator.hasNext();) {
1413 Integer key = (Integer) iterator.next();
1414 int queueID=key.intValue();
1415 Set<Analysis.OoOJava.WaitingElement> waitingQueueSet =
1416 seseWaitingQueue.getWaitingElementSet(queueID);
1417 int enqueueType=seseWaitingQueue.getType(queueID);
1418 if(enqueueType==SESEWaitingQueue.EXCEPTION) {
1419 output.println(" INITIALIZEBUF(runningSESE->memoryQueueArray[" + queueID+ "]);");
1421 for (Iterator iterator2 = waitingQueueSet.iterator(); iterator2.hasNext();) {
1422 Analysis.OoOJava.WaitingElement waitingElement
1423 = (Analysis.OoOJava.WaitingElement) iterator2.next();
1424 if (waitingElement.getStatus() >= ConflictNode.COARSE) {
1425 output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1426 + waitingElement.getStatus()
1427 + ", &(seseToIssue->common));");
1429 TempDescriptor td = waitingElement.getTempDesc();
1430 // decide whether waiting element is dynamic or static
1431 if (fsen.getDynamicInVarSet().contains(td)) {
1432 // dynamic in-var case
1433 output.println(" pointer=seseToIssue->"
1434 + waitingElement.getDynID()
1435 + "_srcSESE+seseToIssue->"
1436 + waitingElement.getDynID()
1438 output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1439 + waitingElement.getStatus()
1440 + ", &(seseToIssue->common), pointer );");
1441 } else if (fsen.getStaticInVarSet().contains(td)) {
1442 // static in-var case
1443 VariableSourceToken vst = fsen.getStaticInVarSrc(td);
1446 String srcId = "SESE_" + vst.getSESE().getPrettyIdentifier()
1447 + vst.getSESE().getIdentifier()
1448 + "_" + vst.getAge();
1449 output.println(" pointer=(void*)&seseToIssue->"
1455 output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1456 + waitingElement.getStatus()
1457 + ", &(seseToIssue->common), pointer );");
1460 output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1461 + waitingElement.getStatus()
1462 + ", &(seseToIssue->common), (void*)&seseToIssue->"
1463 + waitingElement.getDynID()
1467 output.println(" rentry->queue=runningSESE->memoryQueueArray["
1468 + waitingElement.getQueueID()
1471 if(enqueueType==SESEWaitingQueue.NORMAL){
1472 output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;");
1473 output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["
1474 + waitingElement.getQueueID()
1475 + "],rentry)==NOTREADY) {");
1476 output.println(" localCount++;");
1477 output.println(" }");
1479 output.println(" ADDRENTRYTOBUF(runningSESE->memoryQueueArray[" + waitingElement.getQueueID() + "],rentry);");
1482 if(enqueueType!=SESEWaitingQueue.NORMAL){
1483 output.println(" localCount+=RESOLVEBUF(runningSESE->memoryQueueArray["
1484 + queueID+ "],&seseToIssue->common);");
1487 output.println(" }");
1494 if( state.COREPROF ) {
1495 output.println("#ifdef CP_EVENTID_PREPAREMEMQ");
1496 output.println(" CP_LOGEVENT( CP_EVENTID_PREPAREMEMQ, CP_EVENTTYPE_END );");
1497 output.println("#endif");
1500 // Enqueue Task Record
1502 if( fsen != oooa.getMainSESE() && fsen.getInVarsForDynamicCoarseConflictResolution().size()>0){
1503 output.println(" enqueueTR(TRqueue, (void *)seseToIssue);");
1507 // if there were no outstanding dependencies, issue here
1508 output.println(" if( atomic_sub_and_test(10000-localCount,&(seseToIssue->common.unresolvedDependencies) ) ) {");
1509 output.println(" workScheduleSubmit( (void*)seseToIssue );");
1510 output.println(" }");
1514 if( state.COREPROF ) {
1515 output.println("#ifdef CP_EVENTID_TASKDISPATCH");
1516 output.println(" CP_LOGEVENT( CP_EVENTID_TASKDISPATCH, CP_EVENTTYPE_END );");
1517 output.println("#endif");
1520 output.println(" }");
1525 void dispatchMEMRC( FlatMethod fm,
1527 FlatSESEEnterNode fsen,
1528 PrintWriter output ) {
1530 // assumes that there is only one parent, but it is possible that
1531 // currentSESE has more than one so we need to generate
1532 // conditional case for each parent case
1533 assert fsen.getParents().size()>0;
1534 FlatSESEEnterNode parent = fsen.getParents().iterator().next();
1535 Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(parent);
1536 if (graph != null && graph.hasConflictEdge()) {
1537 Set<Analysis.OoOJava.SESELock> seseLockSet = oooa.getLockMappings(graph);
1538 Analysis.OoOJava.SESEWaitingQueue seseWaitingQueue=graph.getWaitingElementSetBySESEID(fsen.getIdentifier(), seseLockSet);
1539 if(seseWaitingQueue.getWaitingElementSize()>0) {
1540 output.println(" {");
1541 output.println(" REntry* rentry=NULL;");
1542 output.println(" INTPTR* pointer=NULL;");
1543 output.println(" seseToIssue->common.rentryIdx=0;");
1544 Vector<TempDescriptor> invars=fsen.getInVarsForDynamicCoarseConflictResolution();
1545 System.out.println(fm.getMethod()+"["+invars+"]");
1547 Vector<Long> queuetovar=new Vector<Long>();
1549 for(int i=0;i<invars.size();i++) {
1550 TempDescriptor td=invars.get(i);
1551 Set<Analysis.OoOJava.WaitingElement> weset=seseWaitingQueue.getWaitingElementSet(td);
1553 Set<Integer> queueSet=new HashSet<Integer>();
1554 for (Iterator iterator = weset.iterator(); iterator.hasNext();) {
1555 Analysis.OoOJava.WaitingElement we = (Analysis.OoOJava.WaitingElement) iterator.next();
1556 Integer queueID=new Integer( we.getQueueID());
1557 if(!queueSet.contains(queueID)){
1559 queueSet.add(queueID);
1562 output.println(" seseToIssue->rcrRecords["+i+"].flag="+numqueues+";");
1563 output.println(" seseToIssue->rcrRecords["+i+"].index=0;");
1564 output.println(" seseToIssue->rcrRecords["+i+"].next=NULL;");
1565 output.println(" int dispCount"+i+"=0;");
1567 for (Iterator<Analysis.OoOJava.WaitingElement> wtit = weset.iterator(); wtit.hasNext();) {
1568 Analysis.OoOJava.WaitingElement waitingElement = wtit.next();
1569 int queueID = waitingElement.getQueueID();
1570 if (queueID >= queuetovar.size())
1571 queuetovar.setSize(queueID + 1);
1572 Long l = queuetovar.get(queueID);
1573 long val = (l != null) ? l.longValue() : 0;
1574 val = val | (1 << i);
1575 queuetovar.set(queueID, new Long(val));
1579 HashSet generatedqueueentry=new HashSet();
1580 for(int i=0;i<invars.size();i++) {
1581 TempDescriptor td=invars.get(i);
1582 Set<Analysis.OoOJava.WaitingElement> weset=seseWaitingQueue.getWaitingElementSet(td);
1583 for(Iterator<Analysis.OoOJava.WaitingElement> wtit=weset.iterator();wtit.hasNext();) {
1584 Analysis.OoOJava.WaitingElement waitingElement=wtit.next();
1585 int queueID=waitingElement.getQueueID();
1587 if(waitingElement.isBogus()){
1591 if (generatedqueueentry.contains(queueID))
1594 generatedqueueentry.add(queueID);
1596 assert(waitingElement.getStatus()>=ConflictNode.COARSE);
1597 long mask=queuetovar.get(queueID);
1598 output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "]," + waitingElement.getStatus() + ", &(seseToIssue->common), "+mask+"LL);");
1599 output.println(" rentry->count=2;");
1600 output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;");
1601 output.println(" rentry->queue=runningSESE->memoryQueueArray[" + waitingElement.getQueueID()+"];");
1603 output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "],rentry)==READY) {");
1604 for(int j=0;mask!=0;j++) {
1606 output.println(" dispCount"+j+"++;");
1609 output.println(" } else ");
1610 output.println(" refCount--;");
1614 if (fsen.getDynamicInVarSet().contains(td)) {
1615 // dynamic in-var case
1616 //output.println(" pointer=seseToIssue->" + waitingElement.getDynID()+ "_srcSESE+seseToIssue->"+ waitingElement.getDynID()+ "_srcOffset;");
1617 //output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", &(seseToIssue->common), pointer );");
1620 for(int i=0;i<invars.size();i++) {
1621 output.println(" if(!dispCount"+i+" || !atomic_sub_and_test(dispCount"+i+",&(seseToIssue->rcrRecords["+i+"].flag)))");
1622 output.println(" localCount++;");
1624 output.println(" }");
1627 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1628 output.println(" RELEASE_REFERENCES_TO((SESEcommon *)seseToIssue, refCount);");
1629 output.println("#endif");
1632 public void generateFlatSESEExitNode( FlatMethod fm,
1634 FlatSESEExitNode fsexn,
1635 PrintWriter output ) {
1637 // get the enter node for this exit that has meta data embedded
1638 FlatSESEEnterNode fsen = fsexn.getFlatEnter();
1640 // there may be an SESE in an unreachable method, skip over
1641 if( !oooa.getAllSESEs().contains( fsen ) ) {
1645 // also, if we have encountered a placeholder, just jump it
1646 //if( fsen.getIsCallerSESEplaceholder() ) {
1650 if( state.COREPROF ) {
1651 output.println("#ifdef CP_EVENTID_TASKEXECUTE");
1652 output.println(" CP_LOGEVENT( CP_EVENTID_TASKEXECUTE, CP_EVENTTYPE_END );");
1653 output.println("#endif");
1656 output.println(" /* SESE exiting */");
1658 if( state.COREPROF ) {
1659 output.println("#ifdef CP_EVENTID_TASKRETIRE");
1660 output.println(" CP_LOGEVENT( CP_EVENTID_TASKRETIRE, CP_EVENTTYPE_BEGIN );");
1661 output.println("#endif");
1665 // this SESE cannot be done until all of its children are done
1666 // so grab your own lock with the condition variable for watching
1667 // that the number of your running children is greater than zero
1668 output.println(" atomic_add(childSESE, &runningSESE->numRunningChildren);");
1669 output.println(" pthread_mutex_lock( &(runningSESE->lock) );");
1670 output.println(" if( runningSESE->numRunningChildren > 0 ) {");
1671 output.println(" stopforgc( (struct garbagelist *)&___locals___ );");
1672 output.println(" do {");
1673 output.println(" pthread_cond_wait( &(runningSESE->runningChildrenCond), &(runningSESE->lock) );");
1674 output.println(" } while( runningSESE->numRunningChildren > 0 );");
1675 output.println(" restartaftergc();");
1676 output.println(" }");
1679 // copy out-set from local temps into the sese record
1680 Iterator<TempDescriptor> itr = fsen.getOutVarSet().iterator();
1681 while( itr.hasNext() ) {
1682 TempDescriptor temp = itr.next();
1684 // only have to do this for primitives non-arrays
1686 temp.getType().isPrimitive() && !temp.getType().isArray()
1692 // have to determine the context enclosing this sese
1693 boolean useParentContext = false;
1695 if( fsen != oooa.getMainSESE() ) {
1696 assert fsen.getParents() != null;
1697 //if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
1698 useParentContext = true;
1703 //if( useParentContext ) {
1704 //from = generateTemp( fsen.getParent().getfmBogus(), temp, null );
1706 from = generateTemp( fsen.getfmEnclosing(), temp, null );
1709 output.println(" "+paramsprefix+
1710 "->"+temp.getSafeSymbol()+
1714 // mark yourself done, your task data is now read-only
1715 output.println(" runningSESE->doneExecuting = TRUE;");
1717 // if parent is stalling on you, let them know you're done
1718 if( fsexn.getFlatEnter() != oooa.getMainSESE() ) {
1719 output.println(" if( runningSESE->parentsStallSem != NULL ) {");
1720 output.println(" psem_give( runningSESE->parentsStallSem );");
1721 output.println(" }");
1724 output.println(" pthread_mutex_unlock( &(runningSESE->lock) );");
1726 // decrement dependency count for all SESE's on your forwarding list
1729 output.println(" while( !isEmpty( &runningSESE->forwardList ) ) {");
1730 output.println(" SESEcommon* consumer = (SESEcommon*) getItem( &runningSESE->forwardList );");
1734 output.println(" if(consumer->rentryIdx>0){");
1735 output.println(" // resolved null pointer");
1736 output.println(" int idx;");
1737 output.println(" for(idx=0;idx<consumer->rentryIdx;idx++){");
1738 output.println(" resolvePointer(consumer->rentryArray[idx]);");
1739 output.println(" }");
1740 output.println(" }");
1743 output.println(" if( atomic_sub_and_test( 1, &(consumer->unresolvedDependencies) ) ){");
1744 output.println(" workScheduleSubmit( (void*)consumer );");
1745 output.println(" }");
1746 output.println(" }");
1749 // clean up its lock element from waiting queue, and decrement dependency count for next SESE block
1750 if( fsen != oooa.getMainSESE() ) {
1752 output.println(" /* check memory dependency*/");
1753 output.println(" {");
1754 output.println(" int idx;");
1755 output.println(" for(idx=0;idx<___params___->common.rentryIdx;idx++){");
1756 output.println(" REntry* re=___params___->common.rentryArray[idx];");
1757 output.println(" RETIRERENTRY(re->queue,re);");
1758 output.println(" }");
1759 output.println(" }");
1762 Vector<TempDescriptor> inset=fsen.getInVarsForDynamicCoarseConflictResolution();
1763 if (state.RCR && inset.size() > 0) {
1764 /* Make sure the running SESE is finished */
1765 output.println(" if (unlikely(runningSESE->rcrstatus!=0)) {");
1766 output.println(" if(CAS(&runningSESE->rcrstatus,1,0)==2) {");
1767 output.println(" while(runningSESE->rcrstatus) {");
1768 output.println(" BARRIER();");
1769 output.println(" sched_yield();");
1770 output.println(" }");
1771 output.println(" }");
1772 output.println(" }");
1773 output.println("{");
1774 output.println(" int idx,idx2;");
1776 output.println(" struct rcrRecord *rec;");
1778 .println(" struct Hashtable_rcr ** hashstruct=runningSESE->parent->allHashStructures;");
1780 for (int i = 0; i < inset.size(); i++) {
1781 output.println(" rec=&" + paramsprefix + "->rcrRecords[" + i + "];");
1782 output.println(" while(rec!=NULL) {");
1783 output.println(" for(idx2=0;idx2<rec->index;idx2++) {");
1785 int weaklyConnectedComponentIndex = rcr.getWeakID(inset.get(i), fsen);
1787 output.println(" rcr_RETIREHASHTABLE(hashstruct[" + weaklyConnectedComponentIndex
1788 + "],&(___params___->common), rec->array[idx2], (BinItem_rcr *) rec->ptrarray[idx2]);");
1790 output.println(" }");// exit idx2 for loop
1791 output.println(" rec=rec->next;");
1792 output.println(" }");// exit rec while loop
1794 output.println("}");
1798 // a task has variables to track static/dynamic instances
1799 // that serve as sources, release the parent's ref of each
1800 // non-null var of these types
1801 output.println(" // releasing static SESEs");
1802 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1804 //Iterator<SESEandAgePair> pItr = fsen.getNeededStaticNames().iterator();
1805 //while( pItr.hasNext() ) {
1806 // SESEandAgePair pair = pItr.next();
1807 // output.println(" if( "+pair+" != NULL ) {");
1808 // output.println(" RELEASE_REFERENCE_TO( "+pair+" );");
1809 // output.println(" }");
1811 //output.println(" // releasing dynamic variable sources");
1812 //Iterator<TempDescriptor> dynSrcItr = fsen.getDynamicVarSet().iterator();
1813 //while( dynSrcItr.hasNext() ) {
1814 // TempDescriptor dynSrcVar = dynSrcItr.next();
1815 // output.println(" if( "+dynSrcVar+"_srcSESE != NULL ) {");
1816 // output.println(" RELEASE_REFERENCE_TO( "+dynSrcVar+"_srcSESE );");
1817 // output.println(" }");
1819 // destroy this task's mempool if it is not a leaf task
1820 if( !fsen.getIsLeafSESE() ) {
1821 output.println(" pooldestroy( runningSESE->taskRecordMemPool );");
1822 if (state.RCR && fsen.getInVarsForDynamicCoarseConflictResolution().size() > 0 ) {
1823 output.println(" returnTR();");
1826 output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1829 output.println("{");
1830 output.println("SESEcommon *myparent=runningSESE->parent;");
1832 // if this is not the Main sese (which has no parent) then return
1833 // THIS task's record to the PARENT'S task record pool, and only if
1834 // the reference count is now zero
1835 if( fsen != oooa.getMainSESE() ) {
1836 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1837 output.println(" RELEASE_REFERENCE_TO( runningSESE );");
1838 output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1840 // the main task has no parent, just free its record
1841 output.println(" mlpFreeSESErecord( runningSESE );");
1845 // last of all, decrement your parent's number of running children
1846 output.println(" if( myparent != NULL ) {");
1847 output.println(" if( atomic_sub_and_test( 1, &(myparent->numRunningChildren) ) ) {");
1848 output.println(" pthread_mutex_lock ( &(myparent->lock) );");
1849 output.println(" pthread_cond_signal ( &(myparent->runningChildrenCond) );");
1850 output.println(" pthread_mutex_unlock( &(myparent->lock) );");
1851 output.println(" }");
1852 output.println(" }");
1854 output.println("}");
1856 // as this thread is wrapping up the task, make sure the thread-local var
1857 // for the currently running task record references an invalid task
1858 output.println(" runningSESE = (SESEcommon*) 0x1;");
1860 if( state.COREPROF ) {
1861 output.println("#ifdef CP_EVENTID_TASKRETIRE");
1862 output.println(" CP_LOGEVENT( CP_EVENTID_TASKRETIRE, CP_EVENTTYPE_END );");
1863 output.println("#endif");
1868 public void generateFlatWriteDynamicVarNode( FlatMethod fm,
1870 FlatWriteDynamicVarNode fwdvn,
1874 Hashtable<TempDescriptor, VSTWrapper> writeDynamic = fwdvn.getVar2src();
1876 assert writeDynamic != null;
1878 Iterator wdItr = writeDynamic.entrySet().iterator();
1879 while( wdItr.hasNext() ) {
1880 Map.Entry me = (Map.Entry) wdItr.next();
1881 TempDescriptor refVar = (TempDescriptor) me.getKey();
1882 VSTWrapper vstW = (VSTWrapper) me.getValue();
1883 VariableSourceToken vst = vstW.vst;
1885 output.println(" {");
1886 output.println(" SESEcommon* oldSrc = "+refVar+"_srcSESE;");
1889 // if there is no given source, this variable is ready so
1890 // mark src pointer NULL to signify that the var is up-to-date
1891 output.println(" "+refVar+"_srcSESE = NULL;");
1893 // otherwise we track where it will come from
1894 SESEandAgePair instance = new SESEandAgePair( vst.getSESE(), vst.getAge() );
1895 output.println(" "+refVar+"_srcSESE = "+instance+";");
1896 output.println(" "+refVar+"_srcOffset = (INTPTR) &((("+
1897 vst.getSESE().getSESErecordName()+"*)0)->"+vst.getAddrVar()+");");
1900 // no matter what we did above, track reference count of whatever
1901 // this variable pointed to, do release last in case we're just
1902 // copying the same value in because 1->2->1 is safe but ref count
1903 // 1->0->1 has a window where it looks like it should be free'd
1904 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1905 output.println(" if( "+refVar+"_srcSESE != NULL ) {");
1906 output.println(" ADD_REFERENCE_TO( "+refVar+"_srcSESE );");
1907 output.println(" }");
1908 output.println(" if( oldSrc != NULL ) {");
1909 output.println(" RELEASE_REFERENCE_TO( oldSrc );");
1910 output.println(" }");
1911 output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1913 output.println(" }");
1918 protected void generateFlatNew( FlatMethod fm,
1921 PrintWriter output ) {
1923 if( fn.getType().isArray() ) {
1924 int arrayid = state.getArrayNumber( fn.getType() )+state.numClasses();
1926 if( GENERATEPRECISEGC ) {
1927 output.println(generateTemp( fm, fn.getDst(), lb )+
1928 "=allocate_newarray_mlp("+localsprefixaddr+
1929 ", "+arrayid+", "+generateTemp( fm, fn.getSize(), lb )+
1931 oooa.getDisjointAnalysis().getAllocationSiteFromFlatNew( fn ).getUniqueAllocSiteID()+
1933 output.println(" oid += oidIncrement;");
1935 output.println(generateTemp( fm, fn.getDst(), lb )+
1936 "=allocate_newarray("+arrayid+
1937 ", "+generateTemp( fm, fn.getSize(), lb )+
1943 if( GENERATEPRECISEGC ) {
1944 output.println( generateTemp( fm, fn.getDst(), lb )+
1945 "=allocate_new_mlp("+localsprefixaddr+
1946 ", "+fn.getType().getClassDesc().getId()+
1948 oooa.getDisjointAnalysis().getAllocationSiteFromFlatNew( fn ).getUniqueAllocSiteID()+
1950 output.println(" oid += oidIncrement;");
1952 output.println( generateTemp( fm, fn.getDst(), lb )+
1953 "=allocate_new("+fn.getType().getClassDesc().getId()+
1960 private int calculateSizeOfSESEParamList(FlatSESEEnterNode fsen){
1962 Set<TempDescriptor> tdSet=new HashSet<TempDescriptor>();
1964 for (Iterator iterator = fsen.getInVarSet().iterator(); iterator.hasNext();) {
1965 TempDescriptor tempDescriptor = (TempDescriptor) iterator.next();
1966 if(!tempDescriptor.getType().isPrimitive() || tempDescriptor.getType().isArray()){
1967 tdSet.add(tempDescriptor);
1971 for (Iterator iterator = fsen.getOutVarSet().iterator(); iterator.hasNext();) {
1972 TempDescriptor tempDescriptor = (TempDescriptor) iterator.next();
1973 if(!tempDescriptor.getType().isPrimitive() || tempDescriptor.getType().isArray()){
1974 tdSet.add(tempDescriptor);
1978 return tdSet.size();
1981 private String calculateSizeOfSESEParamSize(FlatSESEEnterNode fsen){
1982 HashMap <String,Integer> map=new HashMap();
1983 HashSet <TempDescriptor> processed=new HashSet<TempDescriptor>();
1986 // space for all in and out set primitives
1987 Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
1988 inSetAndOutSet.addAll( fsen.getInVarSet() );
1989 inSetAndOutSet.addAll( fsen.getOutVarSet() );
1991 Set<TempDescriptor> inSetAndOutSetPrims = new HashSet<TempDescriptor>();
1993 Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
1994 while( itr.hasNext() ) {
1995 TempDescriptor temp = itr.next();
1996 TypeDescriptor type = temp.getType();
1997 if( !type.isPtr() ) {
1998 inSetAndOutSetPrims.add( temp );
2002 Iterator<TempDescriptor> itrPrims = inSetAndOutSetPrims.iterator();
2003 while( itrPrims.hasNext() ) {
2004 TempDescriptor temp = itrPrims.next();
2005 TypeDescriptor type = temp.getType();
2006 if(type.isPrimitive()){
2007 Integer count=map.get(type.getSymbol());
2009 count=new Integer(1);
2010 map.put(type.getSymbol(), count);
2012 map.put(type.getSymbol(), new Integer(count.intValue()+1));
2017 Set<String> keySet=map.keySet();
2018 for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
2019 String key = (String) iterator.next();
2020 rtr+="+sizeof("+key+")*"+map.get(key);