helpful progress reporting
[IRC.git] / Robust / src / IR / Flat / BuildCodeMultiCore.java
1 package IR.Flat;
2
3 import java.io.FileOutputStream;
4 import java.io.PrintWriter;
5 import java.util.HashSet;
6 import java.util.Hashtable;
7 import java.util.Iterator;
8 import java.util.Queue;
9 import java.util.Vector;
10
11 import Analysis.Locality.LocalityBinding;
12 import Analysis.Scheduling.Schedule;
13 import Analysis.TaskStateAnalysis.FEdge;
14 import Analysis.TaskStateAnalysis.FlagState;
15 import Analysis.TaskStateAnalysis.SafetyAnalysis;
16 import Analysis.Prefetch.*;
17 import IR.ClassDescriptor;
18 import IR.Descriptor;
19 import IR.FlagDescriptor;
20 import IR.MethodDescriptor;
21 import IR.State;
22 import IR.TagVarDescriptor;
23 import IR.TaskDescriptor;
24 import IR.TypeDescriptor;
25 import IR.TypeUtil;
26 import IR.VarDescriptor;
27 import IR.Tree.DNFFlag;
28 import IR.Tree.DNFFlagAtom;
29 import IR.Tree.FlagExpressionNode;
30 import IR.Tree.TagExpressionList;
31
32 public class BuildCodeMultiCore extends BuildCode {
33   private Vector<Schedule> scheduling;
34   int coreNum;
35   Schedule currentSchedule;
36   Hashtable[] fsate2qnames;
37   String objqarrayprefix= "objqueuearray4class";
38   String objqueueprefix = "objqueue4parameter_";
39   String paramqarrayprefix = "paramqueuearray4task";
40   String coreqarrayprefix = "paramqueuearrays_core";
41   String taskprefix = "task_";
42   String taskarrayprefix = "taskarray_core";
43   String otqueueprefix = "___otqueue";
44   int startupcorenum;    // record the core containing startup task, suppose only one core can hava startup object
45
46   public BuildCodeMultiCore(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, Vector<Schedule> scheduling, int coreNum, PrefetchAnalysis pa) {
47     super(st, temptovar, typeutil, sa, pa);
48     this.scheduling = scheduling;
49     this.coreNum = coreNum;
50     this.currentSchedule = null;
51     this.fsate2qnames = null;
52     this.startupcorenum = 0;
53
54     // sometimes there are extra cores then needed in scheduling
55     // TODO
56     // currently, it is guaranteed that in scheduling, the corenum
57     // is started from 0 and continuous.
58     // MAY need modification here in the future when take hardware
59     // information into account.
60     if(this.scheduling.size() < this.coreNum) {
61       this.coreNum = this.scheduling.size();
62     }
63   }
64
65   public void buildCode() {
66     /* Create output streams to write to */
67     PrintWriter outclassdefs=null;
68     PrintWriter outstructs=null;
69     PrintWriter outmethodheader=null;
70     PrintWriter outmethod=null;
71     PrintWriter outvirtual=null;
72     PrintWriter outtask=null;
73     PrintWriter outtaskdefs=null;
74     //PrintWriter outoptionalarrays=null;
75     //PrintWriter optionalheaders=null;
76
77     try {
78       outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
79       outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
80       outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
81       outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
82       outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
83       if (state.TASK) {
84         outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
85         outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
86         /* optional
87            if (state.OPTIONAL){
88             outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
89             optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
90            } */
91       }
92       /*if (state.structfile!=null) {
93           outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
94          }*/
95     } catch (Exception e) {
96       e.printStackTrace();
97       System.exit(-1);
98     }
99
100     /* Build the virtual dispatch tables */
101     super.buildVirtualTables(outvirtual);
102
103     /* Output includes */
104     outmethodheader.println("#ifndef METHODHEADERS_H");
105     outmethodheader.println("#define METHODHEADERS_H");
106     outmethodheader.println("#include \"structdefs.h\"");
107     /*if (state.DSM)
108         outmethodheader.println("#include \"dstm.h\"");*/
109
110     /* Output Structures */
111     super.outputStructs(outstructs);
112
113     // Output the C class declarations
114     // These could mutually reference each other
115     super.outputClassDeclarations(outclassdefs);
116
117     // Output function prototypes and structures for parameters
118     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
119     int numclasses = 0;
120     while(it.hasNext()) {
121       ++numclasses;
122       ClassDescriptor cn=(ClassDescriptor)it.next();
123       super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
124     }
125     outclassdefs.close();
126
127     if (state.TASK) {
128       /* Map flags to integers */
129       /* The runtime keeps track of flags using these integers */
130       it=state.getClassSymbolTable().getDescriptorsIterator();
131       while(it.hasNext()) {
132         ClassDescriptor cn=(ClassDescriptor)it.next();
133         super.mapFlags(cn);
134       }
135       /* Generate Tasks */
136       generateTaskStructs(outstructs, outmethodheader);
137
138       /* Outputs generic task structures if this is a task
139          program */
140       outputTaskTypes(outtask);
141     }
142
143     /* Build the actual methods */
144     super.outputMethods(outmethod);
145
146     if (state.TASK) {
147       Iterator[] taskits = new Iterator[this.coreNum];
148       for(int i = 0; i < taskits.length; ++i) {
149         taskits[i] = null;
150       }
151       int[] numtasks = new int[this.coreNum];
152       int[][] numqueues = new int[this.coreNum][numclasses];
153       /* Output code for tasks */
154       for(int i = 0; i < this.scheduling.size(); ++i) {
155         this.currentSchedule = this.scheduling.elementAt(i);
156         outputTaskCode(outtaskdefs, outmethod, outtask, taskits, numtasks, numqueues);
157       }
158
159       // Output task descriptors
160       boolean comma = false;
161       outtaskdefs.println("struct parameterwrapper ** objectqueues[][NUMCLASSES] = {");
162       boolean needcomma = false;
163       for(int i = 0; i < numqueues.length ; ++i) {
164         if(needcomma) {
165           outtaskdefs.println(",");
166         } else {
167           needcomma = true;
168         }
169         outtaskdefs.println("/* object queue array for core " + i + "*/");
170         outtaskdefs.print("{");
171         comma = false;
172         for(int j = 0; j < numclasses; ++j) {
173           if(comma) {
174             outtaskdefs.println(",");
175           } else {
176             comma = true;
177           }
178           outtaskdefs.print(this.objqarrayprefix + j + "_core" + i);
179         }
180         outtaskdefs.print("}");
181       }
182       outtaskdefs.println("};");
183       needcomma = false;
184       outtaskdefs.println("int numqueues[][NUMCLASSES] = {");
185       for(int i = 0; i < numqueues.length; ++i) {
186         if(needcomma) {
187           outtaskdefs.println(",");
188         } else {
189           needcomma = true;
190         }
191         int[] tmparray = numqueues[i];
192         comma = false;
193         outtaskdefs.print("{");
194         for(int j = 0; j < tmparray.length; ++j) {
195           if(comma) {
196             outtaskdefs.print(",");
197           } else {
198             comma = true;
199           }
200           outtaskdefs.print(tmparray[j]);
201         }
202         outtaskdefs.print("}");
203       }
204       outtaskdefs.println("};");
205
206       /* parameter queue arrays for all the tasks*/
207       outtaskdefs.println("struct parameterwrapper *** paramqueues[] = {");
208       needcomma = false;
209       for(int i = 0; i < this.coreNum ; ++i) {
210         if(needcomma) {
211           outtaskdefs.println(",");
212         } else {
213           needcomma = true;
214         }
215         outtaskdefs.println("/* parameter queue array for core " + i + "*/");
216         outtaskdefs.print(this.coreqarrayprefix + i);
217       }
218       outtaskdefs.println("};");
219
220       for(int i = 0; i < taskits.length; ++i) {
221         outtaskdefs.println("struct taskdescriptor * " + this.taskarrayprefix + i + "[]={");
222         Iterator taskit = taskits[i];
223         if(taskit != null) {
224           boolean first=true;
225           while(taskit.hasNext()) {
226             TaskDescriptor td=(TaskDescriptor)taskit.next();
227             if (first)
228               first=false;
229             else
230               outtaskdefs.println(",");
231             outtaskdefs.print("&" + this.taskprefix +td.getCoreSafeSymbol(i));
232           }
233         }
234         outtaskdefs.println();
235         outtaskdefs.println("};");
236       }
237       outtaskdefs.println("struct taskdescriptor ** taskarray[]= {");
238       comma = false;
239       for(int i = 0; i < taskits.length; ++i) {
240         if (comma)
241           outtaskdefs.println(",");
242         else
243           comma = true;
244         outtaskdefs.print(this.taskarrayprefix + i);
245       }
246       outtaskdefs.println("};");
247
248       outtaskdefs.print("int numtasks[]= {");
249       comma = false;
250       for(int i = 0; i < taskits.length; ++i) {
251         if (comma)
252           outtaskdefs.print(",");
253         else
254           comma=true;
255         outtaskdefs.print(numtasks[i]);
256       }
257       outtaskdefs.println("};");
258       outtaskdefs.println("int corenum=0;");
259
260       outtaskdefs.close();
261       outtask.println("#endif");
262       outtask.close();
263       /* Record maximum number of task parameters */
264       outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
265       /* Record maximum number of all types, i.e. length of classsize[] */
266       outstructs.println("#define NUMTYPES "+(state.numClasses() + state.numArrays()));
267       /* Record number of cores */
268       outstructs.println("#define NUMCORES "+this.coreNum);
269       /* Record number of core containing startup task */
270       outstructs.println("#define STARTUPCORE "+this.startupcorenum);
271       //outstructs.println("#define STARTUPCORESTR \""+this.startupcorenum+"\"");
272     }     //else if (state.main!=null) {
273           /* Generate main method */
274           // outputMainMethod(outmethod);
275           //}
276
277     /* Generate information for task with optional parameters */
278     /*if (state.TASK&&state.OPTIONAL){
279         generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
280         outoptionalarrays.close();
281        } */
282
283     /* Output structure definitions for repair tool */
284     /*if (state.structfile!=null) {
285         buildRepairStructs(outrepairstructs);
286         outrepairstructs.close();
287        }*/
288
289     /* Close files */
290     outmethodheader.println("#endif");
291     outmethodheader.close();
292     outmethod.close();
293     outstructs.println("#endif");
294     outstructs.close();
295   }
296
297   /** This function outputs (1) structures that parameters are
298    * passed in (when PRECISE GC is enabled) and (2) function
299    * prototypes for the tasks */
300
301   private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
302     /* Cycle through tasks */
303     for(int i = 0; i < this.scheduling.size(); ++i) {
304       Schedule tmpschedule = this.scheduling.elementAt(i);
305       int num = tmpschedule.getCoreNum();
306       Iterator<TaskDescriptor> taskit = tmpschedule.getTasks().iterator();
307
308       while(taskit.hasNext()) {
309         /* Classify parameters */
310         TaskDescriptor task=taskit.next();
311         FlatMethod fm=state.getMethodFlat(task);
312         super.generateTempStructs(fm, null);
313
314         ParamsObject objectparams=(ParamsObject) paramstable.get(task);
315         TempObject objecttemps=(TempObject) tempstable.get(task);
316
317         /* Output parameter structure */
318         if (GENERATEPRECISEGC) {
319           output.println("struct "+task.getCoreSafeSymbol(num)+"_params {");
320           output.println("  int size;");
321           output.println("  void * next;");
322           for(int j=0; j<objectparams.numPointers(); j++) {
323             TempDescriptor temp=objectparams.getPointer(j);
324             output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
325           }
326
327           output.println("};\n");
328           if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
329             maxtaskparams=objectparams.numPointers()+fm.numTags();
330           }
331         }
332
333         /* Output temp structure */
334         if (GENERATEPRECISEGC) {
335           output.println("struct "+task.getCoreSafeSymbol(num)+"_locals {");
336           output.println("  int size;");
337           output.println("  void * next;");
338           for(int j=0; j<objecttemps.numPointers(); j++) {
339             TempDescriptor temp=objecttemps.getPointer(j);
340             if (temp.getType().isNull())
341               output.println("  void * "+temp.getSafeSymbol()+";");
342             else if(temp.getType().isTag())
343               output.println("  struct "+
344                              (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
345             else
346               output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
347           }
348           output.println("};\n");
349         }
350
351         /* Output task declaration */
352         headersout.print("void " + task.getCoreSafeSymbol(num)+"(");
353
354         if (GENERATEPRECISEGC) {
355           headersout.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
356         } else
357           headersout.print("void * parameterarray[]");
358         headersout.println(");\n");
359       }
360     }
361
362   }
363
364   /* This method outputs code for each task. */
365
366   private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod, PrintWriter outtask, Iterator[] taskits, int[] numtasks,
367                               int[][] numqueues) {
368     /* Compile task based program */
369     outtaskdefs.println("#include \"task.h\"");
370     outtaskdefs.println("#include \"methodheaders.h\"");
371
372     /* Output object transfer queues into method.c*/
373     generateObjectTransQueues(outmethod);
374
375     //Vector[] qnames = new Vector[2];
376     int numclasses = numqueues[0].length;
377     Vector qnames[]= new Vector[numclasses];
378     for(int i = 0; i < qnames.length; ++i) {
379       qnames[i] = null;
380     }
381     Iterator<TaskDescriptor> taskit=this.currentSchedule.getTasks().iterator();
382     while(taskit.hasNext()) {
383       TaskDescriptor td=taskit.next();
384       FlatMethod fm=state.getMethodFlat(td);
385       generateTaskMethod(fm, null, outmethod);
386       generateTaskDescriptor(outtaskdefs, outtask, fm, td, qnames);
387     }
388
389     // generate queuearray for this core
390     int num = this.currentSchedule.getCoreNum();
391     boolean comma = false;
392     for(int i = 0; i < qnames.length; ++i) {
393       outtaskdefs.println("/* object queue array for class " + i + " on core " + num + "*/");
394       outtaskdefs.println("struct parameterwrapper * " + this.objqarrayprefix + i + "_core" + num + "[] = {");
395       comma = false;
396       Vector tmpvector = qnames[i];
397       if(tmpvector != null) {
398         for(int j = 0; j < tmpvector.size(); ++j) {
399           if(comma) {
400             outtaskdefs.println(",");
401           } else {
402             comma = true;
403           }
404           outtaskdefs.print("&" + tmpvector.elementAt(j));
405         }
406         numqueues[num][i] = tmpvector.size();
407       } else {
408         numqueues[num][i] = 0;
409       }
410       outtaskdefs.println("};");
411     }
412
413     /* All the queues for tasks residing on this core*/
414     comma = false;
415     outtaskdefs.println("/* object queue array for tasks on core " + num + "*/");
416     outtaskdefs.println("struct parameterwrapper ** " + this.coreqarrayprefix + num + "[] = {");
417     taskit=this.currentSchedule.getTasks().iterator();
418     while(taskit.hasNext()) {
419       if (comma) {
420         outtaskdefs.println(",");
421       } else {
422         comma = true;
423       }
424       TaskDescriptor td=taskit.next();
425       outtaskdefs.print(this.paramqarrayprefix + td.getCoreSafeSymbol(num));
426     }
427     outtaskdefs.println("};");
428
429     // record the iterator of tasks on this core
430     taskit=this.currentSchedule.getTasks().iterator();
431     taskits[num] = taskit;
432     numtasks[num] = this.currentSchedule.getTasks().size();
433   }
434
435   /** Prints out definitions for generic task structures */
436   private void outputTaskTypes(PrintWriter outtask) {
437     outtask.println("#ifndef _TASK_H");
438     outtask.println("#define _TASK_H");
439     outtask.println("#include \"ObjectHash.h\"");
440     outtask.println("#include \"structdefs.h\"");
441     outtask.println("#include \"Queue.h\"");
442     outtask.println("#include <string.h>");
443     outtask.println("#ifdef RAW");
444     outtask.println("#include <raw.h>");
445     outtask.println("#endif");
446     outtask.println();
447     outtask.println("struct tagobjectiterator {");
448     outtask.println("  int istag; /* 0 if object iterator, 1 if tag iterator */");
449     outtask.println("  struct ObjectIterator it; /* Object iterator */");
450     outtask.println("  struct ObjectHash * objectset;");
451     outtask.println("#ifdef OPTIONAL");
452     outtask.println("  int failedstate;");
453     outtask.println("#endif");
454     outtask.println("  int slot;");
455     outtask.println("  int tagobjindex; /* Index for tag or object depending on use */");
456     outtask.println("  /*if tag we have an object binding */");
457     outtask.println("  int tagid;");
458     outtask.println("  int tagobjectslot;");
459     outtask.println("  /*if object, we may have one or more tag bindings */");
460     outtask.println("  int numtags;");
461     outtask.println("  int tagbindings[MAXTASKPARAMS-1]; /* list slots */");
462     outtask.println("};");
463     outtask.println();
464     outtask.println("struct parameterwrapper {");
465     outtask.println("  //int type;");
466     outtask.println("  struct ObjectHash * objectset;");
467     outtask.println("  int numberofterms;");
468     outtask.println("  int * intarray;");
469     outtask.println("  int numbertags;");
470     outtask.println("  int * tagarray;");
471     outtask.println("  struct taskdescriptor * task;");
472     outtask.println("  int slot;");
473     outtask.println("  struct tagobjectiterator iterators[MAXTASKPARAMS-1];");
474     outtask.println("};");
475     outtask.println();
476     outtask.println("extern struct parameterwrapper ** objectqueues[][NUMCLASSES];");
477     outtask.println("extern int numqueues[][NUMCLASSES];");
478     outtask.println();
479     outtask.println("struct parameterdescriptor {");
480     outtask.println("  int type;");
481     outtask.println("  int numberterms;");
482     outtask.println("  int *intarray;");
483     outtask.println("  struct parameterwrapper * queue;");
484     outtask.println("  int numbertags;");
485     outtask.println("  int *tagarray;");
486     outtask.println("};");
487     outtask.println();
488     outtask.println("struct taskdescriptor {");
489     outtask.println("  void * taskptr;");
490     outtask.println("  int numParameters;");
491     outtask.println("  int numTotal;");
492     outtask.println("  struct parameterdescriptor **descriptorarray;");
493     outtask.println("  char * name;");
494     outtask.println("};");
495     outtask.println();
496     outtask.println("extern struct taskdescriptor ** taskarray[];");
497     outtask.println("extern int numtasks[];");
498     outtask.println("extern int corenum;");     // define corenum to identify different core
499     outtask.println("extern struct parameterwrapper *** paramqueues[];");
500     outtask.println();
501   }
502
503   private void generateObjectTransQueues(PrintWriter output) {
504     if(this.fsate2qnames == null) {
505       this.fsate2qnames = new Hashtable[this.coreNum];
506       for(int i = 0; i < this.fsate2qnames.length; ++i) {
507         this.fsate2qnames[i] = null;
508       }
509     }
510     int num = this.currentSchedule.getCoreNum();
511     assert(this.fsate2qnames[num] == null);
512     Hashtable<FlagState, String> flag2qname = new Hashtable<FlagState, String>();
513     this.fsate2qnames[num] = flag2qname;
514     Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
515     if(targetCoreTbl != null) {
516       Object[] keys = targetCoreTbl.keySet().toArray();
517       output.println();
518       output.println("/* Object transfer queues for core" + num + ".*/");
519       for(int i = 0; i < keys.length; ++i) {
520         FlagState tmpfstate = (FlagState)keys[i];
521         Object[] targetcores = targetCoreTbl.get(tmpfstate).toArray();
522         String queuename = this.otqueueprefix + tmpfstate.getClassDescriptor().getCoreSafeSymbol(num) + tmpfstate.getuid() + "___";
523         String queueins = queuename + "ins";
524         flag2qname.put(tmpfstate, queuename);
525         output.println("struct " + queuename + " {");
526         output.println("  int * cores;");
527         output.println("  int index;");
528         output.println("  int length;");
529         output.println("};");
530         output.print("int " + queuename + "cores[] = {");
531         for(int j = 0; j < targetcores.length; ++j) {
532           if(j > 0) {
533             output.print(", ");
534           }
535           output.print(((Integer)targetcores[j]).intValue());
536         }
537         output.println("};");
538         output.println("struct " + queuename + " " + queueins + "= {");
539         output.println(/*".cores = " + */ queuename + "cores,");
540         output.println(/*".index = " + */ "0,");
541         output.println(/*".length = " +*/ targetcores.length + "};");
542       }
543     }
544     output.println();
545   }
546
547   private void generateTaskMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
548     /*if (State.PRINTFLAT)
549         System.out.println(fm.printMethod());*/
550     TaskDescriptor task=fm.getTask();
551     assert(task != null);
552     int num = this.currentSchedule.getCoreNum();
553
554     //ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:task);
555     generateTaskHeader(fm, lb, task,output);
556     TempObject objecttemp=(TempObject) tempstable.get(lb!=null ? lb : task);
557     /*if (state.DSM&&lb.getHasAtomic()) {
558         output.println("transrecord_t * trans;");
559        }*/
560
561     if (GENERATEPRECISEGC) {
562       output.print("   struct "+task.getCoreSafeSymbol(num)+"_locals "+localsprefix+"={");
563
564       output.print(objecttemp.numPointers()+",");
565       output.print(paramsprefix);
566       for(int j=0; j<objecttemp.numPointers(); j++)
567         output.print(", NULL");
568       output.println("};");
569     }
570
571     for(int i=0; i<objecttemp.numPrimitives(); i++) {
572       TempDescriptor td=objecttemp.getPrimitive(i);
573       TypeDescriptor type=td.getType();
574       if (type.isNull())
575         output.println("   void * "+td.getSafeSymbol()+";");
576       else if (type.isClass()||type.isArray())
577         output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
578       else
579         output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
580     }
581
582     for(int i = 0; i < fm.numParameters(); ++i) {
583       TempDescriptor temp = fm.getParameter(i);
584       output.println("   int "+generateTempFlagName(fm, temp, lb)+" = "+super.generateTemp(fm, temp, lb)+
585                      "->flag;");
586     }
587
588     /* Assign labels to FlatNode's if necessary.*/
589
590     Hashtable<FlatNode, Integer> nodetolabel=super.assignLabels(fm);
591
592     /* Check to see if we need to do a GC if this is a
593      * multi-threaded program...*/
594
595     /*if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) {
596         if (state.DSM&&lb.isAtomic())
597             output.println("checkcollect2(&"+localsprefix+",trans);");
598         else
599             output.println("checkcollect(&"+localsprefix+");");
600        }*/
601
602     /* Create queues to store objects need to be transferred to other cores and their destination*/
603     output.println("   struct Queue * totransobjqueue = createQueue();");
604     output.println("   struct transObjInfo * tmpObjInfo = NULL;");
605
606     /* generate print information for RAW version */
607     output.println("#ifdef RAW");
608     output.println("int tmpsum = 0;");
609     output.println("char * taskname = \"" + task.getSymbol() + "\";");
610     output.println("int tmplen = " + task.getSymbol().length() + ";");
611     output.println("int tmpindex = 1;");
612     output.println("for(;tmpindex < tmplen; tmpindex++) {");
613     output.println("   tmpsum = tmpsum * 10 + *(taskname + tmpindex) - '0';");
614     output.println("}");
615     output.println("#ifdef RAWPATH");
616     output.println("raw_test_pass(0xAAAA);");
617     output.println("raw_test_pass_reg(tmpsum);");
618     output.println("#endif");
619     output.println("#ifdef RAWDEBUG");
620     output.println("raw_test_pass(0xAAAA);");
621     output.println("raw_test_pass_reg(tmpsum);");
622     output.println("#endif");
623     output.println("#endif");
624
625     for(int i = 0; i < fm.numParameters(); ++i) {
626       TempDescriptor temp = fm.getParameter(i);
627       output.println("   ++" + super.generateTemp(fm, temp, lb)+"->version;");
628     }
629
630     /* Do the actual code generation */
631     FlatNode current_node=null;
632     HashSet tovisit=new HashSet();
633     HashSet visited=new HashSet();
634     tovisit.add(fm.getNext(0));
635     while(current_node!=null||!tovisit.isEmpty()) {
636       if (current_node==null) {
637         current_node=(FlatNode)tovisit.iterator().next();
638         tovisit.remove(current_node);
639       }
640       visited.add(current_node);
641       if (nodetolabel.containsKey(current_node))
642         output.println("L"+nodetolabel.get(current_node)+":");
643       /*if (state.INSTRUCTIONFAILURE) {
644           if (state.THREAD||state.DSM) {
645               output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
646           }
647           else
648               output.println("if ((--instructioncount)==0) injectinstructionfailure();");
649          }*/
650       if (current_node.numNext()==0) {
651         output.print("   ");
652         super.generateFlatNode(fm, lb, current_node, output);
653         if (current_node.kind()!=FKind.FlatReturnNode) {
654           //output.println("   flushAll();");
655           output.println("#ifdef RAW");
656           output.println("raw_user_interrupts_off();");
657           output.println("#ifdef RAWDEBUG");
658           output.println("raw_test_pass(0xec00);");
659           output.println("#endif");
660           output.println("raw_flush_entire_cache();");
661           output.println("#ifdef RAWDEBUG");
662           output.println("raw_test_pass(0xecff);");
663           output.println("#endif");
664           output.println("raw_user_interrupts_on();");
665           output.println("#endif");
666           outputTransCode(output);
667           output.println("   return;");
668         }
669         current_node=null;
670       } else if(current_node.numNext()==1) {
671         output.print("   ");
672         super.generateFlatNode(fm, lb, current_node, output);
673         FlatNode nextnode=current_node.getNext(0);
674         if (visited.contains(nextnode)) {
675           output.println("goto L"+nodetolabel.get(nextnode)+";");
676           current_node=null;
677         } else
678           current_node=nextnode;
679       } else if (current_node.numNext()==2) {
680         /* Branch */
681         output.print("   ");
682         super.generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
683         if (!visited.contains(current_node.getNext(1)))
684           tovisit.add(current_node.getNext(1));
685         if (visited.contains(current_node.getNext(0))) {
686           output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
687           current_node=null;
688         } else
689           current_node=current_node.getNext(0);
690       } else throw new Error();
691     }
692
693     output.println("}\n\n");
694   }
695
696   /** This method outputs TaskDescriptor information */
697   private void generateTaskDescriptor(PrintWriter output, PrintWriter outtask, FlatMethod fm, TaskDescriptor task, Vector[] qnames) {
698     int num = this.currentSchedule.getCoreNum();
699
700     output.println("/* TaskDescriptor information for task " + task.getSymbol() + " on core " + num + "*/");
701
702     for (int i=0; i<task.numParameters(); i++) {
703       VarDescriptor param_var=task.getParameter(i);
704       TypeDescriptor param_type=task.getParamType(i);
705       FlagExpressionNode param_flag=task.getFlag(param_var);
706       TagExpressionList param_tag=task.getTag(param_var);
707
708       int dnfterms;
709       if (param_flag==null) {
710         output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
711         output.println("0x0, 0x0 };");
712         dnfterms=1;
713       } else {
714         DNFFlag dflag=param_flag.getDNF();
715         dnfterms=dflag.size();
716
717         Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
718         output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
719         for(int j=0; j<dflag.size(); j++) {
720           if (j!=0)
721             output.println(",");
722           Vector term=dflag.get(j);
723           int andmask=0;
724           int checkmask=0;
725           for(int k=0; k<term.size(); k++) {
726             DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
727             FlagDescriptor fd=dfa.getFlag();
728             boolean negated=dfa.getNegated();
729             int flagid=1<<((Integer)flags.get(fd)).intValue();
730             andmask|=flagid;
731             if (!negated)
732               checkmask|=flagid;
733           }
734           output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
735         }
736         output.println("};");
737       }
738
739       output.println("int parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
740       //BUG...added next line to fix, test with any task program
741       if (param_tag!=null)
742         for(int j=0; j<param_tag.numTags(); j++) {
743           if (j!=0)
744             output.println(",");
745           /* for each tag we need */
746           /* which slot it is */
747           /* what type it is */
748           TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
749           TempDescriptor tmp=param_tag.getTemp(j);
750           int slot=fm.getTagInt(tmp);
751           output.println(slot+", "+state.getTagId(tvd.getTag()));
752         }
753       output.println("};");
754
755       // generate object queue for this parameter
756       String qname = this.objqueueprefix+i+"_"+task.getCoreSafeSymbol(num);
757       if(param_type.getClassDesc().getSymbol().equals("StartupObject")) {
758         this.startupcorenum = num;
759       }
760       if(qnames[param_type.getClassDesc().getId()] == null) {
761         qnames[param_type.getClassDesc().getId()] = new Vector();
762       }
763       qnames[param_type.getClassDesc().getId()].addElement(qname);
764       outtask.println("extern struct parameterwrapper " + qname + ";");
765       output.println("struct parameterwrapper " + qname + "={");
766       output.println(".objectset = 0,");      // objectset
767       output.println("/* number of DNF terms */ .numberofterms = "+dnfterms+",");     // numberofterms
768       output.println(".intarray = parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+",");    // intarray
769       // numbertags
770       if (param_tag!=null)
771         output.println("/* number of tags */ .numbertags = "+param_tag.numTags()+",");
772       else
773         output.println("/* number of tags */ .numbertags = 0,");
774       output.println(".tagarray = parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+",");    // tagarray
775       output.println(".task = 0,");      // task
776       output.println(".slot = " + i + ",");    // slot
777       // iterators
778       output.println("};");
779
780       output.println("struct parameterdescriptor parameter_"+i+"_"+task.getCoreSafeSymbol(num)+"={");
781       output.println("/* type */"+param_type.getClassDesc().getId()+",");
782       output.println("/* number of DNF terms */"+dnfterms+",");
783       output.println("parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+",");    // intarray
784       output.println("&" + qname + ",");     // queue
785       //BUG, added next line to fix and else statement...test
786       //with any task program
787       if (param_tag!=null)
788         output.println("/* number of tags */"+param_tag.numTags()+",");
789       else
790         output.println("/* number of tags */ 0,");
791       output.println("parametertag_"+i+"_"+task.getCoreSafeSymbol(num));     // tagarray
792       output.println("};");
793     }
794
795     /* parameter queues for this task*/
796     output.println("struct parameterwrapper * " + this.paramqarrayprefix + task.getCoreSafeSymbol(num)+"[] = {");
797     for (int i=0; i<task.numParameters(); i++) {
798       if (i!=0)
799         output.println(",");
800       output.print("&" + this.objqueueprefix + i + "_" + task.getCoreSafeSymbol(num));
801     }
802     output.println("};");
803
804     output.println("struct parameterdescriptor * parameterdescriptors_"+task.getCoreSafeSymbol(num)+"[] = {");
805     for (int i=0; i<task.numParameters(); i++) {
806       if (i!=0)
807         output.println(",");
808       output.print("&parameter_"+i+"_"+task.getCoreSafeSymbol(num));
809     }
810     output.println("};");
811
812     output.println("struct taskdescriptor " + this.taskprefix + task.getCoreSafeSymbol(num) + "={");
813     output.println("&"+task.getCoreSafeSymbol(num)+",");
814     output.println("/* number of parameters */" +task.numParameters() + ",");
815     int numtotal=task.numParameters()+fm.numTags();
816     output.println("/* number total parameters */" +numtotal + ",");
817     output.println("parameterdescriptors_"+task.getCoreSafeSymbol(num)+",");
818     output.println("\""+task.getSymbol()+"\"");
819     output.println("};");
820
821     output.println();
822   }
823
824   /** This method generates header information for the task
825    *  referenced by the Descriptor des. */
826
827   private void generateTaskHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
828     /* Print header */
829     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : des);
830     TaskDescriptor task=(TaskDescriptor) des;
831
832     int num = this.currentSchedule.getCoreNum();
833     //catch the constructor case
834     output.print("void ");
835     output.print(task.getCoreSafeSymbol(num)+"(");
836
837     boolean printcomma=false;
838     if (GENERATEPRECISEGC) {
839       output.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
840       printcomma=true;
841     }
842
843     /*if (state.DSM&&lb.isAtomic()) {
844         if (printcomma)
845             output.print(", ");
846         output.print("transrecord_t * trans");
847         printcomma=true;
848        }*/
849
850     if (!GENERATEPRECISEGC) {
851       /* Imprecise Task */
852       output.println("void * parameterarray[]) {");
853       /* Unpack variables */
854       for(int i=0; i<objectparams.numPrimitives(); i++) {
855         TempDescriptor temp=objectparams.getPrimitive(i);
856         output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
857       }
858       for(int i=0; i<fm.numTags(); i++) {
859         TempDescriptor temp=fm.getTag(i);
860         int offset=i+objectparams.numPrimitives();
861         output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+i+"___=parameterarray["+offset+"];");     // add i to fix bugs of duplicate definition of tags
862       }
863
864       if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
865         maxtaskparams=objectparams.numPrimitives()+fm.numTags();
866     } else output.println(") {");
867   }
868
869   protected void generateFlagOrAnd(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp,
870                                    PrintWriter output, int ormask, int andmask) {
871     if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
872       output.println("flagorandinit("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
873     } else {
874       int num = this.currentSchedule.getCoreNum();
875       ClassDescriptor cd = temp.getType().getClassDesc();
876       Vector<FlagState> initfstates = ffan.getInitFStates(cd);
877       for(int i = 0; i < initfstates.size(); ++i) {
878         FlagState tmpFState = initfstates.elementAt(i);
879         output.println("{");
880         QueueInfo qinfo = outputqueues(tmpFState, num, output, false);
881         output.println("flagorand("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+
882                        ", 0x"+Integer.toHexString(andmask)+", " + qinfo.qname +
883                        ", " + qinfo.length + ");");
884         output.println("}");
885       }
886     }
887   }
888
889   protected void generateObjectDistribute(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp,
890                                           PrintWriter output) {
891     ClassDescriptor cd = temp.getType().getClassDesc();
892     Vector<FlagState> initfstates = null;
893     Vector[] targetFStates = null;
894     if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
895       targetFStates = new Vector[1];
896       targetFStates[0] = ffan.getTargetFStates4NewObj(cd);
897     } else {
898       initfstates = ffan.getInitFStates(cd);
899       targetFStates = new Vector[initfstates.size()];
900       for(int i = 0; i < initfstates.size(); ++i) {
901         FlagState fs = initfstates.elementAt(i);
902         targetFStates[i] = ffan.getTargetFStates(fs);
903
904         if(!fs.isSetmask()) {
905           Hashtable flags=(Hashtable)flagorder.get(cd);
906           int andmask=0;
907           int checkmask=0;
908           Iterator it_flags = fs.getFlags();
909           while(it_flags.hasNext()) {
910             FlagDescriptor fd = (FlagDescriptor)it_flags.next();
911             int flagid=1<<((Integer)flags.get(fd)).intValue();
912             andmask|=flagid;
913             checkmask|=flagid;
914           }
915           fs.setAndmask(andmask);
916           fs.setCheckmask(checkmask);
917           fs.setSetmask(true);
918         }
919       }
920     }
921     boolean isolate = true;     // check if this flagstate can associate to some task with multiple params which can
922                                 // reside on multiple cores
923     if((this.currentSchedule == null) && (fm.getMethod().getClassDesc().getSymbol().equals("ServerSocket"))) {
924       // ServerSocket object will always reside on current core
925       for(int j = 0; j < targetFStates.length; ++j) {
926         if(initfstates != null) {
927           FlagState fs = initfstates.elementAt(j);
928           output.println("if(" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
929                          + ")==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
930         }
931         Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
932         for(int i = 0; i < tmpfstates.size(); ++i) {
933           FlagState tmpFState = tmpfstates.elementAt(i);
934           // TODO
935           // may have bugs here
936           output.println("/* reside on this core*");
937           output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
938         }
939         if(initfstates != null) {
940           output.println("}");
941         }
942       }
943       return;
944     }
945
946     int num = this.currentSchedule.getCoreNum();
947     Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
948     for(int j = 0; j < targetFStates.length; ++j) {
949       FlagState fs = null;
950       if(initfstates != null) {
951         fs = initfstates.elementAt(j);
952         output.println("if((" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
953                        + "))==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
954       }
955       Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
956       for(int i = 0; i < tmpfstates.size(); ++i) {
957         FlagState tmpFState = tmpfstates.elementAt(i);
958
959         if(this.currentSchedule.getAllyCoreTable() == null) {
960           isolate = true;
961         } else {
962           isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) ||
963                     (this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
964         }
965         if(!isolate) {
966           // indentify this object as a shared object
967           // isolate flag is initially set as 1, once this flag is set as 0, it is never reset to 1, i.e. once an object
968           // is shared, it maybe shared all the time afterwards
969           output.println("if(" + super.generateTemp(fm, temp, lb) + "->isolate == 1) {");
970           output.println("  " + super.generateTemp(fm, temp, lb) + "->isolate = 0;");
971           output.println("  " + super.generateTemp(fm, temp, lb) + "->original = (struct ___Object___ *)" + super.generateTemp(fm, temp, lb) + ";");
972           output.println("}");
973         }
974
975         Vector<TranObjInfo> sendto = new Vector<TranObjInfo>();
976         Queue<Integer> queue = null;
977         if(targetCoreTbl != null) {
978           queue = targetCoreTbl.get(tmpFState);
979         }
980         if((queue != null) &&
981            ((queue.size() != 1) ||
982             ((queue.size() == 1) && (queue.element().intValue() != num)))) {
983           // this object may be transferred to other cores
984           String queuename = (String) this.fsate2qnames[num].get(tmpFState);
985           String queueins = queuename + "ins";
986
987           Object[] cores = queue.toArray();
988           String index = "0";
989           Integer targetcore = (Integer)cores[0];
990           if(queue.size() > 1) {
991             index = queueins + ".index";
992           }
993           if(queue.size() > 1) {
994             output.println("switch(" + queueins + ".index % " + queueins + ".length) {");
995             for(int k = 0; k < cores.length; ++k) {
996               output.println("case " + k + ":");
997               targetcore = (Integer)cores[k];
998               if(targetcore.intValue() == num) {
999                 output.println("/* reside on this core*/");
1000                 if(isolate) {
1001                   output.println("{");
1002                   QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1003                   output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1004                                  ", " + qinfo.length + ");");
1005                   output.println("}");
1006                 } else {
1007                   // TODO
1008                   // really needed?
1009                   output.println("/* possibly needed by multi-parameter tasks on this core*/");
1010                   output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1011                 }
1012               } else {
1013                 if(!isolate) {
1014                   // TODO
1015                   // Is it possible to decide the actual queues?
1016                   output.println("/* possibly needed by multi-parameter tasks on this core*/");
1017                   output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1018                 }
1019                 output.println("/* transfer to core " + targetcore.toString() + "*/");
1020                 output.println("{");
1021                 // enqueue this object and its destinations for later process
1022                 // all the possible queues
1023                 QueueInfo qinfo = null;
1024                 TranObjInfo tmpinfo = new TranObjInfo();
1025                 tmpinfo.name = super.generateTemp(fm, temp, lb);
1026                 tmpinfo.targetcore = targetcore;
1027                 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1028                 if(targetFS != null) {
1029                   tmpinfo.fs = targetFS;
1030                 } else {
1031                   tmpinfo.fs = tmpFState;
1032                 }
1033                 if(!contains(sendto, tmpinfo)) {
1034                   qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1035                   output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1036                   output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1037                   output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1038                   output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1039                   output.println("tmpObjInfo->length = " + qinfo.length + ";");
1040                   output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1041                   sendto.add(tmpinfo);
1042                 }
1043                 output.println("}");
1044               }
1045               output.println("break;");
1046             }
1047             output.println("}");
1048           } else {
1049             if(!isolate) {
1050               // TODO
1051               // Is it possible to decide the actual queues?
1052               output.println("/* possibly needed by multi-parameter tasks on this core*/");
1053               output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1054             }
1055             output.println("/* transfer to core " + targetcore.toString() + "*/");
1056             output.println("{");
1057             // enqueue this object and its destinations for later process
1058             // all the possible queues
1059             QueueInfo qinfo = null;
1060             TranObjInfo tmpinfo = new TranObjInfo();
1061             tmpinfo.name = super.generateTemp(fm, temp, lb);
1062             tmpinfo.targetcore = targetcore;
1063             FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1064             if(targetFS != null) {
1065               tmpinfo.fs = targetFS;
1066             } else {
1067               tmpinfo.fs = tmpFState;
1068             }
1069             if(!contains(sendto, tmpinfo)) {
1070               qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1071               output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1072               output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1073               output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1074               output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1075               output.println("tmpObjInfo->length = " + qinfo.length + ";");
1076               output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1077               sendto.add(tmpinfo);
1078             }
1079             output.println("}");
1080           }
1081           output.println("/* increase index*/");
1082           output.println("++" + queueins + ".index;");
1083         } else {
1084           // this object will reside on current core
1085           output.println("/* reside on this core*/");
1086           if(isolate) {
1087             output.println("{");
1088             QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1089             output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1090                            ", " + qinfo.length + ");");
1091             output.println("}");
1092           } else {
1093             // TODO
1094             // really needed?
1095             output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1096           }
1097         }
1098
1099         // codes for multi-params tasks
1100         if(!isolate) {
1101           // flagstate associated with some multi-params tasks
1102           // need to be send to other cores
1103           Vector<Integer> targetcores = this.currentSchedule.getAllyCores(tmpFState);
1104           output.println("/* send the shared object to possible queues on other cores*/");
1105           for(int k = 0; k < targetcores.size(); ++k) {
1106             // TODO
1107             // add the information of exactly which queue
1108             //if(!sendto.contains(targetcores.elementAt(i))) {
1109             // previously not sended to this target core
1110             // enqueue this object and its destinations for later process
1111             output.println("{");
1112             // all the possible queues
1113             QueueInfo qinfo = null;
1114             TranObjInfo tmpinfo = new TranObjInfo();
1115             tmpinfo.name = super.generateTemp(fm, temp, lb);
1116             tmpinfo.targetcore = targetcores.elementAt(i);
1117             FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1118             if(targetFS != null) {
1119               tmpinfo.fs = targetFS;
1120             } else {
1121               tmpinfo.fs = tmpFState;
1122             }
1123             if(!contains(sendto, tmpinfo)) {
1124               qinfo = outputtransqueues(tmpinfo.fs, targetcores.elementAt(i), output);
1125               output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1126               output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1127               output.println("tmpObjInfo->targetcore = "+targetcores.elementAt(i).toString()+";");
1128               output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1129               output.println("tmpObjInfo->length = " + qinfo.length + ";");
1130               output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1131               sendto.add(tmpinfo);
1132             }
1133             output.println("}");
1134             //}
1135           }
1136         }
1137       }
1138
1139       if(initfstates != null) {
1140         output.println("}");
1141       }
1142     }
1143   }
1144
1145   private QueueInfo outputqueues(FlagState tmpFState, int num, PrintWriter output, boolean isEnqueue) {
1146     // queue array
1147     QueueInfo qinfo = new QueueInfo();
1148     qinfo.qname  = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1149     output.println("struct parameterwrapper * " + qinfo.qname + "[] = {");
1150     Iterator it_edges = tmpFState.getEdgeVector().iterator();
1151     Vector<TaskDescriptor> residetasks = this.currentSchedule.getTasks();
1152     Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1153     Vector<Integer> indexes = new Vector<Integer>();
1154     boolean comma = false;
1155     qinfo.length = 0;
1156     while(it_edges.hasNext()) {
1157       FEdge fe = (FEdge)it_edges.next();
1158       TaskDescriptor td = fe.getTask();
1159       int paraindex = fe.getIndex();
1160       if((!isEnqueue) || (isEnqueue && residetasks.contains(td))) {
1161         if((!tasks.contains(td)) ||
1162            ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1163           tasks.addElement(td);
1164           indexes.addElement(paraindex);
1165           if(comma) {
1166             output.println(",");
1167           } else {
1168             comma = true;
1169           }
1170           output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
1171           ++qinfo.length;
1172         }
1173       }
1174     }
1175     output.println("};");
1176     return qinfo;
1177   }
1178
1179   private QueueInfo outputtransqueues(FlagState tmpFState, int targetcore, PrintWriter output) {
1180     // queue array
1181     QueueInfo qinfo = new QueueInfo();
1182     qinfo.qname  = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1183     output.println("int " + qinfo.qname + "_clone[] = {");
1184     Iterator it_edges = tmpFState.getEdgeVector().iterator();
1185     Vector<TaskDescriptor> residetasks = this.scheduling.get(targetcore).getTasks();
1186     Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1187     Vector<Integer> indexes = new Vector<Integer>();
1188     boolean comma = false;
1189     qinfo.length = 0;
1190     while(it_edges.hasNext()) {
1191       FEdge fe = (FEdge)it_edges.next();
1192       TaskDescriptor td = fe.getTask();
1193       int paraindex = fe.getIndex();
1194       if(residetasks.contains(td)) {
1195         if((!tasks.contains(td)) ||
1196            ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1197           tasks.addElement(td);
1198           indexes.addElement(paraindex);
1199           if(comma) {
1200             output.println(",");
1201           } else {
1202             comma = true;
1203           }
1204           output.print(residetasks.indexOf(td) + ", ");
1205           output.print(paraindex);
1206           ++qinfo.length;
1207         }
1208       }
1209     }
1210     output.println("};");
1211     output.println("int * " + qinfo.qname + " = RUNMALLOC(sizeof(int) * " + qinfo.length * 2 + ");");
1212     output.println("memcpy(" + qinfo.qname + ", (int *)" + qinfo.qname + "_clone, sizeof(int) * " + qinfo.length * 2 + ");");
1213     return qinfo;
1214   }
1215
1216   private class QueueInfo {
1217     public int length;
1218     public String qname;
1219   }
1220
1221   private String generateTempFlagName(FlatMethod fm, TempDescriptor td, LocalityBinding lb) {
1222     MethodDescriptor md=fm.getMethod();
1223     TaskDescriptor task=fm.getTask();
1224     TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
1225
1226     if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1227       return td.getSafeSymbol() + "_oldflag";
1228     }
1229
1230     if (objecttemps.isLocalPtr(td)) {
1231       return localsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1232     }
1233
1234     if (objecttemps.isParamPtr(td)) {
1235       return paramsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1236     }
1237     throw new Error();
1238   }
1239
1240   protected void outputTransCode(PrintWriter output) {
1241     output.println("while(0 == isEmpty(totransobjqueue)) {");
1242     output.println("   struct QueueItem * totransitem = getTail(totransobjqueue);");
1243
1244     output.println("   transferObject((struct transObjInfo *)totransitem->objectptr);");
1245     output.println("   RUNFREE(((struct transObjInfo *)totransitem->objectptr)->queues);");
1246     output.println("   RUNFREE(totransitem->objectptr);");
1247     output.println("   removeItem(totransobjqueue, totransitem);");
1248     output.println("}");
1249     output.println("freeQueue(totransobjqueue);");
1250   }
1251
1252   protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
1253     if (frn.getReturnTemp()!=null) {
1254       if (frn.getReturnTemp().getType().isPtr())
1255         output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1256       else
1257         output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1258     } else {
1259       if(fm.getTask() != null) {
1260         //output.println("flushAll();");
1261         output.println("#ifdef RAW");
1262         output.println("raw_user_interrupts_off();");
1263         output.println("#ifdef RAWDEBUG");
1264         output.println("raw_test_pass(0xec00);");
1265         output.println("#endif");
1266         output.println("raw_flush_entire_cache();");
1267         output.println("#ifdef RAWDEBUG");
1268         output.println("raw_test_pass(0xecff);");
1269         output.println("#endif");
1270         output.println("raw_user_interrupts_on();");
1271         output.println("#endif");
1272         outputTransCode(output);
1273       }
1274       output.println("return;");
1275     }
1276   }
1277
1278   class TranObjInfo {
1279     public String name;
1280     public int targetcore;
1281     public FlagState fs;
1282   }
1283
1284   private boolean contains(Vector<TranObjInfo> sendto, TranObjInfo t) {
1285     if(sendto.size() == 0) {
1286       return false;
1287     }
1288     for(int i = 0; i < sendto.size(); i++) {
1289       TranObjInfo tmp = sendto.elementAt(i);
1290       if(!tmp.name.equals(t.name)) {
1291         return false;
1292       }
1293       if(tmp.targetcore != t.targetcore) {
1294         return false;
1295       }
1296       if(tmp.fs != t.fs) {
1297         return false;
1298       }
1299     }
1300     return true;
1301   }
1302 }