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