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