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