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.LinkedList;
9 import java.util.Queue;
11 import java.util.Vector;
13 import Analysis.Locality.LocalityBinding;
14 import Analysis.Scheduling.Schedule;
15 import Analysis.TaskStateAnalysis.FEdge;
16 import Analysis.TaskStateAnalysis.FlagState;
17 import Analysis.TaskStateAnalysis.SafetyAnalysis;
18 import Analysis.OwnershipAnalysis.AllocationSite;
19 import Analysis.OwnershipAnalysis.OwnershipAnalysis;
20 import Analysis.OwnershipAnalysis.HeapRegionNode;
21 import Analysis.Prefetch.*;
22 import IR.ClassDescriptor;
24 import IR.FlagDescriptor;
25 import IR.MethodDescriptor;
27 import IR.TagVarDescriptor;
28 import IR.TaskDescriptor;
29 import IR.TypeDescriptor;
31 import IR.VarDescriptor;
32 import IR.Tree.DNFFlag;
33 import IR.Tree.DNFFlagAtom;
34 import IR.Tree.FlagExpressionNode;
35 import IR.Tree.TagExpressionList;
37 public class BuildCodeMultiCore extends BuildCode {
38 private Vector<Schedule> scheduling;
42 Schedule currentSchedule;
43 Hashtable[] fsate2qnames;
44 String objqarrayprefix= "objqueuearray4class";
45 String objqueueprefix = "objqueue4parameter_";
46 String paramqarrayprefix = "paramqueuearray4task";
47 String coreqarrayprefix = "paramqueuearrays_core";
48 String taskprefix = "task_";
49 String taskarrayprefix = "taskarray_core";
50 String otqueueprefix = "___otqueue";
51 int startupcorenum; // record the core containing startup task, suppose only one core can hava startup object
53 private OwnershipAnalysis m_oa;
54 private Vector<Vector<Integer>> m_aliasSets;
55 Hashtable<Integer, Vector<FlatNew>> m_aliasFNTbl4Para;
56 Hashtable<FlatNew, Vector<FlatNew>> m_aliasFNTbl;
57 Hashtable<FlatNew, Vector<Integer>> m_aliaslocksTbl4FN;
59 public BuildCodeMultiCore(State st,
63 Vector<Schedule> scheduling,
66 PrefetchAnalysis pa) {
67 super(st, temptovar, typeutil, sa, pa);
68 this.scheduling = scheduling;
69 this.coreNum = coreNum; // # of the active cores
70 this.tcoreNum = coreNum; // # of the cores setup by users
71 this.gcoreNum = gcoreNum; // # of the cores for gc if any
72 this.currentSchedule = null;
73 this.fsate2qnames = null;
74 this.startupcorenum = 0;
76 // sometimes there are extra cores then needed in scheduling
78 // currently, it is guaranteed that in scheduling, the corenum
79 // is started from 0 and continuous.
80 // MAY need modification here in the future when take hardware
81 // information into account.
82 if(this.scheduling.size() < this.coreNum) {
83 this.coreNum = this.scheduling.size();
87 this.m_aliasSets = null;
88 this.m_aliasFNTbl4Para = null;
89 this.m_aliasFNTbl = null;
90 this.m_aliaslocksTbl4FN = null;
93 public void setOwnershipAnalysis(OwnershipAnalysis m_oa) {
97 public void buildCode() {
98 /* Create output streams to write to */
99 PrintWriter outclassdefs=null;
100 PrintWriter outglobaldefs=null;
101 PrintWriter outstructs=null;
102 PrintWriter outmethodheader=null;
103 PrintWriter outmethod=null;
104 PrintWriter outvirtual=null;
105 PrintWriter outtask=null;
106 PrintWriter outtaskdefs=null;
107 //PrintWriter outoptionalarrays=null;
108 //PrintWriter optionalheaders=null;
111 outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
112 outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
113 outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
114 outglobaldefs=new PrintWriter(new FileOutputStream(PREFIX+"globaldefs.h"), true);
115 outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
116 outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
118 outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
119 outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
122 outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
123 optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
126 /*if (state.structfile!=null) {
127 outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
129 } catch (Exception e) {
134 /* Build the virtual dispatch tables */
135 super.buildVirtualTables(outvirtual);
137 /* Output includes */
138 outmethodheader.println("#ifndef METHODHEADERS_H");
139 outmethodheader.println("#define METHODHEADERS_H");
140 outmethodheader.println("#include \"structdefs.h\"");
142 outmethodheader.println("#include \"dstm.h\"");*/
144 /* Output Structures */
145 super.outputStructs(outstructs);
147 // Output the C class declarations
148 // These could mutually reference each other
149 outclassdefs.println("#ifndef __CLASSDEF_H_");
150 outclassdefs.println("#define __CLASSDEF_H_");
151 super.outputClassDeclarations(outclassdefs, outglobaldefs);
153 // Output function prototypes and structures for parameters
154 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
155 int numclasses = this.state.numClasses();
156 while(it.hasNext()) {
157 ClassDescriptor cn=(ClassDescriptor)it.next();
158 super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs);
160 outclassdefs.println("#endif");
161 outclassdefs.close();
164 /* Map flags to integers */
165 /* The runtime keeps track of flags using these integers */
166 it=state.getClassSymbolTable().getDescriptorsIterator();
167 while(it.hasNext()) {
168 ClassDescriptor cn=(ClassDescriptor)it.next();
172 generateTaskStructs(outstructs, outmethodheader);
174 /* Outputs generic task structures if this is a task
176 outputTaskTypes(outtask);
179 /* Build the actual methods */
180 super.outputMethods(outmethod);
183 Iterator[] taskits = new Iterator[this.coreNum];
184 for(int i = 0; i < taskits.length; ++i) {
187 int[] numtasks = new int[this.coreNum];
188 int[][] numqueues = new int[this.coreNum][numclasses];
189 /* Output code for tasks */
190 for(int i = 0; i < this.scheduling.size(); ++i) {
191 this.currentSchedule = this.scheduling.elementAt(i);
192 outputTaskCode(outtaskdefs, outmethod, outtask, taskits, numtasks, numqueues);
195 // Output task descriptors
196 boolean comma = false;
197 outtaskdefs.println("struct parameterwrapper ** objectqueues[][NUMCLASSES] = {");
198 boolean needcomma = false;
199 for(int i = 0; i < numqueues.length ; ++i) {
201 outtaskdefs.println(",");
205 outtaskdefs.println("/* object queue array for core " + i + "*/");
206 outtaskdefs.print("{");
208 for(int j = 0; j < numclasses; ++j) {
210 outtaskdefs.println(",");
214 outtaskdefs.print(this.objqarrayprefix + j + "_core" + i);
216 outtaskdefs.print("}");
218 outtaskdefs.println("};");
220 outtaskdefs.println("int numqueues[][NUMCLASSES] = {");
221 for(int i = 0; i < numqueues.length; ++i) {
223 outtaskdefs.println(",");
227 int[] tmparray = numqueues[i];
229 outtaskdefs.print("{");
230 for(int j = 0; j < tmparray.length; ++j) {
232 outtaskdefs.print(",");
236 outtaskdefs.print(tmparray[j]);
238 outtaskdefs.print("}");
240 outtaskdefs.println("};");
242 /* parameter queue arrays for all the tasks*/
243 outtaskdefs.println("struct parameterwrapper *** paramqueues[] = {");
245 for(int i = 0; i < this.coreNum ; ++i) {
247 outtaskdefs.println(",");
251 outtaskdefs.println("/* parameter queue array for core " + i + "*/");
252 outtaskdefs.print(this.coreqarrayprefix + i);
254 outtaskdefs.println("};");
256 for(int i = 0; i < taskits.length; ++i) {
257 outtaskdefs.println("struct taskdescriptor * " + this.taskarrayprefix + i + "[]={");
258 Iterator taskit = taskits[i];
261 while(taskit.hasNext()) {
262 TaskDescriptor td=(TaskDescriptor)taskit.next();
266 outtaskdefs.println(",");
267 outtaskdefs.print("&" + this.taskprefix +td.getCoreSafeSymbol(i));
270 outtaskdefs.println();
271 outtaskdefs.println("};");
273 outtaskdefs.println("struct taskdescriptor ** taskarray[]= {");
275 for(int i = 0; i < taskits.length; ++i) {
277 outtaskdefs.println(",");
280 outtaskdefs.print(this.taskarrayprefix + i);
282 outtaskdefs.println("};");
284 outtaskdefs.print("int numtasks[]= {");
286 for(int i = 0; i < taskits.length; ++i) {
288 outtaskdefs.print(",");
291 outtaskdefs.print(numtasks[i]);
293 outtaskdefs.println("};");
294 outtaskdefs.println("int corenum=0;");
297 outtask.println("#endif");
299 /* Record maximum number of task parameters */
300 outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
301 /* Record maximum number of all types, i.e. length of classsize[] */
302 outstructs.println("#define NUMTYPES "+(state.numClasses() + state.numArrays()));
303 /* Record number of total cores */
304 outstructs.println("#define NUMCORES "+this.tcoreNum);
305 /* Record number of active cores */
306 outstructs.println("#define NUMCORESACTIVE "+this.coreNum); // this.coreNum
307 // can be reset by the scheduling analysis
308 /* Record number of garbage collection cores */
309 outstructs.println("#ifdef MULTICORE_GC");
310 outstructs.println("#define NUMCORES4GC "+this.gcoreNum);
311 outstructs.println("#endif");
312 /* Record number of core containing startup task */
313 outstructs.println("#define STARTUPCORE "+this.startupcorenum);
314 } //else if (state.main!=null) {
315 /* Generate main method */
316 // outputMainMethod(outmethod);
319 /* Generate information for task with optional parameters */
320 /*if (state.TASK&&state.OPTIONAL){
321 generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
322 outoptionalarrays.close();
325 /* Output structure definitions for repair tool */
326 /*if (state.structfile!=null) {
327 buildRepairStructs(outrepairstructs);
328 outrepairstructs.close();
332 outmethodheader.println("#endif");
333 outmethodheader.close();
335 outstructs.println("#endif");
339 /** This function outputs (1) structures that parameters are
340 * passed in (when PRECISE GC is enabled) and (2) function
341 * prototypes for the tasks */
343 private void generateTaskStructs(PrintWriter output,
344 PrintWriter headersout) {
345 /* Cycle through tasks */
346 for(int i = 0; i < this.scheduling.size(); ++i) {
347 Schedule tmpschedule = this.scheduling.elementAt(i);
348 int num = tmpschedule.getCoreNum();
349 Iterator<TaskDescriptor> taskit = tmpschedule.getTasks().iterator();
351 while(taskit.hasNext()) {
352 /* Classify parameters */
353 TaskDescriptor task=taskit.next();
354 FlatMethod fm=state.getMethodFlat(task);
355 super.generateTempStructs(fm, null);
357 ParamsObject objectparams=(ParamsObject) paramstable.get(task);
358 TempObject objecttemps=(TempObject) tempstable.get(task);
360 /* Output parameter structure */
361 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
362 output.println("struct "+task.getCoreSafeSymbol(num)+"_params {");
363 output.println(" int size;");
364 output.println(" void * next;");
365 for(int j=0; j<objectparams.numPointers(); j++) {
366 TempDescriptor temp=objectparams.getPointer(j);
367 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
370 output.println("};\n");
371 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
372 maxtaskparams=objectparams.numPointers()+fm.numTags();
376 /* Output temp structure */
377 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
378 output.println("struct "+task.getCoreSafeSymbol(num)+"_locals {");
379 output.println(" int size;");
380 output.println(" void * next;");
381 for(int j=0; j<objecttemps.numPointers(); j++) {
382 TempDescriptor temp=objecttemps.getPointer(j);
383 if (temp.getType().isNull())
384 output.println(" void * "+temp.getSafeSymbol()+";");
385 else if(temp.getType().isTag())
386 output.println(" struct "+
387 (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
389 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
391 output.println("};\n");
394 /* Output task declaration */
395 headersout.print("void " + task.getCoreSafeSymbol(num)+"(");
397 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
398 headersout.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
400 headersout.print("void * parameterarray[]");
401 headersout.println(");\n");
407 /* This method outputs code for each task. */
409 private void outputTaskCode(PrintWriter outtaskdefs,
410 PrintWriter outmethod,
415 /* Compile task based program */
416 outtaskdefs.println("#include \"task.h\"");
417 outtaskdefs.println("#include \"methodheaders.h\"");
419 /* Output object transfer queues into method.c*/
420 generateObjectTransQueues(outmethod);
422 //Vector[] qnames = new Vector[2];
423 int numclasses = numqueues[0].length;
424 Vector qnames[]= new Vector[numclasses];
425 for(int i = 0; i < qnames.length; ++i) {
428 Iterator<TaskDescriptor> taskit=this.currentSchedule.getTasks().iterator();
429 while(taskit.hasNext()) {
430 TaskDescriptor td=taskit.next();
431 FlatMethod fm=state.getMethodFlat(td);
432 generateTaskMethod(fm, null, outmethod);
433 generateTaskDescriptor(outtaskdefs, outtask, fm, td, qnames);
436 // generate queuearray for this core
437 int num = this.currentSchedule.getCoreNum();
438 boolean comma = false;
439 for(int i = 0; i < qnames.length; ++i) {
440 outtaskdefs.println("/* object queue array for class " + i + " on core " + num + "*/");
441 outtaskdefs.println("struct parameterwrapper * " + this.objqarrayprefix + i + "_core" + num + "[] = {");
443 Vector tmpvector = qnames[i];
444 if(tmpvector != null) {
445 for(int j = 0; j < tmpvector.size(); ++j) {
447 outtaskdefs.println(",");
451 outtaskdefs.print("&" + tmpvector.elementAt(j));
453 numqueues[num][i] = tmpvector.size();
455 numqueues[num][i] = 0;
457 outtaskdefs.println("};");
460 /* All the queues for tasks residing on this core*/
462 outtaskdefs.println("/* object queue array for tasks on core " + num + "*/");
463 outtaskdefs.println("struct parameterwrapper ** " + this.coreqarrayprefix + num + "[] = {");
464 taskit=this.currentSchedule.getTasks().iterator();
465 while(taskit.hasNext()) {
467 outtaskdefs.println(",");
471 TaskDescriptor td=taskit.next();
472 outtaskdefs.print(this.paramqarrayprefix + td.getCoreSafeSymbol(num));
474 outtaskdefs.println("};");
476 // record the iterator of tasks on this core
477 taskit=this.currentSchedule.getTasks().iterator();
478 taskits[num] = taskit;
479 numtasks[num] = this.currentSchedule.getTasks().size();
482 /** Prints out definitions for generic task structures */
483 private void outputTaskTypes(PrintWriter outtask) {
484 outtask.println("#ifndef _TASK_H");
485 outtask.println("#define _TASK_H");
486 outtask.println("#include \"ObjectHash.h\"");
487 outtask.println("#include \"structdefs.h\"");
488 outtask.println("#include \"Queue.h\"");
489 outtask.println("#include <string.h>");
490 outtask.println("#include \"runtime_arch.h\"");
491 //outtask.println("#ifdef RAW");
492 //outtask.println("#include <raw.h>");
493 //outtask.println("#endif");
495 outtask.println("struct tagobjectiterator {");
496 outtask.println(" int istag; /* 0 if object iterator, 1 if tag iterator */");
497 outtask.println(" struct ObjectIterator it; /* Object iterator */");
498 outtask.println(" struct ObjectHash * objectset;");
499 outtask.println("#ifdef OPTIONAL");
500 outtask.println(" int failedstate;");
501 outtask.println("#endif");
502 outtask.println(" int slot;");
503 outtask.println(" int tagobjindex; /* Index for tag or object depending on use */");
504 outtask.println(" /*if tag we have an object binding */");
505 outtask.println(" int tagid;");
506 outtask.println(" int tagobjectslot;");
507 outtask.println(" /*if object, we may have one or more tag bindings */");
508 outtask.println(" int numtags;");
509 outtask.println(" int tagbindings[MAXTASKPARAMS-1]; /* list slots */");
510 outtask.println("};");
512 outtask.println("struct parameterwrapper {");
513 outtask.println(" //int type;");
514 outtask.println(" struct ObjectHash * objectset;");
515 outtask.println(" int numberofterms;");
516 outtask.println(" int * intarray;");
517 outtask.println(" int numbertags;");
518 outtask.println(" int * tagarray;");
519 outtask.println(" struct taskdescriptor * task;");
520 outtask.println(" int slot;");
521 outtask.println(" struct tagobjectiterator iterators[MAXTASKPARAMS-1];");
522 outtask.println("};");
524 outtask.println("extern struct parameterwrapper ** objectqueues[][NUMCLASSES];");
525 outtask.println("extern int numqueues[][NUMCLASSES];");
527 outtask.println("struct parameterdescriptor {");
528 outtask.println(" int type;");
529 outtask.println(" int numberterms;");
530 outtask.println(" int *intarray;");
531 outtask.println(" struct parameterwrapper * queue;");
532 outtask.println(" int numbertags;");
533 outtask.println(" int *tagarray;");
534 outtask.println("};");
536 outtask.println("struct taskdescriptor {");
537 outtask.println(" void * taskptr;");
538 outtask.println(" int numParameters;");
539 outtask.println(" int numTotal;");
540 outtask.println(" struct parameterdescriptor **descriptorarray;");
541 outtask.println(" char * name;");
542 outtask.println("};");
544 outtask.println("extern struct taskdescriptor ** taskarray[];");
545 outtask.println("extern int numtasks[];");
546 outtask.println("extern int corenum;"); // define corenum to identify different core
547 outtask.println("extern struct parameterwrapper *** paramqueues[];");
551 private void generateObjectTransQueues(PrintWriter output) {
552 if(this.fsate2qnames == null) {
553 this.fsate2qnames = new Hashtable[this.coreNum];
554 for(int i = 0; i < this.fsate2qnames.length; ++i) {
555 this.fsate2qnames[i] = null;
558 int num = this.currentSchedule.getCoreNum();
559 assert(this.fsate2qnames[num] == null);
560 Hashtable<FlagState, String> flag2qname = new Hashtable<FlagState, String>();
561 this.fsate2qnames[num] = flag2qname;
562 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
563 if(targetCoreTbl != null) {
564 Object[] keys = targetCoreTbl.keySet().toArray();
566 output.println("/* Object transfer queues for core" + num + ".*/");
567 for(int i = 0; i < keys.length; ++i) {
568 FlagState tmpfstate = (FlagState)keys[i];
569 Object[] targetcores = targetCoreTbl.get(tmpfstate).toArray();
570 String queuename = this.otqueueprefix + tmpfstate.getClassDescriptor().getCoreSafeSymbol(num) + tmpfstate.getuid() + "___";
571 String queueins = queuename + "ins";
572 flag2qname.put(tmpfstate, queuename);
573 output.println("struct " + queuename + " {");
574 output.println(" int * cores;");
575 output.println(" int index;");
576 output.println(" int length;");
577 output.println("};");
578 output.print("int " + queuename + "cores[] = {");
579 for(int j = 0; j < targetcores.length; ++j) {
583 output.print(((Integer)targetcores[j]).intValue());
585 output.println("};");
586 output.println("struct " + queuename + " " + queueins + "= {");
587 output.println(/*".cores = " + */ queuename + "cores,");
588 output.println(/*".index = " + */ "0,");
589 output.println(/*".length = " +*/ targetcores.length + "};");
595 private void generateTaskMethod(FlatMethod fm,
597 PrintWriter output) {
598 /*if (State.PRINTFLAT)
599 System.out.println(fm.printMethod());*/
600 TaskDescriptor task=fm.getTask();
601 assert(task != null);
602 int num = this.currentSchedule.getCoreNum();
604 //ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:task);
605 generateTaskHeader(fm, lb, task,output);
607 TempObject objecttemp=(TempObject) tempstable.get(lb!=null ? lb : task);
608 /*if (state.DSM&&lb.getHasAtomic()) {
609 output.println("transrecord_t * trans;");
612 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
613 output.print(" struct "+task.getCoreSafeSymbol(num)+"_locals "+localsprefix+"={");
615 output.print(objecttemp.numPointers()+",");
616 output.print(paramsprefix);
617 for(int j=0; j<objecttemp.numPointers(); j++)
618 output.print(", NULL");
619 output.println("};");
622 for(int i=0; i<objecttemp.numPrimitives(); i++) {
623 TempDescriptor td=objecttemp.getPrimitive(i);
624 TypeDescriptor type=td.getType();
626 output.println(" void * "+td.getSafeSymbol()+";");
627 else if (state.MGC && type.isClass() && type.getClassDesc().isEnum()) {
628 output.println(" int " + td.getSafeSymbol()+";");
629 } else if (type.isClass()||type.isArray())
630 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
632 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
635 for(int i = 0; i < fm.numParameters(); ++i) {
636 TempDescriptor temp = fm.getParameter(i);
637 output.println(" int "+generateTempFlagName(fm, temp, lb)+" = "+super.generateTemp(fm, temp, lb)+
641 /* Assign labels to FlatNode's if necessary.*/
643 Hashtable<FlatNode, Integer> nodetolabel=super.assignLabels(fm);
645 /* Check to see if we need to do a GC if this is a
646 * multi-threaded program...*/
647 if(this.state.MULTICOREGC) {
648 output.println("if(gcflag) gc("+localsprefixaddr+");");
651 /*if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) {
652 if (state.DSM&&lb.isAtomic())
653 output.println("checkcollect2(&"+localsprefix+",trans);");
655 output.println("checkcollect(&"+localsprefix+");");
658 /* Create queues to store objects need to be transferred to other cores and their destination*/
659 //output.println(" struct Queue * totransobjqueue = createQueue();");
660 output.println(" clearQueue(totransobjqueue);");
661 output.println(" struct transObjInfo * tmpObjInfo = NULL;");
663 this.m_aliasSets = null;
664 this.m_aliasFNTbl4Para = null;
665 this.m_aliasFNTbl = null;
666 this.m_aliaslocksTbl4FN = null;
667 outputAliasLockCode(fm, lb, output);
669 /* generate print information for RAW version */
670 output.println("#ifdef MULTICORE");
673 output.println("int tmpsum = 0;");
674 output.println("char * taskname = \"" + task.getSymbol() + "\";");
675 output.println("int tmplen = " + task.getSymbol().length() + ";");
676 output.println("int tmpindex = 1;");
677 output.println("for(;tmpindex < tmplen; tmpindex++) {");
678 output.println(" tmpsum = tmpsum * 10 + *(taskname + tmpindex) - '0';");
681 output.println("#ifdef RAWPATH");
683 output.println("BAMBOO_DEBUGPRINT(0xAAAA);");
684 output.println("BAMBOO_DEBUGPRINT_REG(tmpsum);");
686 //output.println("BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();");
687 output.println("printf(\"(%x,%x) Process %x(%d): task %s\\n\", udn_tile_coord_x(), udn_tile_coord_y(), corenum, corenum, \"" + task.getSymbol() + "\");");
688 //output.println("BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();");
690 //output.println("BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());");
691 output.println("#endif");
692 output.println("#ifdef DEBUG");
694 output.println("BAMBOO_DEBUGPRINT(0xAAAA);");
695 output.println("BAMBOO_DEBUGPRINT_REG(tmpsum);");
697 //output.println("BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();");
698 output.println("printf(\"(%x,%x) Process %x(%d): task %s\\n\", udn_tile_coord_x(), udn_tile_coord_y(), corenum, corenum, \"" + task.getSymbol() + "\");");
699 //output.println("BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();");
701 output.println("#endif");
705 output.println("#endif");
707 for(int i = 0; i < fm.numParameters(); ++i) {
708 TempDescriptor temp = fm.getParameter(i);
709 output.println(" ++" + super.generateTemp(fm, temp, lb)+"->version;");
712 /* Do the actual code generation */
713 FlatNode current_node=null;
714 HashSet tovisit=new HashSet();
715 HashSet visited=new HashSet();
716 tovisit.add(fm.getNext(0));
717 while(current_node!=null||!tovisit.isEmpty()) {
718 if (current_node==null) {
719 current_node=(FlatNode)tovisit.iterator().next();
720 tovisit.remove(current_node);
722 visited.add(current_node);
723 if (nodetolabel.containsKey(current_node))
724 output.println("L"+nodetolabel.get(current_node)+":");
725 /*if (state.INSTRUCTIONFAILURE) {
726 if (state.THREAD||state.DSM) {
727 output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
730 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
732 if (current_node.numNext()==0) {
734 super.generateFlatNode(fm, lb, current_node, output);
735 if (current_node.kind()!=FKind.FlatReturnNode) {
736 //output.println(" flushAll();");
737 output.println("#ifdef CACHEFLUSH");
738 output.println("BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();");
739 output.println("#ifdef DEBUG");
740 output.println("BAMBOO_DEBUGPRINT(0xec00);");
741 output.println("#endif");
742 output.println("BAMBOO_CACHE_FLUSH_ALL();");
743 output.println("#ifdef DEBUG");
744 output.println("BAMBOO_DEBUGPRINT(0xecff);");
745 output.println("#endif");
746 output.println("BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();");
747 output.println("#endif");
748 outputTransCode(output);
749 output.println(" return;");
752 } else if(current_node.numNext()==1) {
754 super.generateFlatNode(fm, lb, current_node, output);
755 FlatNode nextnode=current_node.getNext(0);
756 if (visited.contains(nextnode)) {
757 output.println("goto L"+nodetolabel.get(nextnode)+";");
760 current_node=nextnode;
761 } else if (current_node.numNext()==2) {
764 super.generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
765 if (!visited.contains(current_node.getNext(1)))
766 tovisit.add(current_node.getNext(1));
767 if (visited.contains(current_node.getNext(0))) {
768 output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
771 current_node=current_node.getNext(0);
772 } else throw new Error();
775 output.println("}\n\n");
778 /** This method outputs TaskDescriptor information */
779 private void generateTaskDescriptor(PrintWriter output,
784 int num = this.currentSchedule.getCoreNum();
786 output.println("/* TaskDescriptor information for task " + task.getSymbol() + " on core " + num + "*/");
788 for (int i=0; i<task.numParameters(); i++) {
789 VarDescriptor param_var=task.getParameter(i);
790 TypeDescriptor param_type=task.getParamType(i);
791 FlagExpressionNode param_flag=task.getFlag(param_var);
792 TagExpressionList param_tag=task.getTag(param_var);
795 if (param_flag==null) {
796 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
797 output.println("0x0, 0x0 };");
800 DNFFlag dflag=param_flag.getDNF();
801 dnfterms=dflag.size();
803 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
804 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
805 for(int j=0; j<dflag.size(); j++) {
808 Vector term=dflag.get(j);
811 for(int k=0; k<term.size(); k++) {
812 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
813 FlagDescriptor fd=dfa.getFlag();
814 boolean negated=dfa.getNegated();
815 int flagid=1<<((Integer)flags.get(fd)).intValue();
820 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
822 output.println("};");
825 output.println("int parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
826 //BUG...added next line to fix, test with any task program
828 for(int j=0; j<param_tag.numTags(); j++) {
831 /* for each tag we need */
832 /* which slot it is */
833 /* what type it is */
834 TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
835 TempDescriptor tmp=param_tag.getTemp(j);
836 int slot=fm.getTagInt(tmp);
837 output.println(slot+", "+state.getTagId(tvd.getTag()));
839 output.println("};");
841 // generate object queue for this parameter
842 String qname = this.objqueueprefix+i+"_"+task.getCoreSafeSymbol(num);
843 if(param_type.getClassDesc().getSymbol().equals("StartupObject")) {
844 this.startupcorenum = num;
846 if(qnames[param_type.getClassDesc().getId()] == null) {
847 qnames[param_type.getClassDesc().getId()] = new Vector();
849 qnames[param_type.getClassDesc().getId()].addElement(qname);
850 outtask.println("extern struct parameterwrapper " + qname + ";");
851 output.println("struct parameterwrapper " + qname + "={");
852 output.println(".objectset = 0,"); // objectset
853 output.println("/* number of DNF terms */ .numberofterms = "+dnfterms+","); // numberofterms
854 output.println(".intarray = parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
857 output.println("/* number of tags */ .numbertags = "+param_tag.numTags()+",");
859 output.println("/* number of tags */ .numbertags = 0,");
860 output.println(".tagarray = parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+","); // tagarray
861 output.println(".task = 0,"); // task
862 output.println(".slot = " + i + ","); // slot
864 output.println("};");
866 output.println("struct parameterdescriptor parameter_"+i+"_"+task.getCoreSafeSymbol(num)+"={");
867 output.println("/* type */"+param_type.getClassDesc().getId()+",");
868 output.println("/* number of DNF terms */"+dnfterms+",");
869 output.println("parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
870 output.println("&" + qname + ","); // queue
871 //BUG, added next line to fix and else statement...test
872 //with any task program
874 output.println("/* number of tags */"+param_tag.numTags()+",");
876 output.println("/* number of tags */ 0,");
877 output.println("parametertag_"+i+"_"+task.getCoreSafeSymbol(num)); // tagarray
878 output.println("};");
881 /* parameter queues for this task*/
882 output.println("struct parameterwrapper * " + this.paramqarrayprefix + task.getCoreSafeSymbol(num)+"[] = {");
883 for (int i=0; i<task.numParameters(); i++) {
886 output.print("&" + this.objqueueprefix + i + "_" + task.getCoreSafeSymbol(num));
888 output.println("};");
890 output.println("struct parameterdescriptor * parameterdescriptors_"+task.getCoreSafeSymbol(num)+"[] = {");
891 for (int i=0; i<task.numParameters(); i++) {
894 output.print("¶meter_"+i+"_"+task.getCoreSafeSymbol(num));
896 output.println("};");
898 output.println("struct taskdescriptor " + this.taskprefix + task.getCoreSafeSymbol(num) + "={");
899 output.println("&"+task.getCoreSafeSymbol(num)+",");
900 output.println("/* number of parameters */" +task.numParameters() + ",");
901 int numtotal=task.numParameters()+fm.numTags();
902 output.println("/* number total parameters */" +numtotal + ",");
903 output.println("parameterdescriptors_"+task.getCoreSafeSymbol(num)+",");
904 output.println("\""+task.getSymbol()+"\"");
905 output.println("};");
910 /** This method generates header information for the task
911 * referenced by the Descriptor des. */
913 private void generateTaskHeader(FlatMethod fm,
916 PrintWriter output) {
918 ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : des);
919 TaskDescriptor task=(TaskDescriptor) des;
921 int num = this.currentSchedule.getCoreNum();
922 //catch the constructor case
923 output.print("void ");
924 output.print(task.getCoreSafeSymbol(num)+"(");
926 boolean printcomma=false;
927 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
928 output.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
932 /*if (state.DSM&&lb.isAtomic()) {
935 output.print("transrecord_t * trans");
939 if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
941 output.println("void * parameterarray[]) {");
942 /* Unpack variables */
943 for(int i=0; i<objectparams.numPrimitives(); i++) {
944 TempDescriptor temp=objectparams.getPrimitive(i);
945 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
947 for(int i=0; i<fm.numTags(); i++) {
948 TempDescriptor temp=fm.getTag(i);
949 int offset=i+objectparams.numPrimitives();
950 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+i+"___=parameterarray["+offset+"];"); // add i to fix bugs of duplicate definition of tags
953 if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
954 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
955 } else output.println(") {");
958 protected void generateFlagOrAnd(FlatFlagActionNode ffan,
965 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
966 output.println("flagorandinit("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
968 int num = this.currentSchedule.getCoreNum();
969 ClassDescriptor cd = temp.getType().getClassDesc();
970 Vector<FlagState> initfstates = ffan.getInitFStates(cd);
971 for(int i = 0; i < initfstates.size(); ++i) {
972 FlagState tmpFState = initfstates.elementAt(i);
974 QueueInfo qinfo = outputqueues(tmpFState, num, output, false);
975 output.println("flagorand("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+
976 ", 0x"+Integer.toHexString(andmask)+", " + qinfo.qname +
977 ", " + qinfo.length + ");");
980 if(ffan.getTaskType()==FlatFlagActionNode.TASKEXIT) {
981 // generate codes for profiling, recording which task exit it is
982 output.println("#ifdef PROFILE");
983 output.println("setTaskExitIndex(" + ffan.getTaskExitIndex() + ");");
984 output.println("#endif");
989 protected void generateObjectDistribute(FlatFlagActionNode ffan,
993 PrintWriter output) {
994 ClassDescriptor cd = temp.getType().getClassDesc();
995 Vector<FlagState> initfstates = null;
996 Vector[] targetFStates = null;
997 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
998 targetFStates = new Vector[1];
999 targetFStates[0] = ffan.getTargetFStates4NewObj(cd);
1001 initfstates = ffan.getInitFStates(cd);
1002 targetFStates = new Vector[initfstates.size()];
1003 for(int i = 0; i < initfstates.size(); ++i) {
1004 FlagState fs = initfstates.elementAt(i);
1005 targetFStates[i] = ffan.getTargetFStates(fs);
1007 if(!fs.isSetmask()) {
1008 Hashtable flags=(Hashtable)flagorder.get(cd);
1011 Iterator it_flags = fs.getFlags();
1012 while(it_flags.hasNext()) {
1013 FlagDescriptor fd = (FlagDescriptor)it_flags.next();
1014 int flagid=1<<((Integer)flags.get(fd)).intValue();
1018 fs.setAndmask(andmask);
1019 fs.setCheckmask(checkmask);
1020 fs.setSetmask(true);
1024 boolean isolate = true; // check if this flagstate can associate to some task with multiple params which can
1025 // reside on multiple cores
1026 if((this.currentSchedule == null) && (fm.getMethod().getClassDesc().getSymbol().equals("ServerSocket"))) {
1027 // ServerSocket object will always reside on current core
1028 for(int j = 0; j < targetFStates.length; ++j) {
1029 if(initfstates != null) {
1030 FlagState fs = initfstates.elementAt(j);
1031 output.println("if(" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
1032 + ")==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
1034 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
1035 for(int i = 0; i < tmpfstates.size(); ++i) {
1036 FlagState tmpFState = tmpfstates.elementAt(i);
1038 // may have bugs here
1039 output.println("/* reside on this core*");
1040 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1042 if(initfstates != null) {
1043 output.println("}");
1049 int num = this.currentSchedule.getCoreNum();
1050 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
1051 for(int j = 0; j < targetFStates.length; ++j) {
1052 FlagState fs = null;
1053 if(initfstates != null) {
1054 fs = initfstates.elementAt(j);
1055 output.println("if((" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
1056 + "))==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
1058 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
1059 for(int i = 0; i < tmpfstates.size(); ++i) {
1060 FlagState tmpFState = tmpfstates.elementAt(i);
1062 if(this.currentSchedule.getAllyCoreTable() == null) {
1065 isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) ||
1066 (this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
1069 Vector<Integer> sendto = new Vector<Integer>();
1070 Queue<Integer> queue = null;
1071 if(targetCoreTbl != null) {
1072 queue = targetCoreTbl.get(tmpFState);
1074 if((queue != null) &&
1075 ((queue.size() != 1) ||
1076 ((queue.size() == 1) && (queue.element().intValue() != num)))) {
1077 // this object may be transferred to other cores
1078 String queuename = (String) this.fsate2qnames[num].get(tmpFState);
1079 String queueins = queuename + "ins";
1081 Object[] cores = queue.toArray();
1083 Integer targetcore = (Integer)cores[0];
1084 if(queue.size() > 1) {
1085 index = queueins + ".index";
1087 if(queue.size() > 1) {
1088 output.println("switch(" + queueins + ".index % " + queueins + ".length) {");
1089 for(int k = 0; k < cores.length; ++k) {
1090 output.println("case " + k + ":");
1091 targetcore = (Integer)cores[k];
1092 if(targetcore.intValue() == num) {
1093 output.println("/* reside on this core*/");
1095 output.println("{");
1096 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1097 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1098 ", " + qinfo.length + ");");
1099 output.println("}");
1103 output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1104 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1105 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1109 // Is it possible to decide the actual queues?
1110 output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1111 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1112 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1113 output.println("/* transfer to core " + targetcore.toString() + "*/");
1114 output.println("{");
1115 // enqueue this object and its destinations for later process
1116 // all the possible queues
1117 QueueInfo qinfo = null;
1118 TranObjInfo tmpinfo = new TranObjInfo();
1119 tmpinfo.name = super.generateTemp(fm, temp, lb);
1120 tmpinfo.targetcore = targetcore;
1121 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1122 if(targetFS != null) {
1123 tmpinfo.fs = targetFS;
1125 tmpinfo.fs = tmpFState;
1127 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1128 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1129 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1130 output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1131 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1132 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1133 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1134 output.println("}");
1136 output.println("break;");
1138 output.println("}");
1142 // Is it possible to decide the actual queues?
1143 output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1144 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1145 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1146 output.println("/* transfer to core " + targetcore.toString() + "*/");
1147 output.println("{");
1148 // enqueue this object and its destinations for later process
1149 // all the possible queues
1150 QueueInfo qinfo = null;
1151 TranObjInfo tmpinfo = new TranObjInfo();
1152 tmpinfo.name = super.generateTemp(fm, temp, lb);
1153 tmpinfo.targetcore = targetcore;
1154 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1155 if(targetFS != null) {
1156 tmpinfo.fs = targetFS;
1158 tmpinfo.fs = tmpFState;
1160 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1161 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1162 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1163 output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1164 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1165 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1166 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1167 output.println("}");
1169 output.println("/* increase index*/");
1170 output.println("++" + queueins + ".index;");
1172 // this object will reside on current core
1173 output.println("/* reside on this core*/");
1175 output.println("{");
1176 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1177 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1178 ", " + qinfo.length + ");");
1179 output.println("}");
1183 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1184 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1187 // codes for multi-params tasks
1189 // flagstate associated with some multi-params tasks
1190 // need to be send to other cores
1191 Vector<Integer> targetcores = this.currentSchedule.getAllyCores(tmpFState);
1192 output.println("/* send the shared object to possible queues on other cores*/");
1193 // TODO, temporary solution, send to mostly the first two
1194 int upperbound = targetcores.size() > 2? 2: targetcores.size();
1195 for(int k = 0; k < upperbound; ++k) {
1197 // add the information of exactly which queue
1198 int targetcore = targetcores.elementAt(k).intValue();
1199 if(!sendto.contains(targetcore)) {
1200 // previously not sended to this target core
1201 // enqueue this object and its destinations for later process
1202 output.println("{");
1203 // all the possible queues
1204 QueueInfo qinfo = null;
1205 TranObjInfo tmpinfo = new TranObjInfo();
1206 tmpinfo.name = super.generateTemp(fm, temp, lb);
1207 tmpinfo.targetcore = targetcore;
1208 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1209 if(targetFS != null) {
1210 tmpinfo.fs = targetFS;
1212 tmpinfo.fs = tmpFState;
1214 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1215 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1216 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1217 output.println("tmpObjInfo->targetcore = "+targetcore+";");
1218 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1219 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1220 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1221 output.println("}");
1222 sendto.addElement(targetcore);
1228 if(initfstates != null) {
1229 output.println("}");
1234 private QueueInfo outputqueues(FlagState tmpFState,
1237 boolean isEnqueue) {
1239 QueueInfo qinfo = new QueueInfo();
1240 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1241 output.println("struct parameterwrapper * " + qinfo.qname + "[] = {");
1242 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1243 Vector<TaskDescriptor> residetasks = this.currentSchedule.getTasks();
1244 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1245 Vector<Integer> indexes = new Vector<Integer>();
1246 boolean comma = false;
1248 while(it_edges.hasNext()) {
1249 FEdge fe = (FEdge)it_edges.next();
1250 TaskDescriptor td = fe.getTask();
1251 int paraindex = fe.getIndex();
1252 if((!isEnqueue) || (isEnqueue && residetasks.contains(td))) {
1253 if((!tasks.contains(td)) ||
1254 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1255 tasks.addElement(td);
1256 indexes.addElement(paraindex);
1258 output.println(",");
1262 output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
1267 output.println("};");
1271 private QueueInfo outputtransqueues(FlagState tmpFState,
1273 PrintWriter output) {
1275 QueueInfo qinfo = new QueueInfo();
1276 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1277 output.println("int " + qinfo.qname + "_clone[] = {");
1278 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1279 Vector<TaskDescriptor> residetasks = this.scheduling.get(targetcore).getTasks();
1280 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1281 Vector<Integer> indexes = new Vector<Integer>();
1282 boolean comma = false;
1284 while(it_edges.hasNext()) {
1285 FEdge fe = (FEdge)it_edges.next();
1286 TaskDescriptor td = fe.getTask();
1287 int paraindex = fe.getIndex();
1288 if(residetasks.contains(td)) {
1289 if((!tasks.contains(td)) ||
1290 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1291 tasks.addElement(td);
1292 indexes.addElement(paraindex);
1294 output.println(",");
1298 output.print(residetasks.indexOf(td) + ", ");
1299 output.print(paraindex);
1304 output.println("};");
1305 output.println("int * " + qinfo.qname + " = RUNMALLOC(sizeof(int) * " + qinfo.length * 2 + ");");
1306 output.println("memcpy(" + qinfo.qname + ", (int *)" + qinfo.qname + "_clone, sizeof(int) * " + qinfo.length * 2 + ");");
1310 private class QueueInfo {
1312 public String qname;
1315 private String generateTempFlagName(FlatMethod fm,
1317 LocalityBinding lb) {
1318 MethodDescriptor md=fm.getMethod();
1319 TaskDescriptor task=fm.getTask();
1320 TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
1322 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1323 return td.getSafeSymbol() + "_oldflag";
1326 if (objecttemps.isLocalPtr(td)) {
1327 return localsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1330 if (objecttemps.isParamPtr(td)) {
1331 return paramsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1336 protected void outputTransCode(PrintWriter output) {
1337 output.println("while(0 == isEmpty(totransobjqueue)) {");
1338 output.println(" struct transObjInfo * totransobj = (struct transObjInfo *)(getItem(totransobjqueue));");
1339 output.println(" transferObject(totransobj);");
1340 output.println(" RUNFREE(totransobj->queues);");
1341 output.println(" RUNFREE(totransobj);");
1342 output.println("}");
1343 //output.println("freeQueue(totransobjqueue);");
1346 protected void outputAliasLockCode(FlatMethod fm,
1348 PrintWriter output) {
1349 if(this.m_oa == null) {
1352 TaskDescriptor td = fm.getTask();
1353 Object[] allocSites = this.m_oa.getFlaggedAllocationSitesReachableFromTask(td).toArray();
1354 Vector<Vector<Integer>> aliasSets = new Vector<Vector<Integer>>();
1355 Vector<Vector<FlatNew>> aliasFNSets = new Vector<Vector<FlatNew>>();
1356 Hashtable<Integer, Vector<FlatNew>> aliasFNTbl4Para = new Hashtable<Integer, Vector<FlatNew>>();
1357 Hashtable<FlatNew, Vector<FlatNew>> aliasFNTbl = new Hashtable<FlatNew, Vector<FlatNew>>();
1358 Set<HeapRegionNode> common;
1359 for( int i = 0; i < fm.numParameters(); ++i ) {
1360 // for the ith parameter check for aliases to all
1361 // higher numbered parameters
1362 aliasSets.add(null);
1363 for( int j = i + 1; j < fm.numParameters(); ++j ) {
1364 common = this.m_oa.createsPotentialAliases(td, i, j);
1365 if(!common.isEmpty()) {
1366 // ith parameter and jth parameter has alias, create lock to protect them
1367 if(aliasSets.elementAt(i) == null) {
1368 aliasSets.setElementAt(new Vector<Integer>(), i);
1370 aliasSets.elementAt(i).add(j);
1374 // for the ith parameter, check for aliases against
1375 // the set of allocation sites reachable from this
1377 aliasFNSets.add(null);
1378 for(int j = 0; j < allocSites.length; j++) {
1379 AllocationSite as = (AllocationSite)allocSites[j];
1380 common = this.m_oa.createsPotentialAliases(td, i, as);
1381 if( !common.isEmpty() ) {
1382 // ith parameter and allocationsite as has alias
1383 if(aliasFNSets.elementAt(i) == null) {
1384 aliasFNSets.setElementAt(new Vector<FlatNew>(), i);
1386 aliasFNSets.elementAt(i).add(as.getFlatNew());
1391 // for each allocation site check for aliases with
1392 // other allocation sites in the context of execution
1394 for( int i = 0; i < allocSites.length; ++i ) {
1395 AllocationSite as1 = (AllocationSite)allocSites[i];
1396 for(int j = i + 1; j < allocSites.length; j++) {
1397 AllocationSite as2 = (AllocationSite)allocSites[j];
1399 common = this.m_oa.createsPotentialAliases(td, as1, as2);
1400 if( !common.isEmpty() ) {
1401 // as1 and as2 has alias
1402 if(!aliasFNTbl.containsKey(as1.getFlatNew())) {
1403 aliasFNTbl.put(as1.getFlatNew(), new Vector<FlatNew>());
1405 if(!aliasFNTbl.get(as1.getFlatNew()).contains(as2.getFlatNew())) {
1406 aliasFNTbl.get(as1.getFlatNew()).add(as2.getFlatNew());
1412 // if FlatNew N1->N2->N3, we group N1, N2, N3 together
1413 Iterator<FlatNew> it = aliasFNTbl.keySet().iterator();
1414 Vector<FlatNew> visited = new Vector<FlatNew>();
1415 while(it.hasNext()) {
1416 FlatNew tmpfn = it.next();
1417 if(visited.contains(tmpfn)) {
1421 Queue<FlatNew> tovisit = new LinkedList<FlatNew>();
1422 Vector<FlatNew> tmpv = aliasFNTbl.get(tmpfn);
1427 for(int j = 0; j < tmpv.size(); j++) {
1428 tovisit.add(tmpv.elementAt(j));
1431 while(!tovisit.isEmpty()) {
1432 FlatNew fn = tovisit.poll();
1434 Vector<FlatNew> tmpset = aliasFNTbl.get(fn);
1435 if(tmpset != null) {
1436 // merge tmpset to the alias set of the ith parameter
1437 for(int j = 0; j < tmpset.size(); j++) {
1438 if(!tmpv.contains(tmpset.elementAt(j))) {
1439 tmpv.add(tmpset.elementAt(j));
1440 tovisit.add(tmpset.elementAt(j));
1443 aliasFNTbl.remove(fn);
1446 it = aliasFNTbl.keySet().iterator();
1449 // check alias between parameters and between parameter-flatnew
1450 for(int i = 0; i < aliasSets.size(); i++) {
1451 Queue<Integer> tovisit = new LinkedList<Integer>();
1452 Vector<Integer> tmpv = aliasSets.elementAt(i);
1457 for(int j = 0; j < tmpv.size(); j++) {
1458 tovisit.add(tmpv.elementAt(j));
1461 while(!tovisit.isEmpty()) {
1462 int index = tovisit.poll().intValue();
1463 Vector<Integer> tmpset = aliasSets.elementAt(index);
1464 if(tmpset != null) {
1465 // merge tmpset to the alias set of the ith parameter
1466 for(int j = 0; j < tmpset.size(); j++) {
1467 if(!tmpv.contains(tmpset.elementAt(j))) {
1468 tmpv.add(tmpset.elementAt(j));
1469 tovisit.add(tmpset.elementAt(j));
1472 aliasSets.setElementAt(null, index);
1475 Vector<FlatNew> tmpFNSet = aliasFNSets.elementAt(index);
1476 if(tmpFNSet != null) {
1477 // merge tmpFNSet to the aliasFNSet of the ith parameter
1478 if(aliasFNSets.elementAt(i) == null) {
1479 aliasFNSets.setElementAt(tmpFNSet, i);
1481 Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1482 for(int j = 0; j < tmpFNSet.size(); j++) {
1483 if(!tmpFNv.contains(tmpFNSet.elementAt(j))) {
1484 tmpFNv.add(tmpFNSet.elementAt(j));
1488 aliasFNSets.setElementAt(null, index);
1494 int numparalock = 0;
1495 Vector<Vector<Integer>> tmpaliasSets = new Vector<Vector<Integer>>();
1496 for(int i = 0; i < aliasSets.size(); i++) {
1497 Vector<Integer> tmpv = aliasSets.elementAt(i);
1500 tmpaliasSets.add(tmpv);
1504 Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1505 if(tmpFNv != null) {
1506 aliasFNTbl4Para.put(i, tmpFNv);
1512 numparalock = numlock;
1515 this.m_aliasSets = tmpaliasSets;
1516 aliasFNSets.clear();
1518 this.m_aliasFNTbl4Para = aliasFNTbl4Para;
1519 this.m_aliasFNTbl = aliasFNTbl;
1520 numlock += this.m_aliasFNTbl.size();
1524 output.println("int aliaslocks[" + numlock + "];");
1525 output.println("int tmpi = 0;");
1526 // associate locks with parameters
1528 for(int i = 0; i < this.m_aliasSets.size(); i++) {
1529 Vector<Integer> toadd = this.m_aliasSets.elementAt(i);
1531 output.println("int tmplen_" + lockindex + " = " + toadd.size());
1532 output.println("void * tmpptrs_" + lockindex + "[] = {");
1533 for(int j = 0; j < toadd.size(); j++) {
1534 int para = toadd.elementAt(j).intValue();
1535 output.print(super.generateTemp(fm, fm.getParameter(para), lb));
1536 if(j < toadd.size() - 1) {
1539 output.println("};");
1542 output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", tmplen_" + lockindex + ", lockRedirectTbl);");
1544 for(int j = 0; j < toadd.size(); j++) {
1545 int para = toadd.elementAt(j).intValue();
1546 output.println("addAliasLock(" + super.generateTemp(fm, fm.getParameter(para), lb) + ", aliaslocks[" + i + "]);");
1548 // check if this lock is also associated with any FlatNew nodes
1549 if(this.m_aliasFNTbl4Para.containsKey(toadd.elementAt(0))) {
1550 if(this.m_aliaslocksTbl4FN == null) {
1551 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1553 Vector<FlatNew> tmpv = this.m_aliasFNTbl4Para.get(toadd.elementAt(0));
1554 for(int j = 0; j < tmpv.size(); j++) {
1555 FlatNew fn = tmpv.elementAt(j);
1556 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1557 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1559 this.m_aliaslocksTbl4FN.get(fn).add(i);
1561 this.m_aliasFNTbl4Para.remove(toadd.elementAt(0));
1566 Object[] key = this.m_aliasFNTbl4Para.keySet().toArray();
1567 for(int i = 0; i < key.length; i++) {
1568 int para = ((Integer)key[i]).intValue();
1570 output.println("void * tmpptrs_" + lockindex + "[] = {" + super.generateTemp(fm, fm.getParameter(para), lb) + "};");
1571 output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", 1, lockRedirectTbl);");
1573 output.println("addAliasLock(" + super.generateTemp(fm, fm.getParameter(para), lb) + ", aliaslocks[" + lockindex + "]);");
1574 Vector<FlatNew> tmpv = this.m_aliasFNTbl4Para.get(para);
1575 for(int j = 0; j < tmpv.size(); j++) {
1576 FlatNew fn = tmpv.elementAt(j);
1577 if(this.m_aliaslocksTbl4FN == null) {
1578 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1580 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1581 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1583 this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
1588 // check m_aliasFNTbl for locks associated with FlatNew nodes
1589 Object[] FNkey = this.m_aliasFNTbl.keySet().toArray();
1590 for(int i = 0; i < FNkey.length; i++) {
1591 FlatNew fn = (FlatNew)FNkey[i];
1592 Vector<FlatNew> tmpv = this.m_aliasFNTbl.get(fn);
1594 output.println("aliaslocks[tmpi++] = (int)(RUNMALLOC(sizeof(int)));");
1596 if(this.m_aliaslocksTbl4FN == null) {
1597 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1599 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1600 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1602 this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
1603 for(int j = 0; j < tmpv.size(); j++) {
1604 FlatNew tfn = tmpv.elementAt(j);
1605 if(!this.m_aliaslocksTbl4FN.containsKey(tfn)) {
1606 this.m_aliaslocksTbl4FN.put(tfn, new Vector<Integer>());
1608 this.m_aliaslocksTbl4FN.get(tfn).add(lockindex);
1615 protected void generateFlatReturnNode(FlatMethod fm,
1618 PrintWriter output) {
1619 if (frn.getReturnTemp()!=null) {
1620 if (frn.getReturnTemp().getType().isPtr())
1621 output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1623 output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1625 if(fm.getTask() != null) {
1626 output.println("#ifdef CACHEFLUSH");
1627 output.println("BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();");
1628 output.println("#ifdef DEBUG");
1629 output.println("BAMBOO_DEBUGPRINT(0xec00);");
1630 output.println("#endif");
1631 output.println("BAMBOO_CACHE_FLUSH_ALL();");
1632 output.println("#ifdef DEBUG");
1633 output.println("BAMBOO_DEBUGPRINT(0xecff);");
1634 output.println("#endif");
1635 output.println("BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();");
1636 output.println("#endif");
1637 outputTransCode(output);
1639 output.println("return;");
1643 protected void generateFlatNew(FlatMethod fm,
1646 PrintWriter output) {
1647 if (state.DSM && locality.getAtomic(lb).get(fn).intValue() > 0
1648 && !fn.isGlobal()) {
1649 // Stash pointer in case of GC
1650 String revertptr = super.generateTemp(fm, reverttable.get(lb), lb);
1651 output.println(revertptr + "=trans->revertlist;");
1653 if (fn.getType().isArray()) {
1654 int arrayid = state.getArrayNumber(fn.getType())
1655 + state.numClasses();
1656 if (fn.isGlobal()) {
1657 output.println(super.generateTemp(fm, fn.getDst(), lb)
1658 + "=allocate_newarrayglobal(trans, " + arrayid + ", "
1659 + super.generateTemp(fm, fn.getSize(), lb) + ");");
1660 } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1661 output.println(super.generateTemp(fm, fn.getDst(), lb)
1662 + "=allocate_newarray(&" + localsprefix + ", "
1663 + arrayid + ", " + super.generateTemp(fm, fn.getSize(), lb)
1666 output.println(super.generateTemp(fm, fn.getDst(), lb)
1667 + "=allocate_newarray(" + arrayid + ", "
1668 + super.generateTemp(fm, fn.getSize(), lb) + ");");
1671 if (fn.isGlobal()) {
1672 output.println(super.generateTemp(fm, fn.getDst(), lb)
1673 + "=allocate_newglobal(trans, "
1674 + fn.getType().getClassDesc().getId() + ");");
1675 } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1676 output.println(super.generateTemp(fm, fn.getDst(), lb)
1677 + "=allocate_new(&" + localsprefix + ", "
1678 + fn.getType().getClassDesc().getId() + ");");
1680 output.println(super.generateTemp(fm, fn.getDst(), lb)
1682 + fn.getType().getClassDesc().getId() + ");");
1685 if (state.DSM && locality.getAtomic(lb).get(fn).intValue() > 0
1686 && !fn.isGlobal()) {
1687 String revertptr = super.generateTemp(fm, reverttable.get(lb), lb);
1688 output.println("trans->revertlist=" + revertptr + ";");
1690 // create alias lock if necessary
1691 if((this.m_aliaslocksTbl4FN != null) && (this.m_aliaslocksTbl4FN.containsKey(fn))) {
1692 Vector<Integer> tmpv = this.m_aliaslocksTbl4FN.get(fn);
1693 for(int i = 0; i < tmpv.size(); i++) {
1694 output.println("addAliasLock(" + super.generateTemp(fm, fn.getDst(), lb) + ", aliaslocks[" + tmpv.elementAt(i).intValue() + "]);");
1697 // generate codes for profiling, recording how many new objects are created
1698 if(!fn.getType().isArray() &&
1699 (fn.getType().getClassDesc() != null)
1700 && (fn.getType().getClassDesc().hasFlags())) {
1701 output.println("#ifdef PROFILE");
1702 output.println("addNewObjInfo(\"" + fn.getType().getClassDesc().getSymbol() + "\");");
1703 output.println("#endif");
1709 public int targetcore;
1710 public FlagState fs;
1713 private boolean contains(Vector<TranObjInfo> sendto,
1715 if(sendto.size() == 0) {
1718 for(int i = 0; i < sendto.size(); i++) {
1719 TranObjInfo tmp = sendto.elementAt(i);
1720 if(!tmp.name.equals(t.name)) {
1723 if(tmp.targetcore != t.targetcore) {
1726 if(tmp.fs != t.fs) {