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 objqarrayprefix= "objqueuearray4class";
37 String objqueueprefix = "objqueue4parameter_";
38 String paramqarrayprefix = "paramqueuearray4task";
39 String coreqarrayprefix = "paramqueuearrays_core";
40 String taskprefix = "task_";
41 String taskarrayprefix = "taskarray_core";
42 String otqueueprefix = "___otqueue";
43 int startupcorenum; // record the core containing startup task, suppose only one core can hava startup object
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 outmethodheader=null;
69 PrintWriter outmethod=null;
70 PrintWriter outvirtual=null;
71 PrintWriter outtask=null;
72 PrintWriter outtaskdefs=null;
73 //PrintWriter outoptionalarrays=null;
74 //PrintWriter optionalheaders=null;
77 outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
78 outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
79 outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
80 outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
81 outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
83 outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
84 outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
87 outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
88 optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
91 /*if (state.structfile!=null) {
92 outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
94 } catch (Exception e) {
99 /* Build the virtual dispatch tables */
100 super.buildVirtualTables(outvirtual);
102 /* Output includes */
103 outmethodheader.println("#ifndef METHODHEADERS_H");
104 outmethodheader.println("#define METHODHEADERS_H");
105 outmethodheader.println("#include \"structdefs.h\"");
107 outmethodheader.println("#include \"dstm.h\"");*/
109 /* Output Structures */
110 super.outputStructs(outstructs);
112 // Output the C class declarations
113 // These could mutually reference each other
114 super.outputClassDeclarations(outclassdefs);
116 // Output function prototypes and structures for parameters
117 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
119 while(it.hasNext()) {
121 ClassDescriptor cn=(ClassDescriptor)it.next();
122 super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
124 outclassdefs.close();
127 /* Map flags to integers */
128 /* The runtime keeps track of flags using these integers */
129 it=state.getClassSymbolTable().getDescriptorsIterator();
130 while(it.hasNext()) {
131 ClassDescriptor cn=(ClassDescriptor)it.next();
135 generateTaskStructs(outstructs, outmethodheader);
137 /* Outputs generic task structures if this is a task
139 outputTaskTypes(outtask);
142 /* Build the actual methods */
143 super.outputMethods(outmethod);
146 Iterator[] taskits = new Iterator[this.coreNum];
147 for(int i = 0; i < taskits.length; ++i) {
150 int[] numtasks = new int[this.coreNum];
151 int[][] numqueues = new int[this.coreNum][numclasses];
152 /* Output code for tasks */
153 for(int i = 0; i < this.scheduling.size(); ++i) {
154 this.currentSchedule = this.scheduling.elementAt(i);
155 outputTaskCode(outtaskdefs, outmethod, outtask, taskits, numtasks, numqueues);
158 // Output task descriptors
159 boolean comma = false;
160 outtaskdefs.println("struct parameterwrapper ** objectqueues[][NUMCLASSES] = {");
161 boolean needcomma = false;
162 for(int i = 0; i < numqueues.length ; ++i) {
164 outtaskdefs.println(",");
168 outtaskdefs.println("/* object queue array for core " + i + "*/");
169 outtaskdefs.print("{");
171 for(int j = 0; j < numclasses; ++j) {
173 outtaskdefs.println(",");
177 outtaskdefs.print(this.objqarrayprefix + j + "_core" + i);
179 outtaskdefs.print("}");
181 outtaskdefs.println("};");
183 outtaskdefs.println("int numqueues[][NUMCLASSES] = {");
184 for(int i = 0; i < numqueues.length; ++i) {
186 outtaskdefs.println(",");
190 int[] tmparray = numqueues[i];
192 outtaskdefs.print("{");
193 for(int j = 0; j < tmparray.length; ++j) {
195 outtaskdefs.print(",");
199 outtaskdefs.print(tmparray[j]);
201 outtaskdefs.print("}");
203 outtaskdefs.println("};");
205 /* parameter queue arrays for all the tasks*/
206 outtaskdefs.println("struct parameterwrapper *** paramqueues[] = {");
208 for(int i = 0; i < this.coreNum ; ++i) {
210 outtaskdefs.println(",");
214 outtaskdefs.println("/* parameter queue array for core " + i + "*/");
215 outtaskdefs.print(this.coreqarrayprefix + i);
217 outtaskdefs.println("};");
219 for(int i = 0; i < taskits.length; ++i) {
220 outtaskdefs.println("struct taskdescriptor * " + this.taskarrayprefix + i + "[]={");
221 Iterator taskit = taskits[i];
224 while(taskit.hasNext()) {
225 TaskDescriptor td=(TaskDescriptor)taskit.next();
229 outtaskdefs.println(",");
230 outtaskdefs.print("&" + this.taskprefix +td.getCoreSafeSymbol(i));
233 outtaskdefs.println();
234 outtaskdefs.println("};");
236 outtaskdefs.println("struct taskdescriptor ** taskarray[]= {");
238 for(int i = 0; i < taskits.length; ++i) {
240 outtaskdefs.println(",");
243 outtaskdefs.print(this.taskarrayprefix + i);
245 outtaskdefs.println("};");
247 outtaskdefs.print("int numtasks[]= {");
249 for(int i = 0; i < taskits.length; ++i) {
251 outtaskdefs.print(",");
254 outtaskdefs.print(numtasks[i]);
256 outtaskdefs.println("};");
257 outtaskdefs.println("int corenum=0;");
260 outtask.println("#endif");
262 /* Record maximum number of task parameters */
263 outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
264 /* Record maximum number of all types, i.e. length of classsize[] */
265 outstructs.println("#define NUMTYPES "+(state.numClasses() + state.numArrays()));
266 /* Record number of cores */
267 outstructs.println("#define NUMCORES "+this.coreNum);
268 /* Record number of core containing startup task */
269 outstructs.println("#define STARTUPCORE "+this.startupcorenum);
270 //outstructs.println("#define STARTUPCORESTR \""+this.startupcorenum+"\"");
271 } //else if (state.main!=null) {
272 /* Generate main method */
273 // outputMainMethod(outmethod);
276 /* Generate information for task with optional parameters */
277 /*if (state.TASK&&state.OPTIONAL){
278 generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
279 outoptionalarrays.close();
282 /* Output structure definitions for repair tool */
283 /*if (state.structfile!=null) {
284 buildRepairStructs(outrepairstructs);
285 outrepairstructs.close();
289 outmethodheader.println("#endif");
290 outmethodheader.close();
292 outstructs.println("#endif");
296 /** This function outputs (1) structures that parameters are
297 * passed in (when PRECISE GC is enabled) and (2) function
298 * prototypes for the tasks */
300 private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
301 /* Cycle through tasks */
302 for(int i = 0; i < this.scheduling.size(); ++i) {
303 Schedule tmpschedule = this.scheduling.elementAt(i);
304 int num = tmpschedule.getCoreNum();
305 Iterator<TaskDescriptor> taskit = tmpschedule.getTasks().iterator();
307 while(taskit.hasNext()) {
308 /* Classify parameters */
309 TaskDescriptor task=taskit.next();
310 FlatMethod fm=state.getMethodFlat(task);
311 super.generateTempStructs(fm, null);
313 ParamsObject objectparams=(ParamsObject) paramstable.get(task);
314 TempObject objecttemps=(TempObject) tempstable.get(task);
316 /* Output parameter structure */
317 if (GENERATEPRECISEGC) {
318 output.println("struct "+task.getCoreSafeSymbol(num)+"_params {");
319 output.println(" int size;");
320 output.println(" void * next;");
321 for(int j=0;j<objectparams.numPointers();j++) {
322 TempDescriptor temp=objectparams.getPointer(j);
323 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
326 output.println("};\n");
327 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
328 maxtaskparams=objectparams.numPointers()+fm.numTags();
332 /* Output temp structure */
333 if (GENERATEPRECISEGC) {
334 output.println("struct "+task.getCoreSafeSymbol(num)+"_locals {");
335 output.println(" int size;");
336 output.println(" void * next;");
337 for(int j=0;j<objecttemps.numPointers();j++) {
338 TempDescriptor temp=objecttemps.getPointer(j);
339 if (temp.getType().isNull())
340 output.println(" void * "+temp.getSafeSymbol()+";");
341 else if(temp.getType().isTag())
342 output.println(" struct "+
343 (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
345 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
347 output.println("};\n");
350 /* Output task declaration */
351 headersout.print("void " + task.getCoreSafeSymbol(num)+"(");
353 if (GENERATEPRECISEGC) {
354 headersout.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
356 headersout.print("void * parameterarray[]");
357 headersout.println(");\n");
363 /* This method outputs code for each task. */
365 private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod, PrintWriter outtask, Iterator[] taskits, int[] numtasks,
367 /* Compile task based program */
368 outtaskdefs.println("#include \"task.h\"");
369 outtaskdefs.println("#include \"methodheaders.h\"");
371 /* Output object transfer queues into method.c*/
372 generateObjectTransQueues(outmethod);
374 //Vector[] qnames = new Vector[2];
375 int numclasses = numqueues[0].length;
376 Vector qnames[]= new Vector[numclasses];
377 for(int i = 0; i < qnames.length; ++i) {
380 Iterator<TaskDescriptor> taskit=this.currentSchedule.getTasks().iterator();
381 while(taskit.hasNext()) {
382 TaskDescriptor td=taskit.next();
383 FlatMethod fm=state.getMethodFlat(td);
384 generateTaskMethod(fm, null, outmethod);
385 generateTaskDescriptor(outtaskdefs, outtask, fm, td, qnames);
388 // generate queuearray for this core
389 int num = this.currentSchedule.getCoreNum();
390 boolean comma = false;
391 for(int i = 0; i < qnames.length; ++i) {
392 outtaskdefs.println("/* object queue array for class " + i + " on core " + num + "*/");
393 outtaskdefs.println("struct parameterwrapper * " + this.objqarrayprefix + i + "_core" + num + "[] = {");
395 Vector tmpvector = qnames[i];
396 if(tmpvector != null) {
397 for(int j = 0; j < tmpvector.size(); ++j) {
399 outtaskdefs.println(",");
403 outtaskdefs.print("&" + tmpvector.elementAt(j));
405 numqueues[num][i] = tmpvector.size();
407 numqueues[num][i] = 0;
409 outtaskdefs.println("};");
412 /* All the queues for tasks residing on this core*/
414 outtaskdefs.println("/* object queue array for tasks on core " + num + "*/");
415 outtaskdefs.println("struct parameterwrapper ** " + this.coreqarrayprefix + num + "[] = {");
416 taskit=this.currentSchedule.getTasks().iterator();
417 while(taskit.hasNext()) {
419 outtaskdefs.println(",");
423 TaskDescriptor td=taskit.next();
424 outtaskdefs.print(this.paramqarrayprefix + td.getCoreSafeSymbol(num));
426 outtaskdefs.println("};");
428 // record the iterator of tasks on this core
429 taskit=this.currentSchedule.getTasks().iterator();
430 taskits[num] = taskit;
431 numtasks[num] = this.currentSchedule.getTasks().size();
434 /** Prints out definitions for generic task structures */
435 private void outputTaskTypes(PrintWriter outtask) {
436 outtask.println("#ifndef _TASK_H");
437 outtask.println("#define _TASK_H");
438 outtask.println("#include \"ObjectHash.h\"");
439 outtask.println("#include \"structdefs.h\"");
440 outtask.println("#include \"Queue.h\"");
441 outtask.println("#include <string.h>");
442 outtask.println("#ifdef RAW");
443 outtask.println("#include <raw.h>");
444 outtask.println("#endif");
446 outtask.println("struct tagobjectiterator {");
447 outtask.println(" int istag; /* 0 if object iterator, 1 if tag iterator */");
448 outtask.println(" struct ObjectIterator it; /* Object iterator */");
449 outtask.println(" struct ObjectHash * objectset;");
450 outtask.println("#ifdef OPTIONAL");
451 outtask.println(" int failedstate;");
452 outtask.println("#endif");
453 outtask.println(" int slot;");
454 outtask.println(" int tagobjindex; /* Index for tag or object depending on use */");
455 outtask.println(" /*if tag we have an object binding */");
456 outtask.println(" int tagid;");
457 outtask.println(" int tagobjectslot;");
458 outtask.println(" /*if object, we may have one or more tag bindings */");
459 outtask.println(" int numtags;");
460 outtask.println(" int tagbindings[MAXTASKPARAMS-1]; /* list slots */");
461 outtask.println("};");
463 outtask.println("struct parameterwrapper {");
464 outtask.println(" //int type;");
465 outtask.println(" struct ObjectHash * objectset;");
466 outtask.println(" int numberofterms;");
467 outtask.println(" int * intarray;");
468 outtask.println(" int numbertags;");
469 outtask.println(" int * tagarray;");
470 outtask.println(" struct taskdescriptor * task;");
471 outtask.println(" int slot;");
472 outtask.println(" struct tagobjectiterator iterators[MAXTASKPARAMS-1];");
473 outtask.println("};");
475 outtask.println("extern struct parameterwrapper ** objectqueues[][NUMCLASSES];");
476 outtask.println("extern int numqueues[][NUMCLASSES];");
478 outtask.println("struct parameterdescriptor {");
479 outtask.println(" int type;");
480 outtask.println(" int numberterms;");
481 outtask.println(" int *intarray;");
482 outtask.println(" struct parameterwrapper * queue;");
483 outtask.println(" int numbertags;");
484 outtask.println(" int *tagarray;");
485 outtask.println("};");
487 outtask.println("struct taskdescriptor {");
488 outtask.println(" void * taskptr;");
489 outtask.println(" int numParameters;");
490 outtask.println(" int numTotal;");
491 outtask.println(" struct parameterdescriptor **descriptorarray;");
492 outtask.println(" char * name;");
493 outtask.println("};");
495 outtask.println("extern struct taskdescriptor ** taskarray[];");
496 outtask.println("extern int numtasks[];");
497 outtask.println("extern int corenum;"); // define corenum to identify different core
498 outtask.println("extern struct parameterwrapper *** paramqueues[];");
502 private void generateObjectTransQueues(PrintWriter output) {
503 if(this.fsate2qnames == null) {
504 this.fsate2qnames = new Hashtable[this.coreNum];
505 for(int i = 0; i < this.fsate2qnames.length; ++i) {
506 this.fsate2qnames[i] = null;
509 int num = this.currentSchedule.getCoreNum();
510 assert(this.fsate2qnames[num] == null);
511 Hashtable<FlagState, String> flag2qname = new Hashtable<FlagState, String>();
512 this.fsate2qnames[num] = flag2qname;
513 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
514 if(targetCoreTbl != null) {
515 Object[] keys = targetCoreTbl.keySet().toArray();
517 output.println("/* Object transfer queues for core" + num + ".*/");
518 for(int i = 0; i < keys.length; ++i) {
519 FlagState tmpfstate = (FlagState)keys[i];
520 Object[] targetcores = targetCoreTbl.get(tmpfstate).toArray();
521 String queuename = this.otqueueprefix + tmpfstate.getClassDescriptor().getCoreSafeSymbol(num) + tmpfstate.getuid() + "___";
522 String queueins = queuename + "ins";
523 flag2qname.put(tmpfstate, queuename);
524 output.println("struct " + queuename + " {");
525 output.println(" int * cores;");
526 output.println(" int index;");
527 output.println(" int length;");
528 output.println("};");
529 output.print("int " + queuename + "cores[] = {");
530 for(int j = 0; j < targetcores.length; ++j) {
534 output.print(((Integer)targetcores[j]).intValue());
536 output.println("};");
537 output.println("struct " + queuename + " " + queueins + "= {");
538 output.println(/*".cores = " + */queuename + "cores,");
539 output.println(/*".index = " + */"0,");
540 output.println(/*".length = " +*/ targetcores.length + "};");
546 private void generateTaskMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
547 /*if (State.PRINTFLAT)
548 System.out.println(fm.printMethod());*/
549 TaskDescriptor task=fm.getTask();
550 assert(task != null);
551 int num = this.currentSchedule.getCoreNum();
553 //ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:task);
554 generateTaskHeader(fm, lb, task,output);
555 TempObject objecttemp=(TempObject) tempstable.get(lb!=null?lb:task);
556 /*if (state.DSM&&lb.getHasAtomic()) {
557 output.println("transrecord_t * trans;");
560 if (GENERATEPRECISEGC) {
561 output.print(" struct "+task.getCoreSafeSymbol(num)+"_locals "+localsprefix+"={");
563 output.print(objecttemp.numPointers()+",");
564 output.print(paramsprefix);
565 for(int j=0;j<objecttemp.numPointers();j++)
566 output.print(", NULL");
567 output.println("};");
570 for(int i=0;i<objecttemp.numPrimitives();i++) {
571 TempDescriptor td=objecttemp.getPrimitive(i);
572 TypeDescriptor type=td.getType();
574 output.println(" void * "+td.getSafeSymbol()+";");
575 else if (type.isClass()||type.isArray())
576 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
578 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
581 for(int i = 0; i < fm.numParameters(); ++i) {
582 TempDescriptor temp = fm.getParameter(i);
583 output.println(" int "+generateTempFlagName(fm, temp, lb)+" = "+super.generateTemp(fm, temp, lb)+
587 /* Assign labels to FlatNode's if necessary.*/
589 Hashtable<FlatNode, Integer> nodetolabel=super.assignLabels(fm);
591 /* Check to see if we need to do a GC if this is a
592 * multi-threaded program...*/
594 /*if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) {
595 if (state.DSM&&lb.isAtomic())
596 output.println("checkcollect2(&"+localsprefix+",trans);");
598 output.println("checkcollect(&"+localsprefix+");");
601 /* Create queues to store objects need to be transferred to other cores and their destination*/
602 output.println(" struct Queue * totransobjqueue = createQueue();");
603 output.println(" struct transObjInfo * tmpObjInfo = NULL;");
605 /* generate print information for RAW version */
606 output.println("#ifdef RAW");
607 output.println("int tmpsum = 0;");
608 output.println("char * taskname = \"" + task.getSymbol() + "\";");
609 output.println("int tmplen = " + task.getSymbol().length() + ";");
610 output.println("int tmpindex = 1;");
611 output.println("for(;tmpindex < tmplen; tmpindex++) {");
612 output.println(" tmpsum = tmpsum * 10 + *(taskname + tmpindex) - '0';");
614 output.println("raw_test_pass(0xAAAA);");
615 output.println("raw_test_pass_reg(tmpsum);");
616 output.println("#endif");
618 for(int i = 0; i < fm.numParameters(); ++i) {
619 TempDescriptor temp = fm.getParameter(i);
620 output.println(" ++" + super.generateTemp(fm, temp, lb)+"->version;");
623 /* Do the actual code generation */
624 FlatNode current_node=null;
625 HashSet tovisit=new HashSet();
626 HashSet visited=new HashSet();
627 tovisit.add(fm.getNext(0));
628 while(current_node!=null||!tovisit.isEmpty()) {
629 if (current_node==null) {
630 current_node=(FlatNode)tovisit.iterator().next();
631 tovisit.remove(current_node);
633 visited.add(current_node);
634 if (nodetolabel.containsKey(current_node))
635 output.println("L"+nodetolabel.get(current_node)+":");
636 /*if (state.INSTRUCTIONFAILURE) {
637 if (state.THREAD||state.DSM) {
638 output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
641 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
643 if (current_node.numNext()==0) {
645 super.generateFlatNode(fm, lb, current_node, output);
646 if (current_node.kind()!=FKind.FlatReturnNode) {
647 output.println(" flushAll();");
648 outputTransCode(output);
649 output.println(" return;");
652 } else if(current_node.numNext()==1) {
654 super.generateFlatNode(fm, lb, current_node, output);
655 FlatNode nextnode=current_node.getNext(0);
656 if (visited.contains(nextnode)) {
657 output.println("goto L"+nodetolabel.get(nextnode)+";");
660 current_node=nextnode;
661 } else if (current_node.numNext()==2) {
664 super.generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
665 if (!visited.contains(current_node.getNext(1)))
666 tovisit.add(current_node.getNext(1));
667 if (visited.contains(current_node.getNext(0))) {
668 output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
671 current_node=current_node.getNext(0);
672 } else throw new Error();
675 output.println("}\n\n");
678 /** This method outputs TaskDescriptor information */
679 private void generateTaskDescriptor(PrintWriter output, PrintWriter outtask, FlatMethod fm, TaskDescriptor task, Vector[] qnames) {
680 int num = this.currentSchedule.getCoreNum();
682 output.println("/* TaskDescriptor information for task " + task.getSymbol() + " on core " + num + "*/");
684 for (int i=0;i<task.numParameters();i++) {
685 VarDescriptor param_var=task.getParameter(i);
686 TypeDescriptor param_type=task.getParamType(i);
687 FlagExpressionNode param_flag=task.getFlag(param_var);
688 TagExpressionList param_tag=task.getTag(param_var);
691 if (param_flag==null) {
692 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
693 output.println("0x0, 0x0 };");
696 DNFFlag dflag=param_flag.getDNF();
697 dnfterms=dflag.size();
699 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
700 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
701 for(int j=0;j<dflag.size();j++) {
704 Vector term=dflag.get(j);
707 for(int k=0;k<term.size();k++) {
708 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
709 FlagDescriptor fd=dfa.getFlag();
710 boolean negated=dfa.getNegated();
711 int flagid=1<<((Integer)flags.get(fd)).intValue();
716 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
718 output.println("};");
721 output.println("int parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
722 //BUG...added next line to fix, test with any task program
724 for(int j=0;j<param_tag.numTags();j++) {
727 /* for each tag we need */
728 /* which slot it is */
729 /* what type it is */
730 TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
731 TempDescriptor tmp=param_tag.getTemp(j);
732 int slot=fm.getTagInt(tmp);
733 output.println(slot+", "+state.getTagId(tvd.getTag()));
735 output.println("};");
737 // generate object queue for this parameter
738 String qname = this.objqueueprefix+i+"_"+task.getCoreSafeSymbol(num);
739 if(param_type.getClassDesc().getSymbol().equals("StartupObject")) {
740 this.startupcorenum = num;
742 if(qnames[param_type.getClassDesc().getId()] == null) {
743 qnames[param_type.getClassDesc().getId()] = new Vector();
745 qnames[param_type.getClassDesc().getId()].addElement(qname);
746 outtask.println("extern struct parameterwrapper " + qname + ";");
747 output.println("struct parameterwrapper " + qname + "={");
748 output.println(".objectset = 0,"); // objectset
749 output.println("/* number of DNF terms */ .numberofterms = "+dnfterms+","); // numberofterms
750 output.println(".intarray = parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
753 output.println("/* number of tags */ .numbertags = "+param_tag.numTags()+",");
755 output.println("/* number of tags */ .numbertags = 0,");
756 output.println(".tagarray = parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+","); // tagarray
757 output.println(".task = 0,"); // task
758 output.println(".slot = " + i + ",");// slot
760 output.println("};");
762 output.println("struct parameterdescriptor parameter_"+i+"_"+task.getCoreSafeSymbol(num)+"={");
763 output.println("/* type */"+param_type.getClassDesc().getId()+",");
764 output.println("/* number of DNF terms */"+dnfterms+",");
765 output.println("parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
766 output.println("&" + qname + ","); // queue
767 //BUG, added next line to fix and else statement...test
768 //with any task program
770 output.println("/* number of tags */"+param_tag.numTags()+",");
772 output.println("/* number of tags */ 0,");
773 output.println("parametertag_"+i+"_"+task.getCoreSafeSymbol(num)); // tagarray
774 output.println("};");
777 /* parameter queues for this task*/
778 output.println("struct parameterwrapper * " + this.paramqarrayprefix + task.getCoreSafeSymbol(num)+"[] = {");
779 for (int i=0;i<task.numParameters();i++) {
782 output.print("&" + this.objqueueprefix + i + "_" + task.getCoreSafeSymbol(num));
784 output.println("};");
786 output.println("struct parameterdescriptor * parameterdescriptors_"+task.getCoreSafeSymbol(num)+"[] = {");
787 for (int i=0;i<task.numParameters();i++) {
790 output.print("¶meter_"+i+"_"+task.getCoreSafeSymbol(num));
792 output.println("};");
794 output.println("struct taskdescriptor " + this.taskprefix + task.getCoreSafeSymbol(num) + "={");
795 output.println("&"+task.getCoreSafeSymbol(num)+",");
796 output.println("/* number of parameters */" +task.numParameters() + ",");
797 int numtotal=task.numParameters()+fm.numTags();
798 output.println("/* number total parameters */" +numtotal + ",");
799 output.println("parameterdescriptors_"+task.getCoreSafeSymbol(num)+",");
800 output.println("\""+task.getSymbol()+"\"");
801 output.println("};");
806 /** This method generates header information for the task
807 * referenced by the Descriptor des. */
809 private void generateTaskHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
811 ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:des);
812 TaskDescriptor task=(TaskDescriptor) des;
814 int num = this.currentSchedule.getCoreNum();
815 //catch the constructor case
816 output.print("void ");
817 output.print(task.getCoreSafeSymbol(num)+"(");
819 boolean printcomma=false;
820 if (GENERATEPRECISEGC) {
821 output.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
825 /*if (state.DSM&&lb.isAtomic()) {
828 output.print("transrecord_t * trans");
832 if (!GENERATEPRECISEGC) {
834 output.println("void * parameterarray[]) {");
835 /* Unpack variables */
836 for(int i=0;i<objectparams.numPrimitives();i++) {
837 TempDescriptor temp=objectparams.getPrimitive(i);
838 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
840 for(int i=0;i<fm.numTags();i++) {
841 TempDescriptor temp=fm.getTag(i);
842 int offset=i+objectparams.numPrimitives();
843 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+i+"___=parameterarray["+offset+"];");// add i to fix bugs of duplicate definition of tags
846 if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
847 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
848 } else output.println(") {");
851 protected void generateFlagOrAnd(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp,
852 PrintWriter output, int ormask, int andmask) {
853 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
854 output.println("flagorandinit("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
856 int num = this.currentSchedule.getCoreNum();
857 ClassDescriptor cd = temp.getType().getClassDesc();
858 Vector<FlagState> initfstates = ffan.getInitFStates(cd);
859 for(int i = 0; i < initfstates.size(); ++i) {
860 FlagState tmpFState = initfstates.elementAt(i);
862 QueueInfo qinfo = outputqueues(tmpFState, num, output, false);
863 output.println("flagorand("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+
864 ", 0x"+Integer.toHexString(andmask)+", " + qinfo.qname +
865 ", " + qinfo.length + ");");
871 protected void generateObjectDistribute(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp,
872 PrintWriter output) {
873 ClassDescriptor cd = temp.getType().getClassDesc();
874 Vector<FlagState> initfstates = null;
875 Vector[] targetFStates = null;
876 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
877 targetFStates = new Vector[1];
878 targetFStates[0] = ffan.getTargetFStates4NewObj(cd);
880 initfstates = ffan.getInitFStates(cd);
881 targetFStates = new Vector[initfstates.size()];
882 for(int i = 0; i < initfstates.size(); ++i) {
883 FlagState fs = initfstates.elementAt(i);
884 targetFStates[i] = ffan.getTargetFStates(fs);
886 if(!fs.isSetmask()) {
887 Hashtable flags=(Hashtable)flagorder.get(cd);
890 Iterator it_flags = fs.getFlags();
891 while(it_flags.hasNext()) {
892 FlagDescriptor fd = (FlagDescriptor)it_flags.next();
893 int flagid=1<<((Integer)flags.get(fd)).intValue();
897 fs.setAndmask(andmask);
898 fs.setCheckmask(checkmask);
903 boolean isolate = true; // check if this flagstate can associate to some task with multiple params which can
904 // reside on multiple cores
905 if((this.currentSchedule == null) && (fm.getMethod().getClassDesc().getSymbol().equals("ServerSocket"))) {
906 // ServerSocket object will always reside on current core
907 for(int j = 0; j < targetFStates.length; ++j) {
908 if(initfstates != null) {
909 FlagState fs = initfstates.elementAt(j);
910 output.println("if(" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
911 + ")==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
913 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
914 for(int i = 0; i < tmpfstates.size(); ++i) {
915 FlagState tmpFState = tmpfstates.elementAt(i);
917 // may have bugs here
918 output.println("/* reside on this core*");
919 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
921 if(initfstates != null) {
928 int num = this.currentSchedule.getCoreNum();
929 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
930 for(int j = 0; j < targetFStates.length; ++j) {
932 if(initfstates != null) {
933 fs = initfstates.elementAt(j);
934 output.println("if((" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
935 + "))==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
937 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
938 for(int i = 0; i < tmpfstates.size(); ++i) {
939 FlagState tmpFState = tmpfstates.elementAt(i);
941 if(this.currentSchedule.getAllyCoreTable() == null) {
944 isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) ||
945 (this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
948 // indentify this object as a shared object
949 // isolate flag is initially set as 1, once this flag is set as 0, it is never reset to 1, i.e. once an object
950 // is shared, it maybe shared all the time afterwards
951 output.println("if(" + super.generateTemp(fm, temp, lb) + "->isolate == 1) {");
952 output.println(" " + super.generateTemp(fm, temp, lb) + "->isolate = 0;");
953 output.println(" " + super.generateTemp(fm, temp, lb) + "->original = (struct ___Object___ *)" + super.generateTemp(fm, temp, lb) + ";");
957 Vector<Integer> sendto = new Vector<Integer>();
958 Queue<Integer> queue = null;
959 if(targetCoreTbl != null) {
960 queue = targetCoreTbl.get(tmpFState);
962 if((queue != null) &&
963 ((queue.size() != 1) ||
964 ((queue.size() == 1) && (queue.element().intValue() != num)))) {
965 // this object may be transferred to other cores
966 String queuename = (String)this.fsate2qnames[num].get(tmpFState);
967 String queueins = queuename + "ins";
969 Object[] cores = queue.toArray();
971 Integer targetcore = (Integer)cores[0];
972 if(queue.size() > 1) {
973 index = queueins + ".index";
975 if(queue.size() > 1) {
976 output.println("switch(" + queueins + ".index % " + queueins + ".length) {");
977 for(int k = 0; k < cores.length; ++k) {
978 output.println("case " + k + ":");
979 targetcore = (Integer)cores[k];
980 if(targetcore.intValue() == num) {
981 output.println("/* reside on this core*/");
984 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
985 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
986 ", " + qinfo.length + ");");
991 output.println("/* possibly needed by multi-parameter tasks on this core*/");
992 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
997 // Is it possible to decide the actual queues?
998 output.println("/* possibly needed by multi-parameter tasks on this core*/");
999 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1001 output.println("/* transfer to core " + targetcore.toString() + "*/");
1002 output.println("{");
1003 // enqueue this object and its destinations for later process
1004 // all the possible queues
1005 QueueInfo qinfo = null;
1006 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1007 if(targetFS != null) {
1008 qinfo = outputtransqueues(targetFS, targetcore, output);
1010 qinfo = outputtransqueues(tmpFState, targetcore, output);
1012 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1013 output.println("tmpObjInfo->objptr = (void *)" + super.generateTemp(fm, temp, lb) + ";");
1014 output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1015 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1016 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1017 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1018 output.println("}");
1019 sendto.add(targetcore);
1021 output.println("break;");
1023 output.println("}");
1027 // Is it possible to decide the actual queues?
1028 output.println("/* possibly needed by multi-parameter tasks on this core*/");
1029 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1031 output.println("/* transfer to core " + targetcore.toString() + "*/");
1032 output.println("{");
1033 // enqueue this object and its destinations for later process
1034 // all the possible queues
1035 QueueInfo qinfo = null;
1036 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1037 if(targetFS != null) {
1038 qinfo = outputtransqueues(targetFS, targetcore, output);
1040 qinfo = outputtransqueues(tmpFState, targetcore, output);
1042 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1043 output.println("tmpObjInfo->objptr = (void *)" + super.generateTemp(fm, temp, lb) + ";");
1044 output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1045 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1046 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1047 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1048 output.println("}");
1049 sendto.add(targetcore);
1051 output.println("/* increase index*/");
1052 output.println("++" + queueins + ".index;");
1054 // this object will reside on current core
1055 output.println("/* reside on this core*/");
1057 output.println("{");
1058 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1059 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1060 ", " + qinfo.length + ");");
1061 output.println("}");
1065 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1069 // codes for multi-params tasks
1071 // flagstate associated with some multi-params tasks
1072 // need to be send to other cores
1073 Vector<Integer> targetcores = this.currentSchedule.getAllyCores(tmpFState);
1074 output.println("/* send the shared object to possible queues on other cores*/");
1075 for(int k = 0; k < targetcores.size(); ++k) {
1077 // add the information of exactly which queue
1078 if(!sendto.contains(targetcores.elementAt(i))) {
1079 // previously not sended to this target core
1080 // enqueue this object and its destinations for later process
1081 output.println("{");
1082 // all the possible queues
1083 QueueInfo qinfo = null;
1084 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1085 if(targetFS != null) {
1086 qinfo = outputtransqueues(targetFS, targetcores.elementAt(i), output);
1088 qinfo = outputtransqueues(tmpFState, targetcores.elementAt(i), output);
1090 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1091 output.println("tmpObjInfo->objptr = (void *)" + super.generateTemp(fm, temp, lb) + ";");
1092 output.println("tmpObjInfo->targetcore = "+targetcores.elementAt(i).toString()+";");
1093 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1094 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1095 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1096 output.println("}");
1102 if(initfstates != null) {
1103 output.println("}");
1108 private QueueInfo outputqueues(FlagState tmpFState, int num, PrintWriter output, boolean isEnqueue) {
1110 QueueInfo qinfo = new QueueInfo();
1111 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1112 output.println("struct parameterwrapper * " + qinfo.qname + "[] = {");
1113 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1114 Vector<TaskDescriptor> residetasks = this.currentSchedule.getTasks();
1115 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1116 Vector<Integer> indexes = new Vector<Integer>();
1117 boolean comma = false;
1119 while(it_edges.hasNext()) {
1120 FEdge fe = (FEdge)it_edges.next();
1121 TaskDescriptor td = fe.getTask();
1122 int paraindex = fe.getIndex();
1123 if((!isEnqueue) || (isEnqueue && residetasks.contains(td))) {
1124 if((!tasks.contains(td)) ||
1125 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1126 tasks.addElement(td);
1127 indexes.addElement(paraindex);
1129 output.println(",");
1133 output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
1138 output.println("};");
1142 private QueueInfo outputtransqueues(FlagState tmpFState, int targetcore, PrintWriter output) {
1144 QueueInfo qinfo = new QueueInfo();
1145 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1146 output.println("int " + qinfo.qname + "_clone[] = {");
1147 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1148 Vector<TaskDescriptor> residetasks = this.scheduling.get(targetcore).getTasks();
1149 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1150 Vector<Integer> indexes = new Vector<Integer>();
1151 boolean comma = false;
1153 while(it_edges.hasNext()) {
1154 FEdge fe = (FEdge)it_edges.next();
1155 TaskDescriptor td = fe.getTask();
1156 int paraindex = fe.getIndex();
1157 if(residetasks.contains(td)) {
1158 if((!tasks.contains(td)) ||
1159 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1160 tasks.addElement(td);
1161 indexes.addElement(paraindex);
1163 output.println(",");
1167 output.print(residetasks.indexOf(td) + ", ");
1168 output.print(paraindex);
1173 output.println("};");
1174 output.println("int * " + qinfo.qname + " = RUNMALLOC(sizeof(int) * " + qinfo.length * 2 + ");");
1175 output.println("memcpy(" + qinfo.qname + ", (int *)" + qinfo.qname + "_clone, sizeof(int) * " + qinfo.length * 2 + ");");
1179 private class QueueInfo {
1181 public String qname;
1184 private String generateTempFlagName(FlatMethod fm, TempDescriptor td, LocalityBinding lb) {
1185 MethodDescriptor md=fm.getMethod();
1186 TaskDescriptor task=fm.getTask();
1187 TempObject objecttemps=(TempObject) tempstable.get(lb!=null?lb:md!=null?md:task);
1189 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1190 return td.getSafeSymbol() + "_oldflag";
1193 if (objecttemps.isLocalPtr(td)) {
1194 return localsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1197 if (objecttemps.isParamPtr(td)) {
1198 return paramsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1203 protected void outputTransCode(PrintWriter output) {
1204 output.println("while(0 == isEmpty(totransobjqueue)) {");
1205 output.println(" struct QueueItem * totransitem = getTail(totransobjqueue);");
1207 output.println(" transferObject((struct transObjInfo *)totransitem->objectptr);");
1208 output.println(" RUNFREE(((struct transObjInfo *)totransitem->objectptr)->queues);");
1209 output.println(" RUNFREE(totransitem->objectptr);");
1210 output.println(" removeItem(totransobjqueue, totransitem);");
1211 output.println("}");
1212 output.println("freeQueue(totransobjqueue);");
1215 protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
1216 if (frn.getReturnTemp()!=null) {
1217 if (frn.getReturnTemp().getType().isPtr())
1218 output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1220 output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1222 if(fm.getTask() != null) {
1223 output.println("flushAll();");
1224 outputTransCode(output);
1226 output.println("return;");