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;
41 Schedule currentSchedule;
42 Hashtable[] fsate2qnames;
43 String objqarrayprefix= "objqueuearray4class";
44 String objqueueprefix = "objqueue4parameter_";
45 String paramqarrayprefix = "paramqueuearray4task";
46 String coreqarrayprefix = "paramqueuearrays_core";
47 String taskprefix = "task_";
48 String taskarrayprefix = "taskarray_core";
49 String otqueueprefix = "___otqueue";
50 int startupcorenum; // record the core containing startup task, suppose only one core can hava startup object
52 private OwnershipAnalysis m_oa;
53 private Vector<Vector<Integer>> m_aliasSets;
54 Hashtable<Integer, Vector<FlatNew>> m_aliasFNTbl4Para;
55 Hashtable<FlatNew, Vector<FlatNew>> m_aliasFNTbl;
56 Hashtable<FlatNew, Vector<Integer>> m_aliaslocksTbl4FN;
58 public BuildCodeMultiCore(State st,
62 Vector<Schedule> scheduling,
64 PrefetchAnalysis pa) {
65 super(st, temptovar, typeutil, sa, pa);
66 this.scheduling = scheduling;
67 this.coreNum = coreNum;
68 this.tcoreNum = coreNum;
69 this.currentSchedule = null;
70 this.fsate2qnames = null;
71 this.startupcorenum = 0;
73 // sometimes there are extra cores then needed in scheduling
75 // currently, it is guaranteed that in scheduling, the corenum
76 // is started from 0 and continuous.
77 // MAY need modification here in the future when take hardware
78 // information into account.
79 if(this.scheduling.size() < this.coreNum) {
80 this.coreNum = this.scheduling.size();
84 this.m_aliasSets = null;
85 this.m_aliasFNTbl4Para = null;
86 this.m_aliasFNTbl = null;
87 this.m_aliaslocksTbl4FN = null;
90 public void setOwnershipAnalysis(OwnershipAnalysis m_oa) {
94 public void buildCode() {
95 /* Create output streams to write to */
96 PrintWriter outclassdefs=null;
97 PrintWriter outstructs=null;
98 PrintWriter outmethodheader=null;
99 PrintWriter outmethod=null;
100 PrintWriter outvirtual=null;
101 PrintWriter outtask=null;
102 PrintWriter outtaskdefs=null;
103 //PrintWriter outoptionalarrays=null;
104 //PrintWriter optionalheaders=null;
107 outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
108 outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
109 outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
110 outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
111 outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
113 outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
114 outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
117 outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
118 optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
121 /*if (state.structfile!=null) {
122 outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
124 } catch (Exception e) {
129 /* Build the virtual dispatch tables */
130 super.buildVirtualTables(outvirtual);
132 /* Output includes */
133 outmethodheader.println("#ifndef METHODHEADERS_H");
134 outmethodheader.println("#define METHODHEADERS_H");
135 outmethodheader.println("#include \"structdefs.h\"");
137 outmethodheader.println("#include \"dstm.h\"");*/
139 /* Output Structures */
140 super.outputStructs(outstructs);
142 // Output the C class declarations
143 // These could mutually reference each other
144 super.outputClassDeclarations(outclassdefs);
146 // Output function prototypes and structures for parameters
147 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
148 int numclasses = this.state.numClasses();
149 while(it.hasNext()) {
150 ClassDescriptor cn=(ClassDescriptor)it.next();
151 super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
153 outclassdefs.close();
156 /* Map flags to integers */
157 /* The runtime keeps track of flags using these integers */
158 it=state.getClassSymbolTable().getDescriptorsIterator();
159 while(it.hasNext()) {
160 ClassDescriptor cn=(ClassDescriptor)it.next();
164 generateTaskStructs(outstructs, outmethodheader);
166 /* Outputs generic task structures if this is a task
168 outputTaskTypes(outtask);
171 /* Build the actual methods */
172 super.outputMethods(outmethod);
175 Iterator[] taskits = new Iterator[this.coreNum];
176 for(int i = 0; i < taskits.length; ++i) {
179 int[] numtasks = new int[this.coreNum];
180 int[][] numqueues = new int[this.coreNum][numclasses];
181 /* Output code for tasks */
182 for(int i = 0; i < this.scheduling.size(); ++i) {
183 this.currentSchedule = this.scheduling.elementAt(i);
184 outputTaskCode(outtaskdefs, outmethod, outtask, taskits, numtasks, numqueues);
187 // Output task descriptors
188 boolean comma = false;
189 outtaskdefs.println("struct parameterwrapper ** objectqueues[][NUMCLASSES] = {");
190 boolean needcomma = false;
191 for(int i = 0; i < numqueues.length ; ++i) {
193 outtaskdefs.println(",");
197 outtaskdefs.println("/* object queue array for core " + i + "*/");
198 outtaskdefs.print("{");
200 for(int j = 0; j < numclasses; ++j) {
202 outtaskdefs.println(",");
206 outtaskdefs.print(this.objqarrayprefix + j + "_core" + i);
208 outtaskdefs.print("}");
210 outtaskdefs.println("};");
212 outtaskdefs.println("int numqueues[][NUMCLASSES] = {");
213 for(int i = 0; i < numqueues.length; ++i) {
215 outtaskdefs.println(",");
219 int[] tmparray = numqueues[i];
221 outtaskdefs.print("{");
222 for(int j = 0; j < tmparray.length; ++j) {
224 outtaskdefs.print(",");
228 outtaskdefs.print(tmparray[j]);
230 outtaskdefs.print("}");
232 outtaskdefs.println("};");
234 /* parameter queue arrays for all the tasks*/
235 outtaskdefs.println("struct parameterwrapper *** paramqueues[] = {");
237 for(int i = 0; i < this.coreNum ; ++i) {
239 outtaskdefs.println(",");
243 outtaskdefs.println("/* parameter queue array for core " + i + "*/");
244 outtaskdefs.print(this.coreqarrayprefix + i);
246 outtaskdefs.println("};");
248 for(int i = 0; i < taskits.length; ++i) {
249 outtaskdefs.println("struct taskdescriptor * " + this.taskarrayprefix + i + "[]={");
250 Iterator taskit = taskits[i];
253 while(taskit.hasNext()) {
254 TaskDescriptor td=(TaskDescriptor)taskit.next();
258 outtaskdefs.println(",");
259 outtaskdefs.print("&" + this.taskprefix +td.getCoreSafeSymbol(i));
262 outtaskdefs.println();
263 outtaskdefs.println("};");
265 outtaskdefs.println("struct taskdescriptor ** taskarray[]= {");
267 for(int i = 0; i < taskits.length; ++i) {
269 outtaskdefs.println(",");
272 outtaskdefs.print(this.taskarrayprefix + i);
274 outtaskdefs.println("};");
276 outtaskdefs.print("int numtasks[]= {");
278 for(int i = 0; i < taskits.length; ++i) {
280 outtaskdefs.print(",");
283 outtaskdefs.print(numtasks[i]);
285 outtaskdefs.println("};");
286 outtaskdefs.println("int corenum=0;");
289 outtask.println("#endif");
291 /* Record maximum number of task parameters */
292 outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
293 /* Record maximum number of all types, i.e. length of classsize[] */
294 outstructs.println("#define NUMTYPES "+(state.numClasses() + state.numArrays()));
295 /* Record number of total cores */
296 outstructs.println("#define NUMCORES "+this.tcoreNum);
297 /* Record number of active cores */
298 outstructs.println("#define NUMCORESACTIVE "+this.coreNum);
299 /* Record number of core containing startup task */
300 outstructs.println("#define STARTUPCORE "+this.startupcorenum);
301 } //else if (state.main!=null) {
302 /* Generate main method */
303 // outputMainMethod(outmethod);
306 /* Generate information for task with optional parameters */
307 /*if (state.TASK&&state.OPTIONAL){
308 generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
309 outoptionalarrays.close();
312 /* Output structure definitions for repair tool */
313 /*if (state.structfile!=null) {
314 buildRepairStructs(outrepairstructs);
315 outrepairstructs.close();
319 outmethodheader.println("#endif");
320 outmethodheader.close();
322 outstructs.println("#endif");
326 /** This function outputs (1) structures that parameters are
327 * passed in (when PRECISE GC is enabled) and (2) function
328 * prototypes for the tasks */
330 private void generateTaskStructs(PrintWriter output,
331 PrintWriter headersout) {
332 /* Cycle through tasks */
333 for(int i = 0; i < this.scheduling.size(); ++i) {
334 Schedule tmpschedule = this.scheduling.elementAt(i);
335 int num = tmpschedule.getCoreNum();
336 Iterator<TaskDescriptor> taskit = tmpschedule.getTasks().iterator();
338 while(taskit.hasNext()) {
339 /* Classify parameters */
340 TaskDescriptor task=taskit.next();
341 FlatMethod fm=state.getMethodFlat(task);
342 super.generateTempStructs(fm, null);
344 ParamsObject objectparams=(ParamsObject) paramstable.get(task);
345 TempObject objecttemps=(TempObject) tempstable.get(task);
347 /* Output parameter structure */
348 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
349 output.println("struct "+task.getCoreSafeSymbol(num)+"_params {");
350 output.println(" int size;");
351 output.println(" void * next;");
352 for(int j=0; j<objectparams.numPointers(); j++) {
353 TempDescriptor temp=objectparams.getPointer(j);
354 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
357 output.println("};\n");
358 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
359 maxtaskparams=objectparams.numPointers()+fm.numTags();
363 /* Output temp structure */
364 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
365 output.println("struct "+task.getCoreSafeSymbol(num)+"_locals {");
366 output.println(" int size;");
367 output.println(" void * next;");
368 for(int j=0; j<objecttemps.numPointers(); j++) {
369 TempDescriptor temp=objecttemps.getPointer(j);
370 if (temp.getType().isNull())
371 output.println(" void * "+temp.getSafeSymbol()+";");
372 else if(temp.getType().isTag())
373 output.println(" struct "+
374 (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
376 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
378 output.println("};\n");
381 /* Output task declaration */
382 headersout.print("void " + task.getCoreSafeSymbol(num)+"(");
384 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
385 headersout.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
387 headersout.print("void * parameterarray[]");
388 headersout.println(");\n");
394 /* This method outputs code for each task. */
396 private void outputTaskCode(PrintWriter outtaskdefs,
397 PrintWriter outmethod,
402 /* Compile task based program */
403 outtaskdefs.println("#include \"task.h\"");
404 outtaskdefs.println("#include \"methodheaders.h\"");
406 /* Output object transfer queues into method.c*/
407 generateObjectTransQueues(outmethod);
409 //Vector[] qnames = new Vector[2];
410 int numclasses = numqueues[0].length;
411 Vector qnames[]= new Vector[numclasses];
412 for(int i = 0; i < qnames.length; ++i) {
415 Iterator<TaskDescriptor> taskit=this.currentSchedule.getTasks().iterator();
416 while(taskit.hasNext()) {
417 TaskDescriptor td=taskit.next();
418 FlatMethod fm=state.getMethodFlat(td);
419 generateTaskMethod(fm, null, outmethod);
420 generateTaskDescriptor(outtaskdefs, outtask, fm, td, qnames);
423 // generate queuearray for this core
424 int num = this.currentSchedule.getCoreNum();
425 boolean comma = false;
426 for(int i = 0; i < qnames.length; ++i) {
427 outtaskdefs.println("/* object queue array for class " + i + " on core " + num + "*/");
428 outtaskdefs.println("struct parameterwrapper * " + this.objqarrayprefix + i + "_core" + num + "[] = {");
430 Vector tmpvector = qnames[i];
431 if(tmpvector != null) {
432 for(int j = 0; j < tmpvector.size(); ++j) {
434 outtaskdefs.println(",");
438 outtaskdefs.print("&" + tmpvector.elementAt(j));
440 numqueues[num][i] = tmpvector.size();
442 numqueues[num][i] = 0;
444 outtaskdefs.println("};");
447 /* All the queues for tasks residing on this core*/
449 outtaskdefs.println("/* object queue array for tasks on core " + num + "*/");
450 outtaskdefs.println("struct parameterwrapper ** " + this.coreqarrayprefix + num + "[] = {");
451 taskit=this.currentSchedule.getTasks().iterator();
452 while(taskit.hasNext()) {
454 outtaskdefs.println(",");
458 TaskDescriptor td=taskit.next();
459 outtaskdefs.print(this.paramqarrayprefix + td.getCoreSafeSymbol(num));
461 outtaskdefs.println("};");
463 // record the iterator of tasks on this core
464 taskit=this.currentSchedule.getTasks().iterator();
465 taskits[num] = taskit;
466 numtasks[num] = this.currentSchedule.getTasks().size();
469 /** Prints out definitions for generic task structures */
470 private void outputTaskTypes(PrintWriter outtask) {
471 outtask.println("#ifndef _TASK_H");
472 outtask.println("#define _TASK_H");
473 outtask.println("#include \"ObjectHash.h\"");
474 outtask.println("#include \"structdefs.h\"");
475 outtask.println("#include \"Queue.h\"");
476 outtask.println("#include <string.h>");
477 outtask.println("#include \"runtime_arch.h\"");
478 //outtask.println("#ifdef RAW");
479 //outtask.println("#include <raw.h>");
480 //outtask.println("#endif");
482 outtask.println("struct tagobjectiterator {");
483 outtask.println(" int istag; /* 0 if object iterator, 1 if tag iterator */");
484 outtask.println(" struct ObjectIterator it; /* Object iterator */");
485 outtask.println(" struct ObjectHash * objectset;");
486 outtask.println("#ifdef OPTIONAL");
487 outtask.println(" int failedstate;");
488 outtask.println("#endif");
489 outtask.println(" int slot;");
490 outtask.println(" int tagobjindex; /* Index for tag or object depending on use */");
491 outtask.println(" /*if tag we have an object binding */");
492 outtask.println(" int tagid;");
493 outtask.println(" int tagobjectslot;");
494 outtask.println(" /*if object, we may have one or more tag bindings */");
495 outtask.println(" int numtags;");
496 outtask.println(" int tagbindings[MAXTASKPARAMS-1]; /* list slots */");
497 outtask.println("};");
499 outtask.println("struct parameterwrapper {");
500 outtask.println(" //int type;");
501 outtask.println(" struct ObjectHash * objectset;");
502 outtask.println(" int numberofterms;");
503 outtask.println(" int * intarray;");
504 outtask.println(" int numbertags;");
505 outtask.println(" int * tagarray;");
506 outtask.println(" struct taskdescriptor * task;");
507 outtask.println(" int slot;");
508 outtask.println(" struct tagobjectiterator iterators[MAXTASKPARAMS-1];");
509 outtask.println("};");
511 outtask.println("extern struct parameterwrapper ** objectqueues[][NUMCLASSES];");
512 outtask.println("extern int numqueues[][NUMCLASSES];");
514 outtask.println("struct parameterdescriptor {");
515 outtask.println(" int type;");
516 outtask.println(" int numberterms;");
517 outtask.println(" int *intarray;");
518 outtask.println(" struct parameterwrapper * queue;");
519 outtask.println(" int numbertags;");
520 outtask.println(" int *tagarray;");
521 outtask.println("};");
523 outtask.println("struct taskdescriptor {");
524 outtask.println(" void * taskptr;");
525 outtask.println(" int numParameters;");
526 outtask.println(" int numTotal;");
527 outtask.println(" struct parameterdescriptor **descriptorarray;");
528 outtask.println(" char * name;");
529 outtask.println("};");
531 outtask.println("extern struct taskdescriptor ** taskarray[];");
532 outtask.println("extern int numtasks[];");
533 outtask.println("extern int corenum;"); // define corenum to identify different core
534 outtask.println("extern struct parameterwrapper *** paramqueues[];");
538 private void generateObjectTransQueues(PrintWriter output) {
539 if(this.fsate2qnames == null) {
540 this.fsate2qnames = new Hashtable[this.coreNum];
541 for(int i = 0; i < this.fsate2qnames.length; ++i) {
542 this.fsate2qnames[i] = null;
545 int num = this.currentSchedule.getCoreNum();
546 assert(this.fsate2qnames[num] == null);
547 Hashtable<FlagState, String> flag2qname = new Hashtable<FlagState, String>();
548 this.fsate2qnames[num] = flag2qname;
549 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
550 if(targetCoreTbl != null) {
551 Object[] keys = targetCoreTbl.keySet().toArray();
553 output.println("/* Object transfer queues for core" + num + ".*/");
554 for(int i = 0; i < keys.length; ++i) {
555 FlagState tmpfstate = (FlagState)keys[i];
556 Object[] targetcores = targetCoreTbl.get(tmpfstate).toArray();
557 String queuename = this.otqueueprefix + tmpfstate.getClassDescriptor().getCoreSafeSymbol(num) + tmpfstate.getuid() + "___";
558 String queueins = queuename + "ins";
559 flag2qname.put(tmpfstate, queuename);
560 output.println("struct " + queuename + " {");
561 output.println(" int * cores;");
562 output.println(" int index;");
563 output.println(" int length;");
564 output.println("};");
565 output.print("int " + queuename + "cores[] = {");
566 for(int j = 0; j < targetcores.length; ++j) {
570 output.print(((Integer)targetcores[j]).intValue());
572 output.println("};");
573 output.println("struct " + queuename + " " + queueins + "= {");
574 output.println(/*".cores = " + */ queuename + "cores,");
575 output.println(/*".index = " + */ "0,");
576 output.println(/*".length = " +*/ targetcores.length + "};");
582 private void generateTaskMethod(FlatMethod fm,
584 PrintWriter output) {
585 /*if (State.PRINTFLAT)
586 System.out.println(fm.printMethod());*/
587 TaskDescriptor task=fm.getTask();
588 assert(task != null);
589 int num = this.currentSchedule.getCoreNum();
591 //ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:task);
592 generateTaskHeader(fm, lb, task,output);
594 TempObject objecttemp=(TempObject) tempstable.get(lb!=null ? lb : task);
595 /*if (state.DSM&&lb.getHasAtomic()) {
596 output.println("transrecord_t * trans;");
599 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
600 output.print(" struct "+task.getCoreSafeSymbol(num)+"_locals "+localsprefix+"={");
602 output.print(objecttemp.numPointers()+",");
603 output.print(paramsprefix);
604 for(int j=0; j<objecttemp.numPointers(); j++)
605 output.print(", NULL");
606 output.println("};");
609 for(int i=0; i<objecttemp.numPrimitives(); i++) {
610 TempDescriptor td=objecttemp.getPrimitive(i);
611 TypeDescriptor type=td.getType();
613 output.println(" void * "+td.getSafeSymbol()+";");
614 else if (type.isClass()||type.isArray())
615 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
617 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
620 for(int i = 0; i < fm.numParameters(); ++i) {
621 TempDescriptor temp = fm.getParameter(i);
622 output.println(" int "+generateTempFlagName(fm, temp, lb)+" = "+super.generateTemp(fm, temp, lb)+
626 /* Assign labels to FlatNode's if necessary.*/
628 Hashtable<FlatNode, Integer> nodetolabel=super.assignLabels(fm);
630 /* Check to see if we need to do a GC if this is a
631 * multi-threaded program...*/
632 if(this.state.MULTICOREGC) {
633 output.println("if(gcflag) gc("+localsprefixaddr+");");
636 /*if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) {
637 if (state.DSM&&lb.isAtomic())
638 output.println("checkcollect2(&"+localsprefix+",trans);");
640 output.println("checkcollect(&"+localsprefix+");");
643 /* Create queues to store objects need to be transferred to other cores and their destination*/
644 //output.println(" struct Queue * totransobjqueue = createQueue();");
645 output.println(" clearQueue(totransobjqueue);");
646 output.println(" struct transObjInfo * tmpObjInfo = NULL;");
648 this.m_aliasSets = null;
649 this.m_aliasFNTbl4Para = null;
650 this.m_aliasFNTbl = null;
651 this.m_aliaslocksTbl4FN = null;
652 outputAliasLockCode(fm, lb, output);
654 /* generate print information for RAW version */
655 output.println("#ifdef MULTICORE");
658 output.println("int tmpsum = 0;");
659 output.println("char * taskname = \"" + task.getSymbol() + "\";");
660 output.println("int tmplen = " + task.getSymbol().length() + ";");
661 output.println("int tmpindex = 1;");
662 output.println("for(;tmpindex < tmplen; tmpindex++) {");
663 output.println(" tmpsum = tmpsum * 10 + *(taskname + tmpindex) - '0';");
666 output.println("#ifdef RAWPATH");
668 output.println("BAMBOO_DEBUGPRINT(0xAAAA);");
669 output.println("BAMBOO_DEBUGPRINT_REG(tmpsum);");
671 output.println("BAMBOO_START_CRITICAL_SECTION();");
672 output.println("tprintf(\"Process %x(%d): task %s\\n\", corenum, corenum, \"" + task.getSymbol() + "\");");
673 output.println("BAMBOO_CLOSE_CRITICAL_SECTION();");
675 //output.println("BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());");
676 output.println("#endif");
677 output.println("#ifdef DEBUG");
679 output.println("BAMBOO_DEBUGPRINT(0xAAAA);");
680 output.println("BAMBOO_DEBUGPRINT_REG(tmpsum);");
682 output.println("BAMBOO_START_CRITICAL_SECTION();");
683 output.println("tprintf(\"Process %x(%d): task %s\\n\", corenum, corenum, \"" + task.getSymbol() + "\");");
684 output.println("BAMBOO_CLOSE_CRITICAL_SECTION();");
686 output.println("#endif");
690 output.println("#endif");
692 for(int i = 0; i < fm.numParameters(); ++i) {
693 TempDescriptor temp = fm.getParameter(i);
694 output.println(" ++" + super.generateTemp(fm, temp, lb)+"->version;");
697 /* Do the actual code generation */
698 FlatNode current_node=null;
699 HashSet tovisit=new HashSet();
700 HashSet visited=new HashSet();
701 tovisit.add(fm.getNext(0));
702 while(current_node!=null||!tovisit.isEmpty()) {
703 if (current_node==null) {
704 current_node=(FlatNode)tovisit.iterator().next();
705 tovisit.remove(current_node);
707 visited.add(current_node);
708 if (nodetolabel.containsKey(current_node))
709 output.println("L"+nodetolabel.get(current_node)+":");
710 /*if (state.INSTRUCTIONFAILURE) {
711 if (state.THREAD||state.DSM) {
712 output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
715 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
717 if (current_node.numNext()==0) {
719 super.generateFlatNode(fm, lb, current_node, output);
720 if (current_node.kind()!=FKind.FlatReturnNode) {
721 //output.println(" flushAll();");
722 output.println("#ifdef CACHEFLUSH");
723 output.println("BAMBOO_START_CRITICAL_SECTION();");
724 output.println("#ifdef DEBUG");
725 output.println("BAMBOO_DEBUGPRINT(0xec00);");
726 output.println("#endif");
727 output.println("BAMBOO_CACHE_FLUSH_ALL();");
728 output.println("#ifdef DEBUG");
729 output.println("BAMBOO_DEBUGPRINT(0xecff);");
730 output.println("#endif");
731 output.println("BAMBOO_CLOSE_CRITICAL_SECTION();");
732 output.println("#endif");
733 outputTransCode(output);
734 output.println(" return;");
737 } else if(current_node.numNext()==1) {
739 super.generateFlatNode(fm, lb, current_node, output);
740 FlatNode nextnode=current_node.getNext(0);
741 if (visited.contains(nextnode)) {
742 output.println("goto L"+nodetolabel.get(nextnode)+";");
745 current_node=nextnode;
746 } else if (current_node.numNext()==2) {
749 super.generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
750 if (!visited.contains(current_node.getNext(1)))
751 tovisit.add(current_node.getNext(1));
752 if (visited.contains(current_node.getNext(0))) {
753 output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
756 current_node=current_node.getNext(0);
757 } else throw new Error();
760 output.println("}\n\n");
763 /** This method outputs TaskDescriptor information */
764 private void generateTaskDescriptor(PrintWriter output,
769 int num = this.currentSchedule.getCoreNum();
771 output.println("/* TaskDescriptor information for task " + task.getSymbol() + " on core " + num + "*/");
773 for (int i=0; i<task.numParameters(); i++) {
774 VarDescriptor param_var=task.getParameter(i);
775 TypeDescriptor param_type=task.getParamType(i);
776 FlagExpressionNode param_flag=task.getFlag(param_var);
777 TagExpressionList param_tag=task.getTag(param_var);
780 if (param_flag==null) {
781 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
782 output.println("0x0, 0x0 };");
785 DNFFlag dflag=param_flag.getDNF();
786 dnfterms=dflag.size();
788 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
789 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
790 for(int j=0; j<dflag.size(); j++) {
793 Vector term=dflag.get(j);
796 for(int k=0; k<term.size(); k++) {
797 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
798 FlagDescriptor fd=dfa.getFlag();
799 boolean negated=dfa.getNegated();
800 int flagid=1<<((Integer)flags.get(fd)).intValue();
805 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
807 output.println("};");
810 output.println("int parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
811 //BUG...added next line to fix, test with any task program
813 for(int j=0; j<param_tag.numTags(); j++) {
816 /* for each tag we need */
817 /* which slot it is */
818 /* what type it is */
819 TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
820 TempDescriptor tmp=param_tag.getTemp(j);
821 int slot=fm.getTagInt(tmp);
822 output.println(slot+", "+state.getTagId(tvd.getTag()));
824 output.println("};");
826 // generate object queue for this parameter
827 String qname = this.objqueueprefix+i+"_"+task.getCoreSafeSymbol(num);
828 if(param_type.getClassDesc().getSymbol().equals("StartupObject")) {
829 this.startupcorenum = num;
831 if(qnames[param_type.getClassDesc().getId()] == null) {
832 qnames[param_type.getClassDesc().getId()] = new Vector();
834 qnames[param_type.getClassDesc().getId()].addElement(qname);
835 outtask.println("extern struct parameterwrapper " + qname + ";");
836 output.println("struct parameterwrapper " + qname + "={");
837 output.println(".objectset = 0,"); // objectset
838 output.println("/* number of DNF terms */ .numberofterms = "+dnfterms+","); // numberofterms
839 output.println(".intarray = parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
842 output.println("/* number of tags */ .numbertags = "+param_tag.numTags()+",");
844 output.println("/* number of tags */ .numbertags = 0,");
845 output.println(".tagarray = parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+","); // tagarray
846 output.println(".task = 0,"); // task
847 output.println(".slot = " + i + ","); // slot
849 output.println("};");
851 output.println("struct parameterdescriptor parameter_"+i+"_"+task.getCoreSafeSymbol(num)+"={");
852 output.println("/* type */"+param_type.getClassDesc().getId()+",");
853 output.println("/* number of DNF terms */"+dnfterms+",");
854 output.println("parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
855 output.println("&" + qname + ","); // queue
856 //BUG, added next line to fix and else statement...test
857 //with any task program
859 output.println("/* number of tags */"+param_tag.numTags()+",");
861 output.println("/* number of tags */ 0,");
862 output.println("parametertag_"+i+"_"+task.getCoreSafeSymbol(num)); // tagarray
863 output.println("};");
866 /* parameter queues for this task*/
867 output.println("struct parameterwrapper * " + this.paramqarrayprefix + task.getCoreSafeSymbol(num)+"[] = {");
868 for (int i=0; i<task.numParameters(); i++) {
871 output.print("&" + this.objqueueprefix + i + "_" + task.getCoreSafeSymbol(num));
873 output.println("};");
875 output.println("struct parameterdescriptor * parameterdescriptors_"+task.getCoreSafeSymbol(num)+"[] = {");
876 for (int i=0; i<task.numParameters(); i++) {
879 output.print("¶meter_"+i+"_"+task.getCoreSafeSymbol(num));
881 output.println("};");
883 output.println("struct taskdescriptor " + this.taskprefix + task.getCoreSafeSymbol(num) + "={");
884 output.println("&"+task.getCoreSafeSymbol(num)+",");
885 output.println("/* number of parameters */" +task.numParameters() + ",");
886 int numtotal=task.numParameters()+fm.numTags();
887 output.println("/* number total parameters */" +numtotal + ",");
888 output.println("parameterdescriptors_"+task.getCoreSafeSymbol(num)+",");
889 output.println("\""+task.getSymbol()+"\"");
890 output.println("};");
895 /** This method generates header information for the task
896 * referenced by the Descriptor des. */
898 private void generateTaskHeader(FlatMethod fm,
901 PrintWriter output) {
903 ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : des);
904 TaskDescriptor task=(TaskDescriptor) des;
906 int num = this.currentSchedule.getCoreNum();
907 //catch the constructor case
908 output.print("void ");
909 output.print(task.getCoreSafeSymbol(num)+"(");
911 boolean printcomma=false;
912 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
913 output.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
917 /*if (state.DSM&&lb.isAtomic()) {
920 output.print("transrecord_t * trans");
924 if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
926 output.println("void * parameterarray[]) {");
927 /* Unpack variables */
928 for(int i=0; i<objectparams.numPrimitives(); i++) {
929 TempDescriptor temp=objectparams.getPrimitive(i);
930 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
932 for(int i=0; i<fm.numTags(); i++) {
933 TempDescriptor temp=fm.getTag(i);
934 int offset=i+objectparams.numPrimitives();
935 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+i+"___=parameterarray["+offset+"];"); // add i to fix bugs of duplicate definition of tags
938 if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
939 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
940 } else output.println(") {");
943 protected void generateFlagOrAnd(FlatFlagActionNode ffan,
950 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
951 output.println("flagorandinit("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
953 int num = this.currentSchedule.getCoreNum();
954 ClassDescriptor cd = temp.getType().getClassDesc();
955 Vector<FlagState> initfstates = ffan.getInitFStates(cd);
956 for(int i = 0; i < initfstates.size(); ++i) {
957 FlagState tmpFState = initfstates.elementAt(i);
959 QueueInfo qinfo = outputqueues(tmpFState, num, output, false);
960 output.println("flagorand("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+
961 ", 0x"+Integer.toHexString(andmask)+", " + qinfo.qname +
962 ", " + qinfo.length + ");");
965 if(ffan.getTaskType()==FlatFlagActionNode.TASKEXIT) {
966 // generate codes for profiling, recording which task exit it is
967 output.println("#ifdef PROFILE");
968 output.println("setTaskExitIndex(" + ffan.getTaskExitIndex() + ");");
969 output.println("#endif");
974 protected void generateObjectDistribute(FlatFlagActionNode ffan,
978 PrintWriter output) {
979 ClassDescriptor cd = temp.getType().getClassDesc();
980 Vector<FlagState> initfstates = null;
981 Vector[] targetFStates = null;
982 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
983 targetFStates = new Vector[1];
984 targetFStates[0] = ffan.getTargetFStates4NewObj(cd);
986 initfstates = ffan.getInitFStates(cd);
987 targetFStates = new Vector[initfstates.size()];
988 for(int i = 0; i < initfstates.size(); ++i) {
989 FlagState fs = initfstates.elementAt(i);
990 targetFStates[i] = ffan.getTargetFStates(fs);
992 if(!fs.isSetmask()) {
993 Hashtable flags=(Hashtable)flagorder.get(cd);
996 Iterator it_flags = fs.getFlags();
997 while(it_flags.hasNext()) {
998 FlagDescriptor fd = (FlagDescriptor)it_flags.next();
999 int flagid=1<<((Integer)flags.get(fd)).intValue();
1003 fs.setAndmask(andmask);
1004 fs.setCheckmask(checkmask);
1005 fs.setSetmask(true);
1009 boolean isolate = true; // check if this flagstate can associate to some task with multiple params which can
1010 // reside on multiple cores
1011 if((this.currentSchedule == null) && (fm.getMethod().getClassDesc().getSymbol().equals("ServerSocket"))) {
1012 // ServerSocket object will always reside on current core
1013 for(int j = 0; j < targetFStates.length; ++j) {
1014 if(initfstates != null) {
1015 FlagState fs = initfstates.elementAt(j);
1016 output.println("if(" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
1017 + ")==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
1019 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
1020 for(int i = 0; i < tmpfstates.size(); ++i) {
1021 FlagState tmpFState = tmpfstates.elementAt(i);
1023 // may have bugs here
1024 output.println("/* reside on this core*");
1025 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1027 if(initfstates != null) {
1028 output.println("}");
1034 int num = this.currentSchedule.getCoreNum();
1035 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
1036 for(int j = 0; j < targetFStates.length; ++j) {
1037 FlagState fs = null;
1038 if(initfstates != null) {
1039 fs = initfstates.elementAt(j);
1040 output.println("if((" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
1041 + "))==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
1043 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
1044 for(int i = 0; i < tmpfstates.size(); ++i) {
1045 FlagState tmpFState = tmpfstates.elementAt(i);
1047 if(this.currentSchedule.getAllyCoreTable() == null) {
1050 isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) ||
1051 (this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
1054 Vector<Integer> sendto = new Vector<Integer>();
1055 Queue<Integer> queue = null;
1056 if(targetCoreTbl != null) {
1057 queue = targetCoreTbl.get(tmpFState);
1059 if((queue != null) &&
1060 ((queue.size() != 1) ||
1061 ((queue.size() == 1) && (queue.element().intValue() != num)))) {
1062 // this object may be transferred to other cores
1063 String queuename = (String) this.fsate2qnames[num].get(tmpFState);
1064 String queueins = queuename + "ins";
1066 Object[] cores = queue.toArray();
1068 Integer targetcore = (Integer)cores[0];
1069 if(queue.size() > 1) {
1070 index = queueins + ".index";
1072 if(queue.size() > 1) {
1073 output.println("switch(" + queueins + ".index % " + queueins + ".length) {");
1074 for(int k = 0; k < cores.length; ++k) {
1075 output.println("case " + k + ":");
1076 targetcore = (Integer)cores[k];
1077 if(targetcore.intValue() == num) {
1078 output.println("/* reside on this core*/");
1080 output.println("{");
1081 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1082 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1083 ", " + qinfo.length + ");");
1084 output.println("}");
1088 output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1089 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1090 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1094 // Is it possible to decide the actual queues?
1095 output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1096 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1097 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1098 output.println("/* transfer to core " + targetcore.toString() + "*/");
1099 output.println("{");
1100 // enqueue this object and its destinations for later process
1101 // all the possible queues
1102 QueueInfo qinfo = null;
1103 TranObjInfo tmpinfo = new TranObjInfo();
1104 tmpinfo.name = super.generateTemp(fm, temp, lb);
1105 tmpinfo.targetcore = targetcore;
1106 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1107 if(targetFS != null) {
1108 tmpinfo.fs = targetFS;
1110 tmpinfo.fs = tmpFState;
1112 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1113 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1114 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1115 output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1116 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1117 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1118 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1119 output.println("}");
1121 output.println("break;");
1123 output.println("}");
1127 // Is it possible to decide the actual queues?
1128 output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1129 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1130 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1131 output.println("/* transfer to core " + targetcore.toString() + "*/");
1132 output.println("{");
1133 // enqueue this object and its destinations for later process
1134 // all the possible queues
1135 QueueInfo qinfo = null;
1136 TranObjInfo tmpinfo = new TranObjInfo();
1137 tmpinfo.name = super.generateTemp(fm, temp, lb);
1138 tmpinfo.targetcore = targetcore;
1139 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1140 if(targetFS != null) {
1141 tmpinfo.fs = targetFS;
1143 tmpinfo.fs = tmpFState;
1145 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1146 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1147 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1148 output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1149 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1150 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1151 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1152 output.println("}");
1154 output.println("/* increase index*/");
1155 output.println("++" + queueins + ".index;");
1157 // this object will reside on current core
1158 output.println("/* reside on this core*/");
1160 output.println("{");
1161 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1162 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1163 ", " + qinfo.length + ");");
1164 output.println("}");
1168 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1169 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1172 // codes for multi-params tasks
1174 // flagstate associated with some multi-params tasks
1175 // need to be send to other cores
1176 Vector<Integer> targetcores = this.currentSchedule.getAllyCores(tmpFState);
1177 output.println("/* send the shared object to possible queues on other cores*/");
1178 // TODO, temporary solution, send to mostly the first two
1179 int upperbound = targetcores.size() > 2? 2: targetcores.size();
1180 for(int k = 0; k < upperbound; ++k) {
1182 // add the information of exactly which queue
1183 int targetcore = targetcores.elementAt(k).intValue();
1184 if(!sendto.contains(targetcore)) {
1185 // previously not sended to this target core
1186 // enqueue this object and its destinations for later process
1187 output.println("{");
1188 // all the possible queues
1189 QueueInfo qinfo = null;
1190 TranObjInfo tmpinfo = new TranObjInfo();
1191 tmpinfo.name = super.generateTemp(fm, temp, lb);
1192 tmpinfo.targetcore = targetcore;
1193 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1194 if(targetFS != null) {
1195 tmpinfo.fs = targetFS;
1197 tmpinfo.fs = tmpFState;
1199 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1200 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1201 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1202 output.println("tmpObjInfo->targetcore = "+targetcore+";");
1203 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1204 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1205 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1206 output.println("}");
1207 sendto.addElement(targetcore);
1213 if(initfstates != null) {
1214 output.println("}");
1219 private QueueInfo outputqueues(FlagState tmpFState,
1222 boolean isEnqueue) {
1224 QueueInfo qinfo = new QueueInfo();
1225 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1226 output.println("struct parameterwrapper * " + qinfo.qname + "[] = {");
1227 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1228 Vector<TaskDescriptor> residetasks = this.currentSchedule.getTasks();
1229 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1230 Vector<Integer> indexes = new Vector<Integer>();
1231 boolean comma = false;
1233 while(it_edges.hasNext()) {
1234 FEdge fe = (FEdge)it_edges.next();
1235 TaskDescriptor td = fe.getTask();
1236 int paraindex = fe.getIndex();
1237 if((!isEnqueue) || (isEnqueue && residetasks.contains(td))) {
1238 if((!tasks.contains(td)) ||
1239 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1240 tasks.addElement(td);
1241 indexes.addElement(paraindex);
1243 output.println(",");
1247 output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
1252 output.println("};");
1256 private QueueInfo outputtransqueues(FlagState tmpFState,
1258 PrintWriter output) {
1260 QueueInfo qinfo = new QueueInfo();
1261 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1262 output.println("int " + qinfo.qname + "_clone[] = {");
1263 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1264 Vector<TaskDescriptor> residetasks = this.scheduling.get(targetcore).getTasks();
1265 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1266 Vector<Integer> indexes = new Vector<Integer>();
1267 boolean comma = false;
1269 while(it_edges.hasNext()) {
1270 FEdge fe = (FEdge)it_edges.next();
1271 TaskDescriptor td = fe.getTask();
1272 int paraindex = fe.getIndex();
1273 if(residetasks.contains(td)) {
1274 if((!tasks.contains(td)) ||
1275 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1276 tasks.addElement(td);
1277 indexes.addElement(paraindex);
1279 output.println(",");
1283 output.print(residetasks.indexOf(td) + ", ");
1284 output.print(paraindex);
1289 output.println("};");
1290 output.println("int * " + qinfo.qname + " = RUNMALLOC(sizeof(int) * " + qinfo.length * 2 + ");");
1291 output.println("memcpy(" + qinfo.qname + ", (int *)" + qinfo.qname + "_clone, sizeof(int) * " + qinfo.length * 2 + ");");
1295 private class QueueInfo {
1297 public String qname;
1300 private String generateTempFlagName(FlatMethod fm,
1302 LocalityBinding lb) {
1303 MethodDescriptor md=fm.getMethod();
1304 TaskDescriptor task=fm.getTask();
1305 TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
1307 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1308 return td.getSafeSymbol() + "_oldflag";
1311 if (objecttemps.isLocalPtr(td)) {
1312 return localsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1315 if (objecttemps.isParamPtr(td)) {
1316 return paramsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1321 protected void outputTransCode(PrintWriter output) {
1322 output.println("while(0 == isEmpty(totransobjqueue)) {");
1323 output.println(" struct transObjInfo * totransobj = (struct transObjInfo *)(getItem(totransobjqueue));");
1324 output.println(" transferObject(totransobj);");
1325 output.println(" RUNFREE(totransobj->queues);");
1326 output.println(" RUNFREE(totransobj);");
1327 output.println("}");
1328 //output.println("freeQueue(totransobjqueue);");
1331 protected void outputAliasLockCode(FlatMethod fm,
1333 PrintWriter output) {
1334 if(this.m_oa == null) {
1337 TaskDescriptor td = fm.getTask();
1338 Object[] allocSites = this.m_oa.getFlaggedAllocationSitesReachableFromTask(td).toArray();
1339 Vector<Vector<Integer>> aliasSets = new Vector<Vector<Integer>>();
1340 Vector<Vector<FlatNew>> aliasFNSets = new Vector<Vector<FlatNew>>();
1341 Hashtable<Integer, Vector<FlatNew>> aliasFNTbl4Para = new Hashtable<Integer, Vector<FlatNew>>();
1342 Hashtable<FlatNew, Vector<FlatNew>> aliasFNTbl = new Hashtable<FlatNew, Vector<FlatNew>>();
1343 Set<HeapRegionNode> common;
1344 for( int i = 0; i < fm.numParameters(); ++i ) {
1345 // for the ith parameter check for aliases to all
1346 // higher numbered parameters
1347 aliasSets.add(null);
1348 for( int j = i + 1; j < fm.numParameters(); ++j ) {
1349 common = this.m_oa.createsPotentialAliases(td, i, j);
1350 if(!common.isEmpty()) {
1351 // ith parameter and jth parameter has alias, create lock to protect them
1352 if(aliasSets.elementAt(i) == null) {
1353 aliasSets.setElementAt(new Vector<Integer>(), i);
1355 aliasSets.elementAt(i).add(j);
1359 // for the ith parameter, check for aliases against
1360 // the set of allocation sites reachable from this
1362 aliasFNSets.add(null);
1363 for(int j = 0; j < allocSites.length; j++) {
1364 AllocationSite as = (AllocationSite)allocSites[j];
1365 common = this.m_oa.createsPotentialAliases(td, i, as);
1366 if( !common.isEmpty() ) {
1367 // ith parameter and allocationsite as has alias
1368 if(aliasFNSets.elementAt(i) == null) {
1369 aliasFNSets.setElementAt(new Vector<FlatNew>(), i);
1371 aliasFNSets.elementAt(i).add(as.getFlatNew());
1376 // for each allocation site check for aliases with
1377 // other allocation sites in the context of execution
1379 for( int i = 0; i < allocSites.length; ++i ) {
1380 AllocationSite as1 = (AllocationSite)allocSites[i];
1381 for(int j = i + 1; j < allocSites.length; j++) {
1382 AllocationSite as2 = (AllocationSite)allocSites[j];
1384 common = this.m_oa.createsPotentialAliases(td, as1, as2);
1385 if( !common.isEmpty() ) {
1386 // as1 and as2 has alias
1387 if(!aliasFNTbl.containsKey(as1.getFlatNew())) {
1388 aliasFNTbl.put(as1.getFlatNew(), new Vector<FlatNew>());
1390 if(!aliasFNTbl.get(as1.getFlatNew()).contains(as2.getFlatNew())) {
1391 aliasFNTbl.get(as1.getFlatNew()).add(as2.getFlatNew());
1397 // if FlatNew N1->N2->N3, we group N1, N2, N3 together
1398 Iterator<FlatNew> it = aliasFNTbl.keySet().iterator();
1399 Vector<FlatNew> visited = new Vector<FlatNew>();
1400 while(it.hasNext()) {
1401 FlatNew tmpfn = it.next();
1402 if(visited.contains(tmpfn)) {
1406 Queue<FlatNew> tovisit = new LinkedList<FlatNew>();
1407 Vector<FlatNew> tmpv = aliasFNTbl.get(tmpfn);
1412 for(int j = 0; j < tmpv.size(); j++) {
1413 tovisit.add(tmpv.elementAt(j));
1416 while(!tovisit.isEmpty()) {
1417 FlatNew fn = tovisit.poll();
1419 Vector<FlatNew> tmpset = aliasFNTbl.get(fn);
1420 if(tmpset != null) {
1421 // merge tmpset to the alias set of the ith parameter
1422 for(int j = 0; j < tmpset.size(); j++) {
1423 if(!tmpv.contains(tmpset.elementAt(j))) {
1424 tmpv.add(tmpset.elementAt(j));
1425 tovisit.add(tmpset.elementAt(j));
1428 aliasFNTbl.remove(fn);
1431 it = aliasFNTbl.keySet().iterator();
1434 // check alias between parameters and between parameter-flatnew
1435 for(int i = 0; i < aliasSets.size(); i++) {
1436 Queue<Integer> tovisit = new LinkedList<Integer>();
1437 Vector<Integer> tmpv = aliasSets.elementAt(i);
1442 for(int j = 0; j < tmpv.size(); j++) {
1443 tovisit.add(tmpv.elementAt(j));
1446 while(!tovisit.isEmpty()) {
1447 int index = tovisit.poll().intValue();
1448 Vector<Integer> tmpset = aliasSets.elementAt(index);
1449 if(tmpset != null) {
1450 // merge tmpset to the alias set of the ith parameter
1451 for(int j = 0; j < tmpset.size(); j++) {
1452 if(!tmpv.contains(tmpset.elementAt(j))) {
1453 tmpv.add(tmpset.elementAt(j));
1454 tovisit.add(tmpset.elementAt(j));
1457 aliasSets.setElementAt(null, index);
1460 Vector<FlatNew> tmpFNSet = aliasFNSets.elementAt(index);
1461 if(tmpFNSet != null) {
1462 // merge tmpFNSet to the aliasFNSet of the ith parameter
1463 if(aliasFNSets.elementAt(i) == null) {
1464 aliasFNSets.setElementAt(tmpFNSet, i);
1466 Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1467 for(int j = 0; j < tmpFNSet.size(); j++) {
1468 if(!tmpFNv.contains(tmpFNSet.elementAt(j))) {
1469 tmpFNv.add(tmpFNSet.elementAt(j));
1473 aliasFNSets.setElementAt(null, index);
1479 int numparalock = 0;
1480 Vector<Vector<Integer>> tmpaliasSets = new Vector<Vector<Integer>>();
1481 for(int i = 0; i < aliasSets.size(); i++) {
1482 Vector<Integer> tmpv = aliasSets.elementAt(i);
1485 tmpaliasSets.add(tmpv);
1489 Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1490 if(tmpFNv != null) {
1491 aliasFNTbl4Para.put(i, tmpFNv);
1497 numparalock = numlock;
1500 this.m_aliasSets = tmpaliasSets;
1501 tmpaliasSets.clear();
1502 tmpaliasSets = null;
1503 aliasFNSets.clear();
1505 this.m_aliasFNTbl4Para = aliasFNTbl4Para;
1506 this.m_aliasFNTbl = aliasFNTbl;
1507 numlock += this.m_aliasFNTbl.size();
1511 output.println("int aliaslocks[" + numlock + "];");
1512 output.println("int tmpi = 0;");
1513 // associate locks with parameters
1515 for(int i = 0; i < this.m_aliasSets.size(); i++) {
1516 Vector<Integer> toadd = this.m_aliasSets.elementAt(i);
1518 output.print("int tmplen_" + lockindex + " = 0;");
1519 output.println("void * tmpptrs_" + lockindex + "[] = {");
1520 for(int j = 0; j < toadd.size(); j++) {
1521 int para = toadd.elementAt(j).intValue();
1522 output.print(super.generateTemp(fm, fm.getParameter(para), lb));
1523 if(j < toadd.size() - 1) {
1526 output.println("};");
1529 output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", tmplen_" + lockindex + ", lockRedirectTbl);");
1531 for(int j = 0; j < toadd.size(); j++) {
1532 int para = toadd.elementAt(j).intValue();
1533 output.println("addAliasLock(" + super.generateTemp(fm, fm.getParameter(para), lb) + ", aliaslocks[" + i + "]);");
1535 // check if this lock is also associated with any FlatNew nodes
1536 if(this.m_aliasFNTbl4Para.containsKey(toadd.elementAt(0))) {
1537 if(this.m_aliaslocksTbl4FN == null) {
1538 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1540 Vector<FlatNew> tmpv = this.m_aliasFNTbl4Para.get(toadd.elementAt(0));
1541 for(int j = 0; j < tmpv.size(); j++) {
1542 FlatNew fn = tmpv.elementAt(j);
1543 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1544 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1546 this.m_aliaslocksTbl4FN.get(fn).add(i);
1548 this.m_aliasFNTbl4Para.remove(toadd.elementAt(0));
1553 Object[] key = this.m_aliasFNTbl4Para.keySet().toArray();
1554 for(int i = 0; i < key.length; i++) {
1555 int para = ((Integer)key[i]).intValue();
1557 output.println("void * tmpptrs_" + lockindex + "[] = {" + super.generateTemp(fm, fm.getParameter(para), lb) + "};");
1558 output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", 1, lockRedirectTbl);");
1560 output.println("addAliasLock(" + super.generateTemp(fm, fm.getParameter(para), lb) + ", aliaslocks[" + lockindex + "]);");
1561 Vector<FlatNew> tmpv = this.m_aliasFNTbl4Para.get(para);
1562 for(int j = 0; j < tmpv.size(); j++) {
1563 FlatNew fn = tmpv.elementAt(j);
1564 if(this.m_aliaslocksTbl4FN == null) {
1565 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1567 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1568 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1570 this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
1575 // check m_aliasFNTbl for locks associated with FlatNew nodes
1576 Object[] FNkey = this.m_aliasFNTbl.keySet().toArray();
1577 for(int i = 0; i < FNkey.length; i++) {
1578 FlatNew fn = (FlatNew)FNkey[i];
1579 Vector<FlatNew> tmpv = this.m_aliasFNTbl.get(fn);
1581 output.println("aliaslocks[tmpi++] = (int)(RUNMALLOC(sizeof(int)));");
1583 if(this.m_aliaslocksTbl4FN == null) {
1584 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1586 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1587 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1589 this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
1590 for(int j = 0; j < tmpv.size(); j++) {
1591 FlatNew tfn = tmpv.elementAt(j);
1592 if(!this.m_aliaslocksTbl4FN.containsKey(tfn)) {
1593 this.m_aliaslocksTbl4FN.put(tfn, new Vector<Integer>());
1595 this.m_aliaslocksTbl4FN.get(tfn).add(lockindex);
1602 protected void generateFlatReturnNode(FlatMethod fm,
1605 PrintWriter output) {
1606 if (frn.getReturnTemp()!=null) {
1607 if (frn.getReturnTemp().getType().isPtr())
1608 output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1610 output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1612 if(fm.getTask() != null) {
1613 output.println("#ifdef CACHEFLUSH");
1614 output.println("BAMBOO_START_CRITICAL_SECTION();");
1615 output.println("#ifdef DEBUG");
1616 output.println("BAMBOO_DEBUGPRINT(0xec00);");
1617 output.println("#endif");
1618 output.println("BAMBOO_CACHE_FLUSH_ALL();");
1619 output.println("#ifdef DEBUG");
1620 output.println("BAMBOO_DEBUGPRINT(0xecff);");
1621 output.println("#endif");
1622 output.println("BAMBOO_CLOSE_CRITICAL_SECTION();");
1623 output.println("#endif");
1624 outputTransCode(output);
1626 output.println("return;");
1630 protected void generateFlatNew(FlatMethod fm,
1633 PrintWriter output) {
1634 if (state.DSM && locality.getAtomic(lb).get(fn).intValue() > 0
1635 && !fn.isGlobal()) {
1636 // Stash pointer in case of GC
1637 String revertptr = super.generateTemp(fm, reverttable.get(lb), lb);
1638 output.println(revertptr + "=trans->revertlist;");
1640 if (fn.getType().isArray()) {
1641 int arrayid = state.getArrayNumber(fn.getType())
1642 + state.numClasses();
1643 if (fn.isGlobal()) {
1644 output.println(super.generateTemp(fm, fn.getDst(), lb)
1645 + "=allocate_newarrayglobal(trans, " + arrayid + ", "
1646 + super.generateTemp(fm, fn.getSize(), lb) + ");");
1647 } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1648 output.println(super.generateTemp(fm, fn.getDst(), lb)
1649 + "=allocate_newarray(&" + localsprefix + ", "
1650 + arrayid + ", " + super.generateTemp(fm, fn.getSize(), lb)
1653 output.println(super.generateTemp(fm, fn.getDst(), lb)
1654 + "=allocate_newarray(" + arrayid + ", "
1655 + super.generateTemp(fm, fn.getSize(), lb) + ");");
1658 if (fn.isGlobal()) {
1659 output.println(super.generateTemp(fm, fn.getDst(), lb)
1660 + "=allocate_newglobal(trans, "
1661 + fn.getType().getClassDesc().getId() + ");");
1662 } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1663 output.println(super.generateTemp(fm, fn.getDst(), lb)
1664 + "=allocate_new(&" + localsprefix + ", "
1665 + fn.getType().getClassDesc().getId() + ");");
1667 output.println(super.generateTemp(fm, fn.getDst(), lb)
1669 + fn.getType().getClassDesc().getId() + ");");
1672 if (state.DSM && locality.getAtomic(lb).get(fn).intValue() > 0
1673 && !fn.isGlobal()) {
1674 String revertptr = super.generateTemp(fm, reverttable.get(lb), lb);
1675 output.println("trans->revertlist=" + revertptr + ";");
1677 // create alias lock if necessary
1678 if((this.m_aliaslocksTbl4FN != null) && (this.m_aliaslocksTbl4FN.containsKey(fn))) {
1679 Vector<Integer> tmpv = this.m_aliaslocksTbl4FN.get(fn);
1680 for(int i = 0; i < tmpv.size(); i++) {
1681 output.println("addAliasLock(" + super.generateTemp(fm, fn.getDst(), lb) + ", aliaslocks[" + tmpv.elementAt(i).intValue() + "]);");
1684 // generate codes for profiling, recording how many new objects are created
1685 if(!fn.getType().isArray() &&
1686 (fn.getType().getClassDesc() != null)
1687 && (fn.getType().getClassDesc().hasFlags())) {
1688 output.println("#ifdef PROFILE");
1689 output.println("addNewObjInfo(\"" + fn.getType().getClassDesc().getSymbol() + "\");");
1690 output.println("#endif");
1696 public int targetcore;
1697 public FlagState fs;
1700 private boolean contains(Vector<TranObjInfo> sendto,
1702 if(sendto.size() == 0) {
1705 for(int i = 0; i < sendto.size(); i++) {
1706 TranObjInfo tmp = sendto.elementAt(i);
1707 if(!tmp.name.equals(t.name)) {
1710 if(tmp.targetcore != t.targetcore) {
1713 if(tmp.fs != t.fs) {