bug fix in locality binding
[IRC.git] / Robust / src / IR / Flat / BuildCode.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 import java.util.*;
10 import java.io.*;
11
12 import Util.Relation;
13 import Analysis.TaskStateAnalysis.FlagState;
14 import Analysis.TaskStateAnalysis.FlagComparator;
15 import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
16 import Analysis.TaskStateAnalysis.Predicate;
17 import Analysis.TaskStateAnalysis.SafetyAnalysis;
18 import Analysis.TaskStateAnalysis.TaskIndex;
19 import Analysis.Locality.LocalityAnalysis;
20 import Analysis.Locality.LocalityBinding;
21 import Analysis.Locality.DiscoverConflicts;
22 import Analysis.Locality.DCWrapper;
23 import Analysis.Locality.DelayComputation;
24 import Analysis.Locality.BranchAnalysis;
25 import Analysis.CallGraph.CallGraph;
26 import Analysis.Prefetch.*;
27 import Analysis.Loops.WriteBarrier;
28 import Analysis.Loops.GlobalFieldType;
29 import Analysis.Locality.TypeAnalysis;
30 import Analysis.MLP.MLPAnalysis;
31 import Analysis.MLP.VariableSourceToken;
32 import Analysis.MLP.CodePlan;
33 import Analysis.MLP.SESEandAgePair;
34
35 public class BuildCode {
36   State state;
37   Hashtable temptovar;
38   Hashtable paramstable;
39   Hashtable tempstable;
40   Hashtable fieldorder;
41   Hashtable flagorder;
42   int tag=0;
43   String localsprefix="___locals___";
44   String localsprefixaddr="&"+localsprefix;
45   String localsprefixderef=localsprefix+".";
46   String fcrevert="___fcrevert___";
47   String paramsprefix="___params___";
48   String oidstr="___nextobject___";
49   String nextobjstr="___nextobject___";
50   String localcopystr="___localcopy___";
51   public static boolean GENERATEPRECISEGC=false;
52   public static String PREFIX="";
53   public static String arraytype="ArrayObject";
54   public static int flagcount = 0;
55   Virtual virtualcalls;
56   TypeUtil typeutil;
57   protected int maxtaskparams=0;
58   private int maxcount=0;
59   ClassDescriptor[] cdarray;
60   TypeDescriptor[] arraytable;
61   LocalityAnalysis locality;
62   Hashtable<LocalityBinding, TempDescriptor> reverttable;
63   Hashtable<LocalityBinding, Hashtable<TempDescriptor, TempDescriptor>> backuptable;
64   SafetyAnalysis sa;
65   PrefetchAnalysis pa;
66   MLPAnalysis mlpa;
67   String mlperrstr = "if(status != 0) { "+
68     "sprintf(errmsg, \"MLP error at %s:%d\", __FILE__, __LINE__); "+
69     "perror(errmsg); exit(-1); }";
70   boolean nonSESEpass=true;
71   WriteBarrier wb;
72   DiscoverConflicts dc;
73   DiscoverConflicts recorddc;
74   DCWrapper delaycomp;
75   CallGraph callgraph;
76
77
78   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa) {
79     this(st, temptovar, typeutil, null, sa, pa, null);
80   }
81
82   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa, MLPAnalysis mlpa) {
83     this(st, temptovar, typeutil, null, sa, pa, mlpa);
84   }
85
86   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, PrefetchAnalysis pa, MLPAnalysis mlpa) {
87     this(st, temptovar, typeutil, locality, null, pa, mlpa);
88   }
89
90   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, SafetyAnalysis sa, PrefetchAnalysis pa, MLPAnalysis mlpa) {
91     this.sa=sa;
92     this.pa=pa;
93     this.mlpa=mlpa;
94     state=st;
95     callgraph=new CallGraph(state);
96     if (state.SINGLETM)
97       oidstr="___objlocation___";
98     this.temptovar=temptovar;
99     paramstable=new Hashtable();
100     tempstable=new Hashtable();
101     fieldorder=new Hashtable();
102     flagorder=new Hashtable();
103     this.typeutil=typeutil;
104     virtualcalls=new Virtual(state,locality);
105     if (locality!=null) {
106       this.locality=locality;
107       this.reverttable=new Hashtable<LocalityBinding, TempDescriptor>();
108       this.backuptable=new Hashtable<LocalityBinding, Hashtable<TempDescriptor, TempDescriptor>>();
109       this.wb=new WriteBarrier(locality, st);
110     }
111     if (state.SINGLETM&&state.DCOPTS) {
112       TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
113       GlobalFieldType gft=new GlobalFieldType(callgraph, st, typeutil.getMain());
114       this.dc=new DiscoverConflicts(locality, st, typeanalysis, gft);
115       dc.doAnalysis();
116     }
117     if (state.DELAYCOMP) {
118       //TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
119       TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
120       GlobalFieldType gft=new GlobalFieldType(callgraph, st, typeutil.getMain());
121       delaycomp=new DCWrapper(locality, st, typeanalysis, gft);
122       dc=delaycomp.getConflicts();
123       recorddc=new DiscoverConflicts(locality, st, typeanalysis, delaycomp.getCannotDelayMap(), true, true, null);
124       recorddc.doAnalysis();
125     }
126   }
127
128   /** The buildCode method outputs C code for all the methods.  The Flat
129    * versions of the methods must already be generated and stored in
130    * the State object. */
131   PrintWriter outsandbox=null;
132
133   public void buildCode() {
134     /* Create output streams to write to */
135     PrintWriter outclassdefs=null;
136     PrintWriter outstructs=null;
137     PrintWriter outrepairstructs=null;
138     PrintWriter outmethodheader=null;
139     PrintWriter outmethod=null;
140     PrintWriter outvirtual=null;
141     PrintWriter outtask=null;
142     PrintWriter outtaskdefs=null;
143     PrintWriter outoptionalarrays=null;
144     PrintWriter optionalheaders=null;
145
146     try {
147       if (state.SANDBOX) {
148         outsandbox=new PrintWriter(new FileOutputStream(PREFIX+"sandboxdefs.c"), true);
149       }
150       outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
151       outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
152       outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
153       outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
154       outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
155       if (state.TASK) {
156         outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
157         outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
158         if (state.OPTIONAL) {
159           outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
160           optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
161         }
162       }
163       if (state.structfile!=null) {
164         outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
165       }
166     } catch (Exception e) {
167       e.printStackTrace();
168       System.exit(-1);
169     }
170
171     /* Build the virtual dispatch tables */
172     buildVirtualTables(outvirtual);
173
174     /* Output includes */
175     outmethodheader.println("#ifndef METHODHEADERS_H");
176     outmethodheader.println("#define METHODHEADERS_H");
177     outmethodheader.println("#include \"structdefs.h\"");
178     if (state.DSM)
179       outmethodheader.println("#include \"dstm.h\"");
180     if (state.SANDBOX) {
181       outmethodheader.println("#include \"sandbox.h\"");
182     }
183     if (state.SINGLETM) {
184       outmethodheader.println("#include \"tm.h\"");
185       outmethodheader.println("#include \"delaycomp.h\"");
186       outmethodheader.println("#include \"inlinestm.h\"");
187     }
188     if (state.ABORTREADERS) {
189       outmethodheader.println("#include \"abortreaders.h\"");
190       outmethodheader.println("#include <setjmp.h>");
191     }
192     if (state.MLP) {
193       outmethodheader.println("#include <stdlib.h>");
194       outmethodheader.println("#include <stdio.h>");
195       outmethodheader.println("#include <string.h>");
196       outmethodheader.println("#include \"mlp_runtime.h\"");
197       outmethodheader.println("#include \"psemaphore.h\"");
198     }
199
200     /* Output Structures */
201     outputStructs(outstructs);
202
203     // Output the C class declarations
204     // These could mutually reference each other
205     outputClassDeclarations(outclassdefs);
206
207     // Output function prototypes and structures for parameters
208     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
209     while(it.hasNext()) {
210       ClassDescriptor cn=(ClassDescriptor)it.next();
211       generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
212     }
213     outclassdefs.close();
214
215     if (state.TASK) {
216       /* Map flags to integers */
217       /* The runtime keeps track of flags using these integers */
218       it=state.getClassSymbolTable().getDescriptorsIterator();
219       while(it.hasNext()) {
220         ClassDescriptor cn=(ClassDescriptor)it.next();
221         mapFlags(cn);
222       }
223       /* Generate Tasks */
224       generateTaskStructs(outstructs, outmethodheader);
225
226       /* Outputs generic task structures if this is a task
227          program */
228       outputTaskTypes(outtask);
229     }
230
231     if( state.MLP ) {
232       // have to initialize some SESE compiler data before
233       // analyzing normal methods, which must happen before
234       // generating SESE internal code
235       for(Iterator<FlatSESEEnterNode> seseit=mlpa.getAllSESEs().iterator();seseit.hasNext();) {
236         FlatSESEEnterNode fsen = seseit.next();
237         initializeSESE( fsen );
238       }
239     }
240
241     /* Build the actual methods */
242     outputMethods(outmethod);
243
244     // Output function prototypes and structures for SESE's and code
245     if( state.MLP ) {
246
247       // used to differentiate, during code generation, whether we are
248       // passing over SESE body code, or non-SESE code
249       nonSESEpass = false;
250
251       // first generate code for each sese's internals
252       for(Iterator<FlatSESEEnterNode> seseit=mlpa.getAllSESEs().iterator();seseit.hasNext();) {
253         FlatSESEEnterNode fsen = seseit.next();
254         generateMethodSESE(fsen, null, outstructs, outmethodheader, outmethod);
255       }
256
257       // then write the invokeSESE switch to decouple scheduler
258       // from having to do unique details of sese invocation
259       generateSESEinvocationMethod(outmethodheader, outmethod);
260     }
261
262     if (state.TASK) {
263       /* Output code for tasks */
264       outputTaskCode(outtaskdefs, outmethod);
265       outtaskdefs.close();
266       /* Record maximum number of task parameters */
267       outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
268     } else if (state.main!=null) {
269       /* Generate main method */
270       outputMainMethod(outmethod);
271     }
272
273     /* Generate information for task with optional parameters */
274     if (state.TASK&&state.OPTIONAL) {
275       generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
276       outoptionalarrays.close();
277     }
278     
279     /* Output structure definitions for repair tool */
280     if (state.structfile!=null) {
281       buildRepairStructs(outrepairstructs);
282       outrepairstructs.close();
283     }
284     
285     /* Close files */
286     outmethodheader.println("#endif");
287     outmethodheader.close();
288     outmethod.close();
289     outstructs.println("#endif");
290     outstructs.close();
291   }
292   
293
294   /* This code just generates the main C method for java programs.
295    * The main C method packs up the arguments into a string array
296    * and passes it to the java main method. */
297
298   private void outputMainMethod(PrintWriter outmethod) {
299     outmethod.println("int main(int argc, const char *argv[]) {");
300     outmethod.println("  int i;");
301
302     if (state.MLP) {
303       //outmethod.println("  pthread_once( &mlpOnceObj, mlpInitOncePerThread );");
304       outmethod.println("  workScheduleInit( "+state.MLP_NUMCORES+", invokeSESEmethod );");
305     }
306
307     if (state.DSM) {
308       outmethod.println("#ifdef TRANSSTATS \n");
309       outmethod.println("handle();\n");
310       outmethod.println("#endif\n");
311     }
312     if (state.THREAD||state.DSM||state.SINGLETM) {
313       outmethod.println("initializethreads();");
314     }
315     if (state.DSM) {
316       outmethod.println("if (dstmStartup(argv[1])) {");
317       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
318         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-2);");
319       } else {
320         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-2);");
321       }
322     } else {
323       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
324         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
325       } else {
326         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
327       }
328     }
329     if (state.DSM) {
330       outmethod.println("  for(i=2;i<argc;i++) {");
331     } else
332       outmethod.println("  for(i=1;i<argc;i++) {");
333     outmethod.println("    int length=strlen(argv[i]);");
334     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
335       outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
336     } else {
337       outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
338     }
339     if (state.DSM)
340       outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-2]=newstring;");
341     else
342       outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
343     outmethod.println("  }");
344
345     MethodDescriptor md=typeutil.getMain();
346     ClassDescriptor cd=typeutil.getMainClass();
347
348     outmethod.println("   {");
349     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
350       if (state.DSM||state.SINGLETM) {
351         outmethod.print("       struct "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
352       } else
353         outmethod.print("       struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
354       outmethod.println("1, NULL,"+"stringarray};");
355       if (state.DSM||state.SINGLETM)
356         outmethod.println("     "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
357       else
358         outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
359     } else {
360       if (state.DSM||state.SINGLETM)
361         outmethod.println("     "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
362       else
363         outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
364     }
365     outmethod.println("   }");
366
367     if (state.DSM) {
368       outmethod.println("}");
369     }
370
371     if (state.THREAD||state.DSM||state.SINGLETM) {
372       outmethod.println("pthread_mutex_lock(&gclistlock);");
373       outmethod.println("threadcount--;");
374       outmethod.println("pthread_cond_signal(&gccond);");
375       outmethod.println("pthread_mutex_unlock(&gclistlock);");
376     }
377
378     if (state.DSM||state.SINGLETM) {
379       outmethod.println("#ifdef TRANSSTATS \n");
380       outmethod.println("printf(\"******  Transaction Stats   ******\\n\");");
381       outmethod.println("printf(\"numTransCommit= %d\\n\", numTransCommit);");
382       outmethod.println("printf(\"numTransAbort= %d\\n\", numTransAbort);");
383       outmethod.println("printf(\"nSoftAbort= %d\\n\", nSoftAbort);");
384       if (state.DSM) {
385         outmethod.println("printf(\"nchashSearch= %d\\n\", nchashSearch);");
386         outmethod.println("printf(\"nmhashSearch= %d\\n\", nmhashSearch);");
387         outmethod.println("printf(\"nprehashSearch= %d\\n\", nprehashSearch);");
388         outmethod.println("printf(\"nRemoteReadSend= %d\\n\", nRemoteSend);");
389         outmethod.println("printf(\"getResponse= %d\\n\", getResponse);");
390         outmethod.println("printf(\"bytesSent= %d\\n\", bytesSent);");
391         outmethod.println("printf(\"bytesRecv= %d\\n\", bytesRecv);");
392       } else if (state.SINGLETM) {
393         outmethod.println("printf(\"nSoftAbortAbort= %d\\n\", nSoftAbortAbort);");
394         outmethod.println("printf(\"nSoftAbortCommit= %d\\n\", nSoftAbortCommit);");
395         outmethod.println("#ifdef STMSTATS\n");
396         outmethod.println("for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {\n");
397         outmethod.println("  printf(\"typesCausingAbort[%2d] numaccess= %5d numabort= %3d\\n\", i, typesCausingAbort[i].numaccess, typesCausingAbort[i].numabort);\n");
398         outmethod.println("}\n");
399         outmethod.println("#endif\n");
400         outmethod.println("fflush(stdout);");
401       }
402       outmethod.println("#endif\n");
403     }
404
405     if (state.THREAD||state.SINGLETM)
406       outmethod.println("pthread_exit(NULL);");
407
408     if (state.MLP) {
409       outmethod.println("  workScheduleBegin();");
410     }
411
412     outmethod.println("}");
413   }
414
415   /* This method outputs code for each task. */
416
417   private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod) {
418     /* Compile task based program */
419     outtaskdefs.println("#include \"task.h\"");
420     outtaskdefs.println("#include \"methodheaders.h\"");
421     Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
422     while(taskit.hasNext()) {
423       TaskDescriptor td=(TaskDescriptor)taskit.next();
424       FlatMethod fm=state.getMethodFlat(td);
425       generateFlatMethod(fm, null, outmethod);
426       generateTaskDescriptor(outtaskdefs, fm, td);
427     }
428
429     //Output task descriptors
430     taskit=state.getTaskSymbolTable().getDescriptorsIterator();
431     outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
432     boolean first=true;
433     while(taskit.hasNext()) {
434       TaskDescriptor td=(TaskDescriptor)taskit.next();
435       if (first)
436         first=false;
437       else
438         outtaskdefs.println(",");
439       outtaskdefs.print("&task_"+td.getSafeSymbol());
440     }
441     outtaskdefs.println("};");
442
443     outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
444   }
445
446   /* This method outputs most of the methods.c file.  This includes
447    * some standard includes and then an array with the sizes of
448    * objets and array that stores supertype and then the code for
449    * the Java methods.. */
450
451   protected void outputMethods(PrintWriter outmethod) {
452     outmethod.println("#include \"methodheaders.h\"");
453     outmethod.println("#include \"virtualtable.h\"");
454     outmethod.println("#include \"runtime.h\"");
455     if (state.SANDBOX) {
456       outmethod.println("#include \"sandboxdefs.c\"");
457     }
458     if (state.DSM) {
459       outmethod.println("#include \"addPrefetchEnhance.h\"");
460       outmethod.println("#include \"localobjects.h\"");
461     }
462     if (state.FASTCHECK) {
463       outmethod.println("#include \"localobjects.h\"");
464     }
465     if(state.MULTICORE) {
466       outmethod.println("#include \"task.h\"");
467           outmethod.println("#include \"multicoreruntime.h\"");
468           outmethod.println("#include \"runtime_arch.h\"");
469     }
470     if (state.THREAD||state.DSM||state.SINGLETM)
471       outmethod.println("#include <thread.h>");
472     if (state.main!=null) {
473       outmethod.println("#include <string.h>");
474     }
475     if (state.CONSCHECK) {
476       outmethod.println("#include \"checkers.h\"");
477     }
478     if (state.MLP) {
479       outmethod.println("#include <stdlib.h>");
480       outmethod.println("#include <stdio.h>");
481       outmethod.println("#include \"mlp_runtime.h\"");
482       outmethod.println("#include \"psemaphore.h\"");
483     }
484
485
486     //Store the sizes of classes & array elements
487     generateSizeArray(outmethod);
488
489     //Store table of supertypes
490     generateSuperTypeTable(outmethod);
491
492     //Store the layout of classes
493     generateLayoutStructs(outmethod);
494
495     /* Generate code for methods */
496     if (state.DSM||state.SINGLETM) {
497       for(Iterator<LocalityBinding> lbit=locality.getLocalityBindings().iterator(); lbit.hasNext();) {
498         LocalityBinding lb=lbit.next();
499         MethodDescriptor md=lb.getMethod();
500         FlatMethod fm=state.getMethodFlat(md);
501         wb.analyze(lb);
502         if (!md.getModifiers().isNative()) {
503           generateFlatMethod(fm, lb, outmethod);
504       //System.out.println("fm= " + fm + " md= " + md);
505         }
506       }
507     } else {
508       Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
509       while(classit.hasNext()) {
510         ClassDescriptor cn=(ClassDescriptor)classit.next();
511         Iterator methodit=cn.getMethods();
512         while(methodit.hasNext()) {
513           /* Classify parameters */
514           MethodDescriptor md=(MethodDescriptor)methodit.next();
515           FlatMethod fm=state.getMethodFlat(md);
516           if (!md.getModifiers().isNative()) {
517             generateFlatMethod(fm, null, outmethod);
518           }
519         }
520       }
521     }
522   }
523
524   protected void outputStructs(PrintWriter outstructs) {
525     outstructs.println("#ifndef STRUCTDEFS_H");
526     outstructs.println("#define STRUCTDEFS_H");
527     outstructs.println("#include \"classdefs.h\"");
528     outstructs.println("#ifndef INTPTR");
529     outstructs.println("#ifdef BIT64");
530     outstructs.println("#define INTPTR long");
531     outstructs.println("#else");
532     outstructs.println("#define INTPTR int");
533     outstructs.println("#endif");
534     outstructs.println("#endif");
535     if( state.MLP ) {
536       outstructs.println("#include \"mlp_runtime.h\"");
537       outstructs.println("#include \"psemaphore.h\"");
538     }
539
540     /* Output #defines that the runtime uses to determine type
541      * numbers for various objects it needs */
542     outstructs.println("#define MAXCOUNT "+maxcount);
543     if (state.DSM||state.SINGLETM) {
544       LocalityBinding lbrun=new LocalityBinding(typeutil.getRun(), false);
545       if (state.DSM) {
546         lbrun.setGlobalThis(LocalityAnalysis.GLOBAL);
547       }
548       else if (state.SINGLETM) {
549         lbrun.setGlobalThis(LocalityAnalysis.NORMAL);
550       }
551       outstructs.println("#define RUNMETHOD "+virtualcalls.getLocalityNumber(lbrun));
552     }
553
554     if (state.DSMTASK) {
555       LocalityBinding lbexecute = new LocalityBinding(typeutil.getExecute(), false);
556       if(state.DSM)
557         lbexecute.setGlobalThis(LocalityAnalysis.GLOBAL);
558       else if( state.SINGLETM)
559         lbexecute.setGlobalThis(LocalityAnalysis.NORMAL);
560       outstructs.println("#define EXECUTEMETHOD " + virtualcalls.getLocalityNumber(lbexecute));
561     }
562
563     outstructs.println("#define STRINGARRAYTYPE "+
564                        (state.getArrayNumber(
565                           (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
566
567     outstructs.println("#define OBJECTARRAYTYPE "+
568                        (state.getArrayNumber(
569                           (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
570
571
572     outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
573     outstructs.println("#define CHARARRAYTYPE "+
574                        (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
575
576     outstructs.println("#define BYTEARRAYTYPE "+
577                        (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
578
579     outstructs.println("#define BYTEARRAYARRAYTYPE "+
580                        (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
581
582     outstructs.println("#define NUMCLASSES "+state.numClasses());
583     int totalClassSize = state.numClasses() + state.numArrays();
584     outstructs.println("#define TOTALNUMCLASSANDARRAY "+ totalClassSize);
585     if (state.TASK) {
586       outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
587       outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
588       outstructs.println("#define TAGARRAYTYPE "+
589                          (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
590     }
591   }
592
593   protected void outputClassDeclarations(PrintWriter outclassdefs) {
594     if (state.THREAD||state.DSM||state.SINGLETM)
595       outclassdefs.println("#include <pthread.h>");
596     outclassdefs.println("#ifndef INTPTR");
597     outclassdefs.println("#ifdef BIT64");
598     outclassdefs.println("#define INTPTR long");
599     outclassdefs.println("#else");
600     outclassdefs.println("#define INTPTR int");
601     outclassdefs.println("#endif");
602     outclassdefs.println("#endif");
603     if(state.OPTIONAL)
604       outclassdefs.println("#include \"optionalstruct.h\"");
605     outclassdefs.println("struct "+arraytype+";");
606     /* Start by declaring all structs */
607     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
608     while(it.hasNext()) {
609       ClassDescriptor cn=(ClassDescriptor)it.next();
610       outclassdefs.println("struct "+cn.getSafeSymbol()+";");
611     }
612     outclassdefs.println("");
613     //Print out definition for array type
614     outclassdefs.println("struct "+arraytype+" {");
615     outclassdefs.println("  int type;");
616     if (state.THREAD) {
617       outclassdefs.println("  pthread_t tid;");
618       outclassdefs.println("  void * lockentry;");
619       outclassdefs.println("  int lockcount;");
620     }
621     if (state.TASK) {
622       outclassdefs.println("  int flag;");
623       if(!state.MULTICORE) {
624         outclassdefs.println("  void * flagptr;");
625       } else {
626         outclassdefs.println("  int version;");
627         outclassdefs.println("  int * lock;");  // lock entry for this obj
628         outclassdefs.println("  int mutex;");  
629         outclassdefs.println("  int lockcount;");
630         if(state.MULTICOREGC) {
631           outclassdefs.println("  int marked;");
632         }
633       }
634       if(state.OPTIONAL) {
635         outclassdefs.println("  int numfses;");
636         outclassdefs.println("  int * fses;");
637       }
638     }
639     printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
640
641     if (state.STMARRAY) {
642       outclassdefs.println("  int lowindex;");
643       outclassdefs.println("  int highindex;");
644     }
645     if (state.ARRAYPAD)
646       outclassdefs.println("  int paddingforarray;");
647     if (state.DUALVIEW) {
648       outclassdefs.println("  int arrayversion;");
649     }
650
651     outclassdefs.println("  int ___length___;");
652     outclassdefs.println("};\n");
653     outclassdefs.println("extern int classsize[];");
654     outclassdefs.println("extern int hasflags[];");
655     outclassdefs.println("extern unsigned INTPTR * pointerarray[];");
656     outclassdefs.println("extern int supertypes[];");
657   }
658
659   /** Prints out definitions for generic task structures */
660
661   private void outputTaskTypes(PrintWriter outtask) {
662     outtask.println("#ifndef _TASK_H");
663     outtask.println("#define _TASK_H");
664     outtask.println("struct parameterdescriptor {");
665     outtask.println("int type;");
666     outtask.println("int numberterms;");
667     outtask.println("int *intarray;");
668     outtask.println("void * queue;");
669     outtask.println("int numbertags;");
670     outtask.println("int *tagarray;");
671     outtask.println("};");
672
673     outtask.println("struct taskdescriptor {");
674     outtask.println("void * taskptr;");
675     outtask.println("int numParameters;");
676     outtask.println("  int numTotal;");
677     outtask.println("struct parameterdescriptor **descriptorarray;");
678     outtask.println("char * name;");
679     outtask.println("};");
680     outtask.println("extern struct taskdescriptor * taskarray[];");
681     outtask.println("extern numtasks;");
682     outtask.println("#endif");
683   }
684
685
686   private void buildRepairStructs(PrintWriter outrepairstructs) {
687     Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
688     while(classit.hasNext()) {
689       ClassDescriptor cn=(ClassDescriptor)classit.next();
690       outrepairstructs.println("structure "+cn.getSymbol()+" {");
691       outrepairstructs.println("  int __type__;");
692       if (state.TASK) {
693         outrepairstructs.println("  int __flag__;");
694         if(!state.MULTICORE) {
695           outrepairstructs.println("  int __flagptr__;");
696         }
697       }
698       printRepairStruct(cn, outrepairstructs);
699       outrepairstructs.println("}\n");
700     }
701
702     for(int i=0; i<state.numArrays(); i++) {
703       TypeDescriptor tdarray=arraytable[i];
704       TypeDescriptor tdelement=tdarray.dereference();
705       outrepairstructs.println("structure "+arraytype+"_"+state.getArrayNumber(tdarray)+" {");
706       outrepairstructs.println("  int __type__;");
707       printRepairStruct(typeutil.getClass(TypeUtil.ObjectClass), outrepairstructs);
708       outrepairstructs.println("  int length;");
709       /*
710          // Need to add support to repair tool for this
711          if (tdelement.isClass()||tdelement.isArray())
712           outrepairstructs.println("  "+tdelement.getRepairSymbol()+" * elem[this.length];");
713          else
714           outrepairstructs.println("  "+tdelement.getRepairSymbol()+" elem[this.length];");
715        */
716       outrepairstructs.println("}\n");
717     }
718   }
719
720   private void printRepairStruct(ClassDescriptor cn, PrintWriter output) {
721     ClassDescriptor sp=cn.getSuperDesc();
722     if (sp!=null)
723       printRepairStruct(sp, output);
724
725     Vector fields=(Vector)fieldorder.get(cn);
726
727     for(int i=0; i<fields.size(); i++) {
728       FieldDescriptor fd=(FieldDescriptor)fields.get(i);
729       if (fd.getType().isArray()) {
730         output.println("  "+arraytype+"_"+ state.getArrayNumber(fd.getType()) +" * "+fd.getSymbol()+";");
731       } else if (fd.getType().isClass())
732         output.println("  "+fd.getType().getRepairSymbol()+" * "+fd.getSymbol()+";");
733       else if (fd.getType().isFloat())
734         output.println("  int "+fd.getSymbol()+"; /* really float */");
735       else
736         output.println("  "+fd.getType().getRepairSymbol()+" "+fd.getSymbol()+";");
737     }
738   }
739
740   /** This method outputs TaskDescriptor information */
741   private void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) {
742     for (int i=0; i<task.numParameters(); i++) {
743       VarDescriptor param_var=task.getParameter(i);
744       TypeDescriptor param_type=task.getParamType(i);
745       FlagExpressionNode param_flag=task.getFlag(param_var);
746       TagExpressionList param_tag=task.getTag(param_var);
747
748       int dnfterms;
749       if (param_flag==null) {
750         output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
751         output.println("0x0, 0x0 };");
752         dnfterms=1;
753       } else {
754         DNFFlag dflag=param_flag.getDNF();
755         dnfterms=dflag.size();
756
757         Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
758         output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
759         for(int j=0; j<dflag.size(); j++) {
760           if (j!=0)
761             output.println(",");
762           Vector term=dflag.get(j);
763           int andmask=0;
764           int checkmask=0;
765           for(int k=0; k<term.size(); k++) {
766             DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
767             FlagDescriptor fd=dfa.getFlag();
768             boolean negated=dfa.getNegated();
769             int flagid=1<<((Integer)flags.get(fd)).intValue();
770             andmask|=flagid;
771             if (!negated)
772               checkmask|=flagid;
773           }
774           output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
775         }
776         output.println("};");
777       }
778
779       output.println("int parametertag_"+i+"_"+task.getSafeSymbol()+"[]={");
780       //BUG...added next line to fix, test with any task program
781       if (param_tag!=null)
782         for(int j=0; j<param_tag.numTags(); j++) {
783           if (j!=0)
784             output.println(",");
785           /* for each tag we need */
786           /* which slot it is */
787           /* what type it is */
788           TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
789           TempDescriptor tmp=param_tag.getTemp(j);
790           int slot=fm.getTagInt(tmp);
791           output.println(slot+", "+state.getTagId(tvd.getTag()));
792         }
793       output.println("};");
794
795       output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
796       output.println("/* type */"+param_type.getClassDesc().getId()+",");
797       output.println("/* number of DNF terms */"+dnfterms+",");
798       output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
799       output.println("0,");
800       //BUG, added next line to fix and else statement...test
801       //with any task program
802       if (param_tag!=null)
803         output.println("/* number of tags */"+param_tag.numTags()+",");
804       else
805         output.println("/* number of tags */ 0,");
806       output.println("parametertag_"+i+"_"+task.getSafeSymbol());
807       output.println("};");
808     }
809
810
811     output.println("struct parameterdescriptor * parameterdescriptors_"+task.getSafeSymbol()+"[] = {");
812     for (int i=0; i<task.numParameters(); i++) {
813       if (i!=0)
814         output.println(",");
815       output.print("&parameter_"+i+"_"+task.getSafeSymbol());
816     }
817     output.println("};");
818
819     output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
820     output.println("&"+task.getSafeSymbol()+",");
821     output.println("/* number of parameters */" +task.numParameters() + ",");
822     int numtotal=task.numParameters()+fm.numTags();
823     output.println("/* number total parameters */" +numtotal + ",");
824     output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
825     output.println("\""+task.getSymbol()+"\"");
826     output.println("};");
827   }
828
829
830   /** The buildVirtualTables method outputs the virtual dispatch
831    * tables for methods. */
832
833   protected void buildVirtualTables(PrintWriter outvirtual) {
834     Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
835     while(classit.hasNext()) {
836       ClassDescriptor cd=(ClassDescriptor)classit.next();
837       if (virtualcalls.getMethodCount(cd)>maxcount)
838         maxcount=virtualcalls.getMethodCount(cd);
839     }
840     MethodDescriptor[][] virtualtable=null;
841     LocalityBinding[][] lbvirtualtable=null;
842     if (state.DSM||state.SINGLETM)
843       lbvirtualtable=new LocalityBinding[state.numClasses()+state.numArrays()][maxcount];
844     else
845       virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
846
847     /* Fill in virtual table */
848     classit=state.getClassSymbolTable().getDescriptorsIterator();
849     while(classit.hasNext()) {
850       ClassDescriptor cd=(ClassDescriptor)classit.next();
851       if (state.DSM||state.SINGLETM)
852         fillinRow(cd, lbvirtualtable, cd.getId());
853       else
854         fillinRow(cd, virtualtable, cd.getId());
855     }
856
857     ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
858     Iterator arrayit=state.getArrayIterator();
859     while(arrayit.hasNext()) {
860       TypeDescriptor td=(TypeDescriptor)arrayit.next();
861       int id=state.getArrayNumber(td);
862       if (state.DSM||state.SINGLETM)
863         fillinRow(objectcd, lbvirtualtable, id+state.numClasses());
864       else
865         fillinRow(objectcd, virtualtable, id+state.numClasses());
866     }
867
868     outvirtual.print("void * virtualtable[]={");
869     boolean needcomma=false;
870     for(int i=0; i<state.numClasses()+state.numArrays(); i++) {
871       for(int j=0; j<maxcount; j++) {
872         if (needcomma)
873           outvirtual.print(", ");
874         if ((state.DSM||state.SINGLETM)&&lbvirtualtable[i][j]!=null) {
875           LocalityBinding lb=lbvirtualtable[i][j];
876           MethodDescriptor md=lb.getMethod();
877           outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
878         } else if (!(state.DSM||state.SINGLETM)&&virtualtable[i][j]!=null) {
879           MethodDescriptor md=virtualtable[i][j];
880           outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
881         } else {
882           outvirtual.print("0");
883         }
884         needcomma=true;
885       }
886       outvirtual.println("");
887     }
888     outvirtual.println("};");
889     outvirtual.close();
890   }
891
892   private void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
893     /* Get inherited methods */
894     if (cd.getSuperDesc()!=null)
895       fillinRow(cd.getSuperDesc(), virtualtable, rownum);
896     /* Override them with our methods */
897     for(Iterator it=cd.getMethods(); it.hasNext();) {
898       MethodDescriptor md=(MethodDescriptor)it.next();
899       if (md.isStatic()||md.getReturnType()==null)
900         continue;
901       int methodnum=virtualcalls.getMethodNumber(md);
902       virtualtable[rownum][methodnum]=md;
903     }
904   }
905
906   private void fillinRow(ClassDescriptor cd, LocalityBinding[][] virtualtable, int rownum) {
907     /* Get inherited methods */
908     if (cd.getSuperDesc()!=null)
909       fillinRow(cd.getSuperDesc(), virtualtable, rownum);
910     /* Override them with our methods */
911     if (locality.getClassBindings(cd)!=null)
912       for(Iterator<LocalityBinding> lbit=locality.getClassBindings(cd).iterator(); lbit.hasNext();) {
913         LocalityBinding lb=lbit.next();
914         MethodDescriptor md=lb.getMethod();
915         //Is the method static or a constructor
916         if (md.isStatic()||md.getReturnType()==null)
917           continue;
918         int methodnum=virtualcalls.getLocalityNumber(lb);
919         virtualtable[rownum][methodnum]=lb;
920       }
921   }
922
923   /** Generate array that contains the sizes of class objects.  The
924    * object allocation functions in the runtime use this
925    * information. */
926
927   private void generateSizeArray(PrintWriter outclassdefs) {
928     outclassdefs.print("extern struct prefetchCountStats * evalPrefetch;\n");
929     outclassdefs.print("#ifdef TRANSSTATS \n");
930     outclassdefs.print("extern int numTransAbort;\n");
931     outclassdefs.print("extern int numTransCommit;\n");
932     outclassdefs.print("extern int nSoftAbort;\n");
933     if (state.DSM) {
934       outclassdefs.print("extern int nchashSearch;\n");
935       outclassdefs.print("extern int nmhashSearch;\n");
936       outclassdefs.print("extern int nprehashSearch;\n");
937       outclassdefs.print("extern int nRemoteSend;\n");
938       outclassdefs.print("extern int getResponse;\n");
939       outclassdefs.print("extern int bytesSent;\n");
940       outclassdefs.print("extern int bytesRecv;\n");
941       outclassdefs.print("extern void handle();\n");
942     } else if (state.SINGLETM) {
943       outclassdefs.println("extern int nSoftAbortAbort;");
944       outclassdefs.println("extern int nSoftAbortCommit;");
945       outclassdefs.println("#ifdef STMSTATS\n");
946       outclassdefs.println("extern objtypestat_t typesCausingAbort[];");
947       outclassdefs.println("#endif\n");
948     }
949     outclassdefs.print("#endif\n");
950     outclassdefs.print("int numprefetchsites = " + pa.prefetchsiteid + ";\n");
951
952     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
953     cdarray=new ClassDescriptor[state.numClasses()];
954     cdarray[0] = null;
955     while(it.hasNext()) {
956       ClassDescriptor cd=(ClassDescriptor)it.next();
957       cdarray[cd.getId()]=cd;
958     }
959
960     arraytable=new TypeDescriptor[state.numArrays()];
961
962     Iterator arrayit=state.getArrayIterator();
963     while(arrayit.hasNext()) {
964       TypeDescriptor td=(TypeDescriptor)arrayit.next();
965       int id=state.getArrayNumber(td);
966       arraytable[id]=td;
967     }
968
969
970
971     /* Print out types */
972     outclassdefs.println("/* ");
973     for(int i=0; i<state.numClasses(); i++) {
974       ClassDescriptor cd=cdarray[i];
975       if(cd == null) {
976         outclassdefs.println("NULL " + i);
977       } else {
978         outclassdefs.println(cd +"  "+i);
979       }
980     }
981
982     for(int i=0; i<state.numArrays(); i++) {
983       TypeDescriptor arraytd=arraytable[i];
984       outclassdefs.println(arraytd.toPrettyString() +"  "+(i+state.numClasses()));
985     }
986
987     outclassdefs.println("*/");
988
989
990     outclassdefs.print("int classsize[]={");
991
992     boolean needcomma=false;
993     for(int i=0; i<state.numClasses(); i++) {
994       if (needcomma)
995         outclassdefs.print(", ");
996       if(i>0) {
997         outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");
998       } else {
999         outclassdefs.print("0");
1000       }
1001       needcomma=true;
1002     }
1003
1004
1005     for(int i=0; i<state.numArrays(); i++) {
1006       if (needcomma)
1007         outclassdefs.print(", ");
1008       TypeDescriptor tdelement=arraytable[i].dereference();
1009       if (tdelement.isArray()||tdelement.isClass())
1010         outclassdefs.print("sizeof(void *)");
1011       else
1012         outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
1013       needcomma=true;
1014     }
1015
1016     outclassdefs.println("};");
1017
1018     ClassDescriptor objectclass=typeutil.getClass(TypeUtil.ObjectClass);
1019     needcomma=false;
1020     outclassdefs.print("int typearray[]={");
1021     for(int i=0; i<state.numClasses(); i++) {
1022       ClassDescriptor cd=cdarray[i];
1023       ClassDescriptor supercd=i>0?cd.getSuperDesc():null;
1024       if (needcomma)
1025         outclassdefs.print(", ");
1026       if (supercd==null)
1027         outclassdefs.print("-1");
1028       else
1029         outclassdefs.print(supercd.getId());
1030       needcomma=true;
1031     }
1032
1033     for(int i=0; i<state.numArrays(); i++) {
1034       TypeDescriptor arraytd=arraytable[i];
1035       ClassDescriptor arraycd=arraytd.getClassDesc();
1036       if (arraycd==null) {
1037         if (needcomma)
1038           outclassdefs.print(", ");
1039         outclassdefs.print(objectclass.getId());
1040         needcomma=true;
1041         continue;
1042       }
1043       ClassDescriptor cd=arraycd.getSuperDesc();
1044       int type=-1;
1045       while(cd!=null) {
1046         TypeDescriptor supertd=new TypeDescriptor(cd);
1047         supertd.setArrayCount(arraytd.getArrayCount());
1048         type=state.getArrayNumber(supertd);
1049         if (type!=-1) {
1050           type+=state.numClasses();
1051           break;
1052         }
1053         cd=cd.getSuperDesc();
1054       }
1055       if (needcomma)
1056         outclassdefs.print(", ");
1057       outclassdefs.print(type);
1058       needcomma=true;
1059     }
1060
1061     outclassdefs.println("};");
1062
1063     needcomma=false;
1064
1065
1066     outclassdefs.print("int typearray2[]={");
1067     for(int i=0; i<state.numArrays(); i++) {
1068       TypeDescriptor arraytd=arraytable[i];
1069       ClassDescriptor arraycd=arraytd.getClassDesc();
1070       if (arraycd==null) {
1071         if (needcomma)
1072           outclassdefs.print(", ");
1073         outclassdefs.print("-1");
1074         needcomma=true;
1075         continue;
1076       }
1077       ClassDescriptor cd=arraycd.getSuperDesc();
1078       int level=arraytd.getArrayCount()-1;
1079       int type=-1;
1080       for(; level>0; level--) {
1081         TypeDescriptor supertd=new TypeDescriptor(objectclass);
1082         supertd.setArrayCount(level);
1083         type=state.getArrayNumber(supertd);
1084         if (type!=-1) {
1085           type+=state.numClasses();
1086           break;
1087         }
1088       }
1089       if (needcomma)
1090         outclassdefs.print(", ");
1091       outclassdefs.print(type);
1092       needcomma=true;
1093     }
1094
1095     outclassdefs.println("};");
1096   }
1097
1098   /** Constructs params and temp objects for each method or task.
1099    * These objects tell the compiler which temps need to be
1100    * allocated.  */
1101
1102   protected void generateTempStructs(FlatMethod fm, LocalityBinding lb) {
1103     MethodDescriptor md=fm.getMethod();
1104     TaskDescriptor task=fm.getTask();
1105     Set<TempDescriptor> saveset=lb!=null ? locality.getTempSet(lb) : null;
1106     ParamsObject objectparams=md!=null ? new ParamsObject(md,tag++) : new ParamsObject(task, tag++);
1107     if (lb!=null) {
1108       paramstable.put(lb, objectparams);
1109       backuptable.put(lb, new Hashtable<TempDescriptor, TempDescriptor>());
1110     } else if (md!=null)
1111       paramstable.put(md, objectparams);
1112     else
1113       paramstable.put(task, objectparams);
1114
1115     for(int i=0; i<fm.numParameters(); i++) {
1116       TempDescriptor temp=fm.getParameter(i);
1117       TypeDescriptor type=temp.getType();
1118       if (type.isPtr()&&((GENERATEPRECISEGC) || (this.state.MULTICOREGC)))
1119         objectparams.addPtr(temp);
1120       else
1121         objectparams.addPrim(temp);
1122       if(lb!=null&&saveset.contains(temp)) {
1123         backuptable.get(lb).put(temp, temp.createNew());
1124       }
1125     }
1126
1127     for(int i=0; i<fm.numTags(); i++) {
1128       TempDescriptor temp=fm.getTag(i);
1129       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
1130         objectparams.addPtr(temp);
1131       else
1132         objectparams.addPrim(temp);
1133     }
1134
1135     TempObject objecttemps=md!=null ? new TempObject(objectparams,md,tag++) : new TempObject(objectparams, task, tag++);
1136     if (lb!=null)
1137       tempstable.put(lb, objecttemps);
1138     else if (md!=null)
1139       tempstable.put(md, objecttemps);
1140     else
1141       tempstable.put(task, objecttemps);
1142
1143     for(Iterator nodeit=fm.getNodeSet().iterator(); nodeit.hasNext();) {
1144       FlatNode fn=(FlatNode)nodeit.next();
1145       TempDescriptor[] writes=fn.writesTemps();
1146       for(int i=0; i<writes.length; i++) {
1147         TempDescriptor temp=writes[i];
1148         TypeDescriptor type=temp.getType();
1149         if (type.isPtr()&&((GENERATEPRECISEGC) || (this.state.MULTICOREGC)))
1150           objecttemps.addPtr(temp);
1151         else
1152           objecttemps.addPrim(temp);
1153         if(lb!=null&&saveset.contains(temp)&&
1154            !backuptable.get(lb).containsKey(temp))
1155           backuptable.get(lb).put(temp, temp.createNew());
1156       }
1157     }
1158
1159     /* Create backup temps */
1160     if (lb!=null) {
1161       for(Iterator<TempDescriptor> tmpit=backuptable.get(lb).values().iterator(); tmpit.hasNext();) {
1162         TempDescriptor tmp=tmpit.next();
1163         TypeDescriptor type=tmp.getType();
1164         if (type.isPtr()&&((GENERATEPRECISEGC) || (this.state.MULTICOREGC)))
1165           objecttemps.addPtr(tmp);
1166         else
1167           objecttemps.addPrim(tmp);
1168       }
1169       /* Create temp to hold revert table */
1170       if (state.DSM&&(lb.getHasAtomic()||lb.isAtomic())) {
1171         TempDescriptor reverttmp=new TempDescriptor("revertlist", typeutil.getClass(TypeUtil.ObjectClass));
1172         if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
1173           objecttemps.addPtr(reverttmp);
1174         else
1175           objecttemps.addPrim(reverttmp);
1176         reverttable.put(lb, reverttmp);
1177       }
1178     }
1179   }
1180
1181   /** This method outputs the following information about classes
1182    * and arrays:
1183    * (1) For classes, what are the locations of pointers.
1184    * (2) For arrays, does the array contain pointers or primitives.
1185    * (3) For classes, does the class contain flags.
1186    */
1187
1188   private void generateLayoutStructs(PrintWriter output) {
1189     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
1190     while(it.hasNext()) {
1191       ClassDescriptor cn=(ClassDescriptor)it.next();
1192       output.println("unsigned INTPTR "+cn.getSafeSymbol()+"_pointers[]={");
1193       Iterator allit=cn.getFieldTable().getAllDescriptorsIterator();
1194       int count=0;
1195       while(allit.hasNext()) {
1196         FieldDescriptor fd=(FieldDescriptor)allit.next();
1197         TypeDescriptor type=fd.getType();
1198         if (state.DSM&&fd.isGlobal())         //Don't GC the global objects for now
1199           continue;
1200         if (type.isPtr())
1201           count++;
1202       }
1203       output.print(count);
1204       allit=cn.getFieldTable().getAllDescriptorsIterator();
1205       while(allit.hasNext()) {
1206         FieldDescriptor fd=(FieldDescriptor)allit.next();
1207         TypeDescriptor type=fd.getType();
1208         if (state.DSM&&fd.isGlobal())         //Don't GC the global objects for now
1209           continue;
1210         if (type.isPtr()) {
1211           output.println(",");
1212           output.print("((unsigned INTPTR)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))");
1213         }
1214       }
1215       output.println("};");
1216     }
1217     output.println("unsigned INTPTR * pointerarray[]={");
1218     boolean needcomma=false;
1219     for(int i=0; i<state.numClasses(); i++) {
1220       ClassDescriptor cn=cdarray[i];
1221       if (needcomma)
1222         output.println(",");
1223       needcomma=true;
1224       if(cn != null) {
1225         output.print(cn.getSafeSymbol()+"_pointers");
1226       } else {
1227         output.print("NULL");
1228       }
1229     }
1230
1231     for(int i=0; i<state.numArrays(); i++) {
1232       if (needcomma)
1233         output.println(", ");
1234       TypeDescriptor tdelement=arraytable[i].dereference();
1235       if (tdelement.isArray()||tdelement.isClass())
1236         output.print("((unsigned INTPTR *)1)");
1237       else
1238         output.print("0");
1239       needcomma=true;
1240     }
1241
1242     output.println("};");
1243     needcomma=false;
1244     output.println("int hasflags[]={");
1245     for(int i=0; i<state.numClasses(); i++) {
1246       ClassDescriptor cn=cdarray[i];
1247       if (needcomma)
1248         output.println(", ");
1249       needcomma=true;
1250       if ((cn != null) && (cn.hasFlags()))
1251         output.print("1");
1252       else
1253         output.print("0");
1254     }
1255     output.println("};");
1256   }
1257
1258   /** Print out table to give us supertypes */
1259   private void generateSuperTypeTable(PrintWriter output) {
1260     output.println("int supertypes[]={");
1261     boolean needcomma=false;
1262     for(int i=0; i<state.numClasses(); i++) {
1263       ClassDescriptor cn=cdarray[i];
1264       if (needcomma)
1265         output.println(",");
1266       needcomma=true;
1267       if ((cn != null) && (cn.getSuperDesc()!=null)) {
1268         ClassDescriptor cdsuper=cn.getSuperDesc();
1269         output.print(cdsuper.getId());
1270       } else
1271         output.print("-1");
1272     }
1273     output.println("};");
1274   }
1275
1276   /** Force consistent field ordering between inherited classes. */
1277
1278   private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
1279
1280     ClassDescriptor sp=cn.getSuperDesc();
1281     if (sp!=null)
1282       printClassStruct(sp, classdefout);
1283
1284     if (!fieldorder.containsKey(cn)) {
1285       Vector fields=new Vector();
1286       fieldorder.put(cn,fields);
1287       Vector fieldvec=cn.getFieldVec();
1288       for(int i=0;i<fieldvec.size();i++) {
1289         FieldDescriptor fd=(FieldDescriptor)fieldvec.get(i);
1290         if ((sp==null||!sp.getFieldTable().contains(fd.getSymbol())))
1291           fields.add(fd);
1292       }
1293     }
1294     Vector fields=(Vector)fieldorder.get(cn);
1295
1296     for(int i=0; i<fields.size(); i++) {
1297       FieldDescriptor fd=(FieldDescriptor)fields.get(i);
1298       if (fd.getType().isClass()||fd.getType().isArray())
1299         classdefout.println("  struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
1300       else
1301         classdefout.println("  "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
1302     }
1303   }
1304
1305
1306   /* Map flags to integers consistently between inherited
1307    * classes. */
1308
1309   protected void mapFlags(ClassDescriptor cn) {
1310     ClassDescriptor sp=cn.getSuperDesc();
1311     if (sp!=null)
1312       mapFlags(sp);
1313     int max=0;
1314     if (!flagorder.containsKey(cn)) {
1315       Hashtable flags=new Hashtable();
1316       flagorder.put(cn,flags);
1317       if (sp!=null) {
1318         Hashtable superflags=(Hashtable)flagorder.get(sp);
1319         Iterator superflagit=superflags.keySet().iterator();
1320         while(superflagit.hasNext()) {
1321           FlagDescriptor fd=(FlagDescriptor)superflagit.next();
1322           Integer number=(Integer)superflags.get(fd);
1323           flags.put(fd, number);
1324           if ((number.intValue()+1)>max)
1325             max=number.intValue()+1;
1326         }
1327       }
1328
1329       Iterator flagit=cn.getFlags();
1330       while(flagit.hasNext()) {
1331         FlagDescriptor fd=(FlagDescriptor)flagit.next();
1332         if (sp==null||!sp.getFlagTable().contains(fd.getSymbol()))
1333           flags.put(fd, new Integer(max++));
1334       }
1335     }
1336   }
1337
1338
1339   /** This function outputs (1) structures that parameters are
1340    * passed in (when PRECISE GC is enabled) and (2) function
1341    * prototypes for the methods */
1342
1343   protected void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
1344     /* Output class structure */
1345     classdefout.println("struct "+cn.getSafeSymbol()+" {");
1346     classdefout.println("  int type;");
1347     if (state.THREAD) {
1348       classdefout.println("  pthread_t tid;");
1349       classdefout.println("  void * lockentry;");
1350       classdefout.println("  int lockcount;");
1351     }
1352
1353     if (state.TASK) {
1354       classdefout.println("  int flag;");
1355       if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) {
1356         classdefout.println("  void * flagptr;");
1357       } else if (state.MULTICORE) {
1358         classdefout.println("  int version;");
1359     classdefout.println("  int * lock;");  // lock entry for this obj
1360     classdefout.println("  int mutex;");  
1361     classdefout.println("  int lockcount;");
1362     if(state.MULTICOREGC) {
1363       classdefout.println("  int marked;");
1364     }
1365       }
1366       if (state.OPTIONAL) {
1367         classdefout.println("  int numfses;");
1368         classdefout.println("  int * fses;");
1369       }
1370     }
1371     printClassStruct(cn, classdefout);
1372     classdefout.println("};\n");
1373
1374     if (state.DSM||state.SINGLETM) {
1375       /* Cycle through LocalityBindings */
1376       HashSet<MethodDescriptor> nativemethods=new HashSet<MethodDescriptor>();
1377       Set<LocalityBinding> lbset=locality.getClassBindings(cn);
1378       if (lbset!=null) {
1379         for(Iterator<LocalityBinding> lbit=lbset.iterator(); lbit.hasNext();) {
1380           LocalityBinding lb=lbit.next();
1381           MethodDescriptor md=lb.getMethod();
1382           if (md.getModifiers().isNative()) {
1383             //make sure we only print a native method once
1384             if (nativemethods.contains(md)) {
1385               FlatMethod fm=state.getMethodFlat(md);
1386               generateTempStructs(fm, lb);
1387               continue;
1388             } else
1389               nativemethods.add(md);
1390           }
1391           generateMethod(cn, md, lb, headersout, output);
1392         }
1393       }
1394       for(Iterator methodit=cn.getMethods(); methodit.hasNext();) {
1395         MethodDescriptor md=(MethodDescriptor)methodit.next();
1396         if (md.getModifiers().isNative()&&!nativemethods.contains(md)) {
1397           //Need to build param structure for library code
1398           FlatMethod fm=state.getMethodFlat(md);
1399           generateTempStructs(fm, null);
1400           generateMethodParam(cn, md, null, output);
1401         }
1402       }
1403
1404     } else
1405       for(Iterator methodit=cn.getMethods(); methodit.hasNext();) {
1406         MethodDescriptor md=(MethodDescriptor)methodit.next();
1407         generateMethod(cn, md, null, headersout, output);
1408       }
1409   }
1410
1411   private void generateMethodParam(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter output) {
1412     /* Output parameter structure */
1413     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1414       ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null ? lb : md);
1415       if ((state.DSM||state.SINGLETM)&&lb!=null)
1416         output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
1417       else
1418         output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
1419       output.println("  INTPTR size;");
1420       output.println("  void * next;");
1421       for(int i=0; i<objectparams.numPointers(); i++) {
1422         TempDescriptor temp=objectparams.getPointer(i);
1423         output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1424       }
1425       output.println("};\n");
1426     }
1427   }
1428
1429   private void generateMethod(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter headersout, PrintWriter output) {
1430     FlatMethod fm=state.getMethodFlat(md);
1431     generateTempStructs(fm, lb);
1432
1433     ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null ? lb : md);
1434     TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md);
1435
1436     generateMethodParam(cn, md, lb, output);
1437
1438     /* Output temp structure */
1439     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1440       if (state.DSM||state.SINGLETM)
1441         output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
1442       else
1443         output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
1444       output.println("  INTPTR size;");
1445       output.println("  void * next;");
1446       for(int i=0; i<objecttemps.numPointers(); i++) {
1447         TempDescriptor temp=objecttemps.getPointer(i);
1448         if (temp.getType().isNull())
1449           output.println("  void * "+temp.getSafeSymbol()+";");
1450         else
1451           output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1452       }
1453       output.println("};\n");
1454     }
1455
1456     /********* Output method declaration ***********/
1457     if (state.DSM||state.SINGLETM) {
1458       headersout.println("#define D"+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+" 1");
1459     } else {
1460       headersout.println("#define D"+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+" 1");
1461     }
1462     /* First the return type */
1463     if (md.getReturnType()!=null) {
1464       if (md.getReturnType().isClass()||md.getReturnType().isArray())
1465         headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1466       else
1467         headersout.print(md.getReturnType().getSafeSymbol()+" ");
1468     } else
1469       //catch the constructor case
1470       headersout.print("void ");
1471
1472     /* Next the method name */
1473     if (state.DSM||state.SINGLETM) {
1474       headersout.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1475     } else {
1476       headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1477     }
1478     boolean printcomma=false;
1479     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1480       if (state.DSM||state.SINGLETM) {
1481         headersout.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1482       } else
1483         headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1484       printcomma=true;
1485     }
1486
1487     /*  Output parameter list*/
1488     for(int i=0; i<objectparams.numPrimitives(); i++) {
1489       TempDescriptor temp=objectparams.getPrimitive(i);
1490       if (printcomma)
1491         headersout.print(", ");
1492       printcomma=true;
1493       if (temp.getType().isClass()||temp.getType().isArray())
1494         headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1495       else
1496         headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1497     }
1498     headersout.println(");\n");
1499   }
1500
1501
1502   /** This function outputs (1) structures that parameters are
1503    * passed in (when PRECISE GC is enabled) and (2) function
1504    * prototypes for the tasks */
1505
1506   private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
1507     /* Cycle through tasks */
1508     Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
1509
1510     while(taskit.hasNext()) {
1511       /* Classify parameters */
1512       TaskDescriptor task=(TaskDescriptor)taskit.next();
1513       FlatMethod fm=state.getMethodFlat(task);
1514       generateTempStructs(fm, null);
1515
1516       ParamsObject objectparams=(ParamsObject) paramstable.get(task);
1517       TempObject objecttemps=(TempObject) tempstable.get(task);
1518
1519       /* Output parameter structure */
1520       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1521         output.println("struct "+task.getSafeSymbol()+"_params {");
1522
1523         output.println("  INTPTR size;");
1524         output.println("  void * next;");
1525         for(int i=0; i<objectparams.numPointers(); i++) {
1526           TempDescriptor temp=objectparams.getPointer(i);
1527           output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1528         }
1529
1530         output.println("};\n");
1531         if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
1532           maxtaskparams=objectparams.numPointers()+fm.numTags();
1533         }
1534       }
1535
1536       /* Output temp structure */
1537       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1538         output.println("struct "+task.getSafeSymbol()+"_locals {");
1539         output.println("  INTPTR size;");
1540         output.println("  void * next;");
1541         for(int i=0; i<objecttemps.numPointers(); i++) {
1542           TempDescriptor temp=objecttemps.getPointer(i);
1543           if (temp.getType().isNull())
1544             output.println("  void * "+temp.getSafeSymbol()+";");
1545           else if(temp.getType().isTag())
1546             output.println("  struct "+
1547                            (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1548           else
1549             output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1550         }
1551         output.println("};\n");
1552       }
1553
1554       /* Output task declaration */
1555       headersout.print("void " + task.getSafeSymbol()+"(");
1556
1557       boolean printcomma=false;
1558       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1559         headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1560       } else
1561         headersout.print("void * parameterarray[]");
1562       headersout.println(");\n");
1563     }
1564   }
1565
1566   /***** Generate code for FlatMethod fm. *****/
1567
1568   Hashtable<FlatAtomicEnterNode, AtomicRecord> atomicmethodmap;
1569   static int atomicmethodcount=0;
1570
1571
1572   BranchAnalysis branchanalysis;
1573   private void generateFlatMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
1574     if (State.PRINTFLAT)
1575       System.out.println(fm.printMethod());
1576     MethodDescriptor md=fm.getMethod();
1577     TaskDescriptor task=fm.getTask();
1578     ClassDescriptor cn=md!=null ? md.getClassDesc() : null;
1579     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : md!=null ? md : task);
1580
1581     HashSet<AtomicRecord> arset=null;
1582     branchanalysis=null;
1583
1584     if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) {
1585       //create map
1586       if (atomicmethodmap==null)
1587         atomicmethodmap=new Hashtable<FlatAtomicEnterNode, AtomicRecord>();
1588
1589       //fix these so we get right strings for local variables
1590       localsprefixaddr=localsprefix;
1591       localsprefixderef=localsprefix+"->";
1592       arset=new HashSet<AtomicRecord>();
1593
1594       //build branchanalysis
1595       branchanalysis=new BranchAnalysis(locality, lb, delaycomp.getNotReady(lb), delaycomp.livecode(lb), state);
1596       
1597       //Generate commit methods here
1598       for(Iterator<FlatNode> fnit=fm.getNodeSet().iterator();fnit.hasNext();) {
1599         FlatNode fn=fnit.next();
1600         if (fn.kind()==FKind.FlatAtomicEnterNode&&
1601             locality.getAtomic(lb).get(fn.getPrev(0)).intValue()==0&&
1602             delaycomp.needsFission(lb, (FlatAtomicEnterNode) fn)) {
1603           //We have an atomic enter
1604           FlatAtomicEnterNode faen=(FlatAtomicEnterNode) fn;
1605           Set<FlatNode> exitset=faen.getExits();
1606           //generate header
1607           String methodname=md.getSymbol()+(atomicmethodcount++);
1608           AtomicRecord ar=new AtomicRecord();
1609           ar.name=methodname;
1610           arset.add(ar);
1611
1612           atomicmethodmap.put(faen, ar);
1613
1614           //build data structure declaration
1615           output.println("struct atomicprimitives_"+methodname+" {");
1616
1617           Set<FlatNode> recordset=delaycomp.livecode(lb);
1618           Set<TempDescriptor> liveinto=delaycomp.liveinto(lb, faen, recordset);
1619           Set<TempDescriptor> liveout=delaycomp.liveout(lb, faen);
1620           Set<TempDescriptor> liveoutvirtualread=delaycomp.liveoutvirtualread(lb, faen);
1621           ar.livein=liveinto;
1622           ar.reallivein=new HashSet(liveinto);
1623           ar.liveout=liveout;
1624           ar.liveoutvirtualread=liveoutvirtualread;
1625
1626           for(Iterator<TempDescriptor> it=liveinto.iterator(); it.hasNext();) {
1627             TempDescriptor tmp=it.next();
1628             //remove the pointers
1629             if (tmp.getType().isPtr()) {
1630               it.remove();
1631             } else {
1632               //let's print it here
1633               output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+";");
1634             }
1635           }
1636           for(Iterator<TempDescriptor> it=liveout.iterator(); it.hasNext();) {
1637             TempDescriptor tmp=it.next();
1638             //remove the pointers
1639             if (tmp.getType().isPtr()) {
1640               it.remove();
1641             } else if (!liveinto.contains(tmp)) {
1642               //let's print it here
1643               output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+";");
1644             }
1645           }
1646           output.println("};");
1647
1648           //print out method name
1649           output.println("void "+methodname+"(struct "+ cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix+", struct "+ cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals *"+localsprefix+", struct atomicprimitives_"+methodname+" * primitives) {");
1650           //build code for commit method
1651           
1652           //first define local primitives
1653           Set<TempDescriptor> alltemps=delaycomp.alltemps(lb, faen, recordset);
1654           for(Iterator<TempDescriptor> tmpit=alltemps.iterator();tmpit.hasNext();) {
1655             TempDescriptor tmp=tmpit.next();
1656             if (!tmp.getType().isPtr()) {
1657               if (liveinto.contains(tmp)||liveoutvirtualread.contains(tmp)) {
1658                 //read from live into set
1659                 output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+"=primitives->"+tmp.getSafeSymbol()+";");
1660               } else {
1661                 //just define
1662                 output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+";");
1663               }
1664             }
1665           }
1666           //turn off write barrier generation
1667           wb.turnoff();
1668           state.SINGLETM=false;
1669           generateCode(faen, fm, lb, exitset, output, false);
1670           state.SINGLETM=true;
1671           //turn on write barrier generation
1672           wb.turnon();
1673           output.println("}\n\n");
1674         }
1675       }
1676     }
1677     //redefine these back to normal
1678
1679     localsprefixaddr="&"+localsprefix;
1680     localsprefixderef=localsprefix+".";
1681
1682     generateHeader(fm, lb, md!=null ? md : task,output);
1683     TempObject objecttemp=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
1684
1685     if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) {
1686       for(Iterator<AtomicRecord> arit=arset.iterator();arit.hasNext();) {
1687         AtomicRecord ar=arit.next();
1688         output.println("struct atomicprimitives_"+ar.name+" primitives_"+ar.name+";");
1689       }
1690     }
1691
1692     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1693       if (md!=null&&(state.DSM||state.SINGLETM))
1694         output.print("   struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1695       else if (md!=null&&!(state.DSM||state.SINGLETM))
1696         output.print("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1697       else
1698         output.print("   struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
1699
1700       output.print(objecttemp.numPointers()+",");
1701       output.print(paramsprefix);
1702       for(int j=0; j<objecttemp.numPointers(); j++)
1703         output.print(", NULL");
1704       output.println("};");
1705     }
1706
1707     for(int i=0; i<objecttemp.numPrimitives(); i++) {
1708       TempDescriptor td=objecttemp.getPrimitive(i);
1709       TypeDescriptor type=td.getType();
1710       if (type.isNull())
1711         output.println("   void * "+td.getSafeSymbol()+";");
1712       else if (type.isClass()||type.isArray())
1713         output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
1714       else
1715         output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
1716     }
1717
1718
1719     if( state.MLP ) {      
1720       if( fm.getNext(0) instanceof FlatSESEEnterNode ) {
1721         FlatSESEEnterNode callerSESEplaceholder = (FlatSESEEnterNode) fm.getNext( 0 );
1722         if( callerSESEplaceholder != mlpa.getMainSESE() ) {
1723           // declare variables for naming static SESE's
1724           output.println("   /* static SESE names */");
1725           Iterator<SESEandAgePair> pItr = callerSESEplaceholder.getNeededStaticNames().iterator();
1726           while( pItr.hasNext() ) {
1727             SESEandAgePair p = pItr.next();
1728             output.println("   void* "+p+";");
1729           }
1730
1731           // declare variables for tracking dynamic sources
1732           output.println("   /* dynamic variable sources */");
1733           Iterator<TempDescriptor> dynSrcItr = callerSESEplaceholder.getDynamicVarSet().iterator();
1734           while( dynSrcItr.hasNext() ) {
1735             TempDescriptor dynSrcVar = dynSrcItr.next();
1736             output.println("   void* "+dynSrcVar+"_srcSESE;");
1737             output.println("   int   "+dynSrcVar+"_srcOffset;");
1738           }    
1739         }
1740       }
1741     }
1742
1743
1744     /* Check to see if we need to do a GC if this is a
1745      * multi-threaded program...*/
1746
1747     if (((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC) 
1748         || this.state.MULTICOREGC) {
1749       //Don't bother if we aren't in recursive methods...The loops case will catch it
1750       if (callgraph.getAllMethods(md).contains(md)) {
1751         if (state.DSM&&lb.isAtomic())
1752           output.println("if (needtocollect) checkcollect2("+localsprefixaddr+");");
1753         else if (this.state.MULTICOREGC) {
1754           output.println("if(gcflag) gc("+localsprefixaddr+");");
1755         } else {
1756           output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
1757         }
1758       }
1759     }
1760
1761     generateCode(fm.getNext(0), fm, lb, null, output, true);
1762
1763     output.println("}\n\n");
1764   }
1765
1766
1767   protected void initializeSESE( FlatSESEEnterNode fsen ) {
1768
1769     FlatMethod       fm = fsen.getfmEnclosing();
1770     MethodDescriptor md = fm.getMethod();
1771     ClassDescriptor  cn = md.getClassDesc();
1772     
1773         
1774     // Creates bogus method descriptor to index into tables
1775     Modifiers modBogus = new Modifiers();
1776     MethodDescriptor mdBogus = 
1777       new MethodDescriptor( modBogus, 
1778                             new TypeDescriptor( TypeDescriptor.VOID ), 
1779                             "sese_"+fsen.getPrettyIdentifier()+fsen.getIdentifier()
1780                             );
1781     
1782     mdBogus.setClassDesc( fsen.getcdEnclosing() );
1783     FlatMethod fmBogus = new FlatMethod( mdBogus, null );
1784     fsen.setfmBogus( fmBogus );
1785     fsen.setmdBogus( mdBogus );
1786
1787     Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
1788     inSetAndOutSet.addAll( fsen.getInVarSet() );
1789     inSetAndOutSet.addAll( fsen.getOutVarSet() );
1790
1791     // Build paramsobj for bogus method descriptor
1792     ParamsObject objectparams = new ParamsObject( mdBogus, tag++ );
1793     paramstable.put( mdBogus, objectparams );
1794     
1795     Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
1796     while( itr.hasNext() ) {
1797       TempDescriptor temp = itr.next();
1798       TypeDescriptor type = temp.getType();
1799       if( type.isPtr() ) {
1800         objectparams.addPtr( temp );
1801       } else {
1802         objectparams.addPrim( temp );
1803       }
1804     }
1805         
1806     // Build normal temp object for bogus method descriptor
1807     TempObject objecttemps = new TempObject( objectparams, mdBogus, tag++ );
1808     tempstable.put( mdBogus, objecttemps );
1809
1810     for( Iterator nodeit = fsen.getNodeSet().iterator(); nodeit.hasNext(); ) {
1811       FlatNode         fn     = (FlatNode)nodeit.next();
1812       TempDescriptor[] writes = fn.writesTemps();
1813
1814       for( int i = 0; i < writes.length; i++ ) {
1815         TempDescriptor temp = writes[i];
1816         TypeDescriptor type = temp.getType();
1817
1818         if( type.isPtr() ) {
1819           objecttemps.addPtr( temp );
1820         } else {
1821           objecttemps.addPrim( temp );
1822         }
1823       }
1824     }
1825   }
1826
1827   protected void generateMethodSESE(FlatSESEEnterNode fsen,
1828                                     LocalityBinding lb,
1829                                     PrintWriter outputStructs,
1830                                     PrintWriter outputMethHead,
1831                                     PrintWriter outputMethods
1832                                     ) {
1833
1834     ParamsObject objectparams = (ParamsObject) paramstable.get( fsen.getmdBogus() );                
1835     TempObject   objecttemps  = (TempObject)   tempstable .get( fsen.getmdBogus() );
1836     
1837     // generate locals structure
1838     outputStructs.println("struct "+
1839                           fsen.getcdEnclosing().getSafeSymbol()+
1840                           fsen.getmdBogus().getSafeSymbol()+"_"+
1841                           fsen.getmdBogus().getSafeMethodDescriptor()+
1842                           "_locals {");
1843     outputStructs.println("  INTPTR size;");
1844     outputStructs.println("  void * next;");
1845     for(int i=0; i<objecttemps.numPointers(); i++) {
1846       TempDescriptor temp=objecttemps.getPointer(i);
1847
1848       if( fsen.getPrettyIdentifier().equals( "calc" ) ) {
1849         System.out.println( "  got a pointer "+temp );
1850       }
1851
1852       if (temp.getType().isNull())
1853         outputStructs.println("  void * "+temp.getSafeSymbol()+";");
1854       else
1855         outputStructs.println("  struct "+
1856                               temp.getType().getSafeSymbol()+" * "+
1857                               temp.getSafeSymbol()+";");
1858     }
1859     outputStructs.println("};\n");
1860
1861     
1862     // generate the SESE record structure
1863     outputStructs.println(fsen.getSESErecordName()+" {");
1864     
1865     // data common to any SESE, and it must be placed first so
1866     // a module that doesn't know what kind of SESE record this
1867     // is can cast the pointer to a common struct
1868     outputStructs.println("  SESEcommon common;");
1869
1870     // then garbage list stuff
1871     outputStructs.println("  INTPTR size;");
1872     outputStructs.println("  void * next;");
1873
1874     // in-set source tracking
1875     // in-vars that are READY come from parent, don't need anything
1876     // stuff STATIC needs a custom SESE pointer for each age pair
1877     Iterator<SESEandAgePair> itrStaticInVarSrcs = fsen.getStaticInVarSrcs().iterator();
1878     while( itrStaticInVarSrcs.hasNext() ) {
1879       SESEandAgePair srcPair = itrStaticInVarSrcs.next();
1880       outputStructs.println("  "+srcPair.getSESE().getSESErecordName()+"* "+srcPair+";");
1881     }    
1882
1883     // DYNAMIC stuff needs a source SESE ptr and offset
1884     Iterator<TempDescriptor> itrDynInVars = fsen.getDynamicInVarSet().iterator();
1885     while( itrDynInVars.hasNext() ) {
1886       TempDescriptor dynInVar = itrDynInVars.next();
1887       outputStructs.println("  void* "+dynInVar+"_srcSESE;");
1888       outputStructs.println("  int   "+dynInVar+"_srcOffset;");
1889     }    
1890
1891     // space for all in and out set primitives
1892     Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
1893     inSetAndOutSet.addAll( fsen.getInVarSet() );
1894     inSetAndOutSet.addAll( fsen.getOutVarSet() );
1895
1896     Set<TempDescriptor> inSetAndOutSetPrims = new HashSet<TempDescriptor>();
1897
1898     Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
1899     while( itr.hasNext() ) {
1900       TempDescriptor temp = itr.next();
1901       TypeDescriptor type = temp.getType();
1902       if( !type.isPtr() ) {
1903         inSetAndOutSetPrims.add( temp );
1904       }
1905     }
1906
1907     Iterator<TempDescriptor> itrPrims = inSetAndOutSetPrims.iterator();
1908     while( itrPrims.hasNext() ) {
1909       TempDescriptor temp = itrPrims.next();
1910       TypeDescriptor type = temp.getType();
1911       outputStructs.println("  "+temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol()+";");
1912     }
1913
1914     for(int i=0; i<objectparams.numPointers(); i++) {
1915       TempDescriptor temp=objectparams.getPointer(i);
1916       if (temp.getType().isNull())
1917         outputStructs.println("  void * "+temp.getSafeSymbol()+";");
1918       else
1919         outputStructs.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1920     }
1921     
1922     outputStructs.println("};\n");
1923
1924     
1925     // write method declaration to header file
1926     outputMethHead.print("void ");
1927     outputMethHead.print(fsen.getSESEmethodName()+"(");
1928     outputMethHead.print(fsen.getSESErecordName()+"* "+paramsprefix);
1929     outputMethHead.println(");\n");
1930
1931
1932     generateFlatMethodSESE( fsen.getfmBogus(), 
1933                             fsen.getcdEnclosing(), 
1934                             fsen, 
1935                             fsen.getFlatExit(), 
1936                             outputMethods );
1937   }
1938
1939   private void generateFlatMethodSESE(FlatMethod fm, 
1940                                       ClassDescriptor cn, 
1941                                       FlatSESEEnterNode fsen, 
1942                                       FlatSESEExitNode  seseExit, 
1943                                       PrintWriter output
1944                                       ) {
1945
1946     MethodDescriptor md=fm.getMethod();
1947
1948     output.print("void ");
1949     output.print(fsen.getSESEmethodName()+"(");
1950     output.print(fsen.getSESErecordName()+"* "+paramsprefix);
1951     output.println("){\n");
1952
1953     TempObject objecttemp=(TempObject) tempstable.get(md);
1954
1955     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1956       output.print("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1957       output.print(objecttemp.numPointers()+",");
1958       output.print("(void*) &("+paramsprefix+"->size)");
1959       for(int j=0; j<objecttemp.numPointers(); j++)
1960         output.print(", NULL");
1961       output.println("};");
1962     }
1963
1964     output.println("   /* regular local primitives */");
1965     for(int i=0; i<objecttemp.numPrimitives(); i++) {
1966       TempDescriptor td=objecttemp.getPrimitive(i);
1967       TypeDescriptor type=td.getType();
1968       if (type.isNull())
1969         output.println("   void * "+td.getSafeSymbol()+";");
1970       else if (type.isClass()||type.isArray())
1971         output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
1972       else
1973         output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
1974     }
1975
1976
1977     // declare variables for naming static SESE's
1978     output.println("   /* static SESE names */");
1979     Iterator<SESEandAgePair> pItr = fsen.getNeededStaticNames().iterator();
1980     while( pItr.hasNext() ) {
1981       SESEandAgePair p = pItr.next();
1982       output.println("   void* "+p+";");
1983     }
1984
1985     // declare variables for tracking dynamic sources
1986     output.println("   /* dynamic variable sources */");
1987     Iterator<TempDescriptor> dynSrcItr = fsen.getDynamicVarSet().iterator();
1988     while( dynSrcItr.hasNext() ) {
1989       TempDescriptor dynSrcVar = dynSrcItr.next();
1990       output.println("   void* "+dynSrcVar+"_srcSESE;");
1991       output.println("   int   "+dynSrcVar+"_srcOffset;");
1992     }    
1993
1994     // declare local temps for in-set primitives, and if it is
1995     // a ready-source variable, get the value from the record
1996     output.println("   /* local temps for in-set primitives */");
1997     Iterator<TempDescriptor> itrInSet = fsen.getInVarSet().iterator();
1998     while( itrInSet.hasNext() ) {
1999       TempDescriptor temp = itrInSet.next();
2000       TypeDescriptor type = temp.getType();
2001       if( !type.isPtr() ) {
2002         if( fsen.getReadyInVarSet().contains( temp ) ) {
2003           output.println("   "+type+" "+temp+" = "+paramsprefix+"->"+temp+";");
2004         } else {
2005           output.println("   "+type+" "+temp+";");
2006         }
2007       }
2008     }    
2009
2010     // declare local temps for out-set primitives if its not already
2011     // in the in-set, and it's value will get written so no problem
2012     output.println("   /* local temp for out-set prim, not already in the in-set */");
2013     Iterator<TempDescriptor> itrOutSet = fsen.getOutVarSet().iterator();
2014     while( itrOutSet.hasNext() ) {
2015       TempDescriptor temp = itrOutSet.next();
2016       TypeDescriptor type = temp.getType();
2017       if( !type.isPtr() && !fsen.getInVarSet().contains( temp ) ) {
2018         output.println("   "+type+" "+temp+";");       
2019       }
2020     }    
2021
2022     // copy in-set into place, ready vars were already 
2023     // copied when the SESE was issued
2024     Iterator<TempDescriptor> tempItr;
2025
2026     // static vars are from a known SESE
2027     tempItr = fsen.getStaticInVarSet().iterator();
2028     while( tempItr.hasNext() ) {
2029       TempDescriptor temp = tempItr.next();
2030       VariableSourceToken vst = fsen.getStaticInVarSrc( temp );
2031       SESEandAgePair srcPair = new SESEandAgePair( vst.getSESE(), vst.getAge() );
2032       
2033       // can't grab something from this source until it is done
2034       output.println("   {");
2035       output.println("     SESEcommon* com = (SESEcommon*)"+paramsprefix+"->"+srcPair+";" );
2036       output.println("     pthread_mutex_lock( &(com->lock) );");
2037       output.println("     while( com->doneExecuting == FALSE ) {");
2038       output.println("       pthread_cond_wait( &(com->doneCond), &(com->lock) );");
2039       output.println("     }");
2040       output.println("     pthread_mutex_unlock( &(com->lock) );");
2041
2042       output.println("     "+generateTemp( fsen.getfmBogus(), temp, null )+
2043                      " = "+paramsprefix+"->"+srcPair+"->"+vst.getAddrVar()+";");
2044
2045       output.println("   }");
2046     }
2047
2048     // dynamic vars come from an SESE and src
2049     tempItr = fsen.getDynamicInVarSet().iterator();
2050     while( tempItr.hasNext() ) {
2051       TempDescriptor temp = tempItr.next();
2052       TypeDescriptor type = temp.getType();
2053       
2054       // go grab it from the SESE source
2055       output.println("   if( "+paramsprefix+"->"+temp+"_srcSESE != NULL ) {");
2056
2057       // gotta wait until the source is done
2058       output.println("     SESEcommon* com = (SESEcommon*)"+paramsprefix+"->"+temp+"_srcSESE;" );
2059       output.println("     pthread_mutex_lock( &(com->lock) );");
2060       output.println("     while( com->doneExecuting == FALSE ) {");
2061       output.println("       pthread_cond_wait( &(com->doneCond), &(com->lock) );");
2062       output.println("     }");
2063       output.println("     pthread_mutex_unlock( &(com->lock) );");
2064
2065       String typeStr;
2066       if( type.isNull() ) {
2067         typeStr = "void*";
2068       } else if( type.isClass() || type.isArray() ) {
2069         typeStr = "struct "+type.getSafeSymbol()+"*";
2070       } else {
2071         typeStr = type.getSafeSymbol();
2072       }
2073       
2074       output.println("     "+generateTemp( fsen.getfmBogus(), temp, null )+
2075                      " = *(("+typeStr+"*) ("+
2076                      paramsprefix+"->"+temp+"_srcSESE + "+
2077                      paramsprefix+"->"+temp+"_srcOffset));");
2078
2079       // or if the source was our parent, its in the record to grab
2080       output.println("   } else {");
2081       output.println("     "+generateTemp( fsen.getfmBogus(), temp, null )+
2082                            " = "+paramsprefix+"->"+temp+";");
2083       output.println("   }");
2084     }
2085
2086     // Check to see if we need to do a GC if this is a
2087     // multi-threaded program...    
2088     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2089       //Don't bother if we aren't in recursive methods...The loops case will catch it
2090       if (callgraph.getAllMethods(md).contains(md)) {
2091         if(this.state.MULTICOREGC) {
2092           output.println("if(gcflag) gc("+localsprefixaddr+");");
2093         } else {
2094           output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
2095         }
2096       }
2097     }    
2098
2099     // initialize thread-local var to a non-zero, invalid address
2100     output.println("   seseCaller = (SESEcommon*) 0x2;");
2101     HashSet<FlatNode> exitset=new HashSet<FlatNode>();
2102     exitset.add(seseExit);    
2103     generateCode(fsen.getNext(0), fm, null, exitset, output, true);
2104     output.println("}\n\n");
2105   }
2106
2107
2108   // when a new mlp thread is created for an issued SESE, it is started
2109   // by running this method which blocks on a cond variable until
2110   // it is allowed to transition to execute.  Then a case statement
2111   // allows it to invoke the method with the proper SESE body, and after
2112   // exiting the SESE method, executes proper SESE exit code before the
2113   // thread can be destroyed
2114   private void generateSESEinvocationMethod(PrintWriter outmethodheader,
2115                                             PrintWriter outmethod
2116                                             ) {
2117
2118     outmethodheader.println("void* invokeSESEmethod( void* seseRecord );");
2119     outmethod.println(      "void* invokeSESEmethod( void* seseRecord ) {");
2120     outmethod.println(      "  int status;");
2121     outmethod.println(      "  char errmsg[128];");
2122
2123     // generate a case for each SESE class that can be invoked
2124     outmethod.println(      "  switch( *((int*)seseRecord) ) {");
2125     outmethod.println(      "    ");
2126     for(Iterator<FlatSESEEnterNode> seseit=mlpa.getAllSESEs().iterator();seseit.hasNext();) {
2127       FlatSESEEnterNode fsen = seseit.next();
2128
2129       outmethod.println(    "    /* "+fsen.getPrettyIdentifier()+" */");
2130       outmethod.println(    "    case "+fsen.getIdentifier()+":");
2131       outmethod.println(    "      "+fsen.getSESEmethodName()+"( seseRecord );");  
2132       
2133       if( fsen.equals( mlpa.getMainSESE() ) ) {
2134         outmethod.println(  "      /* work scheduler works forever, explicitly exit */");
2135         outmethod.println(  "      exit( 0 );");
2136       }
2137
2138       outmethod.println(    "      break;");
2139       outmethod.println(    "");
2140     }
2141
2142     // default case should never be taken, error out
2143     outmethod.println(      "    default:");
2144     outmethod.println(      "      printf(\"Error: unknown SESE class ID in invoke method.\\n\");");
2145     outmethod.println(      "      exit(-30);");
2146     outmethod.println(      "      break;");
2147     outmethod.println(      "  }");
2148     outmethod.println(      "  return NULL;");
2149     outmethod.println(      "}\n\n");
2150   }
2151
2152
2153   protected void generateCode(FlatNode first,
2154                               FlatMethod fm,
2155                               LocalityBinding lb,
2156                               Set<FlatNode> stopset,
2157                               PrintWriter output, boolean firstpass) {
2158
2159     /* Assign labels to FlatNode's if necessary.*/
2160
2161     Hashtable<FlatNode, Integer> nodetolabel;
2162
2163     if (state.DELAYCOMP&&!firstpass)
2164       nodetolabel=dcassignLabels(first, stopset);      
2165     else
2166       nodetolabel=assignLabels(first, stopset);      
2167     
2168     Set<FlatNode> storeset=null;
2169     HashSet<FlatNode> genset=null;
2170     HashSet<FlatNode> refset=null;
2171     Set<FlatNode> unionset=null;
2172
2173     if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) {
2174       storeset=delaycomp.livecode(lb);
2175       genset=new HashSet<FlatNode>();
2176       if (state.STMARRAY&&!state.DUALVIEW) {
2177         refset=new HashSet<FlatNode>();
2178         refset.addAll(delaycomp.getDeref(lb));
2179         refset.removeAll(delaycomp.getCannotDelay(lb));
2180         refset.removeAll(delaycomp.getOther(lb));
2181       }
2182       if (firstpass) {
2183         genset.addAll(delaycomp.getCannotDelay(lb));
2184         genset.addAll(delaycomp.getOther(lb));
2185       } else {
2186         genset.addAll(delaycomp.getNotReady(lb));
2187         if (state.STMARRAY&&!state.DUALVIEW) {
2188           genset.removeAll(refset);
2189         }
2190       }
2191       unionset=new HashSet<FlatNode>();
2192       unionset.addAll(storeset);
2193       unionset.addAll(genset);
2194       if (state.STMARRAY&&!state.DUALVIEW)
2195         unionset.addAll(refset);
2196     }
2197     
2198     /* Do the actual code generation */
2199     FlatNode current_node=null;
2200     HashSet tovisit=new HashSet();
2201     HashSet visited=new HashSet();
2202     if (!firstpass)
2203       tovisit.add(first.getNext(0));
2204     else
2205       tovisit.add(first);
2206     while(current_node!=null||!tovisit.isEmpty()) {
2207       if (current_node==null) {
2208         current_node=(FlatNode)tovisit.iterator().next();
2209         tovisit.remove(current_node);
2210       } else if (tovisit.contains(current_node)) {
2211         tovisit.remove(current_node);
2212       }
2213       visited.add(current_node);
2214       if (nodetolabel.containsKey(current_node)) {
2215         output.println("L"+nodetolabel.get(current_node)+":");
2216       }
2217       if (state.INSTRUCTIONFAILURE) {
2218         if (state.THREAD||state.DSM||state.SINGLETM) {
2219           output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
2220         } else
2221           output.println("if ((--instructioncount)==0) injectinstructionfailure();");
2222       }
2223       if (current_node.numNext()==0||stopset!=null&&stopset.contains(current_node)) {
2224         output.print("   ");
2225         if (!state.DELAYCOMP||firstpass) {
2226           generateFlatNode(fm, lb, current_node, output);
2227         } else {
2228           //store primitive variables in out set
2229           AtomicRecord ar=atomicmethodmap.get((FlatAtomicEnterNode)first);
2230           Set<TempDescriptor> liveout=ar.liveout;
2231           for(Iterator<TempDescriptor> tmpit=liveout.iterator();tmpit.hasNext();) {
2232             TempDescriptor tmp=tmpit.next();
2233             output.println("primitives->"+tmp.getSafeSymbol()+"="+tmp.getSafeSymbol()+";");
2234           }
2235         }
2236         if (state.MLP && stopset!=null) {
2237           assert first.getPrev( 0 ) instanceof FlatSESEEnterNode;
2238           assert current_node       instanceof FlatSESEExitNode;
2239           FlatSESEEnterNode fsen = (FlatSESEEnterNode) first.getPrev( 0 );
2240           FlatSESEExitNode  fsxn = (FlatSESEExitNode)  current_node;
2241           assert fsen.getFlatExit().equals( fsxn );
2242           assert fsxn.getFlatEnter().equals( fsen );
2243         }
2244         if (current_node.kind()!=FKind.FlatReturnNode) {
2245           output.println("   return;");
2246         }
2247         current_node=null;
2248       } else if(current_node.numNext()==1) {
2249         FlatNode nextnode;
2250         if (state.MLP && 
2251             current_node.kind()==FKind.FlatSESEEnterNode && 
2252             !((FlatSESEEnterNode)current_node).getIsCallerSESEplaceholder()
2253            ) {
2254           FlatSESEEnterNode fsen = (FlatSESEEnterNode)current_node;
2255           generateFlatNode(fm, lb, current_node, output);
2256           nextnode=fsen.getFlatExit().getNext(0);
2257         } else if (state.DELAYCOMP) {
2258           boolean specialprimitive=false;
2259           //skip literals...no need to add extra overhead
2260           if (storeset!=null&&storeset.contains(current_node)&&current_node.kind()==FKind.FlatLiteralNode) {
2261             TypeDescriptor typedesc=((FlatLiteralNode)current_node).getType();
2262             if (!typedesc.isClass()&&!typedesc.isArray()) {
2263               specialprimitive=true;
2264             }
2265           }
2266
2267           if (genset==null||genset.contains(current_node)||specialprimitive)
2268             generateFlatNode(fm, lb, current_node, output);
2269           if (state.STMARRAY&&!state.DUALVIEW&&refset!=null&&refset.contains(current_node)) {
2270             //need to acquire lock
2271             handleArrayDeref(fm, lb, current_node, output, firstpass);
2272           }
2273           if (storeset!=null&&storeset.contains(current_node)&&!specialprimitive) {
2274             TempDescriptor wrtmp=current_node.writesTemps()[0];
2275             if (firstpass) {
2276               //need to store value written by previous node
2277               if (wrtmp.getType().isPtr()) {
2278                 //only lock the objects that may actually need locking
2279                 if (recorddc.getNeedTrans(lb, current_node)&&
2280                     (!state.STMARRAY||state.DUALVIEW||!wrtmp.getType().isArray()||
2281                      wrtmp.getType().getSymbol().equals(TypeUtil.ObjectClass))) {
2282                   output.println("STOREPTR("+generateTemp(fm, wrtmp,lb)+");/* "+current_node.nodeid+" */");
2283                 } else {
2284                   output.println("STOREPTRNOLOCK("+generateTemp(fm, wrtmp,lb)+");/* "+current_node.nodeid+" */");
2285                 }
2286               } else {
2287                 output.println("STORE"+wrtmp.getType().getSafeDescriptor()+"("+generateTemp(fm, wrtmp, lb)+");/* "+current_node.nodeid+" */");
2288               }
2289             } else {
2290               //need to read value read by previous node
2291               if (wrtmp.getType().isPtr()) {
2292                 output.println("RESTOREPTR("+generateTemp(fm, wrtmp,lb)+");/* "+current_node.nodeid+" */");
2293               } else {
2294                 output.println("RESTORE"+wrtmp.getType().getSafeDescriptor()+"("+generateTemp(fm, wrtmp, lb)+"); /* "+current_node.nodeid+" */");               
2295               }
2296             }
2297           }
2298           nextnode=current_node.getNext(0);
2299         } else {
2300           output.print("   ");
2301           generateFlatNode(fm, lb, current_node, output);
2302           nextnode=current_node.getNext(0);
2303         }
2304         if (visited.contains(nextnode)) {
2305           output.println("goto L"+nodetolabel.get(nextnode)+";");
2306           current_node=null;
2307         } else 
2308           current_node=nextnode;
2309       } else if (current_node.numNext()==2) {
2310         /* Branch */
2311         if (state.DELAYCOMP) {
2312           boolean computeside=false;
2313           if (firstpass) {
2314             //need to record which way it should go
2315             if (genset==null||genset.contains(current_node)) {
2316               if (storeset!=null&&storeset.contains(current_node)) {
2317                 //need to store which way branch goes
2318                 generateStoreFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
2319               } else
2320                 generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
2321             } else {
2322               //which side to execute
2323               computeside=true;
2324             }
2325           } else {
2326             if (genset.contains(current_node)) {
2327               generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);             
2328             } else if (storeset.contains(current_node)) {
2329               //need to do branch
2330               branchanalysis.generateGroupCode(current_node, output, nodetolabel);
2331             } else {
2332               //which side to execute
2333               computeside=true;
2334             }
2335           }
2336           if (computeside) {
2337             Set<FlatNode> leftset=DelayComputation.getNext(current_node, 0, unionset, lb,locality, true);
2338             int branch=0;
2339             if (leftset.size()==0)
2340               branch=1;
2341             if (visited.contains(current_node.getNext(branch))) {
2342               //already visited -- build jump
2343               output.println("goto L"+nodetolabel.get(current_node.getNext(branch))+";");
2344               current_node=null;
2345             } else {
2346               current_node=current_node.getNext(branch);
2347             }
2348           } else {
2349             if (!visited.contains(current_node.getNext(1)))
2350               tovisit.add(current_node.getNext(1));
2351             if (visited.contains(current_node.getNext(0))) {
2352               output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
2353               current_node=null;
2354             } else 
2355               current_node=current_node.getNext(0);
2356           }
2357         } else {
2358           output.print("   ");  
2359           generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
2360           if (!visited.contains(current_node.getNext(1)))
2361             tovisit.add(current_node.getNext(1));
2362           if (visited.contains(current_node.getNext(0))) {
2363             output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
2364             current_node=null;
2365           } else 
2366             current_node=current_node.getNext(0);
2367         }
2368       } else throw new Error();
2369     }
2370   }
2371
2372   protected void handleArrayDeref(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output, boolean firstpass) {
2373     if (fn.kind()==FKind.FlatSetElementNode) {
2374       FlatSetElementNode fsen=(FlatSetElementNode) fn;
2375       String dst=generateTemp(fm, fsen.getDst(), lb);
2376       String src=generateTemp(fm, fsen.getSrc(), lb);
2377       String index=generateTemp(fm, fsen.getIndex(), lb);      
2378       TypeDescriptor elementtype=fsen.getDst().getType().dereference();
2379       String type="";
2380       if (elementtype.isArray()||elementtype.isClass())
2381         type="void *";
2382       else
2383         type=elementtype.getSafeSymbol()+" ";
2384       if (firstpass) {
2385         output.println("STOREARRAY("+dst+","+index+","+type+")");
2386       } else {
2387         output.println("{");
2388         output.println("  struct ArrayObject *array;");
2389         output.println("  int index;");
2390         output.println("  RESTOREARRAY(array,index);");
2391         output.println("  (("+type+"*)(((char *)&array->___length___)+sizeof(int)))[index]="+src+";");
2392         output.println("}");
2393       }
2394     } else if (fn.kind()==FKind.FlatElementNode) {
2395       FlatElementNode fen=(FlatElementNode) fn;
2396       String src=generateTemp(fm, fen.getSrc(), lb);
2397       String index=generateTemp(fm, fen.getIndex(), lb);
2398       TypeDescriptor elementtype=fen.getSrc().getType().dereference();
2399       String dst=generateTemp(fm, fen.getDst(), lb);
2400       String type="";
2401       if (elementtype.isArray()||elementtype.isClass())
2402         type="void *";
2403       else
2404         type=elementtype.getSafeSymbol()+" ";
2405       if (firstpass) {
2406         output.println("STOREARRAY("+src+","+index+","+type+")");
2407       } else {
2408         output.println("{");
2409         output.println("  struct ArrayObject *array;");
2410         output.println("  int index;");
2411         output.println("  RESTOREARRAY(array,index);");
2412         output.println("  "+dst+"=(("+type+"*)(((char *)&array->___length___)+sizeof(int)))[index];");
2413         output.println("}");
2414       }
2415     }
2416   }
2417   /** Special label assignment for delaycomputation */
2418   protected Hashtable<FlatNode, Integer> dcassignLabels(FlatNode first, Set<FlatNode> lastset) {
2419     HashSet tovisit=new HashSet();
2420     HashSet visited=new HashSet();
2421     int labelindex=0;
2422     Hashtable<FlatNode, Integer> nodetolabel=new Hashtable<FlatNode, Integer>();
2423
2424     //Label targets of branches
2425     Set<FlatNode> targets=branchanalysis.getTargets();
2426     for(Iterator<FlatNode> it=targets.iterator();it.hasNext();) {
2427       nodetolabel.put(it.next(), new Integer(labelindex++));
2428     }
2429
2430
2431     tovisit.add(first);
2432     /*Assign labels first.  A node needs a label if the previous
2433      * node has two exits or this node is a join point. */
2434
2435     while(!tovisit.isEmpty()) {
2436       FlatNode fn=(FlatNode)tovisit.iterator().next();
2437       tovisit.remove(fn);
2438       visited.add(fn);
2439
2440
2441       if(lastset!=null&&lastset.contains(fn)) {
2442         // if last is not null and matches, don't go 
2443         // any further for assigning labels
2444         continue;
2445       }
2446
2447       for(int i=0; i<fn.numNext(); i++) {
2448         FlatNode nn=fn.getNext(i);
2449
2450         if(i>0) {
2451           //1) Edge >1 of node
2452           nodetolabel.put(nn,new Integer(labelindex++));
2453         }
2454         if (!visited.contains(nn)&&!tovisit.contains(nn)) {
2455           tovisit.add(nn);
2456         } else {
2457           //2) Join point
2458           nodetolabel.put(nn,new Integer(labelindex++));
2459         }
2460       }
2461     }
2462     return nodetolabel;
2463
2464   }
2465
2466   protected Hashtable<FlatNode, Integer> assignLabels(FlatNode first) {
2467     return assignLabels(first, null);
2468   }
2469
2470   protected Hashtable<FlatNode, Integer> assignLabels(FlatNode first, Set<FlatNode> lastset) {
2471     HashSet tovisit=new HashSet();
2472     HashSet visited=new HashSet();
2473     int labelindex=0;
2474     Hashtable<FlatNode, Integer> nodetolabel=new Hashtable<FlatNode, Integer>();
2475     tovisit.add(first);
2476
2477     /*Assign labels first.  A node needs a label if the previous
2478      * node has two exits or this node is a join point. */
2479
2480     while(!tovisit.isEmpty()) {
2481       FlatNode fn=(FlatNode)tovisit.iterator().next();
2482       tovisit.remove(fn);
2483       visited.add(fn);
2484
2485
2486       if(lastset!=null&&lastset.contains(fn)) {
2487         // if last is not null and matches, don't go 
2488         // any further for assigning labels
2489         continue;
2490       }
2491
2492       for(int i=0; i<fn.numNext(); i++) {
2493         FlatNode nn=fn.getNext(i);
2494
2495         if(i>0) {
2496           //1) Edge >1 of node
2497           nodetolabel.put(nn,new Integer(labelindex++));
2498         }
2499         if (!visited.contains(nn)&&!tovisit.contains(nn)) {
2500           tovisit.add(nn);
2501         } else {
2502           //2) Join point
2503           nodetolabel.put(nn,new Integer(labelindex++));
2504         }
2505       }
2506     }
2507     return nodetolabel;
2508   }
2509
2510
2511   /** Generate text string that corresponds to the TempDescriptor td. */
2512   protected String generateTemp(FlatMethod fm, TempDescriptor td, LocalityBinding lb) {
2513     MethodDescriptor md=fm.getMethod();
2514     TaskDescriptor task=fm.getTask();
2515     TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
2516
2517     if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
2518       //System.out.println("generateTemp returns " + td.getSafeSymbol());
2519       return td.getSafeSymbol();
2520     }
2521
2522     if (objecttemps.isLocalPtr(td)) {
2523       return localsprefixderef+td.getSafeSymbol();
2524     }
2525
2526     if (objecttemps.isParamPtr(td)) {
2527       return paramsprefix+"->"+td.getSafeSymbol();
2528     }
2529
2530     throw new Error();
2531   }
2532
2533   protected void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) {
2534
2535     // insert pre-node actions from the code plan
2536     if( state.MLP ) {
2537       
2538       CodePlan cp = mlpa.getCodePlan( fn );
2539       if( cp != null ) {                
2540         
2541         FlatSESEEnterNode currentSESE = cp.getCurrentSESE();
2542         
2543         // for each sese and age pair that this parent statement
2544         // must stall on, take that child's stall semaphore, the
2545         // copying of values comes after the statement
2546         Iterator<VariableSourceToken> vstItr = cp.getStallTokens().iterator();
2547         while( vstItr.hasNext() ) {
2548           VariableSourceToken vst = vstItr.next();
2549
2550           SESEandAgePair p = new SESEandAgePair( vst.getSESE(), vst.getAge() );
2551
2552           output.println("   {");
2553           output.println("     SESEcommon* common = (SESEcommon*) "+p+";");
2554
2555           output.println("     pthread_mutex_lock( &(common->lock) );");
2556           output.println("     while( common->doneExecuting == FALSE ) {");
2557           output.println("       pthread_cond_wait( &(common->doneCond), &(common->lock) );");
2558           output.println("     }");
2559           output.println("     pthread_mutex_unlock( &(common->lock) );");
2560                   
2561           //output.println("     psem_take( &(common->stallSem) );");
2562
2563           // copy things we might have stalled for        
2564           output.println("     "+p.getSESE().getSESErecordName()+"* child = ("+
2565                                  p.getSESE().getSESErecordName()+"*) "+p+";");
2566           
2567           Iterator<TempDescriptor> tdItr = cp.getCopySet( vst ).iterator();
2568           while( tdItr.hasNext() ) {
2569             TempDescriptor td = tdItr.next();
2570             FlatMethod fmContext;
2571             if( currentSESE.getIsCallerSESEplaceholder() ) {
2572               fmContext = currentSESE.getfmEnclosing();
2573             } else {
2574               fmContext = currentSESE.getfmBogus();
2575             }
2576             output.println("       "+generateTemp( fmContext, td, null )+
2577                            " = child->"+vst.getAddrVar().getSafeSymbol()+";");
2578           }
2579
2580           output.println("   }");
2581         }
2582         
2583         // for each variable with a dynamic source, stall just for that variable
2584         Iterator<TempDescriptor> dynItr = cp.getDynamicStallSet().iterator();
2585         while( dynItr.hasNext() ) {
2586           TempDescriptor dynVar = dynItr.next();
2587
2588           // only stall if the dynamic source is not yourself, denoted by src==NULL
2589           // otherwise the dynamic write nodes will have the local var up-to-date
2590           output.println("   {");
2591           output.println("     if( "+dynVar+"_srcSESE != NULL ) {");
2592           output.println("       SESEcommon* common = (SESEcommon*) "+dynVar+"_srcSESE;");
2593           output.println("       psem_take( &(common->stallSem) );");
2594
2595           FlatMethod fmContext;
2596           if( currentSESE.getIsCallerSESEplaceholder() ) {
2597             fmContext = currentSESE.getfmEnclosing();
2598           } else {
2599             fmContext = currentSESE.getfmBogus();
2600           }
2601           output.println("       "+generateTemp( fmContext, dynVar, null )+
2602                          " = *(("+dynVar.getType()+"*) ("+
2603                          dynVar+"_srcSESE + "+dynVar+"_srcOffset));");
2604           
2605           output.println("     }");
2606           output.println("   }");
2607         }
2608
2609         // for each assignment of a variable to rhs that has a dynamic source,
2610         // copy the dynamic sources
2611         Iterator dynAssignItr = cp.getDynAssigns().entrySet().iterator();
2612         while( dynAssignItr.hasNext() ) {
2613           Map.Entry      me  = (Map.Entry)      dynAssignItr.next();
2614           TempDescriptor lhs = (TempDescriptor) me.getKey();
2615           TempDescriptor rhs = (TempDescriptor) me.getValue();
2616           output.println("   "+lhs+"_srcSESE   = "+rhs+"_srcSESE;");
2617           output.println("   "+lhs+"_srcOffset = "+rhs+"_srcOffset;");
2618         }
2619
2620         // for each lhs that is dynamic from a non-dynamic source, set the
2621         // dynamic source vars to the current SESE
2622         dynItr = cp.getDynAssignCurr().iterator();
2623         while( dynItr.hasNext() ) {
2624           TempDescriptor dynVar = dynItr.next();
2625           output.println("   "+dynVar+"_srcSESE = NULL;");
2626         }
2627       }     
2628     }
2629
2630     switch(fn.kind()) {
2631     case FKind.FlatAtomicEnterNode:
2632       generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output);
2633       break;
2634
2635     case FKind.FlatAtomicExitNode:
2636       generateFlatAtomicExitNode(fm, lb, (FlatAtomicExitNode) fn, output);
2637       break;
2638
2639     case FKind.FlatInstanceOfNode:
2640       generateFlatInstanceOfNode(fm, lb, (FlatInstanceOfNode)fn, output);
2641       break;
2642
2643     case FKind.FlatSESEEnterNode:
2644       generateFlatSESEEnterNode(fm, lb, (FlatSESEEnterNode)fn, output);
2645       break;
2646
2647     case FKind.FlatSESEExitNode:
2648       generateFlatSESEExitNode(fm, lb, (FlatSESEExitNode)fn, output);
2649       break;
2650       
2651     case FKind.FlatWriteDynamicVarNode:
2652       generateFlatWriteDynamicVarNode(fm, lb, (FlatWriteDynamicVarNode)fn, output);
2653       break;
2654
2655     case FKind.FlatGlobalConvNode:
2656       generateFlatGlobalConvNode(fm, lb, (FlatGlobalConvNode) fn, output);
2657       break;
2658
2659     case FKind.FlatTagDeclaration:
2660       generateFlatTagDeclaration(fm, lb, (FlatTagDeclaration) fn,output);
2661       break;
2662
2663     case FKind.FlatCall:
2664       generateFlatCall(fm, lb, (FlatCall) fn,output);
2665       break;
2666
2667     case FKind.FlatFieldNode:
2668       generateFlatFieldNode(fm, lb, (FlatFieldNode) fn,output);
2669       break;
2670
2671     case FKind.FlatElementNode:
2672       generateFlatElementNode(fm, lb, (FlatElementNode) fn,output);
2673       break;
2674
2675     case FKind.FlatSetElementNode:
2676       generateFlatSetElementNode(fm, lb, (FlatSetElementNode) fn,output);
2677       break;
2678
2679     case FKind.FlatSetFieldNode:
2680       generateFlatSetFieldNode(fm, lb, (FlatSetFieldNode) fn,output);
2681       break;
2682
2683     case FKind.FlatNew:
2684       generateFlatNew(fm, lb, (FlatNew) fn,output);
2685       break;
2686
2687     case FKind.FlatOpNode:
2688       generateFlatOpNode(fm, lb, (FlatOpNode) fn,output);
2689       break;
2690
2691     case FKind.FlatCastNode:
2692       generateFlatCastNode(fm, lb, (FlatCastNode) fn,output);
2693       break;
2694
2695     case FKind.FlatLiteralNode:
2696       generateFlatLiteralNode(fm, lb, (FlatLiteralNode) fn,output);
2697       break;
2698
2699     case FKind.FlatReturnNode:
2700       generateFlatReturnNode(fm, lb, (FlatReturnNode) fn,output);
2701       break;
2702
2703     case FKind.FlatNop:
2704       output.println("/* nop */");
2705       break;
2706
2707     case FKind.FlatExit:
2708       output.println("/* exit */");
2709       break;
2710
2711     case FKind.FlatBackEdge:
2712       if (state.SINGLETM&&state.SANDBOX&&(locality.getAtomic(lb).get(fn).intValue()>0)) {
2713         output.println("if (unlikely((--transaction_check_counter)<=0)) checkObjects();");
2714       }
2715       if (((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC)
2716           || (this.state.MULTICOREGC)) {
2717         if(state.DSM&&locality.getAtomic(lb).get(fn).intValue()>0) {
2718           output.println("if (needtocollect) checkcollect2("+localsprefixaddr+");");
2719         } else if(this.state.MULTICOREGC) {
2720           output.println("if (gcflag) gc("+localsprefixaddr+");");
2721         } else {
2722           output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
2723         }
2724       } else
2725         output.println("/* nop */");
2726       break;
2727
2728     case FKind.FlatCheckNode:
2729       generateFlatCheckNode(fm, lb, (FlatCheckNode) fn, output);
2730       break;
2731
2732     case FKind.FlatFlagActionNode:
2733       generateFlatFlagActionNode(fm, lb, (FlatFlagActionNode) fn, output);
2734       break;
2735
2736     case FKind.FlatPrefetchNode:
2737       generateFlatPrefetchNode(fm,lb, (FlatPrefetchNode) fn, output);
2738       break;
2739
2740     case FKind.FlatOffsetNode:
2741       generateFlatOffsetNode(fm, lb, (FlatOffsetNode)fn, output);
2742       break;
2743
2744     default:
2745       throw new Error();
2746     }
2747
2748     // insert post-node actions from the code-plan    
2749     if( state.MLP ) {
2750       CodePlan cp = mlpa.getCodePlan( fn );
2751
2752       if( cp != null ) {     
2753       }
2754     }    
2755   }
2756
2757   public void generateFlatOffsetNode(FlatMethod fm, LocalityBinding lb, FlatOffsetNode fofn, PrintWriter output) {
2758     output.println("/* FlatOffsetNode */");
2759     FieldDescriptor fd=fofn.getField();
2760     output.println(generateTemp(fm, fofn.getDst(),lb)+ " = (short)(int) (&((struct "+fofn.getClassType().getSafeSymbol() +" *)0)->"+ fd.getSafeSymbol()+");");
2761     output.println("/* offset */");
2762   }
2763
2764   public void generateFlatPrefetchNode(FlatMethod fm, LocalityBinding lb, FlatPrefetchNode fpn, PrintWriter output) {
2765     if (state.PREFETCH) {
2766       Vector oids = new Vector();
2767       Vector fieldoffset = new Vector();
2768       Vector endoffset = new Vector();
2769       int tuplecount = 0;        //Keeps track of number of prefetch tuples that need to be generated
2770       for(Iterator it = fpn.hspp.iterator(); it.hasNext();) {
2771         PrefetchPair pp = (PrefetchPair) it.next();
2772         Integer statusbase = locality.getNodePreTempInfo(lb,fpn).get(pp.base);
2773         /* Find prefetches that can generate oid */
2774         if(statusbase == LocalityAnalysis.GLOBAL) {
2775           generateTransCode(fm, lb, pp, oids, fieldoffset, endoffset, tuplecount, locality.getAtomic(lb).get(fpn).intValue()>0, false);
2776           tuplecount++;
2777         } else if (statusbase == LocalityAnalysis.LOCAL) {
2778           generateTransCode(fm,lb,pp,oids,fieldoffset,endoffset,tuplecount,false,true);
2779         } else {
2780           continue;
2781         }
2782       }
2783       if (tuplecount==0)
2784         return;
2785       System.out.println("Adding prefetch "+fpn+ " to method:" +fm);
2786       output.println("{");
2787       output.println("/* prefetch */");
2788       output.println("/* prefetchid_" + fpn.siteid + " */");
2789       output.println("void * prefptr;");
2790       output.println("int tmpindex;");
2791
2792       output.println("if((evalPrefetch["+fpn.siteid+"].operMode) || (evalPrefetch["+fpn.siteid+"].retrycount <= 0)) {");
2793       /*Create C code for oid array */
2794       output.print("   unsigned int oidarray_[] = {");
2795       boolean needcomma=false;
2796       for (Iterator it = oids.iterator(); it.hasNext();) {
2797         if (needcomma)
2798           output.print(", ");
2799         output.print(it.next());
2800         needcomma=true;
2801       }
2802       output.println("};");
2803
2804       /*Create C code for endoffset values */
2805       output.print("   unsigned short endoffsetarry_[] = {");
2806       needcomma=false;
2807       for (Iterator it = endoffset.iterator(); it.hasNext();) {
2808         if (needcomma)
2809           output.print(", ");
2810         output.print(it.next());
2811         needcomma=true;
2812       }
2813       output.println("};");
2814
2815       /*Create C code for Field Offset Values */
2816       output.print("   short fieldarry_[] = {");
2817       needcomma=false;
2818       for (Iterator it = fieldoffset.iterator(); it.hasNext();) {
2819         if (needcomma)
2820           output.print(", ");
2821         output.print(it.next());
2822         needcomma=true;
2823       }
2824       output.println("};");
2825       /* make the prefetch call to Runtime */
2826       output.println("   if(!evalPrefetch["+fpn.siteid+"].operMode) {");
2827       output.println("     evalPrefetch["+fpn.siteid+"].retrycount = RETRYINTERVAL;");
2828       output.println("   }");
2829       output.println("   prefetch("+fpn.siteid+" ,"+tuplecount+", oidarray_, endoffsetarry_, fieldarry_);");
2830       output.println(" } else {");
2831       output.println("   evalPrefetch["+fpn.siteid+"].retrycount--;");
2832       output.println(" }");
2833       output.println("}");
2834     }
2835   }
2836
2837   public void generateTransCode(FlatMethod fm, LocalityBinding lb,PrefetchPair pp, Vector oids, Vector fieldoffset, Vector endoffset, int tuplecount, boolean inside, boolean localbase) {
2838     short offsetcount = 0;
2839     int breakindex=0;
2840     if (inside) {
2841       breakindex=1;
2842     } else if (localbase) {
2843       for(; breakindex<pp.desc.size(); breakindex++) {
2844         Descriptor desc=pp.getDescAt(breakindex);
2845         if (desc instanceof FieldDescriptor) {
2846           FieldDescriptor fd=(FieldDescriptor)desc;
2847           if (fd.isGlobal()) {
2848             break;
2849           }
2850         }
2851       }
2852       breakindex++;
2853     }
2854
2855     if (breakindex>pp.desc.size())     //all local
2856       return;
2857
2858     TypeDescriptor lasttype=pp.base.getType();
2859     String basestr=generateTemp(fm, pp.base, lb);
2860     String teststr="";
2861     boolean maybenull=fm.getMethod().isStatic()||
2862                        !pp.base.equals(fm.getParameter(0));
2863
2864     for(int i=0; i<breakindex; i++) {
2865       String indexcheck="";
2866
2867       Descriptor desc=pp.getDescAt(i);
2868       if (desc instanceof FieldDescriptor) {
2869         FieldDescriptor fd=(FieldDescriptor)desc;
2870         if (maybenull) {
2871           if (!teststr.equals(""))
2872             teststr+="&&";
2873           teststr+="((prefptr="+basestr+")!=NULL)";
2874           basestr="((struct "+lasttype.getSafeSymbol()+" *)prefptr)->"+fd.getSafeSymbol();
2875         } else {
2876           basestr=basestr+"->"+fd.getSafeSymbol();
2877           maybenull=true;
2878         }
2879         lasttype=fd.getType();
2880       } else {
2881         IndexDescriptor id=(IndexDescriptor)desc;
2882         indexcheck="((tmpindex=";
2883         for(int j=0; j<id.tddesc.size(); j++) {
2884           indexcheck+=generateTemp(fm, id.getTempDescAt(j), lb)+"+";
2885         }
2886         indexcheck+=id.offset+")>=0)&(tmpindex<((struct ArrayObject *)prefptr)->___length___)";
2887
2888         if (!teststr.equals(""))
2889           teststr+="&&";
2890         teststr+="((prefptr="+basestr+")!= NULL) &&"+indexcheck;
2891         basestr="((void **)(((char *) &(((struct ArrayObject *)prefptr)->___length___))+sizeof(int)))[tmpindex]";
2892         maybenull=true;
2893         lasttype=lasttype.dereference();
2894       }
2895     }
2896
2897     String oid;
2898     if (teststr.equals("")) {
2899       oid="((unsigned int)"+basestr+")";
2900     } else {
2901       oid="((unsigned int)(("+teststr+")?"+basestr+":NULL))";
2902     }
2903     oids.add(oid);
2904
2905     for(int i = breakindex; i < pp.desc.size(); i++) {
2906       String newfieldoffset;
2907       Object desc = pp.getDescAt(i);
2908       if(desc instanceof FieldDescriptor) {
2909         FieldDescriptor fd=(FieldDescriptor)desc;
2910         newfieldoffset = new String("(unsigned int)(&(((struct "+ lasttype.getSafeSymbol()+" *)0)->"+ fd.getSafeSymbol()+ "))");
2911         lasttype=fd.getType();
2912       } else {
2913         newfieldoffset = "";
2914         IndexDescriptor id=(IndexDescriptor)desc;
2915         for(int j = 0; j < id.tddesc.size(); j++) {
2916           newfieldoffset += generateTemp(fm, id.getTempDescAt(j), lb) + "+";
2917         }
2918         newfieldoffset += id.offset.toString();
2919         lasttype=lasttype.dereference();
2920       }
2921       fieldoffset.add(newfieldoffset);
2922     }
2923
2924     int base=(tuplecount>0) ? ((Short)endoffset.get(tuplecount-1)).intValue() : 0;
2925     base+=pp.desc.size()-breakindex;
2926     endoffset.add(new Short((short)base));
2927   }
2928
2929
2930
2931   public void generateFlatGlobalConvNode(FlatMethod fm, LocalityBinding lb, FlatGlobalConvNode fgcn, PrintWriter output) {
2932     if (lb!=fgcn.getLocality())
2933       return;
2934     /* Have to generate flat globalconv */
2935     if (fgcn.getMakePtr()) {
2936       if (state.DSM) {
2937         output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", (unsigned int) "+generateTemp(fm, fgcn.getSrc(),lb)+");");
2938       } else {
2939         if ((dc==null)||!state.READSET&&dc.getNeedTrans(lb, fgcn)||state.READSET&&dc.getNeedWriteTrans(lb, fgcn)) {
2940           //need to do translation
2941           output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+", (void *)("+localsprefixaddr+"));");
2942         } else if (state.READSET&&dc.getNeedTrans(lb, fgcn)) {
2943           output.println("TRANSREADRD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+");");
2944         }
2945       }
2946     } else {
2947       /* Need to convert to OID */
2948       if ((dc==null)||dc.getNeedSrcTrans(lb,fgcn)) {
2949         if (fgcn.doConvert()||(delaycomp!=null&&delaycomp.needsFission(lb, fgcn.getAtomicEnter())&&atomicmethodmap.get(fgcn.getAtomicEnter()).reallivein.contains(fgcn.getSrc()))) {
2950           output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
2951         } else {
2952           output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=NULL;");
2953         }
2954       }
2955     }
2956   }
2957
2958   public void generateFlatInstanceOfNode(FlatMethod fm,  LocalityBinding lb, FlatInstanceOfNode fion, PrintWriter output) {
2959     int type;
2960     if (fion.getType().isArray()) {
2961       type=state.getArrayNumber(fion.getType())+state.numClasses();
2962     } else {
2963       type=fion.getType().getClassDesc().getId();
2964     }
2965
2966     if (fion.getType().getSymbol().equals(TypeUtil.ObjectClass))
2967       output.println(generateTemp(fm, fion.getDst(), lb)+"=1;");
2968     else
2969       output.println(generateTemp(fm, fion.getDst(), lb)+"=instanceof("+generateTemp(fm,fion.getSrc(),lb)+","+type+");");
2970   }
2971
2972   int sandboxcounter=0;
2973   public void generateFlatAtomicEnterNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) {
2974     /* Check to see if we need to generate code for this atomic */
2975     if (locality==null) {
2976       if (GENERATEPRECISEGC) {
2977         output.println("if (pthread_mutex_trylock(&atomiclock)!=0) {");
2978         output.println("stopforgc((struct garbagelist *) &___locals___);");
2979         output.println("pthread_mutex_lock(&atomiclock);");
2980         output.println("restartaftergc();");
2981         output.println("}");
2982       } else {
2983         output.println("pthread_mutex_lock(&atomiclock);");
2984       }
2985       return;
2986     }
2987
2988     if (locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
2989       return;
2990
2991
2992     if (state.SANDBOX) {
2993       outsandbox.println("int atomiccounter"+sandboxcounter+"=LOW_CHECK_FREQUENCY;");
2994       output.println("counter_reset_pointer=&atomiccounter"+sandboxcounter+";");
2995     }
2996
2997     if (state.DELAYCOMP&&delaycomp.needsFission(lb, faen)) {
2998       AtomicRecord ar=atomicmethodmap.get(faen);
2999       //copy in
3000       for(Iterator<TempDescriptor> tmpit=ar.livein.iterator();tmpit.hasNext();) {
3001         TempDescriptor tmp=tmpit.next();
3002         output.println("primitives_"+ar.name+"."+tmp.getSafeSymbol()+"="+tmp.getSafeSymbol()+";");
3003       }
3004
3005       //copy outs that depend on path
3006       for(Iterator<TempDescriptor> tmpit=ar.liveoutvirtualread.iterator();tmpit.hasNext();) {
3007         TempDescriptor tmp=tmpit.next();
3008         if (!ar.livein.contains(tmp))
3009           output.println("primitives_"+ar.name+"."+tmp.getSafeSymbol()+"="+tmp.getSafeSymbol()+";");
3010       }
3011     }
3012
3013     /* Backup the temps. */
3014     for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator(); tmpit.hasNext();) {
3015       TempDescriptor tmp=tmpit.next();
3016       output.println(generateTemp(fm, backuptable.get(lb).get(tmp),lb)+"="+generateTemp(fm,tmp,lb)+";");
3017     }
3018
3019     output.println("goto transstart"+faen.getIdentifier()+";");
3020
3021     /******* Print code to retry aborted transaction *******/
3022     output.println("transretry"+faen.getIdentifier()+":");
3023
3024     /* Restore temps */
3025     for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator(); tmpit.hasNext();) {
3026       TempDescriptor tmp=tmpit.next();
3027       output.println(generateTemp(fm, tmp,lb)+"="+generateTemp(fm,backuptable.get(lb).get(tmp),lb)+";");
3028     }
3029
3030     if (state.DSM) {
3031       /********* Need to revert local object store ********/
3032       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
3033
3034       output.println("while ("+revertptr+") {");
3035       output.println("struct ___Object___ * tmpptr;");
3036       output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
3037       output.println("REVERT_OBJ("+revertptr+");");
3038       output.println(revertptr+"=tmpptr;");
3039       output.println("}");
3040     }
3041     /******* Tell the runtime to start the transaction *******/
3042
3043     output.println("transstart"+faen.getIdentifier()+":");
3044     if (state.SANDBOX) {
3045       output.println("transaction_check_counter=*counter_reset_pointer;");
3046       sandboxcounter++;
3047     }
3048     output.println("transStart();");
3049
3050     if (state.ABORTREADERS||state.SANDBOX) {
3051       if (state.SANDBOX)
3052         output.println("abortenabled=1;");
3053       output.println("if (_setjmp(aborttrans)) {");
3054       output.println("  goto transretry"+faen.getIdentifier()+"; }");
3055     }
3056   }
3057
3058   public void generateFlatAtomicExitNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicExitNode faen, PrintWriter output) {
3059     /* Check to see if we need to generate code for this atomic */
3060     if (locality==null) {
3061       output.println("pthread_mutex_unlock(&atomiclock);");
3062       return;
3063     }
3064     if (locality.getAtomic(lb).get(faen).intValue()>0)
3065       return;
3066     //store the revert list before we lose the transaction object
3067     
3068     if (state.DSM) {
3069       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
3070       output.println(revertptr+"=revertlist;");
3071       output.println("if (transCommit()) {");
3072       output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
3073       output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
3074       output.println("} else {");
3075       /* Need to commit local object store */
3076       output.println("while ("+revertptr+") {");
3077       output.println("struct ___Object___ * tmpptr;");
3078       output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
3079       output.println("COMMIT_OBJ("+revertptr+");");
3080       output.println(revertptr+"=tmpptr;");
3081       output.println("}");
3082       output.println("}");
3083       return;
3084     }
3085
3086     if (!state.DELAYCOMP) {
3087       //Normal STM stuff
3088       output.println("if (transCommit()) {");
3089       /* Transaction aborts if it returns true */
3090       output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
3091       output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
3092       output.println("}");
3093     } else {
3094       if (delaycomp.optimizeTrans(lb, faen.getAtomicEnter())&&(!state.STMARRAY||state.DUALVIEW))  {
3095         AtomicRecord ar=atomicmethodmap.get(faen.getAtomicEnter());
3096         output.println("LIGHTWEIGHTCOMMIT("+ar.name+", &primitives_"+ar.name+", &"+localsprefix+", "+paramsprefix+", transretry"+faen.getAtomicEnter().getIdentifier()+");");
3097         //copy out
3098         for(Iterator<TempDescriptor> tmpit=ar.liveout.iterator();tmpit.hasNext();) {
3099           TempDescriptor tmp=tmpit.next();
3100           output.println(tmp.getSafeSymbol()+"=primitives_"+ar.name+"."+tmp.getSafeSymbol()+";");
3101         }
3102       } else if (delaycomp.needsFission(lb, faen.getAtomicEnter())) {
3103         AtomicRecord ar=atomicmethodmap.get(faen.getAtomicEnter());
3104         //do call
3105         output.println("if (transCommit((void (*)(void *, void *, void *))&"+ar.name+", &primitives_"+ar.name+", &"+localsprefix+", "+paramsprefix+")) {");
3106         output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
3107         output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
3108         output.println("}");
3109         //copy out
3110         output.println("else {");
3111         for(Iterator<TempDescriptor> tmpit=ar.liveout.iterator();tmpit.hasNext();) {
3112           TempDescriptor tmp=tmpit.next();
3113           output.println(tmp.getSafeSymbol()+"=primitives_"+ar.name+"."+tmp.getSafeSymbol()+";");
3114         }
3115         output.println("}");
3116       } else {
3117         output.println("if (transCommit(NULL, NULL, NULL, NULL)) {");
3118         output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
3119         output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
3120         output.println("}");
3121       }
3122     }
3123   }
3124
3125   public void generateFlatSESEEnterNode( FlatMethod fm,  
3126                                          LocalityBinding lb, 
3127                                          FlatSESEEnterNode fsen, 
3128                                          PrintWriter output 
3129                                        ) {
3130
3131     // if MLP flag is off, okay that SESE nodes are in IR graph, 
3132     // just skip over them and code generates exactly the same
3133     if( !state.MLP ) {
3134       return;
3135     }    
3136
3137     // there may be an SESE in an unreachable method, skip over
3138     if( !mlpa.getAllSESEs().contains( fsen ) ) {
3139       return;
3140     }
3141
3142     // also, if we have encountered a placeholder, just skip it
3143     if( fsen.getIsCallerSESEplaceholder() ) {
3144       return;
3145     }
3146
3147     output.println("   {");
3148
3149     // set up the parent
3150     if( fsen == mlpa.getMainSESE() ) {
3151       output.println("     SESEcommon* parentCommon = NULL;");
3152     } else {
3153       if( fsen.getParent() == null ) {
3154         System.out.println( "in "+fm+", "+fsen+" has null parent" );
3155       }
3156       assert fsen.getParent() != null;
3157       if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
3158         output.println("     SESEcommon* parentCommon = &("+paramsprefix+"->common);");
3159       } else {
3160         //output.println("     SESEcommon* parentCommon = (SESEcommon*) peekItem( seseCallStack );");
3161         output.println("     SESEcommon* parentCommon = seseCaller;");
3162       }
3163     }
3164
3165     // before doing anything, lock your own record and increment the running children
3166     if( fsen != mlpa.getMainSESE() ) {      
3167       output.println("     pthread_mutex_lock( &(parentCommon->lock) );");
3168       output.println("     ++(parentCommon->numRunningChildren);");
3169       output.println("     pthread_mutex_unlock( &(parentCommon->lock) );");      
3170     }
3171
3172     // just allocate the space for this record
3173     output.println("     "+fsen.getSESErecordName()+"* seseToIssue = ("+
3174                            fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+
3175                            fsen.getSESErecordName()+" ) );");
3176
3177     // and keep the thread-local sese stack up to date
3178     //output.println("     addNewItem( seseCallStack, (void*) seseToIssue);");
3179
3180     // fill in common data
3181     output.println("     seseToIssue->common.classID = "+fsen.getIdentifier()+";");
3182     output.println("     psem_init( &(seseToIssue->common.stallSem) );");
3183
3184     output.println("     seseToIssue->common.forwardList = createQueue();");
3185     output.println("     seseToIssue->common.unresolvedDependencies = 0;");
3186     output.println("     pthread_cond_init( &(seseToIssue->common.doneCond), NULL );");
3187     output.println("     seseToIssue->common.doneExecuting = FALSE;");    
3188     output.println("     pthread_cond_init( &(seseToIssue->common.runningChildrenCond), NULL );");
3189     output.println("     seseToIssue->common.numRunningChildren = 0;");
3190     output.println("     seseToIssue->common.parent = parentCommon;");
3191
3192     // all READY in-vars should be copied now and be done with it
3193     Iterator<TempDescriptor> tempItr = fsen.getReadyInVarSet().iterator();
3194     while( tempItr.hasNext() ) {
3195       TempDescriptor temp = tempItr.next();
3196
3197       // when we are issuing the main SESE or an SESE with placeholder
3198       // caller SESE as parent, generate temp child child's eclosing method,
3199       // otherwise use the parent's enclosing method as the context
3200       boolean useParentContext = false;
3201
3202       if( fsen != mlpa.getMainSESE() ) {
3203         assert fsen.getParent() != null;
3204         if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
3205           useParentContext = true;
3206         }
3207       }
3208
3209       if( useParentContext ) {
3210         output.println("     seseToIssue->"+temp+" = "+
3211                        generateTemp( fsen.getParent().getfmBogus(), temp, null )+";");   
3212       } else {
3213         output.println("     seseToIssue->"+temp+" = "+
3214                        generateTemp( fsen.getfmEnclosing(), temp, null )+";");
3215       }
3216     }
3217
3218     // before potentially adding this SESE to other forwarding lists,
3219     //  create it's lock and take it immediately
3220     output.println("     pthread_mutex_init( &(seseToIssue->common.lock), NULL );");
3221     output.println("     pthread_mutex_lock( &(seseToIssue->common.lock) );");
3222
3223     if( fsen != mlpa.getMainSESE() ) {
3224       // count up outstanding dependencies, static first, then dynamic
3225       Iterator<SESEandAgePair> staticSrcsItr = fsen.getStaticInVarSrcs().iterator();
3226       while( staticSrcsItr.hasNext() ) {
3227         SESEandAgePair srcPair = staticSrcsItr.next();
3228         output.println("     {");
3229         output.println("       SESEcommon* src = (SESEcommon*)"+srcPair+";");
3230         output.println("       pthread_mutex_lock( &(src->lock) );");
3231         output.println("       if( !isEmpty( src->forwardList ) &&");
3232         output.println("           seseToIssue == peekItem( src->forwardList ) ) {");
3233         output.println("         printf( \"This shouldnt already be here\\n\");");
3234         output.println("         exit( -1 );");
3235         output.println("       }");
3236         output.println("       if( !src->doneExecuting ) {");
3237         output.println("         addNewItem( src->forwardList, seseToIssue );");
3238         output.println("         ++(seseToIssue->common.unresolvedDependencies);");
3239         output.println("       }");
3240         output.println("       pthread_mutex_unlock( &(src->lock) );");
3241         output.println("     }");
3242
3243         // whether or not it is an outstanding dependency, make sure
3244         // to pass the static name to the child's record
3245         output.println("     seseToIssue->"+srcPair+" = "+srcPair+";");
3246       }
3247
3248       // dynamic sources might already be accounted for in the static list,
3249       // so only add them to forwarding lists if they're not already there
3250       Iterator<TempDescriptor> dynVarsItr = fsen.getDynamicInVarSet().iterator();
3251       while( dynVarsItr.hasNext() ) {
3252         TempDescriptor dynInVar = dynVarsItr.next();
3253         output.println("     {");
3254         output.println("       SESEcommon* src = (SESEcommon*)"+dynInVar+"_srcSESE;");
3255
3256         // the dynamic source is NULL if it comes from your own space--you can't pass
3257         // the address off to the new child, because you're not done executing and
3258         // might change the variable, so copy it right now
3259         output.println("       if( src != NULL ) {");
3260         output.println("         pthread_mutex_lock( &(src->lock) );");
3261         output.println("         if( isEmpty( src->forwardList ) ||");
3262         output.println("             seseToIssue != peekItem( src->forwardList ) ) {");
3263         output.println("           if( !src->doneExecuting ) {");
3264         output.println("             addNewItem( src->forwardList, seseToIssue );");
3265         output.println("             ++(seseToIssue->common.unresolvedDependencies);");
3266         output.println("           }");
3267         output.println("         }");
3268         output.println("         pthread_mutex_unlock( &(src->lock) );");       
3269         output.println("         seseToIssue->"+dynInVar+"_srcOffset = "+dynInVar+"_srcOffset;");
3270         output.println("       } else {");
3271
3272         boolean useParentContext = false;
3273         if( fsen != mlpa.getMainSESE() ) {
3274           assert fsen.getParent() != null;
3275           if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
3276             useParentContext = true;
3277           }
3278         }       
3279         if( useParentContext ) {
3280           output.println("         seseToIssue->"+dynInVar+" = "+
3281                          generateTemp( fsen.getParent().getfmBogus(), dynInVar, null )+";");
3282         } else {
3283           output.println("         seseToIssue->"+dynInVar+" = "+
3284                          generateTemp( fsen.getfmEnclosing(), dynInVar, null )+";");
3285         }
3286         
3287         output.println("       }");
3288         output.println("     }");
3289         
3290         // even if the value is already copied, make sure your NULL source
3291         // gets passed so child knows it already has the dynamic value
3292         output.println("     seseToIssue->"+dynInVar+"_srcSESE = "+dynInVar+"_srcSESE;");
3293       }
3294       
3295       // maintain pointers for for finding dynamic SESE 
3296       // instances from static names      
3297       SESEandAgePair p = new SESEandAgePair( fsen, 0 );
3298       if(  fsen.getParent() != null && 
3299            //!fsen.getParent().getIsCallerSESEplaceholder() &&
3300            fsen.getParent().getNeededStaticNames().contains( p ) 
3301         ) {       
3302
3303         for( int i = fsen.getOldestAgeToTrack(); i > 0; --i ) {
3304           SESEandAgePair p1 = new SESEandAgePair( fsen, i   );
3305           SESEandAgePair p2 = new SESEandAgePair( fsen, i-1 );
3306           output.println("     "+p1+" = "+p2+";");
3307         }      
3308         output.println("     "+p+" = seseToIssue;");
3309       }
3310     }
3311
3312     // if there were no outstanding dependencies, issue here
3313     output.println("     if( seseToIssue->common.unresolvedDependencies == 0 ) {");
3314     output.println("       workScheduleSubmit( (void*)seseToIssue );");
3315     output.println("     }");
3316
3317     // release this SESE for siblings to update its dependencies or,
3318     // eventually, for it to mark itself finished
3319     output.println("     pthread_mutex_unlock( &(seseToIssue->common.lock) );");
3320     output.println("   }");
3321
3322   }
3323
3324   public void generateFlatSESEExitNode( FlatMethod fm,  
3325                                         LocalityBinding lb, 
3326                                         FlatSESEExitNode fsexn, 
3327                                         PrintWriter output
3328                                       ) {
3329
3330     // if MLP flag is off, okay that SESE nodes are in IR graph, 
3331     // just skip over them and code generates exactly the same 
3332     if( !state.MLP ) {
3333       return;
3334     }
3335
3336     // get the enter node for this exit that has meta data embedded
3337     FlatSESEEnterNode fsen = fsexn.getFlatEnter();
3338
3339     // there may be an SESE in an unreachable method, skip over
3340     if( !mlpa.getAllSESEs().contains( fsen ) ) {
3341       return;
3342     }
3343
3344     // also, if we have encountered a placeholder, just jump it
3345     if( fsen.getIsCallerSESEplaceholder() ) {
3346       return;
3347     }
3348
3349     output.println("   /* SESE exiting */");
3350
3351     String com = paramsprefix+"->common";
3352
3353     // this SESE cannot be done until all of its children are done
3354     // so grab your own lock with the condition variable for watching
3355     // that the number of your running children is greater than zero    
3356     output.println("   pthread_mutex_lock( &("+com+".lock) );");
3357     output.println("   while( "+com+".numRunningChildren > 0 ) {");
3358     output.println("     pthread_cond_wait( &("+com+".runningChildrenCond), &("+com+".lock) );");
3359     output.println("   }");
3360
3361     // copy out-set from local temps into the sese record
3362     Iterator<TempDescriptor> itr = fsen.getOutVarSet().iterator();
3363     while( itr.hasNext() ) {
3364       TempDescriptor temp = itr.next();
3365
3366       // only have to do this for primitives
3367       if( !temp.getType().isPrimitive() ) {
3368         continue;
3369       }
3370
3371       // have to determine the context enclosing this sese
3372       boolean useParentContext = false;
3373
3374       if( fsen != mlpa.getMainSESE() ) {
3375         assert fsen.getParent() != null;
3376         if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
3377           useParentContext = true;
3378         }
3379       }
3380
3381       String from;
3382       if( useParentContext ) {
3383         from = generateTemp( fsen.getParent().getfmBogus(), temp, null );
3384       } else {
3385         from = generateTemp( fsen.getfmEnclosing(),         temp, null );
3386       }
3387
3388       output.println("   "+paramsprefix+
3389                      "->"+temp.getSafeSymbol()+
3390                      " = "+from+";");
3391     }    
3392     
3393     // mark yourself done, your SESE data is now read-only
3394     output.println("   "+com+".doneExecuting = TRUE;");
3395     output.println("   pthread_cond_signal( &("+com+".doneCond) );");
3396     output.println("   pthread_mutex_unlock( &("+com+".lock) );");
3397
3398     // decrement dependency count for all SESE's on your forwarding list
3399     output.println("   while( !isEmpty( "+com+".forwardList ) ) {");
3400     output.println("     SESEcommon* consumer = (SESEcommon*) getItem( "+com+".forwardList );");
3401     output.println("     pthread_mutex_lock( &(consumer->lock) );");
3402     output.println("     --(consumer->unresolvedDependencies);");
3403     output.println("     if( consumer->unresolvedDependencies == 0 ) {");
3404     output.println("       workScheduleSubmit( (void*)consumer );");
3405     output.println("     }");
3406     output.println("     pthread_mutex_unlock( &(consumer->lock) );");
3407     output.println("   }");
3408     
3409     // if parent is stalling on you, let them know you're done
3410     if( fsexn.getFlatEnter() != mlpa.getMainSESE() ) {
3411       output.println("   psem_give( &("+paramsprefix+"->common.stallSem) );");
3412     }
3413
3414     // last of all, decrement your parent's number of running children    
3415     output.println("   if( "+paramsprefix+"->common.parent != NULL ) {");
3416     output.println("     pthread_mutex_lock( &("+paramsprefix+"->common.parent->lock) );");
3417     output.println("     --("+paramsprefix+"->common.parent->numRunningChildren);");
3418     output.println("     pthread_cond_signal( &("+paramsprefix+"->common.parent->runningChildrenCond) );");
3419     output.println("     pthread_mutex_unlock( &("+paramsprefix+"->common.parent->lock) );");
3420     output.println("   }");    
3421
3422     // this is a thread-only variable that can be handled when critical sese-to-sese
3423     // data has been taken care of--set sese pointer to remember self over method
3424     // calls to a non-zero, invalid address
3425     output.println("   seseCaller = (SESEcommon*) 0x1;");    
3426   }
3427
3428   public void generateFlatWriteDynamicVarNode( FlatMethod fm,  
3429                                                LocalityBinding lb, 
3430                                                FlatWriteDynamicVarNode fwdvn,
3431                                                PrintWriter output
3432                                              ) {
3433     if( !state.MLP ) {
3434       // should node should not be in an IR graph if the
3435       // MLP flag is not set
3436       throw new Error("Unexpected presence of FlatWriteDynamicVarNode");
3437     }
3438         
3439     Hashtable<TempDescriptor, VariableSourceToken> writeDynamic = 
3440       fwdvn.getVar2src();
3441
3442     assert writeDynamic != null;
3443
3444     Iterator wdItr = writeDynamic.entrySet().iterator();
3445     while( wdItr.hasNext() ) {
3446       Map.Entry           me     = (Map.Entry)           wdItr.next();
3447       TempDescriptor      refVar = (TempDescriptor)      me.getKey();
3448       VariableSourceToken vst    = (VariableSourceToken) me.getValue();
3449       
3450       FlatSESEEnterNode current = fwdvn.getEnclosingSESE();
3451
3452       // only do this if the variable in question should be tracked,
3453       // meaning that it was explicitly added to the dynamic var set
3454       if( !current.getDynamicVarSet().contains( vst.getAddrVar() ) ) {
3455         continue;
3456       }
3457
3458       SESEandAgePair instance = new SESEandAgePair( vst.getSESE(), vst.getAge() );      
3459
3460       output.println("   {");
3461
3462       if( current.equals( vst.getSESE() ) ) {
3463         // if the src comes from this SESE, it's a method local variable,
3464         // mark src pointer NULL to signify that the var is up-to-date
3465         output.println("     "+vst.getAddrVar()+"_srcSESE = NULL;");
3466
3467       } else {
3468         // otherwise we track where it will come from
3469         output.println("     "+vst.getAddrVar()+"_srcSESE = "+instance+";");    
3470         output.println("     "+vst.getAddrVar()+"_srcOffset = (int) &((("+
3471                        vst.getSESE().getSESErecordName()+"*)0)->"+vst.getAddrVar()+");");
3472       }
3473
3474       output.println("   }");
3475     }   
3476   }
3477
3478   
3479   private void generateFlatCheckNode(FlatMethod fm,  LocalityBinding lb, FlatCheckNode fcn, PrintWriter output) {
3480     if (state.CONSCHECK) {
3481       String specname=fcn.getSpec();
3482       String varname="repairstate___";
3483       output.println("{");
3484       output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
3485
3486       TempDescriptor[] temps=fcn.getTemps();
3487       String[] vars=fcn.getVars();
3488       for(int i=0; i<temps.length; i++) {
3489         output.println(varname+"->"+vars[i]+"=(unsigned int)"+generateTemp(fm, temps[i],lb)+";");
3490       }
3491
3492       output.println("if (doanalysis"+specname+"("+varname+")) {");
3493       output.println("free"+specname+"_state("+varname+");");
3494       output.println("} else {");
3495       output.println("/* Bad invariant */");
3496       output.println("free"+specname+"_state("+varname+");");
3497       output.println("abort_task();");
3498       output.println("}");
3499       output.println("}");
3500     }
3501   }
3502
3503   private void generateFlatCall(FlatMethod fm, LocalityBinding lb, FlatCall fc, PrintWriter output) {
3504
3505     if( state.MLP && !nonSESEpass ) {
3506       output.println("     seseCaller = (SESEcommon*)"+paramsprefix+";");
3507     }
3508
3509     MethodDescriptor md=fc.getMethod();
3510     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? locality.getBinding(lb, fc) : md);
3511     ClassDescriptor cn=md.getClassDesc();
3512     output.println("{");
3513     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
3514       if (lb!=null) {
3515         LocalityBinding fclb=locality.getBinding(lb, fc);
3516         output.print("       struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
3517       } else
3518         output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
3519
3520       output.print(objectparams.numPointers());
3521       output.print(", "+localsprefixaddr);
3522       if (md.getThis()!=null) {
3523         output.print(", ");
3524         output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis(),lb));
3525       }
3526       if (fc.getThis()!=null&&md.getThis()==null) {
3527         System.out.println("WARNING!!!!!!!!!!!!");
3528         System.out.println("Source code calls static method "+md+" on an object in "+fm.getMethod()+"!");
3529       }
3530
3531
3532       for(int i=0; i<fc.numArgs(); i++) {
3533         Descriptor var=md.getParameter(i);
3534         TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
3535         if (objectparams.isParamPtr(paramtemp)) {
3536           TempDescriptor targ=fc.getArg(i);
3537           output.print(", ");
3538           TypeDescriptor td=md.getParamType(i);
3539           if (td.isTag())
3540             output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()  +" *)"+generateTemp(fm, targ,lb));
3541           else
3542             output.print("(struct "+md.getParamType(i).getSafeSymbol()  +" *)"+generateTemp(fm, targ,lb));
3543         }
3544       }
3545       output.println("};");
3546     }
3547     output.print("       ");
3548
3549
3550     if (fc.getReturnTemp()!=null)
3551       output.print(generateTemp(fm,fc.getReturnTemp(),lb)+"=");
3552
3553     /* Do we need to do virtual dispatch? */
3554     if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
3555       //no
3556       if (lb!=null) {
3557         LocalityBinding fclb=locality.getBinding(lb, fc);
3558         output.print(cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
3559       } else {
3560         output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
3561       }
3562     } else {
3563       //yes
3564       output.print("((");
3565       if (md.getReturnType().isClass()||md.getReturnType().isArray())
3566         output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
3567       else
3568         output.print(md.getReturnType().getSafeSymbol()+" ");
3569       output.print("(*)(");
3570
3571       boolean printcomma=false;
3572       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
3573         if (lb!=null) {
3574           LocalityBinding fclb=locality.getBinding(lb, fc);
3575           output.print("struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
3576         } else
3577           output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
3578         printcomma=true;
3579       }
3580
3581       for(int i=0; i<objectparams.numPrimitives(); i++) {
3582         TempDescriptor temp=objectparams.getPrimitive(i);
3583         if (printcomma)
3584           output.print(", ");
3585         printcomma=true;
3586         if (temp.getType().isClass()||temp.getType().isArray())
3587           output.print("struct " + temp.getType().getSafeSymbol()+" * ");
3588         else
3589           output.print(temp.getType().getSafeSymbol());
3590       }
3591
3592
3593       if (lb!=null) {
3594         LocalityBinding fclb=locality.getBinding(lb, fc);
3595         output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getLocalityNumber(fclb)+"])");
3596       } else
3597         output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
3598     }
3599
3600     output.print("(");
3601     boolean needcomma=false;
3602     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
3603       output.print("&__parameterlist__");
3604       needcomma=true;
3605     }
3606
3607     if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
3608       if (fc.getThis()!=null) {
3609         TypeDescriptor ptd=md.getThis().getType();
3610         if (needcomma)
3611           output.print(",");
3612         if (ptd.isClass()&&!ptd.isArray())
3613           output.print("(struct "+ptd.getSafeSymbol()+" *) ");
3614         output.print(generateTemp(fm,fc.getThis(),lb));
3615         needcomma=true;
3616       }
3617     }
3618
3619     for(int i=0; i<fc.numArgs(); i++) {
3620       Descriptor var=md.getParameter(i);
3621       TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
3622       if (objectparams.isParamPrim(paramtemp)) {
3623         TempDescriptor targ=fc.getArg(i);
3624         if (needcomma)
3625           output.print(", ");
3626
3627         TypeDescriptor ptd=md.getParamType(i);
3628         if (ptd.isClass()&&!ptd.isArray())
3629           output.print("(struct "+ptd.getSafeSymbol()+" *) ");
3630         output.print(generateTemp(fm, targ,lb));
3631         needcomma=true;
3632       }
3633     }
3634     output.println(");");
3635     output.println("   }");
3636   }
3637
3638   private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
3639     Set subclasses=typeutil.getSubClasses(thiscd);
3640     if (subclasses==null)
3641       return true;
3642     for(Iterator classit=subclasses.iterator(); classit.hasNext();) {
3643       ClassDescriptor cd=(ClassDescriptor)classit.next();
3644       Set possiblematches=cd.getMethodTable().getSetFromSameScope(md.getSymbol());
3645       for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
3646         MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
3647         if (md.matches(matchmd))
3648           return false;
3649       }
3650     }
3651     return true;
3652   }
3653
3654   private void generateFlatFieldNode(FlatMethod fm, LocalityBinding lb, FlatFieldNode ffn, PrintWriter output) {
3655     if (state.SINGLETM) {
3656       //single machine transactional memory case
3657       String field=ffn.getField().getSafeSymbol();
3658       String src=generateTemp(fm, ffn.getSrc(),lb);
3659       String dst=generateTemp(fm, ffn.getDst(),lb);
3660
3661       output.println(dst+"="+ src +"->"+field+ ";");
3662       if (ffn.getField().getType().isPtr()&&locality.getAtomic(lb).get(ffn).intValue()>0&&
3663           locality.getNodePreTempInfo(lb, ffn).get(ffn.getSrc())!=LocalityAnalysis.SCRATCH) {
3664         if ((dc==null)||(!state.READSET&&dc.getNeedTrans(lb, ffn))||
3665             (state.READSET&&dc.getNeedWriteTrans(lb, ffn))) {
3666           output.println("TRANSREAD("+dst+", "+dst+", (void *) (" + localsprefixaddr + "));");
3667         } else if (state.READSET&&dc.getNeedTrans(lb, ffn)) {
3668           output.println("TRANSREADRD("+dst+", "+dst+");");
3669         }
3670       }
3671     } else if (state.DSM) {
3672       Integer status=locality.getNodePreTempInfo(lb,ffn).get(ffn.getSrc());
3673       if (status==LocalityAnalysis.GLOBAL) {
3674         String field=ffn.getField().getSafeSymbol();
3675         String src=generateTemp(fm, ffn.getSrc(),lb);
3676         String dst=generateTemp(fm, ffn.getDst(),lb);
3677
3678         if (ffn.getField().getType().isPtr()) {
3679
3680           //TODO: Uncomment this when we have runtime support
3681           //if (ffn.getSrc()==ffn.getDst()) {
3682           //output.println("{");
3683           //output.println("void * temp="+src+";");
3684           //output.println("if (temp&0x1) {");
3685           //output.println("temp=(void *) transRead(trans, (unsigned int) temp);");
3686           //output.println(src+"->"+field+"="+temp+";");
3687           //output.println("}");
3688           //output.println(dst+"=temp;");
3689           //output.println("}");
3690           //} else {
3691           output.println(dst+"="+ src +"->"+field+ ";");
3692           //output.println("if ("+dst+"&0x1) {");
3693           output.println("TRANSREAD("+dst+", (unsigned int) "+dst+");");
3694           //output.println(src+"->"+field+"="+src+"->"+field+";");
3695           //output.println("}");
3696           //}
3697         } else {
3698           output.println(dst+"="+ src+"->"+field+";");
3699         }
3700       } else if (status==LocalityAnalysis.LOCAL) {
3701         if (ffn.getField().getType().isPtr()&&
3702             ffn.getField().isGlobal()) {
3703           String field=ffn.getField().getSafeSymbol();
3704           String src=generateTemp(fm, ffn.getSrc(),lb);
3705           String dst=generateTemp(fm, ffn.getDst(),lb);
3706           output.println(dst+"="+ src +"->"+field+ ";");
3707           if (locality.getAtomic(lb).get(ffn).intValue()>0)
3708             output.println("TRANSREAD("+dst+", (unsigned int) "+dst+");");
3709         } else
3710           output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
3711       } else if (status==LocalityAnalysis.EITHER) {
3712         //Code is reading from a null pointer
3713         output.println("if ("+generateTemp(fm, ffn.getSrc(),lb)+") {");
3714         output.println("#ifndef RAW");
3715         output.println("printf(\"BIG ERROR\\n\");exit(-1);}");
3716         output.println("#endif");
3717         //This should throw a suitable null pointer error
3718         output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
3719       } else
3720         throw new Error("Read from non-global/non-local in:"+lb.getExplanation());
3721     } else
3722       output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
3723   }
3724
3725
3726   private void generateFlatSetFieldNode(FlatMethod fm, LocalityBinding lb, FlatSetFieldNode fsfn, PrintWriter output) {
3727     if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
3728       throw new Error("Can't set array length");
3729     if (state.SINGLETM && locality.getAtomic(lb).get(fsfn).intValue()>0) {
3730       //Single Machine Transaction Case
3731       boolean srcptr=fsfn.getSrc().getType().isPtr();
3732       String src=generateTemp(fm,fsfn.getSrc(),lb);
3733       String dst=generateTemp(fm,fsfn.getDst(),lb);
3734       output.println("//"+srcptr+" "+fsfn.getSrc().getType().isNull());
3735       if (srcptr&&!fsfn.getSrc().getType().isNull()) {
3736         output.println("{");
3737         if ((dc==null)||dc.getNeedSrcTrans(lb, fsfn)&&
3738             locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getSrc())!=LocalityAnalysis.SCRATCH) {
3739           output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
3740         } else {
3741           output.println("INTPTR srcoid=(INTPTR)"+src+";");
3742         }
3743       }
3744       if (wb.needBarrier(fsfn)&&
3745           locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getDst())!=LocalityAnalysis.SCRATCH) {
3746         output.println("*((unsigned int *)&("+dst+"->___objstatus___))|=DIRTY;");
3747       }
3748       if (srcptr&!fsfn.getSrc().getType().isNull()) {
3749         output.println("*((unsigned INTPTR *)&("+dst+"->"+ fsfn.getField().getSafeSymbol()+"))=srcoid;");
3750         output.println("}");
3751       } else {
3752         output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
3753       }
3754     } else if (state.DSM && locality.getAtomic(lb).get(fsfn).intValue()>0) {
3755       Integer statussrc=locality.getNodePreTempInfo(lb,fsfn).get(fsfn.getSrc());
3756       Integer statusdst=locality.getNodeTempInfo(lb).get(fsfn).get(fsfn.getDst());
3757       boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL;
3758
3759       String src=generateTemp(fm,fsfn.getSrc(),lb);
3760       String dst=generateTemp(fm,fsfn.getDst(),lb);
3761       if (srcglobal) {
3762         output.println("{");
3763         output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
3764       }
3765       if (statusdst.equals(LocalityAnalysis.GLOBAL)) {
3766         String glbdst=dst;
3767         //mark it dirty
3768         if (wb.needBarrier(fsfn))
3769           output.println("*((unsigned int *)&("+dst+"->___localcopy___))|=DIRTY;");
3770         if (srcglobal) {
3771           output.println("*((unsigned INTPTR *)&("+glbdst+"->"+ fsfn.getField().getSafeSymbol()+"))=srcoid;");
3772         } else
3773           output.println(glbdst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
3774       } else if (statusdst.equals(LocalityAnalysis.LOCAL)) {
3775         /** Check if we need to copy */
3776         output.println("if(!"+dst+"->"+localcopystr+") {");
3777         /* Link object into list */
3778         String revertptr=generateTemp(fm, reverttable.get(lb),lb);
3779         output.println(revertptr+"=revertlist;");
3780         if (GENERATEPRECISEGC || this.state.MULTICOREGC)
3781           output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
3782         else
3783           output.println("COPY_OBJ("+dst+");");
3784         output.println(dst+"->"+nextobjstr+"="+revertptr+";");
3785         output.println("revertlist=(struct ___Object___ *)"+dst+";");
3786         output.println("}");
3787         if (srcglobal)
3788           output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=(void *) srcoid;");
3789         else
3790           output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
3791       } else if (statusdst.equals(LocalityAnalysis.EITHER)) {
3792         //writing to a null...bad
3793         output.println("if ("+dst+") {");
3794         output.println("printf(\"BIG ERROR 2\\n\");exit(-1);}");
3795         if (srcglobal)
3796           output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=(void *) srcoid;");
3797         else
3798           output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
3799       }
3800       if (srcglobal) {
3801         output.println("}");
3802       }
3803     } else {
3804       if (state.FASTCHECK) {
3805         String dst=generateTemp(fm, fsfn.getDst(),lb);
3806         output.println("if(!"+dst+"->"+localcopystr+") {");
3807         /* Link object into list */
3808         if (GENERATEPRECISEGC || this.state.MULTICOREGC)
3809           output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
3810         else
3811           output.println("COPY_OBJ("+dst+");");
3812         output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
3813         output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
3814         output.println("}");
3815       }
3816       output.println(generateTemp(fm, fsfn.getDst(),lb)+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";");
3817     }
3818   }
3819
3820   private void generateFlatElementNode(FlatMethod fm, LocalityBinding lb, FlatElementNode fen, PrintWriter output) {
3821     TypeDescriptor elementtype=fen.getSrc().getType().dereference();
3822     String type="";
3823
3824     if (elementtype.isArray()||elementtype.isClass())
3825       type="void *";
3826     else
3827       type=elementtype.getSafeSymbol()+" ";
3828
3829     if (this.state.ARRAYBOUNDARYCHECK && fen.needsBoundsCheck()) {
3830       output.println("if (unlikely(((unsigned int)"+generateTemp(fm, fen.getIndex(),lb)+") >= "+generateTemp(fm,fen.getSrc(),lb) + "->___length___))");
3831       output.println("failedboundschk();");
3832     }
3833     if (state.SINGLETM) {
3834       //Single machine transaction case
3835       String dst=generateTemp(fm, fen.getDst(),lb);
3836       if ((!state.STMARRAY)||(!wb.needBarrier(fen))||locality.getNodePreTempInfo(lb, fen).get(fen.getSrc())==LocalityAnalysis.SCRATCH||locality.getAtomic(lb).get(fen).intValue()==0||(state.READSET&&!dc.getNeedGet(lb, fen))) {
3837         output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
3838       } else {
3839         output.println("STMGETARRAY("+dst+", "+ generateTemp(fm,fen.getSrc(),lb)+", "+generateTemp(fm, fen.getIndex(),lb)+", "+type+");");
3840       }
3841
3842       if (elementtype.isPtr()&&locality.getAtomic(lb).get(fen).intValue()>0&&
3843           locality.getNodePreTempInfo(lb, fen).get(fen.getSrc())!=LocalityAnalysis.SCRATCH) {
3844         if ((dc==null)||!state.READSET&&dc.getNeedTrans(lb, fen)||state.READSET&&dc.getNeedWriteTrans(lb, fen)) {
3845           output.println("TRANSREAD("+dst+", "+dst+", (void *)(" + localsprefixaddr+"));");
3846         } else if (state.READSET&&dc.getNeedTrans(lb, fen)) {
3847           output.println("TRANSREADRD("+dst+", "+dst+");");
3848         }
3849       }
3850     } else if (state.DSM) {
3851       Integer status=locality.getNodePreTempInfo(lb,fen).get(fen.getSrc());
3852       if (status==LocalityAnalysis.GLOBAL) {
3853         String dst=generateTemp(fm, fen.getDst(),lb);
3854         if (elementtype.isPtr()) {
3855           output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
3856           output.println("TRANSREAD("+dst+", "+dst+");");
3857         } else {
3858           output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
3859         }
3860       } else if (status==LocalityAnalysis.LOCAL) {
3861         output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
3862       } else if (status==LocalityAnalysis.EITHER) {
3863         //Code is reading from a null pointer
3864         output.println("if ("+generateTemp(fm, fen.getSrc(),lb)+") {");
3865         output.println("#ifndef RAW");
3866         output.println("printf(\"BIG ERROR\\n\");exit(-1);}");
3867         output.println("#endif");
3868         //This should throw a suitable null pointer error
3869         output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
3870       } else
3871         throw new Error("Read from non-global/non-local in:"+lb.getExplanation());
3872     } else {
3873       output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
3874     }
3875   }
3876
3877   private void generateFlatSetElementNode(FlatMethod fm, LocalityBinding lb, FlatSetElementNode fsen, PrintWriter output) {
3878     //TODO: need dynamic check to make sure this assignment is actually legal
3879     //Because Object[] could actually be something more specific...ie. Integer[]
3880
3881     TypeDescriptor elementtype=fsen.getDst().getType().dereference();
3882     String type="";
3883
3884     if (elementtype.isArray()||elementtype.isClass())
3885       type="void *";
3886     else
3887       type=elementtype.getSafeSymbol()+" ";
3888
3889     if (this.state.ARRAYBOUNDARYCHECK && fsen.needsBoundsCheck()) {
3890       output.println("if (unlikely(((unsigned int)"+generateTemp(fm, fsen.getIndex(),lb)+") >= "+generateTemp(fm,fsen.getDst(),lb) + "->___length___))");
3891       output.println("failedboundschk();");
3892     }
3893
3894     if (state.SINGLETM && locality.getAtomic(lb).get(fsen).intValue()>0) {
3895       //Transaction set element case
3896       if (wb.needBarrier(fsen)&&
3897           locality.getNodePreTempInfo(lb, fsen).get(fsen.getDst())!=LocalityAnalysis.SCRATCH) {
3898         output.println("*((unsigned int *)&("+generateTemp(fm,fsen.getDst(),lb)+"->___objstatus___))|=DIRTY;");
3899       }
3900       if (fsen.getSrc().getType().isPtr()&&!fsen.getSrc().getType().isNull()) {
3901         output.println("{");
3902         String src=generateTemp(fm, fsen.getSrc(), lb);
3903         if ((dc==null)||dc.getNeedSrcTrans(lb, fsen)&&
3904             locality.getNodePreTempInfo(lb, fsen).get(fsen.getSrc())!=LocalityAnalysis.SCRATCH) {
3905           output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
3906         } else {
3907           output.println("INTPTR srcoid=(INTPTR)"+src+";");
3908         }
3909         if (state.STMARRAY&&locality.getNodePreTempInfo(lb, fsen).get(fsen.getDst())!=LocalityAnalysis.SCRATCH&&wb.needBarrier(fsen)&&locality.getAtomic(lb).get(fsen).intValue()>0) {
3910           output.println("STMSETARRAY("+generateTemp(fm, fsen.getDst(),lb)+", "+generateTemp(fm, fsen.getIndex(),lb)+", srcoid, INTPTR);");
3911         } else {
3912           output.println("((INTPTR*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]=srcoid;");
3913         }
3914         output.println("}");
3915       } else {
3916         if (state.STMARRAY&&locality.getNodePreTempInfo(lb, fsen).get(fsen.getDst())!=LocalityAnalysis.SCRATCH&&wb.needBarrier(fsen)&&locality.getAtomic(lb).get(fsen).intValue()>0) {
3917           output.println("STMSETARRAY("+generateTemp(fm, fsen.getDst(),lb)+", "+generateTemp(fm, fsen.getIndex(),lb)+", "+ generateTemp(fm, fsen.getSrc(), lb) +", "+type+");");
3918         } else {
3919           output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
3920         }
3921       }
3922     } else if (state.DSM && locality.getAtomic(lb).get(fsen).intValue()>0) {
3923       Integer statussrc=locality.getNodePreTempInfo(lb,fsen).get(fsen.getSrc());
3924       Integer statusdst=locality.getNodePreTempInfo(lb,fsen).get(fsen.getDst());
3925       boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL;
3926       boolean dstglobal=statusdst==LocalityAnalysis.GLOBAL;
3927       boolean dstlocal=(statusdst==LocalityAnalysis.LOCAL)||(statusdst==LocalityAnalysis.EITHER);
3928       
3929       if (dstglobal) {
3930         if (wb.needBarrier(fsen))
3931           output.println("*((unsigned int *)&("+generateTemp(fm,fsen.getDst(),lb)+"->___localcopy___))|=DIRTY;");
3932       } else if (dstlocal) {
3933         /** Check if we need to copy */
3934         String dst=generateTemp(fm, fsen.getDst(),lb);
3935         output.println("if(!"+dst+"->"+localcopystr+") {");
3936         /* Link object into list */
3937         String revertptr=generateTemp(fm, reverttable.get(lb),lb);
3938         output.println(revertptr+"=revertlist;");
3939         if ((GENERATEPRECISEGC) || this.state.MULTICOREGC)
3940         output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
3941         else
3942           output.println("COPY_OBJ("+dst+");");
3943         output.println(dst+"->"+nextobjstr+"="+revertptr+";");
3944         output.println("revertlist=(struct ___Object___ *)"+dst+";");
3945         output.println("}");
3946       } else {
3947         System.out.println("Node: "+fsen);
3948         System.out.println(lb);
3949         System.out.println("statusdst="+statusdst);
3950         System.out.println(fm.printMethod());
3951         throw new Error("Unknown array type");
3952       }
3953       if (srcglobal) {
3954         output.println("{");
3955         String src=generateTemp(fm, fsen.getSrc(), lb);
3956         output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
3957         output.println("((INTPTR*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]=srcoid;");
3958         output.println("}");
3959       } else {
3960         output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
3961       }
3962     } else {
3963       if (state.FASTCHECK) {
3964         String dst=generateTemp(fm, fsen.getDst(),lb);
3965         output.println("if(!"+dst+"->"+localcopystr+") {");
3966         /* Link object into list */
3967         if (GENERATEPRECISEGC || this.state.MULTICOREGC)
3968           output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
3969         else
3970           output.println("COPY_OBJ("+dst+");");
3971         output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
3972         output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
3973         output.println("}");
3974       }
3975       output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
3976     }
3977   }
3978
3979   protected void generateFlatNew(FlatMethod fm, LocalityBinding lb, FlatNew fn, PrintWriter output) {
3980     if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) {
3981       //Stash pointer in case of GC
3982       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
3983       output.println(revertptr+"=revertlist;");
3984     }
3985     if (state.SINGLETM) {
3986       if (fn.getType().isArray()) {
3987         int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
3988         if (locality.getAtomic(lb).get(fn).intValue()>0) {
3989           //inside transaction
3990           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarraytrans("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
3991         } else {
3992           //outside transaction
3993           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
3994         }
3995       } else {
3996         if (locality.getAtomic(lb).get(fn).intValue()>0) {
3997           //inside transaction
3998           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newtrans("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");");
3999         } else {
4000           //outside transaction
4001           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");");
4002         }
4003       }
4004     } else if (fn.getType().isArray()) {
4005       int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
4006       if (fn.isGlobal()&&(state.DSM||state.SINGLETM)) {
4007         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarrayglobal("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
4008       } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
4009         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
4010       } else {
4011         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
4012       }
4013     } else {
4014       if (fn.isGlobal()&&(state.DSM||state.SINGLETM)) {
4015         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newglobal("+fn.getType().getClassDesc().getId()+");");
4016       } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
4017         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");");
4018       } else {
4019         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
4020       }
4021     }
4022     if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) {
4023       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
4024       String dst=generateTemp(fm,fn.getDst(),lb);
4025       output.println(dst+"->___localcopy___=(struct ___Object___*)1;");
4026       output.println(dst+"->"+nextobjstr+"="+revertptr+";");
4027       output.println("revertlist=(struct ___Object___ *)"+dst+";");
4028     }
4029     if (state.FASTCHECK) {
4030       String dst=generateTemp(fm,fn.getDst(),lb);
4031       output.println(dst+"->___localcopy___=(struct ___Object___*)1;");
4032       output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
4033       output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
4034     }
4035   }
4036
4037   private void generateFlatTagDeclaration(FlatMethod fm, LocalityBinding lb, FlatTagDeclaration fn, PrintWriter output) {
4038     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
4039       output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag("+localsprefixaddr+", "+state.getTagId(fn.getType())+");");
4040     } else {
4041       output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag("+state.getTagId(fn.getType())+");");
4042     }
4043   }
4044
4045   private void generateFlatOpNode(FlatMethod fm, LocalityBinding lb, FlatOpNode fon, PrintWriter output) {
4046     if (fon.getRight()!=null) {
4047       if (fon.getOp().getOp()==Operation.URIGHTSHIFT) {
4048         if (fon.getLeft().getType().isLong())
4049           output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned long long)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";");
4050         else
4051           output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned int)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";");
4052
4053       } else if (dc!=null) {
4054         output.print(generateTemp(fm, fon.getDest(),lb)+" = (");
4055         if (fon.getLeft().getType().isPtr()&&(fon.getOp().getOp()==Operation.EQUAL||fon.getOp().getOp()==Operation.NOTEQUAL))
4056             output.print("(void *)");
4057         if (dc.getNeedLeftSrcTrans(lb, fon))
4058           output.print("("+generateTemp(fm, fon.getLeft(),lb)+"!=NULL?"+generateTemp(fm, fon.getLeft(),lb)+"->"+oidstr+":NULL)");
4059         else
4060           output.print(generateTemp(fm, fon.getLeft(),lb));
4061         output.print(")"+fon.getOp().toString()+"(");
4062         if (fon.getRight().getType().isPtr()&&(fon.getOp().getOp()==Operation.EQUAL||fon.getOp().getOp()==Operation.NOTEQUAL))
4063             output.print("(void *)");
4064         if (dc.getNeedRightSrcTrans(lb, fon))
4065           output.println("("+generateTemp(fm, fon.getRight(),lb)+"!=NULL?"+generateTemp(fm, fon.getRight(),lb)+"->"+oidstr+":NULL));");
4066         else
4067           output.println(generateTemp(fm,fon.getRight(),lb)+");");
4068       } else
4069         output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+fon.getOp().toString()+generateTemp(fm,fon.getRight(),lb)+";");
4070     } else if (fon.getOp().getOp()==Operation.ASSIGN)
4071       output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
4072     else if (fon.getOp().getOp()==Operation.UNARYPLUS)
4073       output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
4074     else if (fon.getOp().getOp()==Operation.UNARYMINUS)
4075       output.println(generateTemp(fm, fon.getDest(),lb)+" = -"+generateTemp(fm, fon.getLeft(),lb)+";");
4076     else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
4077       output.println(generateTemp(fm, fon.getDest(),lb)+" = !"+generateTemp(fm, fon.getLeft(),lb)+";");
4078     else if (fon.getOp().getOp()==Operation.COMP)
4079       output.println(generateTemp(fm, fon.getDest(),lb)+" = ~"+generateTemp(fm, fon.getLeft(),lb)+";");
4080     else if (fon.getOp().getOp()==Operation.ISAVAILABLE) {
4081       output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+"->fses==NULL;");
4082     } else
4083       output.println(generateTemp(fm, fon.getDest(),lb)+fon.getOp().toString()+generateTemp(fm, fon.getLeft(),lb)+";");
4084   }
4085
4086   private void generateFlatCastNode(FlatMethod fm, LocalityBinding lb, FlatCastNode fcn, PrintWriter output) {
4087     /* TODO: Do type check here */
4088     if (fcn.getType().isArray()) {
4089       output.println(generateTemp(fm,fcn.getDst(),lb)+"=(struct ArrayObject *)"+generateTemp(fm,fcn.getSrc(),lb)+";");
4090     } else if (fcn.getType().isClass())
4091       output.println(generateTemp(fm,fcn.getDst(),lb)+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc(),lb)+";");
4092     else
4093       output.println(generateTemp(fm,fcn.getDst(),lb)+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc(),lb)+";");
4094   }
4095
4096   private void generateFlatLiteralNode(FlatMethod fm, LocalityBinding lb, FlatLiteralNode fln, PrintWriter output) {
4097     if (fln.getValue()==null)
4098       output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
4099     else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
4100       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
4101         if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) {
4102           //Stash pointer in case of GC
4103           String revertptr=generateTemp(fm, reverttable.get(lb),lb);
4104           output.println(revertptr+"=revertlist;");
4105         }
4106         output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString("+localsprefixaddr+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
4107         if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) {
4108           //Stash pointer in case of GC
4109           String revertptr=generateTemp(fm, reverttable.get(lb),lb);
4110           output.println("revertlist="+revertptr+";");
4111         }
4112       } else {
4113         output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
4114       }
4115     } else if (fln.getType().isBoolean()) {
4116       if (((Boolean)fln.getValue()).booleanValue())
4117         output.println(generateTemp(fm, fln.getDst(),lb)+"=1;");
4118       else
4119         output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
4120     } else if (fln.getType().isChar()) {
4121       String st=FlatLiteralNode.escapeString(fln.getValue().toString());
4122       output.println(generateTemp(fm, fln.getDst(),lb)+"='"+st+"';");
4123     } else if (fln.getType().isLong()) {
4124       output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+"LL;");
4125     } else
4126       output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+";");
4127   }
4128
4129   protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
4130     if (frn.getReturnTemp()!=null) {
4131       if (frn.getReturnTemp().getType().isPtr())
4132         output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
4133       else
4134         output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
4135     } else {
4136       output.println("return;");
4137     }
4138   }
4139
4140   protected void generateStoreFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
4141     int left=-1;
4142     int right=-1;
4143     //only record if this group has more than one exit
4144     if (branchanalysis.numJumps(fcb)>1) {
4145       left=branchanalysis.jumpValue(fcb, 0);
4146       right=branchanalysis.jumpValue(fcb, 1);
4147     }
4148     output.println("if (!"+generateTemp(fm, fcb.getTest(),lb)+") {");
4149     if (right!=-1)
4150       output.println("STOREBRANCH("+right+");");
4151     output.println("goto "+label+";");
4152     output.println("}");
4153     if (left!=-1)
4154       output.println("STOREBRANCH("+left+");");
4155   }
4156
4157   protected void generateFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
4158     output.println("if (!"+generateTemp(fm, fcb.getTest(),lb)+") goto "+label+";");
4159   }
4160
4161   /** This method generates header information for the method or
4162    * task referenced by the Descriptor des. */
4163   private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
4164     generateHeader(fm, lb, des, output, false);
4165   }
4166
4167   private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output, boolean addSESErecord) {
4168     /* Print header */
4169     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : des);
4170     MethodDescriptor md=null;
4171     TaskDescriptor task=null;
4172     if (des instanceof MethodDescriptor)
4173       md=(MethodDescriptor) des;
4174     else
4175       task=(TaskDescriptor) des;
4176
4177     ClassDescriptor cn=md!=null ? md.getClassDesc() : null;
4178
4179     if (md!=null&&md.getReturnType()!=null) {
4180       if (md.getReturnType().isClass()||md.getReturnType().isArray())
4181         output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
4182       else
4183         output.print(md.getReturnType().getSafeSymbol()+" ");
4184     } else
4185       //catch the constructor case
4186       output.print("void ");
4187     if (md!=null) {
4188       if (state.DSM||state.SINGLETM) {
4189         output.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
4190       } else
4191         output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
4192     } else
4193       output.print(task.getSafeSymbol()+"(");
4194     
4195     boolean printcomma=false;
4196     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
4197       if (md!=null) {
4198         if (state.DSM||state.SINGLETM) {
4199           output.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
4200         } else
4201           output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
4202       } else
4203         output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
4204       printcomma=true;
4205     }
4206
4207     if (md!=null) {
4208       /* Method */
4209       for(int i=0; i<objectparams.numPrimitives(); i++) {
4210         TempDescriptor temp=objectparams.getPrimitive(i);
4211         if (printcomma)
4212           output.print(", ");
4213         printcomma=true;
4214         if (temp.getType().isClass()||temp.getType().isArray())
4215           output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
4216         else
4217           output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
4218       }
4219       output.println(") {");
4220     } else if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
4221       /* Imprecise Task */
4222       output.println("void * parameterarray[]) {");
4223       /* Unpack variables */
4224       for(int i=0; i<objectparams.numPrimitives(); i++) {
4225         TempDescriptor temp=objectparams.getPrimitive(i);
4226         output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
4227       }
4228       for(int i=0; i<fm.numTags(); i++) {
4229         TempDescriptor temp=fm.getTag(i);
4230         int offset=i+objectparams.numPrimitives();
4231         output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
4232       }
4233
4234       if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
4235         maxtaskparams=objectparams.numPrimitives()+fm.numTags();
4236     } else output.println(") {");
4237   }
4238
4239   public void generateFlatFlagActionNode(FlatMethod fm, LocalityBinding lb, FlatFlagActionNode ffan, PrintWriter output) {
4240     output.println("/* FlatFlagActionNode */");
4241
4242
4243     /* Process tag changes */
4244     Relation tagsettable=new Relation();
4245     Relation tagcleartable=new Relation();
4246
4247     Iterator tagsit=ffan.getTempTagPairs();
4248     while (tagsit.hasNext()) {
4249       TempTagPair ttp=(TempTagPair) tagsit.next();
4250       TempDescriptor objtmp=ttp.getTemp();
4251       TagDescriptor tag=ttp.getTag();
4252       TempDescriptor tagtmp=ttp.getTagTemp();
4253       boolean tagstatus=ffan.getTagChange(ttp);
4254       if (tagstatus) {
4255         tagsettable.put(objtmp, tagtmp);
4256       } else {
4257         tagcleartable.put(objtmp, tagtmp);
4258       }
4259     }
4260
4261
4262     Hashtable flagandtable=new Hashtable();
4263     Hashtable flagortable=new Hashtable();
4264
4265     /* Process flag changes */
4266     Iterator flagsit=ffan.getTempFlagPairs();
4267     while(flagsit.hasNext()) {
4268       TempFlagPair tfp=(TempFlagPair)flagsit.next();
4269       TempDescriptor temp=tfp.getTemp();
4270       Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
4271       FlagDescriptor flag=tfp.getFlag();
4272       if (flag==null) {
4273         //Newly allocate objects that don't set any flags case
4274         if (flagortable.containsKey(temp)) {
4275           throw new Error();
4276         }
4277         int mask=0;
4278         flagortable.put(temp,new Integer(mask));
4279       } else {
4280         int flagid=1<<((Integer)flagtable.get(flag)).intValue();
4281         boolean flagstatus=ffan.getFlagChange(tfp);
4282         if (flagstatus) {
4283           int mask=0;
4284           if (flagortable.containsKey(temp)) {
4285             mask=((Integer)flagortable.get(temp)).intValue();
4286           }
4287           mask|=flagid;
4288           flagortable.put(temp,new Integer(mask));
4289         } else {
4290           int mask=0xFFFFFFFF;
4291           if (flagandtable.containsKey(temp)) {
4292             mask=((Integer)flagandtable.get(temp)).intValue();
4293           }
4294           mask&=(0xFFFFFFFF^flagid);
4295           flagandtable.put(temp,new Integer(mask));
4296         }
4297       }
4298     }
4299
4300
4301     HashSet flagtagset=new HashSet();
4302     flagtagset.addAll(flagortable.keySet());
4303     flagtagset.addAll(flagandtable.keySet());
4304     flagtagset.addAll(tagsettable.keySet());
4305     flagtagset.addAll(tagcleartable.keySet());
4306
4307     Iterator ftit=flagtagset.iterator();
4308     while(ftit.hasNext()) {
4309       TempDescriptor temp=(TempDescriptor)ftit.next();
4310
4311
4312       Set tagtmps=tagcleartable.get(temp);
4313       if (tagtmps!=null) {
4314         Iterator tagit=tagtmps.iterator();
4315         while(tagit.hasNext()) {
4316           TempDescriptor tagtmp=(TempDescriptor)tagit.next();
4317           if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
4318             output.println("tagclear("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
4319           else
4320             output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
4321         }
4322       }
4323
4324       tagtmps=tagsettable.get(temp);
4325       if (tagtmps!=null) {
4326         Iterator tagit=tagtmps.iterator();
4327         while(tagit.hasNext()) {
4328           TempDescriptor tagtmp=(TempDescriptor)tagit.next();
4329           if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
4330             output.println("tagset("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
4331           else
4332             output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp, lb)+", "+generateTemp(fm,tagtmp, lb)+");");
4333         }
4334       }
4335
4336       int ormask=0;
4337       int andmask=0xFFFFFFF;
4338
4339       if (flagortable.containsKey(temp))
4340         ormask=((Integer)flagortable.get(temp)).intValue();
4341       if (flagandtable.containsKey(temp))
4342         andmask=((Integer)flagandtable.get(temp)).intValue();
4343       generateFlagOrAnd(ffan, fm, lb, temp, output, ormask, andmask);
4344       generateObjectDistribute(ffan, fm, lb, temp, output);
4345     }
4346   }
4347
4348   protected void generateFlagOrAnd(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp,
4349                                    PrintWriter output, int ormask, int andmask) {
4350     if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
4351       output.println("flagorandinit("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
4352     } else {
4353       output.println("flagorand("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
4354     }
4355   }
4356
4357   protected void generateObjectDistribute(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp, PrintWriter output) {
4358     output.println("enqueueObject("+generateTemp(fm, temp, lb)+");");
4359   }
4360
4361   void generateOptionalHeader(PrintWriter headers) {
4362
4363     //GENERATE HEADERS
4364     headers.println("#include \"task.h\"\n\n");
4365     headers.println("#ifndef _OPTIONAL_STRUCT_");
4366     headers.println("#define _OPTIONAL_STRUCT_");
4367
4368     //STRUCT PREDICATEMEMBER
4369     headers.println("struct predicatemember{");
4370     headers.println("int type;");
4371     headers.println("int numdnfterms;");
4372     headers.println("int * flags;");
4373     headers.println("int numtags;");
4374     headers.println("int * tags;\n};\n\n");
4375
4376     //STRUCT OPTIONALTASKDESCRIPTOR
4377     headers.println("struct optionaltaskdescriptor{");
4378     headers.println("struct taskdescriptor * task;");
4379     headers.println("int index;");
4380     headers.println("int numenterflags;");
4381     headers.println("int * enterflags;");
4382     headers.println("int numpredicatemembers;");
4383     headers.println("struct predicatemember ** predicatememberarray;");
4384     headers.println("};\n\n");
4385
4386     //STRUCT TASKFAILURE
4387     headers.println("struct taskfailure {");
4388     headers.println("struct taskdescriptor * task;");
4389     headers.println("int index;");
4390     headers.println("int numoptionaltaskdescriptors;");
4391     headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
4392
4393     //STRUCT FSANALYSISWRAPPER
4394     headers.println("struct fsanalysiswrapper{");
4395     headers.println("int  flags;");
4396     headers.println("int numtags;");
4397     headers.println("int * tags;");
4398     headers.println("int numtaskfailures;");
4399     headers.println("struct taskfailure ** taskfailurearray;");
4400     headers.println("int numoptionaltaskdescriptors;");
4401     headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
4402
4403     //STRUCT CLASSANALYSISWRAPPER
4404     headers.println("struct classanalysiswrapper{");
4405     headers.println("int type;");
4406     headers.println("int numotd;");
4407     headers.println("struct optionaltaskdescriptor ** otdarray;");
4408     headers.println("int numfsanalysiswrappers;");
4409     headers.println("struct fsanalysiswrapper ** fsanalysiswrapperarray;\n};");
4410
4411     headers.println("extern struct classanalysiswrapper * classanalysiswrapperarray[];");
4412
4413     Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
4414     while(taskit.hasNext()) {
4415       TaskDescriptor td=(TaskDescriptor)taskit.next();
4416       headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
4417     }
4418
4419   }
4420
4421   //CHECK OVER THIS -- THERE COULD BE SOME ERRORS HERE
4422   int generateOptionalPredicate(Predicate predicate, OptionalTaskDescriptor otd, ClassDescriptor cdtemp, PrintWriter output) {
4423     int predicateindex = 0;
4424     //iterate through the classes concerned by the predicate
4425     Set c_vard = predicate.vardescriptors;
4426     Hashtable<TempDescriptor, Integer> slotnumber=new Hashtable<TempDescriptor, Integer>();
4427     int current_slot=0;
4428
4429     for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();) {
4430       VarDescriptor vard = (VarDescriptor)vard_it.next();
4431       TypeDescriptor typed = vard.getType();
4432
4433       //generate for flags
4434       HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
4435       output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
4436       int numberterms=0;
4437       if (fen_hashset!=null) {
4438         for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();) {
4439           FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
4440           if (fen!=null) {
4441             DNFFlag dflag=fen.getDNF();
4442             numberterms+=dflag.size();
4443
4444             Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
4445
4446             for(int j=0; j<dflag.size(); j++) {
4447               if (j!=0)
4448                 output.println(",");
4449               Vector term=dflag.get(j);
4450               int andmask=0;
4451               int checkmask=0;
4452               for(int k=0; k<term.size(); k++) {
4453                 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
4454                 FlagDescriptor fd=dfa.getFlag();
4455                 boolean negated=dfa.getNegated();
4456                 int flagid=1<<((Integer)flags.get(fd)).intValue();
4457                 andmask|=flagid;
4458                 if (!negated)
4459                   checkmask|=flagid;
4460               }
4461               output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
4462             }
4463           }
4464         }
4465       }
4466       output.println("};\n");
4467
4468       //generate for tags
4469       TagExpressionList tagel = predicate.tags.get(vard.getSymbol());
4470       output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
4471       int numtags = 0;
4472       if (tagel!=null) {
4473         for(int j=0; j<tagel.numTags(); j++) {
4474           if (j!=0)
4475             output.println(",");
4476           TempDescriptor tmp=tagel.getTemp(j);
4477           if (!slotnumber.containsKey(tmp)) {
4478             Integer slotint=new Integer(current_slot++);
4479             slotnumber.put(tmp,slotint);
4480           }
4481           int slot=slotnumber.get(tmp).intValue();
4482           output.println("/* slot */"+ slot+", /*tagid*/"+state.getTagId(tmp.getTag()));
4483         }
4484         numtags = tagel.numTags();
4485       }
4486       output.println("};");
4487
4488       //store the result into a predicatemember struct
4489       output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
4490       output.println("/*type*/"+typed.getClassDesc().getId()+",");
4491       output.println("/* number of dnf terms */"+numberterms+",");
4492       output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
4493       output.println("/* number of tag */"+numtags+",");
4494       output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
4495       output.println("};\n");
4496       predicateindex++;
4497     }
4498
4499
4500     //generate an array that stores the entire predicate
4501     output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
4502     for( int j = 0; j<predicateindex; j++) {
4503       if( j != predicateindex-1) output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
4504       else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
4505     }
4506     output.println("};\n");
4507     return predicateindex;
4508   }
4509
4510
4511   void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, Set<OptionalTaskDescriptor>>> safeexecution, Hashtable optionaltaskdescriptors) {
4512     generateOptionalHeader(headers);
4513     //GENERATE STRUCTS
4514     output.println("#include \"optionalstruct.h\"\n\n");
4515     output.println("#include \"stdlib.h\"\n");
4516
4517     HashSet processedcd = new HashSet();
4518     int maxotd=0;
4519     Enumeration e = safeexecution.keys();
4520     while (e.hasMoreElements()) {
4521       int numotd=0;
4522       //get the class
4523       ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
4524       Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);       //will be used several times
4525
4526       //Generate the struct of optionals
4527       Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
4528       numotd = c_otd.size();
4529       if(maxotd<numotd) maxotd = numotd;
4530       if( !c_otd.isEmpty() ) {
4531         for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();) {
4532           OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
4533
4534           //generate the int arrays for the predicate
4535           Predicate predicate = otd.predicate;
4536           int predicateindex = generateOptionalPredicate(predicate, otd, cdtemp, output);
4537           TreeSet<Integer> fsset=new TreeSet<Integer>();
4538           //iterate through possible FSes corresponding to
4539           //the state when entering
4540
4541           for(Iterator fses = otd.enterflagstates.iterator(); fses.hasNext();) {
4542             FlagState fs = (FlagState)fses.next();
4543             int flagid=0;
4544             for(Iterator flags = fs.getFlags(); flags.hasNext();) {
4545               FlagDescriptor flagd = (FlagDescriptor)flags.next();
4546               int id=1<<((Integer)flaginfo.get(flagd)).intValue();
4547               flagid|=id;
4548             }
4549             fsset.add(new Integer(flagid));
4550             //tag information not needed because tag
4551             //changes are not tolerated.
4552           }
4553
4554           output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
4555           boolean needcomma=false;
4556           for(Iterator<Integer> it=fsset.iterator(); it.hasNext();) {
4557             if(needcomma)
4558               output.print(", ");
4559             output.println(it.next());
4560           }
4561
4562           output.println("};\n");
4563
4564
4565           //generate optionaltaskdescriptor that actually
4566           //includes exit fses, predicate and the task
4567           //concerned
4568           output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
4569           output.println("&task_"+otd.td.getSafeSymbol()+",");
4570           output.println("/*index*/"+otd.getIndex()+",");
4571           output.println("/*number of enter flags*/"+fsset.size()+",");
4572           output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
4573           output.println("/*number of members */"+predicateindex+",");
4574           output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
4575           output.println("};\n");
4576         }
4577       } else
4578         continue;
4579       // if there are no optionals, there is no need to build the rest of the struct
4580
4581       output.println("struct optionaltaskdescriptor * otdarray"+cdtemp.getSafeSymbol()+"[]={");
4582       c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
4583       if( !c_otd.isEmpty() ) {
4584         boolean needcomma=false;
4585         for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();) {
4586           OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
4587           if(needcomma)
4588             output.println(",");
4589           needcomma=true;
4590           output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
4591         }
4592       }
4593       output.println("};\n");
4594
4595       //get all the possible flagstates reachable by an object
4596       Hashtable hashtbtemp = safeexecution.get(cdtemp);
4597       int fscounter = 0;
4598       TreeSet fsts=new TreeSet(new FlagComparator(flaginfo));
4599       fsts.addAll(hashtbtemp.keySet());
4600       for(Iterator fsit=fsts.iterator(); fsit.hasNext();) {
4601         FlagState fs = (FlagState)fsit.next();
4602         fscounter++;
4603
4604         //get the set of OptionalTaskDescriptors corresponding
4605         HashSet<OptionalTaskDescriptor> availabletasks = (HashSet<OptionalTaskDescriptor>)hashtbtemp.get(fs);
4606         //iterate through the OptionalTaskDescriptors and
4607         //store the pointers to the optionals struct (see on
4608         //top) into an array
4609
4610         output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
4611         for(Iterator<OptionalTaskDescriptor> mos = ordertd(availabletasks).iterator(); mos.hasNext();) {
4612           OptionalTaskDescriptor mm = mos.next();
4613           if(!mos.hasNext())
4614             output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol());
4615           else
4616             output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
4617         }
4618
4619         output.println("};\n");
4620
4621         //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
4622
4623         int flagid=0;
4624         for(Iterator flags = fs.getFlags(); flags.hasNext();) {
4625           FlagDescriptor flagd = (FlagDescriptor)flags.next();
4626           int id=1<<((Integer)flaginfo.get(flagd)).intValue();
4627           flagid|=id;
4628         }
4629
4630         //process tag information
4631
4632         int tagcounter = 0;
4633         boolean first = true;
4634         Enumeration tag_enum = fs.getTags();
4635         output.println("int tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
4636         while(tag_enum.hasMoreElements()) {
4637           tagcounter++;
4638           TagDescriptor tagd = (TagDescriptor)tag_enum.nextElement();
4639           if(first==true)
4640             first = false;
4641           else
4642             output.println(", ");
4643           output.println("/*tagid*/"+state.getTagId(tagd));
4644         }
4645         output.println("};");
4646
4647         Set<TaskIndex> tiset=sa.getTaskIndex(fs);
4648         for(Iterator<TaskIndex> itti=tiset.iterator(); itti.hasNext();) {
4649           TaskIndex ti=itti.next();
4650           if (ti.isRuntime())
4651             continue;
4652
4653           Set<OptionalTaskDescriptor> otdset=sa.getOptions(fs, ti);
4654
4655           output.print("struct optionaltaskdescriptor * optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array[] = {");
4656           boolean needcomma=false;
4657           for(Iterator<OptionalTaskDescriptor> otdit=ordertd(otdset).iterator(); otdit.hasNext();) {
4658             OptionalTaskDescriptor otd=otdit.next();
4659             if(needcomma)
4660               output.print(", ");
4661             needcomma=true;
4662             output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
4663           }
4664           output.println("};");
4665
4666           output.print("struct taskfailure taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+" = {");
4667           output.print("&task_"+ti.getTask().getSafeSymbol()+", ");
4668           output.print(ti.getIndex()+", ");
4669           output.print(otdset.size()+", ");
4670           output.print("optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array");
4671           output.println("};");
4672         }
4673
4674         tiset=sa.getTaskIndex(fs);
4675         boolean needcomma=false;
4676         int runtimeti=0;
4677         output.println("struct taskfailure * taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
4678         for(Iterator<TaskIndex> itti=tiset.iterator(); itti.hasNext();) {
4679           TaskIndex ti=itti.next();
4680           if (ti.isRuntime()) {
4681             runtimeti++;
4682             continue;
4683           }
4684           if (needcomma)
4685             output.print(", ");
4686           needcomma=true;
4687           output.print("&taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex());
4688         }
4689         output.println("};\n");
4690
4691         //Store the result in fsanalysiswrapper
4692
4693         output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
4694         output.println("/*flag*/"+flagid+",");
4695         output.println("/* number of tags*/"+tagcounter+",");
4696         output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
4697         output.println("/* numtask failures */"+(tiset.size()-runtimeti)+",");
4698         output.println("taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
4699         output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
4700         output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
4701         output.println("};\n");
4702
4703       }
4704
4705       //Build the array of fsanalysiswrappers
4706       output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
4707       boolean needcomma=false;
4708       for(int i = 0; i<fscounter; i++) {
4709         if (needcomma) output.print(",");
4710         output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol());
4711         needcomma=true;
4712       }
4713       output.println("};");
4714
4715       //Build the classanalysiswrapper referring to the previous array
4716       output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
4717       output.println("/*type*/"+cdtemp.getId()+",");
4718       output.println("/*numotd*/"+numotd+",");
4719       output.println("otdarray"+cdtemp.getSafeSymbol()+",");
4720       output.println("/* number of fsanalysiswrappers */"+fscounter+",");
4721       output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
4722       processedcd.add(cdtemp);
4723     }
4724
4725     //build an array containing every classes for which code has been build
4726     output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
4727     for(int i=0; i<state.numClasses(); i++) {
4728       ClassDescriptor cn=cdarray[i];
4729       if (i>0)
4730         output.print(", ");
4731       if ((cn != null) && (processedcd.contains(cn)))
4732         output.print("&classanalysiswrapper_"+cn.getSafeSymbol());
4733       else
4734         output.print("NULL");
4735     }
4736     output.println("};");
4737
4738     output.println("#define MAXOTD "+maxotd);
4739     headers.println("#endif");
4740   }
4741
4742   public List<OptionalTaskDescriptor> ordertd(Set<OptionalTaskDescriptor> otdset) {
4743     Relation r=new Relation();
4744     for(Iterator<OptionalTaskDescriptor>otdit=otdset.iterator(); otdit.hasNext();) {
4745       OptionalTaskDescriptor otd=otdit.next();
4746       TaskIndex ti=new TaskIndex(otd.td, otd.getIndex());
4747       r.put(ti, otd);
4748     }
4749
4750     LinkedList<OptionalTaskDescriptor> l=new LinkedList<OptionalTaskDescriptor>();
4751     for(Iterator it=r.keySet().iterator(); it.hasNext();) {
4752       Set s=r.get(it.next());
4753       for(Iterator it2=s.iterator(); it2.hasNext();) {
4754         OptionalTaskDescriptor otd=(OptionalTaskDescriptor)it2.next();
4755         l.add(otd);
4756       }
4757     }
4758
4759     return l;
4760   }
4761
4762   protected void outputTransCode(PrintWriter output) {
4763   }
4764 }
4765
4766
4767
4768
4769
4770