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