9857ca60e88f352bcb664a18ebd002b587953d2e
[IRC.git] / Robust / src / IR / Flat / BuildOoOJavaCode.java
1 package IR.Flat;
2 import IR.*;
3 import IR.Tree.*;
4
5 import java.util.*;
6 import java.io.*;
7
8 import Util.*;
9 import Analysis.TaskStateAnalysis.*;
10 import Analysis.CallGraph.*;
11 import Analysis.Disjoint.*;
12 import Analysis.OoOJava.*;
13 import Analysis.Loops.*;
14 import Analysis.Locality.*;
15
16
17
18 public class BuildOoOJavaCode extends BuildCode {
19
20   OoOJavaAnalysis oooa;
21
22   String maxTaskRecSizeStr="__maxTaskRecSize___";
23
24   String mlperrstr = 
25     "if(status != 0) { "+
26     "sprintf(errmsg, \"MLP error at %s:%d\", __FILE__, __LINE__); "+
27     "perror(errmsg); exit(-1); }";
28
29   RuntimeConflictResolver rcr = null;
30
31   public BuildOoOJavaCode( State            st, 
32                            Hashtable        temptovar, 
33                            TypeUtil         typeutil, 
34                            SafetyAnalysis   sa, 
35                            OoOJavaAnalysis  oooa
36                            ) {
37     super( st, temptovar, typeutil, sa);
38
39     this.oooa = oooa;
40   }
41
42
43   protected void additionalIncludesMethodsHeader( PrintWriter outmethodheader ) {
44
45     outmethodheader.println("#include <stdlib.h>");
46     outmethodheader.println("#include <stdio.h>");
47     outmethodheader.println("#include <string.h>");
48     outmethodheader.println("#include \"mlp_runtime.h\"");
49     outmethodheader.println("#include \"psemaphore.h\"");
50     outmethodheader.println("#include \"memPool.h\"");
51
52     if (state.RCR) {
53       outmethodheader.println("#include \"rcr_runtime.h\"");
54     }
55
56     // spit out a global to inform all worker threads what
57     // the maximum size is for any task record
58     outmethodheader.println("extern int "+maxTaskRecSizeStr+";");
59   }
60
61
62   protected void preCodeGenInitialization() {
63
64     // have to initialize some SESE compiler data before
65     // analyzing normal methods, which must happen before
66     // generating SESE internal code
67       
68     Iterator<FlatSESEEnterNode> seseit = oooa.getAllSESEs().iterator();
69
70     while( seseit.hasNext() ) {
71       FlatSESEEnterNode fsen = seseit.next();
72       initializeSESE( fsen );
73     }
74       
75     //TODO signal the object that will report errors
76     if( state.RCR ) {
77       try {
78         rcr = new RuntimeConflictResolver( PREFIX, 
79                                            oooa,
80                                            state );
81         System.out.println("Runtime Conflict Resolver started.");
82       } catch (FileNotFoundException e) {
83         System.out.println("Runtime Conflict Resolver could not create output file.");
84       }
85     }
86   }
87
88
89   protected void initializeSESE( FlatSESEEnterNode fsen ) {
90
91     FlatMethod       fm = fsen.getfmEnclosing();
92     MethodDescriptor md = fm.getMethod();
93     ClassDescriptor  cn = md.getClassDesc();    
94         
95     // Creates bogus method descriptor to index into tables
96     Modifiers modBogus = new Modifiers();
97     MethodDescriptor mdBogus = 
98       new MethodDescriptor( modBogus, 
99                             new TypeDescriptor( TypeDescriptor.VOID ), 
100                             "sese_"+fsen.getPrettyIdentifier()+fsen.getIdentifier()
101                             );
102     
103     mdBogus.setClassDesc( fsen.getcdEnclosing() );
104     FlatMethod fmBogus = new FlatMethod( mdBogus, null );
105     fsen.setfmBogus( fmBogus );
106     fsen.setmdBogus( mdBogus );
107     
108     Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
109     inSetAndOutSet.addAll( fsen.getInVarSet() );
110     inSetAndOutSet.addAll( fsen.getOutVarSet() );
111
112     // Build paramsobj for bogus method descriptor
113     ParamsObject objectparams = new ParamsObject( mdBogus, tag++ );
114     paramstable.put( mdBogus, objectparams );
115     
116     Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
117     while( itr.hasNext() ) {
118       TempDescriptor temp = itr.next();
119       TypeDescriptor type = temp.getType();
120       if( type.isPtr() ) {
121         objectparams.addPtr( temp );
122       } else {
123         objectparams.addPrim( temp );
124       }
125     }
126         
127     // Build normal temp object for bogus method descriptor
128     TempObject objecttemps = new TempObject( objectparams, mdBogus, tag++ );
129     tempstable.put( mdBogus, objecttemps );
130
131     for( Iterator nodeit = fsen.getNodeSet().iterator(); nodeit.hasNext(); ) {
132       FlatNode         fn     = (FlatNode)nodeit.next();
133       TempDescriptor[] writes = fn.writesTemps();
134
135       for( int i = 0; i < writes.length; i++ ) {
136         TempDescriptor temp = writes[i];
137         TypeDescriptor type = temp.getType();
138
139         if( type.isPtr() ) {
140           objecttemps.addPtr( temp );
141         } else {
142           objecttemps.addPrim( temp );
143         }
144       }
145     }
146   }
147
148
149   protected void postCodeGenCleanUp() {
150     if(rcr != null) {
151       rcr.close();
152       System.out.println("Runtime Conflict Resolver Done.");
153     }
154   }
155
156   
157   protected void additionalCodeGen( PrintWriter outmethodheader,
158                                     PrintWriter outstructs,
159                                     PrintWriter outmethod ) {
160
161     // Output function prototypes and structures for SESE's and code
162
163     // spit out a global to inform all worker threads with
164     // the maximum size is for any task record
165     outmethod.println( "int "+maxTaskRecSizeStr+" = 0;" );
166
167     // first generate code for each sese's internals     
168     Iterator<FlatSESEEnterNode> seseit;
169     seseit = oooa.getAllSESEs().iterator();
170       
171     while( seseit.hasNext() ) {
172       FlatSESEEnterNode fsen = seseit.next();
173       generateMethodSESE( fsen, outstructs, outmethodheader, outmethod );
174     }
175
176     // then write the invokeSESE switch to decouple scheduler
177     // from having to do unique details of sese invocation
178     generateSESEinvocationMethod( outmethodheader, outmethod );
179   }
180
181
182   protected void additionalCodeAtTopOfMain( PrintWriter outmethod ) {
183     
184     // do a calculation to determine which task record
185     // is the largest, store that as a global value for
186     // allocating records
187     Iterator<FlatSESEEnterNode> seseit = oooa.getAllSESEs().iterator();
188     while( seseit.hasNext() ) {
189       FlatSESEEnterNode fsen = seseit.next();
190       outmethod.println("if( sizeof( "+fsen.getSESErecordName()+
191                         " ) > "+maxTaskRecSizeStr+
192                         " ) { "+maxTaskRecSizeStr+
193                         " = sizeof( "+fsen.getSESErecordName()+
194                         " ); }" );
195     }
196       
197     outmethod.println("  runningSESE = NULL;");
198
199     outmethod.println("  workScheduleInit( "+state.OOO_NUMCORES+", invokeSESEmethod );");
200       
201     //initializes data structures needed for the RCR traverser
202     if( state.RCR && rcr != null ) {
203       outmethod.println("  initializeStructsRCR();");
204       outmethod.println("  createAndFillMasterHashStructureArray();");
205     }
206   }
207
208
209   protected void additionalCodeAtBottomOfMain( PrintWriter outmethod ) {
210     outmethod.println("  workScheduleBegin();");
211   }
212
213
214   protected void additionalIncludesMethodsImplementation( PrintWriter outmethod ) {
215     outmethod.println("#include <stdlib.h>");
216     outmethod.println("#include <stdio.h>");
217     outmethod.println("#include \"mlp_runtime.h\"");
218     outmethod.println("#include \"psemaphore.h\"");
219       
220     if( state.RCR ) {
221       outmethod.println("#include \"trqueue.h\"");
222       outmethod.println("#include \"RuntimeConflictResolver.h\"");
223       outmethod.println("#include \"rcr_runtime.h\"");
224       outmethod.println("#include \"hashStructure.h\"");
225     }
226   }
227
228
229   protected void additionalIncludesStructsHeader( PrintWriter outstructs ) {
230     outstructs.println("#include \"mlp_runtime.h\"");
231     outstructs.println("#include \"psemaphore.h\"");
232     if( state.RCR ) {
233       outstructs.println("#include \"rcr_runtime.h\"");
234     }
235   }
236
237
238   protected void additionalClassObjectFields( PrintWriter outclassdefs ) {
239     outclassdefs.println("  int oid;");
240     outclassdefs.println("  int allocsite;");
241   }
242
243
244   protected void additionalCodeAtTopMethodsImplementation( PrintWriter outmethod ) {
245     outmethod.print("extern __thread int oid;\n");
246     outmethod.print("extern int oidIncrement;\n");
247   }
248
249
250   protected void additionalCodeAtTopFlatMethodBody( PrintWriter output, FlatMethod fm ) {
251
252     // declare variables for naming static and dynamic SESE's
253     ContextTaskNames context = oooa.getContextTaskNames( fm );
254
255     output.println("   /* static SESE names */");
256     Iterator<SESEandAgePair> pItr = context.getNeededStaticNames().iterator();
257     while( pItr.hasNext() ) {
258       SESEandAgePair pair = pItr.next();
259       output.println("   void* "+pair+" = NULL;");
260     }
261     
262     output.println("   /* dynamic variable sources */");
263     Iterator<TempDescriptor> dynSrcItr = context.getDynamicVarSet().iterator();
264     while( dynSrcItr.hasNext() ) {
265       TempDescriptor dynSrcVar = dynSrcItr.next();
266       output.println("   SESEcommon*  "+dynSrcVar+"_srcSESE = NULL;");
267       output.println("   INTPTR       "+dynSrcVar+"_srcOffset = 0x1;");
268     }    
269
270           
271     // eom - set up related allocation sites's waiting queues
272     // TODO: we have to do a table-based thing here...
273     // jjenista, I THINK WE LOSE THIS ALTOGETHER!
274     /*
275     FlatSESEEnterNode callerSESEplaceholder = (FlatSESEEnterNode) fm.getNext( 0 );
276     if(callerSESEplaceholder!= oooa.getMainSESE()){
277       Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(callerSESEplaceholder);       
278       if (graph != null && graph.hasConflictEdge()) {          
279         output.println("   // set up waiting queues ");
280         output.println("   int numMemoryQueue=0;");
281         output.println("   int memoryQueueItemID=0;");
282         Set<Analysis.OoOJava.SESELock> lockSet = oooa.getLockMappings(graph);
283         System.out.println("#lockSet="+lockSet.hashCode());
284         System.out.println("lockset="+lockSet);
285         for (Iterator iterator = lockSet.iterator(); iterator.hasNext();) {
286           Analysis.OoOJava.SESELock seseLock = (Analysis.OoOJava.SESELock) iterator.next();
287           System.out.println("id="+seseLock.getID());
288           System.out.println("#="+seseLock);
289         }
290         System.out.println("size="+lockSet.size());
291         if (lockSet.size() > 0) {
292           output.println("   numMemoryQueue=" + lockSet.size() + ";");
293           output.println("   runningSESE->numMemoryQueue=numMemoryQueue;");
294           output.println("   runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);");
295           output.println();
296         }
297       }
298     }
299     */
300   }
301
302
303   protected void generateMethodSESE(FlatSESEEnterNode fsen,
304                                     PrintWriter       outputStructs,
305                                     PrintWriter       outputMethHead,
306                                     PrintWriter       outputMethods) {
307
308     ParamsObject objectparams = (ParamsObject) paramstable.get( fsen.getmdBogus() );                
309     TempObject   objecttemps  = (TempObject)   tempstable .get( fsen.getmdBogus() );
310     
311     // generate locals structure
312     outputStructs.println("struct "+
313                           fsen.getcdEnclosing().getSafeSymbol()+
314                           fsen.getmdBogus().getSafeSymbol()+"_"+
315                           fsen.getmdBogus().getSafeMethodDescriptor()+
316                           "_locals {");
317     
318     outputStructs.println("  int size;");
319     outputStructs.println("  void * next;");
320
321     for(int i=0; i<objecttemps.numPointers(); i++) {
322       TempDescriptor temp=objecttemps.getPointer(i);
323
324       if (temp.getType().isNull())
325         outputStructs.println("  void * "+temp.getSafeSymbol()+";");
326       else
327         outputStructs.println("  struct "+
328                               temp.getType().getSafeSymbol()+" * "+
329                               temp.getSafeSymbol()+";");
330     }
331     outputStructs.println("};\n");
332
333     
334     // divide in-set and out-set into objects and primitives to prep
335     // for the record generation just below
336     Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
337     inSetAndOutSet.addAll( fsen.getInVarSet() );
338     inSetAndOutSet.addAll( fsen.getOutVarSet() );
339
340     Set<TempDescriptor> inSetAndOutSetObjs  = new HashSet<TempDescriptor>();
341     Set<TempDescriptor> inSetAndOutSetPrims = new HashSet<TempDescriptor>();
342
343     Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
344     while( itr.hasNext() ) {
345       TempDescriptor temp = itr.next();
346       TypeDescriptor type = temp.getType();
347       if( type.isPtr() ) {
348         inSetAndOutSetObjs.add( temp );
349       } else {
350         inSetAndOutSetPrims.add( temp );
351       }
352     }
353
354
355     // generate the SESE record structure
356     outputStructs.println(fsen.getSESErecordName()+" {");
357     
358     // data common to any SESE, and it must be placed first so
359     // a module that doesn't know what kind of SESE record this
360     // is can cast the pointer to a common struct
361     outputStructs.println("  SESEcommon common;");
362
363     // then garbage list stuff
364     outputStructs.println("  /* next is in-set and out-set objects that look like a garbage list */");
365     outputStructs.println("  int size;");
366     outputStructs.println("  void * next;");
367
368     // I think that the set of TempDescriptors inSetAndOutSetObjs
369     // calculated above should match the pointer object params
370     // used in the following code, but let's just leave the working
371     // implementation unless there is actually a problem...
372
373     Vector<TempDescriptor> inset=fsen.getInVarsForDynamicCoarseConflictResolution();
374     for(int i=0; i<inset.size();i++) {
375       TempDescriptor temp=inset.get(i);
376       if (temp.getType().isNull())
377         outputStructs.println("  void * "+temp.getSafeSymbol()+
378                               ";  /* in-or-out-set obj in gl */");
379       else
380         outputStructs.println("  struct "+temp.getType().getSafeSymbol()+" * "+
381                               temp.getSafeSymbol()+"; /* in-or-out-set obj in gl */");
382     }
383
384     for(int i=0; i<objectparams.numPointers(); i++) {
385       TempDescriptor temp=objectparams.getPointer(i);
386       if (!inset.contains(temp)) {
387         if (temp.getType().isNull())
388           outputStructs.println("  void * "+temp.getSafeSymbol()+
389                                 ";  /* in-or-out-set obj in gl */");
390         else
391           outputStructs.println("  struct "+temp.getType().getSafeSymbol()+" * "+
392                                 temp.getSafeSymbol()+"; /* in-or-out-set obj in gl */");
393       }
394     }
395     
396     outputStructs.println("  /* next is primitives for in-set and out-set and dynamic tracking */");
397
398     Iterator<TempDescriptor> itrPrims = inSetAndOutSetPrims.iterator();
399     while( itrPrims.hasNext() ) {
400       TempDescriptor temp = itrPrims.next();
401       TypeDescriptor type = temp.getType();
402       if(type.isPrimitive()){
403           outputStructs.println("  "+temp.getType().getSafeSymbol()+" "+
404                                 temp.getSafeSymbol()+"; /* in-set or out-set primitive */");
405       }      
406     }
407     
408     // note that the sese record pointer will be added below, just primitive part of tracking here
409     Iterator<TempDescriptor> itrDynInVars = fsen.getDynamicInVarSet().iterator();
410     while( itrDynInVars.hasNext() ) {
411       TempDescriptor dynInVar = itrDynInVars.next();
412       outputStructs.println("  INTPTR "+dynInVar+"_srcOffset; /* dynamic tracking primitive */");
413     }  
414     
415     
416     outputStructs.println("  /* everything after this should be pointers to an SESE record */" );
417
418     // other half of info for dynamic tracking, the SESE record pointer
419     itrDynInVars = fsen.getDynamicInVarSet().iterator();
420     while( itrDynInVars.hasNext() ) {
421       TempDescriptor dynInVar = itrDynInVars.next();
422       String depRecField = dynInVar+"_srcSESE";
423       outputStructs.println("  SESEcommon* "+depRecField+";");
424       addingDepRecField( fsen, depRecField );
425     }  
426     
427     // statically known sese sources are record pointers, too
428     Iterator<SESEandAgePair> itrStaticInVarSrcs = fsen.getStaticInVarSrcs().iterator();
429     while( itrStaticInVarSrcs.hasNext() ) {
430       SESEandAgePair srcPair = itrStaticInVarSrcs.next();
431       outputStructs.println("  "+srcPair.getSESE().getSESErecordName()+"* "+srcPair+";");
432       addingDepRecField(fsen, srcPair.toString());
433     }
434
435     if (state.RCR) {
436       if (inset.size()!=0) {
437         outputStructs.println("struct rcrRecord rcrRecords["+inset.size()+"];");
438       } 
439     }
440     
441     if( fsen.getFirstDepRecField() != null ) {
442       outputStructs.println("  /* compiler believes first dependent SESE record field above is: "+
443                             fsen.getFirstDepRecField()+" */" );
444     }
445     outputStructs.println("};\n");
446
447     
448     // write method declaration to header file
449     outputMethHead.print("void ");
450     outputMethHead.print(fsen.getSESEmethodName()+"(");
451     outputMethHead.print(fsen.getSESErecordName()+"* "+paramsprefix);
452     outputMethHead.println(");\n");
453
454
455     generateFlatMethodSESE( fsen.getfmBogus(), 
456                             fsen.getcdEnclosing(), 
457                             fsen, 
458                             fsen.getFlatExit(), 
459                             outputMethods );
460   }
461
462   // used when generating the specific SESE record struct
463   // to remember the FIRST field name of sese records 
464   // that the current SESE depends on--we need to know the
465   // offset to the first one for garbage collection
466   protected void addingDepRecField( FlatSESEEnterNode fsen,
467                                     String            field ) {
468     if( fsen.getFirstDepRecField() == null ) {
469       fsen.setFirstDepRecField( field );
470     }
471     fsen.incNumDepRecs();
472   }
473
474
475   private void generateFlatMethodSESE(FlatMethod        fm, 
476                                       ClassDescriptor   cn, 
477                                       FlatSESEEnterNode fsen, 
478                                       FlatSESEExitNode  seseExit, 
479                                       PrintWriter       output
480                                       ) {
481
482     MethodDescriptor md = fm.getMethod();
483
484     output.print("void ");
485     output.print(fsen.getSESEmethodName()+"(");
486     output.print(fsen.getSESErecordName()+"* "+paramsprefix);
487     output.println("){\n");
488
489
490     TempObject objecttemp=(TempObject) tempstable.get(md);
491
492     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
493       output.print("   struct "+
494                    cn.getSafeSymbol()+
495                    md.getSafeSymbol()+"_"+
496                    md.getSafeMethodDescriptor()+
497                    "_locals "+localsprefix+"={");
498       output.print(objecttemp.numPointers()+",");
499       output.print("&(((SESEcommon*)(___params___))[1])");
500       for(int j=0; j<objecttemp.numPointers(); j++)
501         output.print(", NULL");
502       output.println("};");
503     }
504
505     output.println("   /* regular local primitives */");
506     for(int i=0; i<objecttemp.numPrimitives(); i++) {
507       TempDescriptor td=objecttemp.getPrimitive(i);
508       TypeDescriptor type=td.getType();
509       if (type.isNull())
510         output.println("   void * "+td.getSafeSymbol()+";");
511       else if (type.isClass()||type.isArray())
512         output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
513       else
514         output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
515     }
516
517
518     // declare variables for naming static and dynamic SESE's
519     ContextTaskNames context = oooa.getContextTaskNames( fsen );
520
521     output.println("   /* static SESE names */");
522     Iterator<SESEandAgePair> pItr = context.getNeededStaticNames().iterator();
523     while( pItr.hasNext() ) {
524       SESEandAgePair pair = pItr.next();
525       output.println("   SESEcommon* "+pair+" = NULL;");
526     }
527     
528     // declare variables for tracking dynamic sources
529     output.println("   /* dynamic variable sources */");
530     Iterator<TempDescriptor> dynSrcItr = context.getDynamicVarSet().iterator();
531     while( dynSrcItr.hasNext() ) {
532       TempDescriptor dynSrcVar = dynSrcItr.next();
533       output.println("   SESEcommon*  "+dynSrcVar+"_srcSESE = NULL;");
534       output.println("   INTPTR       "+dynSrcVar+"_srcOffset = 0x1;");
535     }    
536
537
538     // declare local temps for in-set primitives, and if it is
539     // a ready-source variable, get the value from the record
540     output.println("   /* local temps for in-set primitives */");
541     Iterator<TempDescriptor> itrInSet = fsen.getInVarSet().iterator();
542     while( itrInSet.hasNext() ) {
543       TempDescriptor temp = itrInSet.next();
544       TypeDescriptor type = temp.getType();
545       if( !type.isPtr() ) {
546         if( fsen.getReadyInVarSet().contains( temp ) ) {
547           output.println("   "+type+" "+temp+" = "+paramsprefix+"->"+temp+";");
548         } else {
549           output.println("   "+type+" "+temp+";");
550         }
551       }
552     }    
553
554     // declare local temps for out-set primitives if its not already
555     // in the in-set, and it's value will get written so no problem
556     output.println("   /* local temp for out-set prim, not already in the in-set */");
557     Iterator<TempDescriptor> itrOutSet = fsen.getOutVarSet().iterator();
558     while( itrOutSet.hasNext() ) {
559       TempDescriptor temp = itrOutSet.next();
560       TypeDescriptor type = temp.getType();
561       if( !type.isPtr() && !fsen.getInVarSet().contains( temp ) ) {
562         output.println("   "+type+" "+temp+";");       
563       }
564     }
565
566
567     // initialize thread-local var to a the task's record, which is fused
568     // with the param list
569     output.println("   ");
570     output.println("   // code of this task's body should use this to access the running task record");
571     output.println("   runningSESE = &(___params___->common);");
572     output.println("   childSESE = 0;");
573     output.println("   ");
574     
575
576     // eom - setup memory queue
577     output.println("   // set up memory queues ");
578     output.println("   int numMemoryQueue=0;");
579     output.println("   int memoryQueueItemID=0;");
580     Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph( fsen );
581     if( graph != null && graph.hasConflictEdge() ) {
582       output.println("   {");
583       Set<Analysis.OoOJava.SESELock> lockSet = oooa.getLockMappings( graph );
584       System.out.println("#lockSet="+lockSet);
585       if( lockSet.size() > 0 ) {
586         output.println("   numMemoryQueue=" + lockSet.size() + ";");
587         output.println("   runningSESE->numMemoryQueue=numMemoryQueue;");
588         output.println("   runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);");
589         output.println();
590       }
591       output.println("   }");
592     }
593
594
595     // set up a task's mem pool to recycle the allocation of children tasks
596     // don't bother if the task never has children (a leaf task)
597     output.println( "#ifndef OOO_DISABLE_TASKMEMPOOL" );
598     if( !fsen.getIsLeafSESE() ) {
599       output.println("   runningSESE->taskRecordMemPool = poolcreate( "+
600                      maxTaskRecSizeStr+", freshTaskRecordInitializer );");
601       if (state.RCR && !rcr.hasEmptyTraversers(fsen)) {
602         output.println("   createTR();");
603         output.println("   runningSESE->allHashStructures=TRqueue->allHashStructures;");
604       }
605     } else {
606       // make it clear we purposefully did not initialize this
607       output.println("   runningSESE->taskRecordMemPool = (MemPool*)0x7;");
608     }
609     output.println( "#endif // OOO_DISABLE_TASKMEMPOOL" );
610
611
612     // copy in-set into place, ready vars were already 
613     // copied when the SESE was issued
614     Iterator<TempDescriptor> tempItr;
615
616     // static vars are from a known SESE
617     output.println("   // copy variables from static sources");
618     tempItr = fsen.getStaticInVarSet().iterator();
619     while( tempItr.hasNext() ) {
620       TempDescriptor temp = tempItr.next();
621       VariableSourceToken vst = fsen.getStaticInVarSrc( temp );
622       SESEandAgePair srcPair = new SESEandAgePair( vst.getSESE(), vst.getAge() );
623       output.println("   "+generateTemp( fsen.getfmBogus(), temp)+
624                      " = "+paramsprefix+"->"+srcPair+"->"+vst.getAddrVar()+";");
625     }
626     
627     output.println("   // decrement references to static sources");
628     for( Iterator<SESEandAgePair> pairItr = fsen.getStaticInVarSrcs().iterator(); pairItr.hasNext(); ) {
629       SESEandAgePair srcPair = pairItr.next();
630       output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
631       output.println("   {");
632       output.println("     SESEcommon* src = &("+paramsprefix+"->"+srcPair+"->common);");
633       output.println("     RELEASE_REFERENCE_TO( src );");
634       output.println("   }");
635       output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
636     }
637
638
639     // dynamic vars come from an SESE and src
640     output.println("     // copy variables from dynamic sources");
641     tempItr = fsen.getDynamicInVarSet().iterator();
642     while( tempItr.hasNext() ) {
643       TempDescriptor temp = tempItr.next();
644       TypeDescriptor type = temp.getType();
645       
646       // go grab it from the SESE source
647       output.println("   if( "+paramsprefix+"->"+temp+"_srcSESE != NULL ) {");
648
649       String typeStr;
650       if( type.isNull() ) {
651         typeStr = "void*";
652       } else if( type.isClass() || type.isArray() ) {
653         typeStr = "struct "+type.getSafeSymbol()+"*";
654       } else {
655         typeStr = type.getSafeSymbol();
656       }
657       
658       output.println("     "+generateTemp( fsen.getfmBogus(), temp)+
659                      " = *(("+typeStr+"*) ((void*)"+
660                      paramsprefix+"->"+temp+"_srcSESE + "+
661                      paramsprefix+"->"+temp+"_srcOffset));");
662
663       output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
664       output.println("     SESEcommon* src = "+paramsprefix+"->"+temp+"_srcSESE;");
665       output.println("     RELEASE_REFERENCE_TO( src );");
666       output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
667
668       // or if the source was our parent, its already in our record to grab
669       output.println("   } else {");
670       output.println("     "+generateTemp( fsen.getfmBogus(), temp)+
671                            " = "+paramsprefix+"->"+temp+";");
672       output.println("   }");
673     }
674
675     // Check to see if we need to do a GC if this is a
676     // multi-threaded program...    
677     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
678         output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
679       //Don't bother if we aren't in recursive methods...The loops case will catch it
680 //      if (callgraph.getAllMethods(md).contains(md)) {
681 //        if(this.state.MULTICOREGC) {
682 //          output.println("if(gcflag) gc("+localsprefixaddr+");");
683 //        } else {
684 //        output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
685 //      }
686 //      }
687     }    
688
689     if( state.COREPROF ) {
690       output.println("#ifdef CP_EVENTID_TASKEXECUTE");
691       output.println("   CP_LOGEVENT( CP_EVENTID_TASKEXECUTE, CP_EVENTTYPE_BEGIN );");
692       output.println("#endif");
693     }
694
695     HashSet<FlatNode> exitset=new HashSet<FlatNode>();
696     exitset.add(seseExit);    
697     generateCode(fsen.getNext(0), fm, exitset, output);
698     output.println("}\n\n");    
699   }
700
701
702   // when a new mlp thread is created for an issued SESE, it is started
703   // by running this method which blocks on a cond variable until
704   // it is allowed to transition to execute.  Then a case statement
705   // allows it to invoke the method with the proper SESE body, and after
706   // exiting the SESE method, executes proper SESE exit code before the
707   // thread can be destroyed
708   private void generateSESEinvocationMethod(PrintWriter outmethodheader,
709                                             PrintWriter outmethod
710                                             ) {
711
712     outmethodheader.println("void* invokeSESEmethod( void* seseRecord );");
713     outmethod.println(      "void* invokeSESEmethod( void* seseRecord ) {");
714     outmethod.println(      "  int status;");
715     outmethod.println(      "  char errmsg[128];");
716
717     // generate a case for each SESE class that can be invoked
718     outmethod.println(      "  switch( ((SESEcommon*)seseRecord)->classID ) {");
719     outmethod.println(      "    ");
720     Iterator<FlatSESEEnterNode> seseit;
721     seseit = oooa.getAllSESEs().iterator();
722
723     while( seseit.hasNext() ) {
724       FlatSESEEnterNode fsen = seseit.next();
725
726       outmethod.println(    "    /* "+fsen.getPrettyIdentifier()+" */");
727       outmethod.println(    "    case "+fsen.getIdentifier()+":");
728       outmethod.println(    "      "+fsen.getSESEmethodName()+"( seseRecord );");  
729       
730       if( fsen.getIsMainSESE() ) {
731         outmethod.println(  "      workScheduleExit();");
732       }
733
734       outmethod.println(    "      break;");
735       outmethod.println(    "");
736     }
737
738     // default case should never be taken, error out
739     outmethod.println(      "    default:");
740     outmethod.println(      "      printf(\"Error: unknown SESE class ID in invoke method.\\n\");");
741     outmethod.println(      "      exit(-30);");
742     outmethod.println(      "      break;");
743     outmethod.println(      "  }");
744     outmethod.println(      "  return NULL;");
745     outmethod.println(      "}\n\n");
746   }
747
748
749
750   protected void stallMEMRCR( FlatMethod fm, 
751                               FlatNode fn, 
752                               Set<WaitingElement> waitingElementSet, PrintWriter output) {
753     output.println("// stall on parent's stall sites ");
754     output.println("   {");
755     output.println("     REntry* rentry;");
756     output.println("     // stallrecord sometimes is used as a task record for instance ");
757     output.println("     // when you call RELEASE_REFERENCE_TO on a stall record.");
758     output.println("     // so the parent field must be initialized.");
759     output.println("     SESEstall * stallrecord=(SESEstall *) poolalloc(runningSESE->taskRecordMemPool);");    
760     output.println("     stallrecord->common.parent=runningSESE;");
761     output.println("     stallrecord->common.unresolvedDependencies=10000;");
762     output.println("     stallrecord->common.rcrstatus=1;");
763     output.println("     stallrecord->common.offsetToParamRecords=(INTPTR) & (((SESEstall *)0)->rcrRecords);");
764     output.println("     stallrecord->common.refCount = 3;");
765     output.println("     int localCount=10000;");
766     output.println("     stallrecord->rcrRecords[0].index=0;");
767     output.println("     stallrecord->rcrRecords[0].flag=0;");
768     output.println("     stallrecord->rcrRecords[0].next=NULL;");
769     output.println("     stallrecord->common.parentsStallSem=&runningSESEstallSem;");
770     output.println("     psem_reset( &runningSESEstallSem);");
771     output.println("     stallrecord->tag=runningSESEstallSem.tag;");
772
773     TempDescriptor stalltd=null;
774     for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) {
775       WaitingElement waitingElement =(WaitingElement) iterator.next();
776       if (waitingElement.getStatus() >= ConflictNode.COARSE) {
777         output.println("     rentry=mlpCreateREntry(runningSESE->memoryQueueArray["
778                        + waitingElement.getQueueID() + "]," + waitingElement.getStatus()
779                        + ", (SESEcommon *) stallrecord, 1LL);");
780       } else {
781         throw new Error("Fine-grained conflict: This should not happen in RCR");
782       }
783       output.println("     rentry->queue=runningSESE->memoryQueueArray["
784                      + waitingElement.getQueueID() + "];");
785       output.println("     if(ADDRENTRY(runningSESE->memoryQueueArray["
786                      + waitingElement.getQueueID() + "],rentry)==NOTREADY) {");
787       output.println("       localCount--;");
788       output.println("     }");
789       output.println("#if defined(RCR)&&!defined(OOO_DISABLE_TASKMEMPOOL)");
790       output.println("     else poolfreeinto(runningSESE->memoryQueueArray["+
791                      waitingElement.getQueueID()+
792                      "]->rentrypool, rentry);");
793       output.println("#endif");
794       if (stalltd==null) {
795         stalltd=waitingElement.getTempDesc();
796       } else if (stalltd!=waitingElement.getTempDesc()) {
797         throw new Error("Multiple temp descriptors at stall site"+stalltd+"!="+waitingElement.getTempDesc());
798       }
799     }
800
801     //did all of the course grained stuff
802     output.println("     if(!atomic_sub_and_test(localCount, &(stallrecord->common.unresolvedDependencies))) {");
803     //have to do fine-grained work also
804     output.println("       stallrecord->___obj___=(struct ___Object___ *)"
805                    + generateTemp(fm, stalltd) + ";");
806     output.println("       stallrecord->common.classID=-"
807                    + rcr.getTraverserID(stalltd, fn) + ";");
808     
809     output.println("       enqueueTR(TRqueue, (void *)stallrecord);");
810
811     if (state.COREPROF) {
812       output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
813       output
814         .println("        CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );");
815       output.println("#endif");
816     }    
817     
818     output.println("       psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
819     
820     if (state.COREPROF) {
821       output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
822       output
823         .println("        CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );");
824       output.println("#endif");
825     }
826
827     output.println("     } else {");//exit if condition
828     //release traversers reference if we didn't use traverser
829     output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
830     output.println("  RELEASE_REFERENCES_TO((SESEcommon *)stallrecord, 2);");
831     output.println("#endif");
832     output.println("     }");
833     //release our reference to stall record
834     output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
835     output.println("  RELEASE_REFERENCE_TO((SESEcommon *)stallrecord);");
836     output.println("#endif");
837     output.println("   }");//exit block
838   }
839
840
841   protected void additionalCodePreNode( FlatMethod      fm, 
842                                         FlatNode        fn, 
843                                         PrintWriter     output ) {
844     // insert pre-node actions from the code plan
845       
846     CodePlan cp = oooa.getCodePlan(fn);
847
848     if( cp != null ) {
849
850       // the current task for a code plan is either the
851       // locally-defined enclosing task, or the caller proxy task.
852       // When it is the caller proxy, it is possible to ask what are
853       // all the possible tasks that the proxy might stand for
854       FlatSESEEnterNode currentSESE = cp.getCurrentSESE();
855
856       FlatMethod fmContext;
857       if( currentSESE.getIsCallerProxySESE() ) {
858         fmContext = oooa.getContainingFlatMethod( fn );
859       } else {
860         fmContext = currentSESE.getfmBogus();
861       }
862
863       ContextTaskNames contextTaskNames;
864       if( currentSESE.getIsCallerProxySESE() ) {
865         contextTaskNames = oooa.getContextTaskNames( oooa.getContainingFlatMethod( fn ) );
866       } else {
867         contextTaskNames = oooa.getContextTaskNames( currentSESE );
868       }
869
870       // for each sese and age pair that this parent statement
871       // must stall on, take that child's stall semaphore, the
872       // copying of values comes after the statement
873       Iterator<VariableSourceToken> vstItr = cp.getStallTokens().iterator();
874       while( vstItr.hasNext() ) {
875         VariableSourceToken vst = vstItr.next();
876
877         SESEandAgePair pair = new SESEandAgePair( vst.getSESE(), vst.getAge() );
878
879         output.println("   {");
880         output.println("     "+
881                        pair.getSESE().getSESErecordName()+"* child = ("+
882                        pair.getSESE().getSESErecordName()+"*) "+pair+";");
883
884         output.println("     SESEcommon* childCom = (SESEcommon*) "+pair+";");
885
886         if( state.COREPROF ) {
887           output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
888           output.println("     CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );");
889           output.println("#endif");
890         }
891
892         output.println("     pthread_mutex_lock( &(childCom->lock) );");
893         output.println("     if( childCom->doneExecuting == FALSE ) {");
894         output.println("       psem_reset( &runningSESEstallSem );");
895         output.println("       childCom->parentsStallSem = &runningSESEstallSem;");
896         output.println("       pthread_mutex_unlock( &(childCom->lock) );");
897         output.println("       psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
898         output.println("     } else {");
899         output.println("       pthread_mutex_unlock( &(childCom->lock) );");
900         output.println("     }");
901
902         // copy things we might have stalled for                  
903         Iterator<TempDescriptor> tdItr = cp.getCopySet( vst ).iterator();
904         while( tdItr.hasNext() ) {
905           TempDescriptor td = tdItr.next();
906           output.println("       "+generateTemp( fmContext, td)+
907                          " = child->"+vst.getAddrVar().getSafeSymbol()+";");
908         }
909
910         if( state.COREPROF ) {
911           output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
912           output.println("     CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );");
913           output.println("#endif");
914         }
915
916         output.println("   }");
917       }
918   
919       // for each variable with a dynamic source, stall just for that variable
920       Iterator<TempDescriptor> dynItr = cp.getDynamicStallSet().iterator();
921       while( dynItr.hasNext() ) {
922         TempDescriptor dynVar = dynItr.next();
923
924         // only stall if the dynamic source is not yourself, denoted by src==NULL
925         // otherwise the dynamic write nodes will have the local var up-to-date
926         output.println("   {");
927         output.println("     if( "+dynVar+"_srcSESE != NULL ) {");
928
929         output.println("       SESEcommon* childCom = (SESEcommon*) "+dynVar+"_srcSESE;");
930
931         if( state.COREPROF ) {
932           output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
933           output.println("       CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );");
934           output.println("#endif");
935         }
936
937         output.println("     pthread_mutex_lock( &(childCom->lock) );");
938         output.println("     if( childCom->doneExecuting == FALSE ) {");
939         output.println("       psem_reset( &runningSESEstallSem );");
940         output.println("       childCom->parentsStallSem = &runningSESEstallSem;");
941         output.println("       pthread_mutex_unlock( &(childCom->lock) );");
942         output.println("       psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
943         output.println("     } else {");
944         output.println("       pthread_mutex_unlock( &(childCom->lock) );");
945         output.println("     }");
946           
947         TypeDescriptor type = dynVar.getType();
948         String typeStr;
949         if( type.isNull() ) {
950           typeStr = "void*";
951         } else if( type.isClass() || type.isArray() ) {
952           typeStr = "struct "+type.getSafeSymbol()+"*";
953         } else {
954           typeStr = type.getSafeSymbol();
955         }
956       
957         output.println("       "+generateTemp( fmContext, dynVar )+
958                        " = *(("+typeStr+"*) ((void*)"+
959                        dynVar+"_srcSESE + "+dynVar+"_srcOffset));");
960
961         if( state.COREPROF ) {
962           output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
963           output.println("       CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );");
964           output.println("#endif");
965         }
966
967         output.println("     }");
968         output.println("   }");
969       }
970
971       // for each assignment of a variable to rhs that has a dynamic source,
972       // copy the dynamic sources
973       Iterator dynAssignItr = cp.getDynAssigns().entrySet().iterator();
974       while( dynAssignItr.hasNext() ) {
975         Map.Entry      me  = (Map.Entry)      dynAssignItr.next();
976         TempDescriptor lhs = (TempDescriptor) me.getKey();
977         TempDescriptor rhs = (TempDescriptor) me.getValue();
978
979         output.println("   {");
980         output.println("   SESEcommon* oldSrc = "+lhs+"_srcSESE;");
981           
982         output.println("   "+lhs+"_srcSESE   = "+rhs+"_srcSESE;");
983         output.println("   "+lhs+"_srcOffset = "+rhs+"_srcOffset;");
984
985         // no matter what we did above, track reference count of whatever
986         // this variable pointed to, do release last in case we're just
987         // copying the same value in because 1->2->1 is safe but ref count
988         // 1->0->1 has a window where it looks like it should be free'd
989         output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
990         output.println("     if( "+rhs+"_srcSESE != NULL ) {");
991         output.println("       ADD_REFERENCE_TO( "+rhs+"_srcSESE );");
992         output.println("     }");
993         output.println("     if( oldSrc != NULL ) {");
994         output.println("       RELEASE_REFERENCE_TO( oldSrc );");
995         output.println("     }");
996         output.println("   }");
997         output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
998       }
999
1000       // for each lhs that is dynamic from a non-dynamic source, set the
1001       // dynamic source vars to the current SESE
1002       dynItr = cp.getDynAssignCurr().iterator();
1003       while( dynItr.hasNext() ) {
1004         TempDescriptor dynVar = dynItr.next();    
1005
1006         assert contextTaskNames.getDynamicVarSet().contains( dynVar );
1007
1008         // first release a reference to current record
1009         output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1010         output.println("   if( "+dynVar+"_srcSESE != NULL ) {");
1011         output.println("     RELEASE_REFERENCE_TO( oldSrc );");
1012         output.println("   }");
1013         output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1014
1015         output.println("   "+dynVar+"_srcSESE = NULL;");
1016       }
1017
1018         
1019       // handling stall site, consider that one of several tasks might be
1020       // executing, so create a switch on task ID, because waiting elements
1021       // generated by this stall site should be inserted into possibly a
1022       // different memory queue index, depending on which task type it is
1023       // update: only generate the switch statement if there is at least
1024       // one non-empty case that will go in it!
1025       boolean atLeastOneCase = false;
1026
1027       // create a case for each class of task that might be executing
1028       Iterator<FlatSESEEnterNode> taskItr = oooa.getPossibleExecutingRBlocks( fn ).iterator();
1029       while( taskItr.hasNext() ) {
1030         FlatSESEEnterNode parent = taskItr.next();
1031         ConflictGraph     graph  = oooa.getConflictGraph( parent );
1032
1033         if( graph == null ) {
1034           continue;
1035         }
1036
1037         Set<SESELock>       seseLockSet       = oooa.getLockMappings( graph );
1038         Set<WaitingElement> waitingElementSet = graph.getStallSiteWaitingElementSet( fn, seseLockSet );
1039         
1040         if( waitingElementSet.size() == 0 ) {
1041           continue;
1042         }
1043
1044         // TODO: THIS STRATEGY CAN BE OPTIMIZED EVEN FURTHER, IF THERE
1045         // IS EXACTLY ONE CASE, DON'T GENERATE A SWITCH AT ALL
1046         if( atLeastOneCase == false ) {
1047           atLeastOneCase = true;
1048           output.println("   // potential stall site ");      
1049           output.println("   switch( runningSESE->classID ) {");
1050         }
1051
1052         output.println("     case "+parent.getIdentifier()+": {");
1053
1054         if( state.RCR ) {
1055           stallMEMRCR(fm, fn, waitingElementSet, output);
1056         } else {
1057
1058           output.println("       REntry* rentry;");
1059                 
1060           for( Iterator iterator = waitingElementSet.iterator(); iterator.hasNext(); ) {
1061             WaitingElement waitingElement = (WaitingElement) iterator.next();
1062
1063             if (waitingElement.getStatus() >= ConflictNode.COARSE) {
1064               output.println("       rentry=mlpCreateREntry(runningSESE->memoryQueueArray["
1065                              + waitingElement.getQueueID() + "]," + waitingElement.getStatus()
1066                              + ", runningSESE);");
1067             } else {
1068               output.println("       rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["
1069                              + waitingElement.getQueueID() + "]," + waitingElement.getStatus()
1070                              + ", runningSESE,  (void*)&"
1071                              + generateTemp(fm, waitingElement.getTempDesc()) + ");");
1072             }
1073             output.println("       rentry->parentStallSem=&runningSESEstallSem;");
1074             output.println("       psem_reset( &runningSESEstallSem);");
1075             output.println("       rentry->tag=runningSESEstallSem.tag;");
1076             output.println("       rentry->queue=runningSESE->memoryQueueArray["
1077                            + waitingElement.getQueueID() + "];");
1078             output.println("       if(ADDRENTRY(runningSESE->memoryQueueArray["
1079                            + waitingElement.getQueueID() + "],rentry)==NOTREADY){");
1080             if (state.COREPROF) {
1081               output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
1082               output.println("       CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );");
1083               output.println("#endif");
1084             }
1085                   
1086             output.println("       psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
1087                   
1088             if (state.COREPROF) {
1089               output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
1090               output.println("       CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );");
1091               output.println("#endif");
1092             }
1093             output.println("     }  ");
1094           }
1095
1096         }
1097         output.println("     } break; // end case "+parent.getIdentifier());
1098       }
1099
1100       if( atLeastOneCase ) {
1101         output.println("   } // end stall site switch");
1102       }
1103     }
1104   }
1105   
1106
1107   protected void additionalCodePostNode( FlatMethod      fm, 
1108                                          FlatNode        fn, 
1109                                          PrintWriter     output ) {
1110
1111     // insert post-node actions from the code-plan (none right now...)
1112   }
1113
1114
1115   public void generateFlatSESEEnterNode( FlatMethod        fm,  
1116                                          FlatSESEEnterNode fsen, 
1117                                          PrintWriter       output ) {
1118
1119     // there may be an SESE in an unreachable method, skip over
1120     if( !oooa.getAllSESEs().contains( fsen ) ) {
1121       return;
1122     }
1123
1124     // assert we are never generating code for the caller proxy
1125     // it should only appear in analysis results
1126     assert !fsen.getIsCallerProxySESE();
1127
1128
1129     output.println("   { // issue new task instance");
1130
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");
1135     }
1136
1137
1138     // before doing anything, lock your own record and increment the running children
1139     if( !fsen.getIsMainSESE() ) {
1140       output.println("     childSESE++;");
1141     }
1142
1143     // allocate the space for this record
1144     output.println( "#ifndef OOO_DISABLE_TASKMEMPOOL" );
1145
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.getIsMainSESE() ) {
1150       output.println("     "+
1151                      fsen.getSESErecordName()+"* seseToIssue = ("+
1152                      fsen.getSESErecordName()+"*) poolalloc( runningSESE->taskRecordMemPool );");
1153       output.println("     CHECK_RECORD( seseToIssue );");
1154     } else {
1155       output.println("     "+
1156                      fsen.getSESErecordName()+"* seseToIssue = ("+
1157                      fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+
1158                      fsen.getSESErecordName()+" ) );");
1159     }
1160     output.println( "#ifdef CP_EVENTID_POOLALLOC");
1161     output.println( "     CP_LOGEVENT( CP_EVENTID_POOLALLOC, CP_EVENTTYPE_END );");
1162     output.println( "#endif");
1163
1164     output.println( "#else // OOO_DISABLE_TASKMEMPOOL" );
1165       output.println("     "+
1166                      fsen.getSESErecordName()+"* seseToIssue = ("+
1167                      fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+
1168                      fsen.getSESErecordName()+" ) );");
1169     output.println( "#endif // OOO_DISABLE_TASKMEMPOOL" );
1170
1171
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;");
1178
1179     if(state.RCR) {
1180       //flag the SESE status as 1...it will be reset
1181       output.println("     seseToIssue->common.rcrstatus=1;");
1182     }
1183
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()+";");
1190     
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()+");"
1197                      );
1198     }
1199     
1200     if( state.RCR &&
1201         fsen.getInVarsForDynamicCoarseConflictResolution().size() > 0 
1202         ) {
1203       output.println("    seseToIssue->common.offsetToParamRecords=(INTPTR) & ((("+
1204                      fsen.getSESErecordName()+"*)0)->rcrRecords);");
1205     }
1206
1207     // fill in common data
1208     output.println("     int localCount=0;");
1209     output.println("     seseToIssue->common.classID = "+fsen.getIdentifier()+";");
1210     output.println("     seseToIssue->common.unresolvedDependencies = 10000;");
1211     output.println("     seseToIssue->common.parentsStallSem = NULL;");
1212     output.println("     initQueue(&seseToIssue->common.forwardList);");
1213     output.println("     seseToIssue->common.doneExecuting = FALSE;");    
1214     output.println("     seseToIssue->common.numRunningChildren = 0;");
1215     output.println( "#ifdef OOO_DISABLE_TASKMEMPOOL" );
1216     output.println("     pthread_cond_init( &(seseToIssue->common.runningChildrenCond), NULL );");
1217     output.println("#endif");
1218     output.println("     seseToIssue->common.parent = runningSESE;");
1219     // start with refCount = 2, one being the count that the child itself
1220     // will decrement when it retires, to say it is done using its own
1221     // record, and the other count is for the parent that will remember
1222     // the static name of this new child below
1223     if( state.RCR ) {
1224       // if we're using RCR, ref count is 3 because the traverser has
1225       // a reference, too
1226       if( !fsen.getIsMainSESE() && fsen.getInVarsForDynamicCoarseConflictResolution().size()>0){
1227         output.println("     seseToIssue->common.refCount = 10003;");
1228       } else {
1229         output.println("     seseToIssue->common.refCount = 10002;");
1230       }
1231       output.println("     int refCount=10000;");
1232     } else {
1233       output.println("     seseToIssue->common.refCount = 2;");
1234     }
1235
1236     // all READY in-vars should be copied now and be done with it
1237     Iterator<TempDescriptor> tempItr = fsen.getReadyInVarSet().iterator();
1238     while( tempItr.hasNext() ) {
1239       TempDescriptor temp = tempItr.next();
1240
1241       // determine whether this new task instance is in a method context,
1242       // or within the body of another task
1243       assert !fsen.getIsCallerProxySESE();
1244       FlatSESEEnterNode parent = fsen.getLocalParent();
1245       if( parent != null && !parent.getIsCallerProxySESE() ) {
1246         output.println("     seseToIssue->"+temp+" = "+
1247                        generateTemp( parent.getfmBogus(), temp )+";");   
1248       } else {
1249         output.println("     seseToIssue->"+temp+" = "+
1250                        generateTemp( fsen.getfmEnclosing(), temp )+";");
1251       }
1252     }
1253     
1254     // before potentially adding this SESE to other forwarding lists,
1255     // create it's lock
1256     output.println( "#ifdef OOO_DISABLE_TASKMEMPOOL" );
1257     output.println("     pthread_mutex_init( &(seseToIssue->common.lock), NULL );");
1258     output.println("#endif");
1259   
1260     if( !fsen.getIsMainSESE() ) {
1261       // count up outstanding dependencies, static first, then dynamic
1262       Iterator<SESEandAgePair> staticSrcsItr = fsen.getStaticInVarSrcs().iterator();
1263       while( staticSrcsItr.hasNext() ) {
1264         SESEandAgePair srcPair = staticSrcsItr.next();
1265         output.println("     {");
1266         output.println("       SESEcommon* src = (SESEcommon*)"+srcPair+";");
1267         output.println("       pthread_mutex_lock( &(src->lock) );");
1268         // FORWARD TODO - ...what? make it a chain of arrays instead of true linked-list?
1269         output.println("       if( !src->doneExecuting ) {");
1270         output.println("         addNewItem( &src->forwardList, seseToIssue );");       
1271         output.println("         ++(localCount);");
1272         output.println("       }");
1273         output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1274         output.println("       ADD_REFERENCE_TO( src );");
1275         output.println("#endif" );
1276         output.println("       pthread_mutex_unlock( &(src->lock) );");
1277         output.println("     }");
1278
1279         // whether or not it is an outstanding dependency, make sure
1280         // to pass the static name to the child's record
1281         output.println("     seseToIssue->"+srcPair+" = "+
1282                        "("+srcPair.getSESE().getSESErecordName()+"*)"+
1283                        srcPair+";");
1284       }
1285       
1286       // dynamic sources might already be accounted for in the static list,
1287       // so only add them to forwarding lists if they're not already there
1288       Iterator<TempDescriptor> dynVarsItr = fsen.getDynamicInVarSet().iterator();
1289       while( dynVarsItr.hasNext() ) {
1290         TempDescriptor dynInVar = dynVarsItr.next();
1291         output.println("     {");
1292         output.println("       SESEcommon* src = (SESEcommon*)"+dynInVar+"_srcSESE;");
1293
1294         // the dynamic source is NULL if it comes from your own space--you can't pass
1295         // the address off to the new child, because you're not done executing and
1296         // might change the variable, so copy it right now
1297         output.println("       if( src != NULL ) {");
1298         output.println("         pthread_mutex_lock( &(src->lock) );");
1299
1300         // FORWARD TODO
1301
1302         output.println("         if( isEmpty( &src->forwardList ) ||");
1303         output.println("             seseToIssue != peekItem( &src->forwardList ) ) {");
1304         output.println("           if( !src->doneExecuting ) {");
1305         output.println("             addNewItem( &src->forwardList, seseToIssue );");
1306         output.println("             ++(localCount);");
1307         output.println("           }");
1308         output.println("         }");
1309         output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1310         output.println("         ADD_REFERENCE_TO( src );");
1311         output.println("#endif" );
1312         output.println("         pthread_mutex_unlock( &(src->lock) );");       
1313         output.println("         seseToIssue->"+dynInVar+"_srcOffset = "+dynInVar+"_srcOffset;");
1314         output.println("       } else {");
1315
1316
1317         // determine whether this new task instance is in a method context,
1318         // or within the body of another task
1319         assert !fsen.getIsCallerProxySESE();
1320         FlatSESEEnterNode parent = fsen.getLocalParent();
1321         if( parent != null && !parent.getIsCallerProxySESE() ) {
1322           output.println("         seseToIssue->"+dynInVar+" = "+
1323                          generateTemp( parent.getfmBogus(), dynInVar )+";");
1324         } else {
1325           output.println("         seseToIssue->"+dynInVar+" = "+
1326                          generateTemp( fsen.getfmEnclosing(), dynInVar )+";");
1327         }
1328         
1329         output.println("       }");
1330         output.println("     }");
1331         
1332         // even if the value is already copied, make sure your NULL source
1333         // gets passed so child knows it already has the dynamic value
1334         output.println("     seseToIssue->"+dynInVar+"_srcSESE = "+dynInVar+"_srcSESE;");
1335       }
1336
1337
1338       // maintain pointers for finding dynamic SESE 
1339       // instances from static names, do a shuffle as instances age
1340       // and also release references that have become too old
1341       if( !fsen.getIsMainSESE() ) {
1342
1343         FlatSESEEnterNode currentSESE = fsen.getLocalParent();        
1344
1345         ContextTaskNames contextTaskNames;
1346         if( currentSESE == null ) {
1347           contextTaskNames = oooa.getContextTaskNames( oooa.getContainingFlatMethod( fsen ) );
1348         } else {
1349           contextTaskNames = oooa.getContextTaskNames( currentSESE );
1350         }
1351
1352         SESEandAgePair pairNewest = new SESEandAgePair( fsen, 0 );
1353         SESEandAgePair pairOldest = new SESEandAgePair( fsen, fsen.getOldestAgeToTrack() );
1354         if( contextTaskNames.getNeededStaticNames().contains( pairNewest ) ) {       
1355           output.println("     {");
1356           output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1357           output.println("       SESEcommon* oldest = "+pairOldest+";");
1358           output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1359
1360           for( int i = fsen.getOldestAgeToTrack(); i > 0; --i ) {
1361             SESEandAgePair pair1 = new SESEandAgePair( fsen, i   );
1362             SESEandAgePair pair2 = new SESEandAgePair( fsen, i-1 );
1363             output.println("       "+pair1+" = "+pair2+";");
1364           }      
1365           output.println("       "+pairNewest+" = &(seseToIssue->common);");
1366
1367           // no need to add a reference to whatever is the newest record, because
1368           // we initialized seseToIssue->refCount to *2*
1369           // but release a reference to whatever was the oldest BEFORE the shift
1370           output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1371           output.println("       if( oldest != NULL ) {");
1372           output.println("         RELEASE_REFERENCE_TO( oldest );");
1373           output.println("       }");
1374           output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1375           output.println("     }");
1376         }
1377       }
1378     }
1379
1380
1381     //////////////////////
1382     // count up memory conflict dependencies,
1383     ///////////////////////
1384     if( !fsen.getIsMainSESE() ) {
1385
1386       if( state.COREPROF ) {
1387         output.println("#ifdef CP_EVENTID_PREPAREMEMQ");
1388         output.println("     CP_LOGEVENT( CP_EVENTID_PREPAREMEMQ, CP_EVENTTYPE_BEGIN );");
1389         output.println("#endif");
1390       }
1391
1392       if(state.RCR) {
1393         dispatchMEMRC(fm, fsen, output);
1394       } else {
1395
1396         // there may be several task types that can get to this
1397         // program point (issue this new task) so create a switch
1398         // based on task ID, each type of task has a different index
1399         // scheme for its memory queue's, and the cases here drop the
1400         // new task instance in the right bucket
1401         boolean atLeastOneCase = false;
1402
1403         // create a case for each class of task that might be executing
1404         Iterator<FlatSESEEnterNode> taskItr = oooa.getPossibleExecutingRBlocks( fsen ).iterator();
1405         while( taskItr.hasNext() ) {
1406           FlatSESEEnterNode parent = taskItr.next();
1407           ConflictGraph     graph  = oooa.getConflictGraph( parent );
1408
1409           if( graph == null || !graph.hasConflictEdge() ) {
1410             continue;
1411           }
1412
1413           Set<SESELock> seseLockSet = oooa.getLockMappings(graph);
1414
1415           SESEWaitingQueue seseWaitingQueue =
1416             graph.getWaitingElementSetBySESEID(fsen.getIdentifier(), seseLockSet);
1417           
1418           if( seseWaitingQueue.getWaitingElementSize() == 0 ) {
1419             continue;
1420           }
1421
1422           if( atLeastOneCase == false ) {
1423             atLeastOneCase = true;
1424             output.println("   // add new task instance to current task's memory queues if needed ");      
1425             output.println("   switch( runningSESE->classID ) {");
1426           }
1427
1428           output.println("     case "+parent.getIdentifier()+": {");
1429           output.println("       REntry* rentry=NULL;");
1430           output.println("       INTPTR* pointer=NULL;");
1431           output.println("       seseToIssue->common.rentryIdx=0;");
1432
1433           Set<Integer> queueIDSet=seseWaitingQueue.getQueueIDSet();
1434           for (Iterator iterator = queueIDSet.iterator(); iterator.hasNext();) {
1435             Integer key = (Integer) iterator.next();
1436             int queueID=key.intValue();
1437             Set<WaitingElement> waitingQueueSet =  
1438               seseWaitingQueue.getWaitingElementSet(queueID);
1439             int enqueueType=seseWaitingQueue.getType(queueID);
1440             if(enqueueType==SESEWaitingQueue.EXCEPTION) {
1441               output.println("       INITIALIZEBUF(runningSESE->memoryQueueArray[" + queueID+ "]);");
1442             }
1443             for (Iterator iterator2 = waitingQueueSet.iterator(); iterator2.hasNext();) {
1444               WaitingElement waitingElement 
1445                 = (WaitingElement) iterator2.next();
1446               if (waitingElement.getStatus() >= ConflictNode.COARSE) {
1447                 output.println("       rentry=mlpCreateREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1448                                + waitingElement.getStatus()
1449                                + ", &(seseToIssue->common));");
1450               } else {
1451                 TempDescriptor td = waitingElement.getTempDesc();
1452                 // decide whether waiting element is dynamic or static
1453                 if (fsen.getDynamicInVarSet().contains(td)) {
1454                   // dynamic in-var case
1455                   output.println("       pointer=seseToIssue->"
1456                                  + waitingElement.getDynID()
1457                                  + "_srcSESE+seseToIssue->"
1458                                  + waitingElement.getDynID()
1459                                  + "_srcOffset;");
1460                   output.println("       rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1461                                  + waitingElement.getStatus()
1462                                  + ", &(seseToIssue->common),  pointer );");
1463                 } else if (fsen.getStaticInVarSet().contains(td)) {
1464                   // static in-var case
1465                   VariableSourceToken vst = fsen.getStaticInVarSrc(td);
1466                   if (vst != null) {
1467   
1468                     String srcId = "SESE_" + vst.getSESE().getPrettyIdentifier()
1469                       + vst.getSESE().getIdentifier()
1470                       + "_" + vst.getAge();
1471                     output.println("       pointer=(void*)&seseToIssue->"
1472                                    + srcId
1473                                    + "->"
1474                                    + waitingElement
1475                                    .getDynID()
1476                                    + ";");
1477                     output.println("       rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1478                                    + waitingElement.getStatus()
1479                                    + ", &(seseToIssue->common),  pointer );");
1480                   }
1481                 } else {
1482                   output.println("       rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1483                                  + waitingElement.getStatus()
1484                                  + ", &(seseToIssue->common), (void*)&seseToIssue->"
1485                                  + waitingElement.getDynID()
1486                                  + ");");
1487                 }
1488               }
1489               output.println("       rentry->queue=runningSESE->memoryQueueArray["
1490                              + waitingElement.getQueueID()
1491                              + "];");
1492                 
1493               if(enqueueType==SESEWaitingQueue.NORMAL){
1494                 output.println("       seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;");
1495                 output.println("       if(ADDRENTRY(runningSESE->memoryQueueArray["
1496                                + waitingElement.getQueueID()
1497                                + "],rentry)==NOTREADY) {");
1498                 output.println("          localCount++;");
1499                 output.println("       }");
1500               } else {
1501                 output.println("       ADDRENTRYTOBUF(runningSESE->memoryQueueArray[" + waitingElement.getQueueID() + "],rentry);");
1502               }
1503             }
1504             if(enqueueType!=SESEWaitingQueue.NORMAL){
1505               output.println("       localCount+=RESOLVEBUF(runningSESE->memoryQueueArray["
1506                              + queueID+ "],&seseToIssue->common);");
1507             }       
1508           }
1509           output.println("     } break; // end case "+parent.getIdentifier());
1510           output.println();          
1511         }
1512
1513         if( atLeastOneCase ) {
1514           output.println("   } // end stall site switch");
1515         }
1516       }      
1517       
1518       if( state.COREPROF ) {
1519         output.println("#ifdef CP_EVENTID_PREPAREMEMQ");
1520         output.println("     CP_LOGEVENT( CP_EVENTID_PREPAREMEMQ, CP_EVENTTYPE_END );");
1521         output.println("#endif");
1522       }
1523     }
1524
1525     // Enqueue Task Record
1526     if (state.RCR) {
1527       if( fsen != oooa.getMainSESE() && fsen.getInVarsForDynamicCoarseConflictResolution().size()>0){
1528         output.println("    enqueueTR(TRqueue, (void *)seseToIssue);");
1529       }
1530     }
1531
1532     // if there were no outstanding dependencies, issue here
1533     output.println("     if(  atomic_sub_and_test(10000-localCount,&(seseToIssue->common.unresolvedDependencies) ) ) {");
1534     output.println("       workScheduleSubmit( (void*)seseToIssue );");
1535     output.println("     }");
1536
1537     
1538
1539     if( state.COREPROF ) {
1540       output.println("#ifdef CP_EVENTID_TASKDISPATCH");
1541       output.println("     CP_LOGEVENT( CP_EVENTID_TASKDISPATCH, CP_EVENTTYPE_END );");
1542       output.println("#endif");
1543     }
1544
1545     output.println("   } // end task issue");
1546   }
1547
1548
1549   void dispatchMEMRC( FlatMethod        fm,  
1550                       FlatSESEEnterNode newChild, 
1551                       PrintWriter       output ) {   
1552     // what we need to do here is create RCR records for the
1553     // new task and insert it into the appropriate parent queues
1554     // IF NEEDED!!!!!!!!
1555     assert newChild.getParents().size() > 0;
1556
1557     output.println("     switch( runningSESE->classID ) {");
1558
1559     Iterator<FlatSESEEnterNode> pItr = newChild.getParents().iterator();
1560     while( pItr.hasNext() ) {
1561
1562       FlatSESEEnterNode parent = pItr.next();
1563       ConflictGraph     graph  = oooa.getConflictGraph( parent );
1564
1565       if( graph != null && graph.hasConflictEdge() ) {
1566         Set<SESELock> seseLockSet = oooa.getLockMappings(graph);
1567         SESEWaitingQueue seseWaitingQueue=graph.getWaitingElementSetBySESEID(newChild.getIdentifier(), seseLockSet);
1568         if(seseWaitingQueue.getWaitingElementSize()>0) {
1569
1570           output.println("       /* "+parent.getPrettyIdentifier()+" */");
1571           output.println("       case "+parent.getIdentifier()+": {");
1572
1573           output.println("         REntry* rentry=NULL;");
1574           output.println("         INTPTR* pointer=NULL;");
1575           output.println("         seseToIssue->common.rentryIdx=0;");
1576           Vector<TempDescriptor> invars=newChild.getInVarsForDynamicCoarseConflictResolution();
1577           //System.out.println(fm.getMethod()+"["+invars+"]");
1578         
1579           Vector<Long> queuetovar=new Vector<Long>();
1580
1581           for(int i=0;i<invars.size();i++) {
1582             TempDescriptor td=invars.get(i);
1583             Set<WaitingElement> weset=seseWaitingQueue.getWaitingElementSet(td);
1584             
1585             //TODO FIX MEEEEE!!!!
1586             //Weset is sometimes null which breaks the following code and 
1587             //we don't know what weset = null means. For now, we bail when it's null
1588             //until we find out what to do....
1589 //            if(weset == null) {
1590 //              continue;
1591 //            }
1592             //UPDATE: This hack DOES NOT FIX IT!.
1593             
1594             
1595             
1596             int numqueues=0;
1597             Set<Integer> queueSet=new HashSet<Integer>();
1598             for (Iterator iterator = weset.iterator(); iterator.hasNext();) {
1599               WaitingElement  we = (WaitingElement) iterator.next();
1600               Integer queueID=new Integer( we.getQueueID());
1601               if(!queueSet.contains(queueID)){
1602                 numqueues++;
1603                 queueSet.add(queueID);
1604               }    
1605             }
1606
1607             output.println("        seseToIssue->rcrRecords["+i+"].flag="+numqueues+";");
1608             output.println("        seseToIssue->rcrRecords["+i+"].index=0;");
1609             output.println("        seseToIssue->rcrRecords["+i+"].next=NULL;");
1610             output.println("        int dispCount"+i+"=0;");
1611
1612             for (Iterator<WaitingElement> wtit = weset.iterator(); wtit.hasNext();) {
1613               WaitingElement waitingElement = wtit.next();
1614               int queueID = waitingElement.getQueueID();
1615               if (queueID >= queuetovar.size())
1616                 queuetovar.setSize(queueID + 1);
1617               Long l = queuetovar.get(queueID);
1618               long val = (l != null) ? l.longValue() : 0;
1619               val = val | (1 << i);
1620               queuetovar.set(queueID, new Long(val));
1621             }
1622           }
1623
1624           HashSet generatedqueueentry=new HashSet();
1625           for(int i=0;i<invars.size();i++) {
1626             TempDescriptor td=invars.get(i);
1627             Set<WaitingElement> weset=seseWaitingQueue.getWaitingElementSet(td);
1628             
1629             
1630             
1631             //TODO FIX MEEEEE!!!!
1632             //Weset is sometimes null which breaks the following code and 
1633             //we don't know what weset = null means. For now, we bail when it's null
1634             //until we find out what to do....
1635 //            if(weset == null) {
1636 //              continue;
1637 //            }
1638             //UPDATE: This hack DOES NOT FIX IT!.
1639             
1640             
1641             
1642             for(Iterator<WaitingElement> wtit=weset.iterator();wtit.hasNext();) {
1643               WaitingElement waitingElement=wtit.next();
1644               int queueID=waitingElement.getQueueID();
1645               
1646               if(waitingElement.isBogus()){
1647                 continue;
1648               }
1649             
1650               if (generatedqueueentry.contains(queueID))
1651                 continue;
1652               else 
1653                 generatedqueueentry.add(queueID);
1654               
1655               assert(waitingElement.getStatus()>=ConflictNode.COARSE);
1656               long mask=queuetovar.get(queueID);
1657               output.println("         rentry=mlpCreateREntry(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "]," + waitingElement.getStatus() + ", &(seseToIssue->common), "+mask+"LL);");
1658               output.println("         rentry->count=2;");
1659               output.println("         seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;");
1660               output.println("         rentry->queue=runningSESE->memoryQueueArray[" + waitingElement.getQueueID()+"];");
1661                                 
1662               output.println("         if(ADDRENTRY(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "],rentry)==READY) {");
1663               for(int j=0;mask!=0;j++) {
1664                 if ((mask&1)==1)
1665                   output.println("            dispCount"+j+"++;");
1666                 mask=mask>>1;
1667               }
1668               output.println("         } else ");
1669               output.println("           refCount--;");
1670           }
1671
1672             if (newChild.getDynamicInVarSet().contains(td)) {
1673               // dynamic in-var case
1674               //output.println("       pointer=seseToIssue->"+waitingElement.getDynID()+ 
1675               //               "_srcSESE+seseToIssue->"+waitingElement.getDynID()+ 
1676               //               "_srcOffset;");
1677               //output.println("       rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+
1678               //               ", &(seseToIssue->common),  pointer );");
1679             }
1680           }
1681           for(int i=0;i<invars.size();i++) {
1682             output.println("       if(!dispCount"+i+" || !atomic_sub_and_test(dispCount"+i+",&(seseToIssue->rcrRecords["+i+"].flag)))");
1683             output.println("         localCount++;");
1684           }
1685           output.println("      } break;");
1686         }
1687       }
1688     }
1689
1690     output.println("     } // end switch");
1691
1692     output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1693     output.println("  RELEASE_REFERENCES_TO((SESEcommon *)seseToIssue, refCount);");
1694     output.println("#endif");
1695   }
1696
1697
1698   public void generateFlatSESEExitNode( FlatMethod       fm,
1699                                         FlatSESEExitNode fsexn,
1700                                         PrintWriter      output ) {
1701
1702     // get the enter node for this exit that has meta data embedded
1703     FlatSESEEnterNode fsen = fsexn.getFlatEnter();
1704
1705     // there may be an SESE in an unreachable method, skip over
1706     if( !oooa.getAllSESEs().contains( fsen ) ) {
1707       return;
1708     }
1709
1710     // assert we are never generating code for the caller proxy
1711     // it should only appear in analysis results
1712     assert !fsen.getIsCallerProxySESE();
1713
1714     
1715     if( state.COREPROF ) {
1716       output.println("#ifdef CP_EVENTID_TASKEXECUTE");
1717       output.println("   CP_LOGEVENT( CP_EVENTID_TASKEXECUTE, CP_EVENTTYPE_END );");
1718       output.println("#endif");
1719     }
1720
1721     output.println("   /* SESE exiting */");
1722
1723     if( state.COREPROF ) {
1724       output.println("#ifdef CP_EVENTID_TASKRETIRE");
1725       output.println("   CP_LOGEVENT( CP_EVENTID_TASKRETIRE, CP_EVENTTYPE_BEGIN );");
1726       output.println("#endif");
1727     }
1728     
1729
1730     // this SESE cannot be done until all of its children are done
1731     // so grab your own lock with the condition variable for watching
1732     // that the number of your running children is greater than zero    
1733     output.println("   atomic_add(childSESE, &runningSESE->numRunningChildren);");
1734     output.println("   pthread_mutex_lock( &(runningSESE->lock) );");
1735     output.println("   if( runningSESE->numRunningChildren > 0 ) {");
1736     output.println("     stopforgc( (struct garbagelist *)&___locals___ );");
1737     output.println("     do {");
1738     output.println("       pthread_cond_wait( &(runningSESE->runningChildrenCond), &(runningSESE->lock) );");
1739     output.println("     } while( runningSESE->numRunningChildren > 0 );");
1740     output.println("     restartaftergc();");
1741     output.println("   }");
1742
1743
1744     // copy out-set from local temps into the sese record
1745     Iterator<TempDescriptor> itr = fsen.getOutVarSet().iterator();
1746     while( itr.hasNext() ) {
1747       TempDescriptor temp = itr.next();
1748
1749       // only have to do this for primitives non-arrays
1750       if( !(
1751             temp.getType().isPrimitive() && !temp.getType().isArray()
1752            )
1753         ) {
1754         continue;
1755       }
1756
1757       String from;
1758
1759       // determine whether this new task instance is in a method context,
1760       // or within the body of another task
1761       assert !fsen.getIsCallerProxySESE();
1762       FlatSESEEnterNode parent = fsen.getLocalParent();
1763       if( parent != null && !parent.getIsCallerProxySESE() ) {
1764         from = generateTemp( parent.getfmBogus(),   temp );
1765       } else {
1766         from = generateTemp( fsen.getfmEnclosing(), temp );
1767       }
1768
1769       output.println("   "+paramsprefix+
1770                      "->"+temp.getSafeSymbol()+
1771                      " = "+from+";");
1772     }    
1773     
1774     // mark yourself done, your task data is now read-only
1775     output.println("   runningSESE->doneExecuting = TRUE;");
1776
1777     // if parent is stalling on you, let them know you're done
1778     if( !fsen.getIsMainSESE() ) {
1779       output.println("   if( runningSESE->parentsStallSem != NULL ) {");
1780       output.println("     psem_give( runningSESE->parentsStallSem );");
1781       output.println("   }");
1782     }
1783
1784     output.println("   pthread_mutex_unlock( &(runningSESE->lock) );");
1785
1786     // decrement dependency count for all SESE's on your forwarding list
1787
1788     // FORWARD TODO
1789     output.println("   while( !isEmpty( &runningSESE->forwardList ) ) {");
1790     output.println("     SESEcommon* consumer = (SESEcommon*) getItem( &runningSESE->forwardList );");
1791     
1792    
1793     if (!state.RCR) {
1794       output.println("     if(consumer->rentryIdx>0){");
1795       output.println("        // resolved null pointer");
1796       output.println("        int idx;");
1797       output.println("        for(idx=0;idx<consumer->rentryIdx;idx++){");
1798       output.println("           resolvePointer(consumer->rentryArray[idx]);");
1799       output.println("        }");
1800       output.println("     }");
1801     }
1802
1803     output.println("     if( atomic_sub_and_test( 1, &(consumer->unresolvedDependencies) ) ){");
1804     output.println("       workScheduleSubmit( (void*)consumer );");
1805     output.println("     }");
1806     output.println("   }");
1807     
1808     
1809     // clean up its lock element from waiting queue, and decrement dependency count for next SESE block
1810     if( !fsen.getIsMainSESE() ) {
1811       output.println();
1812       output.println("   /* check memory dependency*/");
1813       output.println("  {");
1814       output.println("      int idx;");
1815       output.println("      for(idx=0;idx<___params___->common.rentryIdx;idx++){");
1816       output.println("           REntry* re=___params___->common.rentryArray[idx];");
1817       output.println("           RETIRERENTRY(re->queue,re);");
1818       output.println("      }");
1819       output.println("   }");
1820     }
1821     
1822     Vector<TempDescriptor> inset=fsen.getInVarsForDynamicCoarseConflictResolution();
1823     if (state.RCR && inset.size() > 0) {
1824       /* Make sure the running SESE is finished */
1825       output.println("   if (unlikely(runningSESE->rcrstatus!=0)) {");
1826       output.println("     if(CAS(&runningSESE->rcrstatus,1,0)==2) {");
1827       output.println("       while(runningSESE->rcrstatus) {");
1828       output.println("         BARRIER();");
1829       output.println("         sched_yield();");
1830       output.println("       }");
1831       output.println("     }");
1832       output.println("   }");
1833       output.println("{");
1834       output.println("  int idx,idx2;");
1835
1836       output.println("    struct rcrRecord *rec;");
1837       output.println("    struct Hashtable_rcr ** hashstruct=runningSESE->parent->allHashStructures;");
1838
1839       for (int i = 0; i < inset.size(); i++) {
1840         output.println("    rec=&" + paramsprefix + "->rcrRecords[" + i + "];");
1841         output.println("    while(rec!=NULL) {");
1842         output.println("      for(idx2=0;idx2<rec->index;idx2++) {");
1843
1844         int weaklyConnectedComponentIndex = rcr.getWeakID(inset.get(i), fsen);
1845
1846         output.println("        rcr_RETIREHASHTABLE(hashstruct[" + weaklyConnectedComponentIndex
1847             + "],&(___params___->common), rec->array[idx2], (BinItem_rcr *) rec->ptrarray[idx2]);");
1848
1849         output.println("      }");// exit idx2 for loop
1850         output.println("      rec=rec->next;");
1851         output.println("    }");// exit rec while loop
1852       }
1853       output.println("}");
1854     }
1855
1856
1857     // a task has variables to track static/dynamic instances
1858     // that serve as sources, release the parent's ref of each
1859     // non-null var of these types
1860     output.println("   // releasing static SESEs");
1861     output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1862
1863     ContextTaskNames contextTaskNames = oooa.getContextTaskNames( fsen );
1864
1865     Iterator<SESEandAgePair> pItr = contextTaskNames.getNeededStaticNames().iterator();
1866     while( pItr.hasNext() ) {
1867       SESEandAgePair pair = pItr.next();
1868       output.println("   if( "+pair+" != NULL ) {");
1869       output.println("     RELEASE_REFERENCE_TO( "+pair+" );");
1870       output.println("   }");
1871     }
1872     output.println("   // releasing dynamic variable sources");
1873     Iterator<TempDescriptor> dynSrcItr = contextTaskNames.getDynamicVarSet().iterator();
1874     while( dynSrcItr.hasNext() ) {
1875       TempDescriptor dynSrcVar = dynSrcItr.next();
1876       output.println("   if( "+dynSrcVar+"_srcSESE != NULL ) {");
1877       output.println("     RELEASE_REFERENCE_TO( "+dynSrcVar+"_srcSESE );");
1878       output.println("   }");
1879     }    
1880
1881     // destroy this task's mempool if it is not a leaf task
1882     if( !fsen.getIsLeafSESE() ) {
1883       output.println("     pooldestroy( runningSESE->taskRecordMemPool );");
1884       if (state.RCR && fsen.getInVarsForDynamicCoarseConflictResolution().size() > 0 ) {
1885         output.println("     returnTR();");
1886       }
1887     }
1888     output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1889
1890
1891     output.println("{");
1892     output.println("SESEcommon *myparent=runningSESE->parent;");
1893
1894     // if this is not the Main sese (which has no parent) then return
1895     // THIS task's record to the PARENT'S task record pool, and only if
1896     // the reference count is now zero
1897     if( !fsen.getIsMainSESE() ) {
1898       output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1899       output.println("   RELEASE_REFERENCE_TO( runningSESE );");
1900       output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1901     } else {
1902       // the main task has no parent, just free its record
1903       output.println("   mlpFreeSESErecord( runningSESE );");
1904     }
1905
1906
1907     // last of all, decrement your parent's number of running children    
1908     output.println("   if( myparent != NULL ) {");
1909     output.println("     if( atomic_sub_and_test( 1, &(myparent->numRunningChildren) ) ) {");
1910     output.println("       pthread_mutex_lock  ( &(myparent->lock) );");
1911     output.println("       pthread_cond_signal ( &(myparent->runningChildrenCond) );");
1912     output.println("       pthread_mutex_unlock( &(myparent->lock) );");
1913     output.println("     }");
1914     output.println("   }");
1915
1916     output.println("}");
1917     
1918     // as this thread is wrapping up the task, make sure the thread-local var
1919     // for the currently running task record references an invalid task
1920     output.println("   runningSESE = (SESEcommon*) 0x1;");
1921
1922     if( state.COREPROF ) {
1923       output.println("#ifdef CP_EVENTID_TASKRETIRE");
1924       output.println("   CP_LOGEVENT( CP_EVENTID_TASKRETIRE, CP_EVENTTYPE_END );");
1925       output.println("#endif");
1926     }
1927   }
1928
1929  
1930   public void generateFlatWriteDynamicVarNode( FlatMethod              fm,  
1931                                                FlatWriteDynamicVarNode fwdvn,
1932                                                PrintWriter             output
1933                                              ) {
1934         
1935     Hashtable<TempDescriptor, VSTWrapper> writeDynamic = fwdvn.getVar2src();
1936
1937     assert writeDynamic != null;
1938
1939     Iterator wdItr = writeDynamic.entrySet().iterator();
1940     while( wdItr.hasNext() ) {
1941       Map.Entry           me     = (Map.Entry)      wdItr.next();
1942       TempDescriptor      refVar = (TempDescriptor) me.getKey();
1943       VSTWrapper          vstW   = (VSTWrapper)     me.getValue();
1944       VariableSourceToken vst    =                  vstW.vst;
1945
1946       output.println("     {");
1947       output.println("       SESEcommon* oldSrc = "+refVar+"_srcSESE;");
1948
1949       if( vst == null ) {
1950         // if there is no given source, this variable is ready so
1951         // mark src pointer NULL to signify that the var is up-to-date
1952         output.println("       "+refVar+"_srcSESE = NULL;");
1953       } else {
1954         // otherwise we track where it will come from
1955         SESEandAgePair instance = new SESEandAgePair( vst.getSESE(), vst.getAge() );
1956         output.println("       "+refVar+"_srcSESE = "+instance+";");    
1957         output.println("       "+refVar+"_srcOffset = (INTPTR) &((("+
1958                        vst.getSESE().getSESErecordName()+"*)0)->"+vst.getAddrVar()+");");
1959       }
1960
1961       // no matter what we did above, track reference count of whatever
1962       // this variable pointed to, do release last in case we're just
1963       // copying the same value in because 1->2->1 is safe but ref count
1964       // 1->0->1 has a window where it looks like it should be free'd
1965       output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1966       output.println("       if( "+refVar+"_srcSESE != NULL ) {");
1967       output.println("         ADD_REFERENCE_TO( "+refVar+"_srcSESE );");
1968       output.println("       }");
1969       output.println("       if( oldSrc != NULL ) {");
1970       output.println("         RELEASE_REFERENCE_TO( oldSrc );");
1971       output.println("       }");
1972       output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1973
1974       output.println("     }");
1975     }   
1976   }
1977
1978
1979   protected void generateFlatNew( FlatMethod      fm, 
1980                                   FlatNew         fn, 
1981                                   PrintWriter     output ) {
1982
1983     if( fn.getType().isArray() ) {
1984       int arrayid = state.getArrayNumber( fn.getType() )+state.numClasses();
1985
1986       if( GENERATEPRECISEGC ) {
1987         output.println(generateTemp( fm, fn.getDst())+
1988                        "=allocate_newarray_mlp("+localsprefixaddr+
1989                        ", "+arrayid+", "+generateTemp( fm, fn.getSize())+
1990                        ", oid, "+
1991                        oooa.getDisjointAnalysis().getAllocationSiteFromFlatNew( fn ).getUniqueAllocSiteID()+
1992                        ");");
1993         output.println("    oid += oidIncrement;");
1994       } else {
1995         output.println(generateTemp( fm, fn.getDst())+
1996                        "=allocate_newarray("+arrayid+
1997                        ", "+generateTemp( fm, fn.getSize())+
1998                        ");");
1999       }
2000
2001     } else {
2002       // not an array
2003       if( GENERATEPRECISEGC ) {
2004         output.println( generateTemp( fm, fn.getDst())+
2005                         "=allocate_new_mlp("+localsprefixaddr+
2006                         ", "+fn.getType().getClassDesc().getId()+
2007                         ", oid, "+
2008                         oooa.getDisjointAnalysis().getAllocationSiteFromFlatNew( fn ).getUniqueAllocSiteID()+
2009                         ");");
2010         output.println("    oid += oidIncrement;");        
2011       } else {
2012         output.println( generateTemp( fm, fn.getDst())+
2013                         "=allocate_new("+fn.getType().getClassDesc().getId()+
2014                         ");");
2015       }
2016     }
2017   }
2018
2019
2020   private int calculateSizeOfSESEParamList(FlatSESEEnterNode fsen){
2021           
2022     Set<TempDescriptor> tdSet=new HashSet<TempDescriptor>();
2023           
2024     for (Iterator iterator = fsen.getInVarSet().iterator(); iterator.hasNext();) {
2025       TempDescriptor tempDescriptor = (TempDescriptor) iterator.next();
2026       if(!tempDescriptor.getType().isPrimitive() || tempDescriptor.getType().isArray()){
2027         tdSet.add(tempDescriptor);
2028       } 
2029     }
2030           
2031     for (Iterator iterator = fsen.getOutVarSet().iterator(); iterator.hasNext();) {
2032       TempDescriptor tempDescriptor = (TempDescriptor) iterator.next();
2033       if(!tempDescriptor.getType().isPrimitive() || tempDescriptor.getType().isArray()){
2034         tdSet.add(tempDescriptor);
2035       } 
2036     }     
2037                   
2038     return tdSet.size();
2039   }
2040
2041   
2042   private String calculateSizeOfSESEParamSize(FlatSESEEnterNode fsen){
2043     HashMap <String,Integer> map=new HashMap();
2044     HashSet <TempDescriptor> processed=new HashSet<TempDescriptor>();
2045     String rtr="";
2046           
2047     // space for all in and out set primitives
2048     Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
2049     inSetAndOutSet.addAll( fsen.getInVarSet() );
2050     inSetAndOutSet.addAll( fsen.getOutVarSet() );
2051             
2052     Set<TempDescriptor> inSetAndOutSetPrims = new HashSet<TempDescriptor>();
2053
2054     Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
2055     while( itr.hasNext() ) {
2056       TempDescriptor temp = itr.next();
2057       TypeDescriptor type = temp.getType();
2058       if( !type.isPtr() ) {
2059         inSetAndOutSetPrims.add( temp );
2060       }
2061     }
2062             
2063     Iterator<TempDescriptor> itrPrims = inSetAndOutSetPrims.iterator();
2064     while( itrPrims.hasNext() ) {
2065       TempDescriptor temp = itrPrims.next();
2066       TypeDescriptor type = temp.getType();
2067       if(type.isPrimitive()){
2068         Integer count=map.get(type.getSymbol());
2069         if(count==null){
2070           count=new Integer(1);
2071           map.put(type.getSymbol(), count);
2072         }else{
2073           map.put(type.getSymbol(), new Integer(count.intValue()+1));
2074         }
2075       }      
2076     }
2077           
2078     Set<String> keySet=map.keySet();
2079     for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
2080       String key = (String) iterator.next();
2081       rtr+="+sizeof("+key+")*"+map.get(key);
2082     }
2083     return  rtr;
2084   }
2085
2086 }