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