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