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;
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;
18 import IR.FlagDescriptor;
19 import IR.MethodDescriptor;
21 import IR.TagVarDescriptor;
22 import IR.TaskDescriptor;
23 import IR.TypeDescriptor;
25 import IR.VarDescriptor;
26 import IR.Tree.DNFFlag;
27 import IR.Tree.DNFFlagAtom;
28 import IR.Tree.FlagExpressionNode;
29 import IR.Tree.TagExpressionList;
31 public class BuildCodeMultiCore extends BuildCode {
32 private Vector<Schedule> scheduling;
34 Schedule currentSchedule;
35 Hashtable[] fsate2qnames;
36 //String objqs4startupprefix= "objqueuearray4startup";
37 //String objqs4socketprefix= "objqueuearray4socket";
38 String objqarrayprefix= "objqueuearray4class";
39 String objqueueprefix = "objqueue4parameter_";
40 String taskprefix = "task_";
41 String taskarrayprefix = "taskarray_core";
42 String otqueueprefix = "___otqueue";
43 int startupcorenum; // record the core containing startup task, suppose only one core can hava startup object
45 public BuildCodeMultiCore(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, Vector<Schedule> scheduling, int coreNum) {
46 super(st, temptovar, typeutil, sa);
47 this.scheduling = scheduling;
48 this.coreNum = coreNum;
49 this.currentSchedule = null;
50 this.fsate2qnames = null;
51 this.startupcorenum = 0;
53 // sometimes there are extra cores then needed in scheduling
55 // currently, it is guaranteed that in scheduling, the corenum
56 // is started from 0 and continuous.
57 // MAY need modification here in the future when take hardware
58 // information into account.
59 if(this.scheduling.size() < this.coreNum) {
60 this.coreNum = this.scheduling.size();
64 public void buildCode() {
65 /* Create output streams to write to */
66 PrintWriter outclassdefs=null;
67 PrintWriter outstructs=null;
68 //PrintWriter outrepairstructs=null;
69 PrintWriter outmethodheader=null;
70 PrintWriter outmethod=null;
71 PrintWriter outvirtual=null;
72 PrintWriter outtask=null;
73 PrintWriter outtaskdefs=null;
74 //PrintWriter[] outtaskdefs=null;
75 //PrintWriter outoptionalarrays=null;
76 //PrintWriter optionalheaders=null;
79 outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
80 outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
81 outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
82 outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
83 outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
85 outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
86 outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
87 /*if(this.scheduling != null) {
88 outtaskdefs = new PrintWriter[this.coreNum];
89 for(int i = 0; i < this.scheduling.size(); ++i) {
90 this.currentSchedule = this.scheduling.elementAt(i);
91 outtaskdefs[this.currentSchedule.getCoreNum()] = new PrintWriter(
92 new FileOutputStream(PREFIX+"taskdefs_"+this.currentSchedule.getCoreNum()+".c"), true);
97 outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
98 optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
101 /*if (state.structfile!=null) {
102 outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
104 } catch (Exception e) {
109 /* Build the virtual dispatch tables */
110 super.buildVirtualTables(outvirtual);
112 /* Output includes */
113 outmethodheader.println("#ifndef METHODHEADERS_H");
114 outmethodheader.println("#define METHODHEADERS_H");
115 outmethodheader.println("#include \"structdefs.h\"");
117 outmethodheader.println("#include \"dstm.h\"");*/
119 /* Output Structures */
120 super.outputStructs(outstructs);
122 // Output the C class declarations
123 // These could mutually reference each other
124 super.outputClassDeclarations(outclassdefs);
126 // Output function prototypes and structures for parameters
127 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
129 while(it.hasNext()) {
131 ClassDescriptor cn=(ClassDescriptor)it.next();
132 super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
134 outclassdefs.close();
137 /* Map flags to integers */
138 /* The runtime keeps track of flags using these integers */
139 it=state.getClassSymbolTable().getDescriptorsIterator();
140 while(it.hasNext()) {
141 ClassDescriptor cn=(ClassDescriptor)it.next();
145 generateTaskStructs(outstructs, outmethodheader);
147 /* Outputs generic task structures if this is a task
149 outputTaskTypes(outtask);
152 /* Build the actual methods */
153 super.outputMethods(outmethod);
156 Iterator[] taskits = new Iterator[this.coreNum];
157 for(int i = 0; i < taskits.length; ++i) {
160 int[] numtasks = new int[this.coreNum];
161 int[][] numqueues = new int[this.coreNum][numclasses];
162 // arrays record the queues for startup object & socket object
163 //int[][] numqueues = new int[2][this.coreNum];
164 /* Output code for tasks */
165 for(int i = 0; i < this.scheduling.size(); ++i) {
166 this.currentSchedule = this.scheduling.elementAt(i);
167 outputTaskCode(outtaskdefs, outmethod, outtask, taskits, numtasks, numqueues);
168 /*outputTaskCode(outtaskdefs[this.currentSchedule.getCoreNum()], outmethod);
169 outtaskdefs[this.currentSchedule.getCoreNum()].close();*/
172 // Output task descriptors
173 boolean comma = false;
175 for(int index = 0; index < 2; ++index) {
177 outtaskdefs.println("struct parameterwrapper ** objq4startupobj[] = {");
179 outtaskdefs.println("struct parameterwrapper ** objq4socketobj[] = {");
182 for(int i = 0; i < this.coreNum; ++i) {
184 outtaskdefs.println(",");
188 outtaskdefs.println("/* object queue array for core " + i + "* /");
189 outtaskdefs.print(this.objqs4startupprefix + "_core" + i);
191 outtaskdefs.println("};");
193 outtaskdefs.println("int numqueues4startupobj[] = {");
195 outtaskdefs.println("int numqueues4socketobj[] = {");
197 int[] tmparray = numqueues[index];
199 for(int i = 0; i < tmparray.length; ++i) {
201 outtaskdefs.print(",");
205 outtaskdefs.print(tmparray[i]);
207 outtaskdefs.println("};");
209 outtaskdefs.println("struct parameterwrapper ** objectqueues[][NUMCLASSES] = {");
210 boolean needcomma = false;
211 for(int i = 0; i < numqueues.length ; ++i) {
213 outtaskdefs.println(",");
217 outtaskdefs.println("/* object queue array for core " + i + "*/");
218 outtaskdefs.print("{");
220 for(int j = 0; j < numclasses; ++j) {
222 outtaskdefs.println(",");
226 outtaskdefs.print(this.objqarrayprefix + j + "_core" + i);
228 outtaskdefs.print("}");
230 outtaskdefs.println("};");
232 outtaskdefs.println("int numqueues[][NUMCLASSES] = {");
233 for(int i = 0; i < numqueues.length; ++i) {
235 outtaskdefs.println(",");
239 int[] tmparray = numqueues[i];
241 outtaskdefs.print("{");
242 for(int j = 0; j < tmparray.length; ++j) {
244 outtaskdefs.print(",");
248 outtaskdefs.print(tmparray[j]);
250 outtaskdefs.print("}");
252 outtaskdefs.println("};");
254 for(int i = 0; i < taskits.length; ++i) {
255 outtaskdefs.println("struct taskdescriptor * " + this.taskarrayprefix + i + "[]={");
256 Iterator taskit = taskits[i];
259 while(taskit.hasNext()) {
260 TaskDescriptor td=(TaskDescriptor)taskit.next();
264 outtaskdefs.println(",");
265 outtaskdefs.print("&" + this.taskprefix +td.getCoreSafeSymbol(i));
268 outtaskdefs.println();
269 outtaskdefs.println("};");
271 outtaskdefs.println("struct taskdescriptor ** taskarray[]= {");
273 for(int i = 0; i < taskits.length; ++i) {
275 outtaskdefs.println(",");
278 outtaskdefs.print(this.taskarrayprefix + i);
280 outtaskdefs.println("};");
282 outtaskdefs.print("int numtasks[]= {");
284 for(int i = 0; i < taskits.length; ++i) {
286 outtaskdefs.print(",");
289 outtaskdefs.print(numtasks[i]);
291 outtaskdefs.println("};");
293 outtaskdefs.println("#ifdef RAW");
294 outtaskdefs.println("#include \"raw.h\"");
295 outtaskdefs.println("int corenum=raw_get_tile_num();");
296 outtaskdefs.println("#else");
297 outtaskdefs.println("int corenum=0;");
298 outtaskdefs.println("#endif");
301 outtask.println("#endif");
303 /* Record maximum number of task parameters */
304 outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
305 /* Record maximum number of all types, i.e. length of classsize[] */
306 outstructs.println("#define NUMTYPES "+(state.numClasses() + state.numArrays()));
307 /* Record number of cores */
308 outstructs.println("#define NUMCORES "+this.coreNum);
309 /* Record number of core containing startup task */
310 outstructs.println("#define STARTUPCORE "+this.startupcorenum);
311 //outstructs.println("#define STARTUPCORESTR \""+this.startupcorenum+"\"");
312 } //else if (state.main!=null) {
313 /* Generate main method */
314 // outputMainMethod(outmethod);
317 /* Generate information for task with optional parameters */
318 /*if (state.TASK&&state.OPTIONAL){
319 generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
320 outoptionalarrays.close();
323 /* Output structure definitions for repair tool */
324 /*if (state.structfile!=null) {
325 buildRepairStructs(outrepairstructs);
326 outrepairstructs.close();
330 outmethodheader.println("#endif");
331 outmethodheader.close();
333 outstructs.println("#endif");
337 /** This function outputs (1) structures that parameters are
338 * passed in (when PRECISE GC is enabled) and (2) function
339 * prototypes for the tasks */
341 private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
342 /* Cycle through tasks */
343 for(int i = 0; i < this.scheduling.size(); ++i) {
344 Schedule tmpschedule = this.scheduling.elementAt(i);
345 int num = tmpschedule.getCoreNum();
346 Iterator<TaskDescriptor> taskit = tmpschedule.getTasks().iterator();
348 while(taskit.hasNext()) {
349 /* Classify parameters */
350 TaskDescriptor task=taskit.next();
351 FlatMethod fm=state.getMethodFlat(task);
352 super.generateTempStructs(fm, null);
354 ParamsObject objectparams=(ParamsObject) paramstable.get(task);
355 TempObject objecttemps=(TempObject) tempstable.get(task);
357 /* Output parameter structure */
358 if (GENERATEPRECISEGC) {
359 output.println("struct "+task.getCoreSafeSymbol(num)+"_params {");
360 output.println(" int size;");
361 output.println(" void * next;");
362 for(int j=0;j<objectparams.numPointers();j++) {
363 TempDescriptor temp=objectparams.getPointer(j);
364 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
367 output.println("};\n");
368 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
369 maxtaskparams=objectparams.numPointers()+fm.numTags();
373 /* Output temp structure */
374 if (GENERATEPRECISEGC) {
375 output.println("struct "+task.getCoreSafeSymbol(num)+"_locals {");
376 output.println(" int size;");
377 output.println(" void * next;");
378 for(int j=0;j<objecttemps.numPointers();j++) {
379 TempDescriptor temp=objecttemps.getPointer(j);
380 if (temp.getType().isNull())
381 output.println(" void * "+temp.getSafeSymbol()+";");
382 else if(temp.getType().isTag())
383 output.println(" struct "+
384 (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
386 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
388 output.println("};\n");
391 /* Output task declaration */
392 headersout.print("void " + task.getCoreSafeSymbol(num)+"(");
394 if (GENERATEPRECISEGC) {
395 headersout.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
397 headersout.print("void * parameterarray[]");
398 headersout.println(");\n");
404 /* This method outputs code for each task. */
406 private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod, PrintWriter outtask, Iterator[] taskits, int[] numtasks,
408 /* Compile task based program */
409 outtaskdefs.println("#include \"task.h\"");
410 outtaskdefs.println("#include \"methodheaders.h\"");
412 /* Output object transfer queues into method.c*/
413 generateObjectTransQueues(outmethod);
415 //Vector[] qnames = new Vector[2];
416 int numclasses = numqueues[0].length;
417 Vector qnames[]= new Vector[numclasses];
418 for(int i = 0; i < qnames.length; ++i) {
421 Iterator<TaskDescriptor> taskit=this.currentSchedule.getTasks().iterator();
422 while(taskit.hasNext()) {
423 TaskDescriptor td=taskit.next();
424 FlatMethod fm=state.getMethodFlat(td);
425 generateTaskMethod(fm, null, outmethod);
426 generateTaskDescriptor(outtaskdefs, outtask, fm, td, qnames);
429 // generate queuearray for this core
430 int num = this.currentSchedule.getCoreNum();
431 boolean comma = false;
432 /*for(int i = 0; i < 2; ++i) {
434 outtaskdefs.println("/* object queue array for class StartupObject on core " + num + "* /");
436 outtaskdefs.println("/* object queue array for class Socket on core " + num + "* /");
439 outtaskdefs.println("struct parameterwrapper * " + this.objqs4startupprefix + "_core" + num + "[] = {");
441 outtaskdefs.println("struct parameterwrapper * " + this.objqs4socketprefix + "_core" + num + "[] = {");
443 Vector tmpvector = qnames[i];
445 if(tmpvector != null) {
446 for(int j = 0; j < tmpvector.size(); ++j) {
448 outtaskdefs.println(",");
452 outtaskdefs.print("&" + tmpvector.elementAt(j));
454 numqueues[i][num] = tmpvector.size();
456 numqueues[i][num] = 0;
458 outtaskdefs.println();
459 outtaskdefs.println("};");
461 for(int i = 0; i < qnames.length; ++i) {
462 outtaskdefs.println("/* object queue array for class " + i + " on core " + num + "*/");
463 outtaskdefs.println("struct parameterwrapper * " + this.objqarrayprefix + i + "_core" + num + "[] = {");
464 //outtaskdefs.print("0");
466 Vector tmpvector = qnames[i];
467 if(tmpvector != null) {
468 for(int j = 0; j < tmpvector.size(); ++j) {
470 outtaskdefs.println(",");
474 outtaskdefs.print("&" + tmpvector.elementAt(j));
476 numqueues[num][i] = tmpvector.size();// + 1;
478 numqueues[num][i] = 0;//1;
480 outtaskdefs.println("};");
483 // record the iterator of tasks on this core
484 taskit=this.currentSchedule.getTasks().iterator();
485 taskits[num] = taskit;
486 numtasks[num] = this.currentSchedule.getTasks().size();
489 /** Prints out definitions for generic task structures */
490 private void outputTaskTypes(PrintWriter outtask) {
491 outtask.println("#ifndef _TASK_H");
492 outtask.println("#define _TASK_H");
493 outtask.println("#include \"ObjectHash.h\"");
494 outtask.println("#include \"structdefs.h\"");
495 outtask.println("#include \"Queue.h\"");
497 outtask.println("struct tagobjectiterator {");
498 outtask.println(" int istag; /* 0 if object iterator, 1 if tag iterator */");
499 outtask.println(" struct ObjectIterator it; /* Object iterator */");
500 outtask.println(" struct ObjectHash * objectset;");
501 outtask.println("#ifdef OPTIONAL");
502 outtask.println(" int failedstate;");
503 outtask.println("#endif");
504 outtask.println(" int slot;");
505 outtask.println(" int tagobjindex; /* Index for tag or object depending on use */");
506 outtask.println(" /*if tag we have an object binding */");
507 outtask.println(" int tagid;");
508 outtask.println(" int tagobjectslot;");
509 outtask.println(" /*if object, we may have one or more tag bindings */");
510 outtask.println(" int numtags;");
511 outtask.println(" int tagbindings[MAXTASKPARAMS-1]; /* list slots */");
512 outtask.println("};");
514 outtask.println("struct parameterwrapper {");
515 outtask.println(" //int type;");
516 outtask.println(" struct ObjectHash * objectset;");
517 outtask.println(" int numberofterms;");
518 outtask.println(" int * intarray;");
519 outtask.println(" int numbertags;");
520 outtask.println(" int * tagarray;");
521 outtask.println(" struct taskdescriptor * task;");
522 outtask.println(" int slot;");
523 outtask.println(" struct tagobjectiterator iterators[MAXTASKPARAMS-1];");
524 outtask.println("};");
527 outtask.println("extern struct parameterwrapper ** objq4startupobj[];");
528 outtask.println("extern int numqueues4startupobj[];");
529 outtask.println("extern struct parameterwrapper ** objq4socketobj[];");
530 outtask.println("extern int numqueues4socketobj[];");
532 outtask.println("extern struct parameterwrapper ** objectqueues[][NUMCLASSES];");
533 outtask.println("extern int numqueues[][NUMCLASSES];");
535 outtask.println("struct parameterdescriptor {");
536 outtask.println(" int type;");
537 outtask.println(" int numberterms;");
538 outtask.println(" int *intarray;");
539 outtask.println(" struct parameterwrapper * queue;");
540 outtask.println(" int numbertags;");
541 outtask.println(" int *tagarray;");
542 outtask.println("};");
544 outtask.println("struct taskdescriptor {");
545 outtask.println(" void * taskptr;");
546 outtask.println(" int numParameters;");
547 outtask.println(" int numTotal;");
548 outtask.println(" struct parameterdescriptor **descriptorarray;");
549 outtask.println(" char * name;");
550 outtask.println("};");
552 outtask.println("extern struct taskdescriptor ** taskarray[];");
553 outtask.println("extern int numtasks[];");
554 outtask.println("extern int corenum;"); // define corenum to identify different core
558 private void generateObjectTransQueues(PrintWriter output) {
559 if(this.fsate2qnames == null) {
560 this.fsate2qnames = new Hashtable[this.coreNum];
561 for(int i = 0; i < this.fsate2qnames.length; ++i) {
562 this.fsate2qnames[i] = null;
565 int num = this.currentSchedule.getCoreNum();
566 assert(this.fsate2qnames[num] == null);
567 Hashtable<FlagState, String> flag2qname = new Hashtable<FlagState, String>();
568 this.fsate2qnames[num] = flag2qname;
569 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
570 if(targetCoreTbl != null) {
571 Object[] keys = targetCoreTbl.keySet().toArray();
573 output.println("/* Object transfer queues for core" + num + ".*/");
574 for(int i = 0; i < keys.length; ++i) {
575 FlagState tmpfstate = (FlagState)keys[i];
576 Object[] targetcores = targetCoreTbl.get(tmpfstate).toArray();
577 String queuename = this.otqueueprefix + tmpfstate.getClassDescriptor().getCoreSafeSymbol(num) + tmpfstate.getuid() + "___";
578 String queueins = queuename + "ins";
579 flag2qname.put(tmpfstate, queuename);
580 output.println("struct " + queuename + " {");
581 output.println(" int * cores;");
582 output.println(" int index;");
583 output.println(" int length;");
584 output.println("};");
585 output.print("int " + queuename + "cores[] = {");
586 for(int j = 0; j < targetcores.length; ++j) {
590 output.print(((Integer)targetcores[j]).intValue());
592 output.println("};");
593 output.println("struct " + queuename + " " + queueins + "= {");
594 output.println(/*".cores = " + */queuename + "cores,");
595 output.println(/*".index = " + */"0,");
596 output.println(/*".length = " +*/ targetcores.length + "};");
602 private void generateTaskMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
603 /*if (State.PRINTFLAT)
604 System.out.println(fm.printMethod());*/
605 TaskDescriptor task=fm.getTask();
606 assert(task != null);
607 int num = this.currentSchedule.getCoreNum();
609 //ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:task);
610 generateTaskHeader(fm, lb, task,output);
611 TempObject objecttemp=(TempObject) tempstable.get(lb!=null?lb:task);
612 /*if (state.DSM&&lb.getHasAtomic()) {
613 output.println("transrecord_t * trans;");
616 if (GENERATEPRECISEGC) {
617 output.print(" struct "+task.getCoreSafeSymbol(num)+"_locals "+localsprefix+"={");
619 output.print(objecttemp.numPointers()+",");
620 output.print(paramsprefix);
621 for(int j=0;j<objecttemp.numPointers();j++)
622 output.print(", NULL");
623 output.println("};");
626 for(int i=0;i<objecttemp.numPrimitives();i++) {
627 TempDescriptor td=objecttemp.getPrimitive(i);
628 TypeDescriptor type=td.getType();
630 //output.println(" void * "+td.getCoreSafeSymbol(num)+";");
631 output.println(" void * "+td.getSafeSymbol()+";");
632 else if (type.isClass()||type.isArray())
633 //output.println(" struct "+type.getSafeSymbol()+" * "+td.getCoreSafeSymbol(num)+";");
634 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
636 //output.println(" "+type.getSafeSymbol()+" "+td.getCoreSafeSymbol(num)+";");
637 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
640 for(int i = 0; i < fm.numParameters(); ++i) {
641 TempDescriptor temp = fm.getParameter(i);
642 output.println(" int "+generateTempFlagName(fm, temp, lb)+" = "+super.generateTemp(fm, temp, lb)+
644 output.println(" ++" + super.generateTemp(fm, temp, lb)+"->version;");
647 /* Assign labels to FlatNode's if necessary.*/
649 Hashtable<FlatNode, Integer> nodetolabel=super.assignLabels(fm);
651 /* Check to see if we need to do a GC if this is a
652 * multi-threaded program...*/
654 /*if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) {
655 if (state.DSM&&lb.isAtomic())
656 output.println("checkcollect2(&"+localsprefix+",trans);");
658 output.println("checkcollect(&"+localsprefix+");");
661 /* Create queues to store objects need to be transferred to other cores and their destination*/
662 output.println(" struct Queue * totransobjqueue = createQueue();");
663 output.println(" struct Queue * desqueue = createQueue();");
664 output.println("int tmpint = 0;");
666 /* Do the actual code generation */
667 FlatNode current_node=null;
668 HashSet tovisit=new HashSet();
669 HashSet visited=new HashSet();
670 tovisit.add(fm.getNext(0));
671 while(current_node!=null||!tovisit.isEmpty()) {
672 if (current_node==null) {
673 current_node=(FlatNode)tovisit.iterator().next();
674 tovisit.remove(current_node);
676 visited.add(current_node);
677 if (nodetolabel.containsKey(current_node))
678 output.println("L"+nodetolabel.get(current_node)+":");
679 /*if (state.INSTRUCTIONFAILURE) {
680 if (state.THREAD||state.DSM) {
681 output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
684 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
686 if (current_node.numNext()==0) {
688 super.generateFlatNode(fm, lb, current_node, output);
689 if (current_node.kind()!=FKind.FlatReturnNode) {
690 outputTransCode(output);
691 output.println(" return;");
694 } else if(current_node.numNext()==1) {
696 super.generateFlatNode(fm, lb, current_node, output);
697 FlatNode nextnode=current_node.getNext(0);
698 if (visited.contains(nextnode)) {
699 output.println("goto L"+nodetolabel.get(nextnode)+";");
702 current_node=nextnode;
703 } else if (current_node.numNext()==2) {
706 super.generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
707 if (!visited.contains(current_node.getNext(1)))
708 tovisit.add(current_node.getNext(1));
709 if (visited.contains(current_node.getNext(0))) {
710 output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
713 current_node=current_node.getNext(0);
714 } else throw new Error();
717 output.println("}\n\n");
720 /** This method outputs TaskDescriptor information */
721 private void generateTaskDescriptor(PrintWriter output, PrintWriter outtask, FlatMethod fm, TaskDescriptor task, Vector[] qnames) {
722 int num = this.currentSchedule.getCoreNum();
724 output.println("/* TaskDescriptor information for task " + task.getSymbol() + " on core " + num + "*/");
726 for (int i=0;i<task.numParameters();i++) {
727 VarDescriptor param_var=task.getParameter(i);
728 TypeDescriptor param_type=task.getParamType(i);
729 FlagExpressionNode param_flag=task.getFlag(param_var);
730 TagExpressionList param_tag=task.getTag(param_var);
733 if (param_flag==null) {
734 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
735 output.println("0x0, 0x0 };");
738 DNFFlag dflag=param_flag.getDNF();
739 dnfterms=dflag.size();
741 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
742 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
743 for(int j=0;j<dflag.size();j++) {
746 Vector term=dflag.get(j);
749 for(int k=0;k<term.size();k++) {
750 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
751 FlagDescriptor fd=dfa.getFlag();
752 boolean negated=dfa.getNegated();
753 int flagid=1<<((Integer)flags.get(fd)).intValue();
758 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
760 output.println("};");
763 output.println("int parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
764 //BUG...added next line to fix, test with any task program
766 for(int j=0;j<param_tag.numTags();j++) {
769 /* for each tag we need */
770 /* which slot it is */
771 /* what type it is */
772 TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
773 TempDescriptor tmp=param_tag.getTemp(j);
774 int slot=fm.getTagInt(tmp);
775 output.println(slot+", "+state.getTagId(tvd.getTag()));
777 output.println("};");
779 // generate object queue for this parameter
780 String qname = this.objqueueprefix+i+"_"+task.getCoreSafeSymbol(num);
781 if(param_type.getClassDesc().getSymbol().equals("StartupObject")) {
782 this.startupcorenum = num;
784 /*if(param_type.getClassDesc().getSymbol().equals("StartupObject")) {
785 if(qnames[0] == null) {
786 qnames[0] = new Vector();
788 qnames[0].addElement(qname);
789 } else if(param_type.getClassDesc().getSymbol().equals("Socket")) {
790 if(qnames[1] == null) {
791 qnames[1] = new Vector();
793 qnames[1].addElement(qname);
795 if(qnames[param_type.getClassDesc().getId()] == null) {
796 qnames[param_type.getClassDesc().getId()] = new Vector();
798 qnames[param_type.getClassDesc().getId()].addElement(qname);
799 outtask.println("extern struct parameterwrapper " + qname + ";");
800 output.println("struct parameterwrapper " + qname + "={");
801 //output.println(".type = " + param_type.getClassDesc().getId() + ","); // type
802 output.println(".objectset = 0,"); // objectset
803 output.println("/* number of DNF terms */ .numberofterms = "+dnfterms+","); // numberofterms
804 output.println(".intarray = parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
807 output.println("/* number of tags */ .numbertags = "+param_tag.numTags()+",");
809 output.println("/* number of tags */ .numbertags = 0,");
810 output.println(".tagarray = parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+","); // tagarray
811 output.println(".task = 0,"); // task
812 output.println(".slot = " + i + ",");// slot
814 output.println("};");
816 output.println("struct parameterdescriptor parameter_"+i+"_"+task.getCoreSafeSymbol(num)+"={");
817 output.println("/* type */"+param_type.getClassDesc().getId()+",");
818 output.println("/* number of DNF terms */"+dnfterms+",");
819 output.println("parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
820 output.println("&" + qname + ","); // queue
821 //BUG, added next line to fix and else statement...test
822 //with any task program
824 output.println("/* number of tags */"+param_tag.numTags()+",");
826 output.println("/* number of tags */ 0,");
827 output.println("parametertag_"+i+"_"+task.getCoreSafeSymbol(num)); // tagarray
828 output.println("};");
832 output.println("struct parameterdescriptor * parameterdescriptors_"+task.getCoreSafeSymbol(num)+"[] = {");
833 for (int i=0;i<task.numParameters();i++) {
836 output.print("¶meter_"+i+"_"+task.getCoreSafeSymbol(num));
838 output.println("};");
840 output.println("struct taskdescriptor " + this.taskprefix + task.getCoreSafeSymbol(num) + "={");
841 output.println("&"+task.getCoreSafeSymbol(num)+",");
842 output.println("/* number of parameters */" +task.numParameters() + ",");
843 int numtotal=task.numParameters()+fm.numTags();
844 output.println("/* number total parameters */" +numtotal + ",");
845 output.println("parameterdescriptors_"+task.getCoreSafeSymbol(num)+",");
846 output.println("\""+task.getSymbol()+"\"");
847 output.println("};");
852 /** This method generates header information for the task
853 * referenced by the Descriptor des. */
855 private void generateTaskHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
857 ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:des);
858 TaskDescriptor task=(TaskDescriptor) des;
860 int num = this.currentSchedule.getCoreNum();
861 //catch the constructor case
862 output.print("void ");
863 output.print(task.getCoreSafeSymbol(num)+"(");
865 boolean printcomma=false;
866 if (GENERATEPRECISEGC) {
867 output.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
871 /*if (state.DSM&&lb.isAtomic()) {
874 output.print("transrecord_t * trans");
878 if (!GENERATEPRECISEGC) {
880 output.println("void * parameterarray[]) {");
881 /* Unpack variables */
882 for(int i=0;i<objectparams.numPrimitives();i++) {
883 TempDescriptor temp=objectparams.getPrimitive(i);
884 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
886 for(int i=0;i<fm.numTags();i++) {
887 TempDescriptor temp=fm.getTag(i);
888 int offset=i+objectparams.numPrimitives();
889 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+i+"___=parameterarray["+offset+"];");// add i to fix bugs of duplicate definition of tags
892 if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
893 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
894 } else output.println(") {");
897 protected void generateFlagOrAnd(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp,
898 PrintWriter output, int ormask, int andmask) {
899 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
900 output.println("flagorandinit("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
902 int num = this.currentSchedule.getCoreNum();
903 ClassDescriptor cd = temp.getType().getClassDesc();
904 Vector<FlagState> initfstates = ffan.getInitFStates(cd);
905 for(int i = 0; i < initfstates.size(); ++i) {
906 FlagState tmpFState = initfstates.elementAt(i);
908 QueueInfo qinfo = outputqueues(tmpFState, num, output, false);
909 output.println("flagorand("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+
910 ", 0x"+Integer.toHexString(andmask)+", " + qinfo.qname +
911 ", " + qinfo.length + ");");
913 //output.println("flagorand("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
917 protected void generateObjectDistribute(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp,
918 PrintWriter output) {
919 ClassDescriptor cd = temp.getType().getClassDesc();
920 Vector<FlagState> initfstates = null;
921 Vector[] targetFStates = null;
922 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
923 targetFStates = new Vector[1];
924 targetFStates[0] = ffan.getTargetFStates4NewObj(cd);
926 initfstates = ffan.getInitFStates(cd);
927 targetFStates = new Vector[initfstates.size()];
928 for(int i = 0; i < initfstates.size(); ++i) {
929 FlagState fs = initfstates.elementAt(i);
930 targetFStates[i] = ffan.getTargetFStates(fs);
932 if(!fs.isSetmask()) {
933 Hashtable flags=(Hashtable)flagorder.get(cd);
936 Iterator it_flags = fs.getFlags();
937 while(it_flags.hasNext()) {
938 FlagDescriptor fd = (FlagDescriptor)it_flags.next();
939 int flagid=1<<((Integer)flags.get(fd)).intValue();
943 fs.setAndmask(andmask);
944 fs.setCheckmask(checkmask);
949 boolean isolate = true; // check if this flagstate can associate to some task with multiple params which can
950 // reside on multiple cores
951 if((this.currentSchedule == null) && (fm.getMethod().getClassDesc().getSymbol().equals("ServerSocket"))) {
952 // ServerSocket object will always reside on current core
953 for(int j = 0; j < targetFStates.length; ++j) {
954 if(initfstates != null) {
955 FlagState fs = initfstates.elementAt(j);
956 //isolate = this.currentSchedule.getAllyCoreTable().keySet().contains(fs);
957 output.println("if(" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
958 + ")==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
960 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
961 for(int i = 0; i < tmpfstates.size(); ++i) {
962 FlagState tmpFState = tmpfstates.elementAt(i);
964 // may have bugs here
965 output.println("/* reside on this core*");
966 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
967 //output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", objq4socketobj[corenum], numqueues4socketobj[corenum]);");
968 //output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+");");
970 if(initfstates != null) {
974 //output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+");");
978 int num = this.currentSchedule.getCoreNum();
979 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
980 for(int j = 0; j < targetFStates.length; ++j) {
982 if(initfstates != null) {
983 fs = initfstates.elementAt(j);
984 output.println("if((" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
985 + "))==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
987 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
988 for(int i = 0; i < tmpfstates.size(); ++i) {
989 FlagState tmpFState = tmpfstates.elementAt(i);
991 if(this.currentSchedule.getAllyCoreTable() == null) {
994 isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) ||
995 (this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
998 output.println(super.generateTemp(fm, temp, lb) + "->isolate = 1;"); // not shared object
1001 // indentify this object as a shared object
1002 // isolate flag is initially set as 1, once this flag is set as 0, it is never reset to 1, i.e. once an object
1003 // is shared, it maybe shared all the time afterwards
1004 output.println(super.generateTemp(fm, temp, lb) + "->isolate = 0;");
1005 output.println(super.generateTemp(fm, temp, lb) + "->original = (struct ___Object___ *)" + super.generateTemp(fm, temp, lb) + ";");
1008 Vector<Integer> sendto = new Vector<Integer>();
1009 Queue<Integer> queue = null;
1010 if(targetCoreTbl != null) {
1011 queue = targetCoreTbl.get(tmpFState);
1013 if((queue != null) &&
1014 ((queue.size() != 1) ||
1015 ((queue.size() == 1) && (queue.element().intValue() != num)))) {
1016 // this object may be transferred to other cores
1017 String queuename = (String)this.fsate2qnames[num].get(tmpFState);
1018 String queueins = queuename + "ins";
1020 Object[] cores = queue.toArray();
1022 Integer targetcore = (Integer)cores[0];
1023 if(queue.size() > 1) {
1024 index = queueins + ".index";
1026 if(queue.size() > 1) {
1027 output.println("switch(" + queueins + ".index % " + queueins + ".length) {");
1028 for(int k = 0; k < cores.length; ++k) {
1029 output.println("case " + k + ":");
1030 targetcore = (Integer)cores[k];
1031 if(targetcore.intValue() == num) {
1032 output.println("/* reside on this core*/");
1034 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1035 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1036 ", " + qinfo.length + ");");
1038 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1041 //output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+");");
1044 output.println("/* possibly needed by multi-parameter tasks on this core*/");
1045 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1047 output.println("/* transfer to core " + targetcore.toString() + "*/");
1048 // method call of transfer objects
1049 //output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() + ");");
1050 // enqueue this object and its destination
1051 output.println(";");
1052 output.println("tmpint = "+targetcore.toString()+";");
1053 output.println("addNewItem(totransobjqueue, (void*)" +super.generateTemp(fm, temp, lb) + ");");
1054 output.println("addNewItem(desqueue, (void *)tmpint);");
1055 sendto.add(targetcore);
1056 //output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() +
1057 // ", \"" + targetcore.toString() + "\"" + ");");
1059 output.println("break;");
1061 output.println("}");
1064 output.println("/* possibly needed by multi-parameter tasks on this core*/");
1065 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1067 output.println("/* transfer to core " + targetcore.toString() + "*/");
1068 // method call of transfer objectts
1069 //output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() + ");");
1070 // enqueue this object and its destination
1071 output.println(";");
1072 output.println("tmpint = "+targetcore.toString()+";");
1073 output.println("addNewItem(totransobjqueue, (void*)" +super.generateTemp(fm, temp, lb) + ");");
1074 output.println("addNewItem(desqueue, (void *)tmpint);");
1075 sendto.add(targetcore);
1076 //output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() +
1077 // ", \"" + targetcore.toString() + "\"" + ");");
1079 output.println("/* increase index*/");
1080 output.println("++" + queueins + ".index;");
1082 // this object will reside on current core
1083 output.println("/* reside on this core*/");
1085 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1086 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1087 ", " + qinfo.length + ");");
1089 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1092 //output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+");");
1095 // codes for multi-params tasks
1097 // flagstate associated with some multi-params tasks
1098 // need to be send to other cores
1099 Vector<Integer> targetcores = this.currentSchedule.getAllyCores(tmpFState);
1100 output.println("/* send the shared object to possible queues on other cores*/");
1101 for(int k = 0; k < targetcores.size(); ++k) {
1102 //QueueInfo qinfo = outputqueues(tmpFState, num, output);
1104 // add the information of exactly which queue
1105 if(!sendto.contains(targetcores.elementAt(i))) {
1106 // previously not sended to this target core
1107 //output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcores.elementAt(i).toString() + ");");
1108 // enqueue this object and its destination
1109 output.println(";");
1110 output.println("tmpint = "+targetcores.elementAt(i).toString()+";");
1111 output.println("addNewItem(totransobjqueue, (void*)" +super.generateTemp(fm, temp, lb) + ");");
1112 output.println("addNewItem(desqueue, (void *)tmpint);");
1118 if(initfstates != null) {
1119 output.println("}");
1124 private QueueInfo outputqueues(FlagState tmpFState, int num, PrintWriter output, boolean isEnqueue) {
1126 QueueInfo qinfo = new QueueInfo();
1127 output.println(";");
1128 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1129 output.println("struct parameterwrapper * " + qinfo.qname + "[] = {");
1130 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1131 Vector<TaskDescriptor> residetasks = this.currentSchedule.getTasks();
1132 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1133 Vector<Integer> indexes = new Vector<Integer>();
1134 boolean comma = false;
1136 while(it_edges.hasNext()) {
1137 FEdge fe = (FEdge)it_edges.next();
1138 TaskDescriptor td = fe.getTask();
1139 int paraindex = fe.getIndex();
1140 if((!isEnqueue) || (isEnqueue && residetasks.contains(td))) {
1141 if((!tasks.contains(td)) ||
1142 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1143 tasks.addElement(td);
1144 indexes.addElement(paraindex);
1146 output.println(",");
1150 output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
1155 output.println("};");
1159 private class QueueInfo {
1161 public String qname;
1164 private String generateTempFlagName(FlatMethod fm, TempDescriptor td, LocalityBinding lb) {
1165 MethodDescriptor md=fm.getMethod();
1166 TaskDescriptor task=fm.getTask();
1167 TempObject objecttemps=(TempObject) tempstable.get(lb!=null?lb:md!=null?md:task);
1169 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1170 return td.getSafeSymbol() + "_oldflag";
1173 if (objecttemps.isLocalPtr(td)) {
1174 return localsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1177 if (objecttemps.isParamPtr(td)) {
1178 return paramsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1183 protected void outputTransCode(PrintWriter output) {
1184 output.println("while(0 == isEmpty(totransobjqueue)) {");
1185 output.println(" struct QueueItem * totransitem = getTail(totransobjqueue);");
1186 output.println(" struct QueueItem * desitem = getTail(desqueue);");
1187 output.println(" transferObject(totransitem->objectptr, (int)desitem->objectptr);");
1188 output.println(" removeItem(totransobjqueue, totransitem);");
1189 output.println(" removeItem(desqueue, desitem);");
1190 output.println("}");
1191 output.println("freeQueue(totransobjqueue);");
1192 output.println("freeQueue(desqueue);");
1195 protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
1196 if (frn.getReturnTemp()!=null) {
1197 if (frn.getReturnTemp().getType().isPtr())
1198 output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1200 output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1202 if(fm.getTask() != null) {
1203 outputTransCode(output);
1205 output.println("return;");