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