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