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.Scheduling.Schedule;
14 import Analysis.TaskStateAnalysis.FEdge;
15 import Analysis.TaskStateAnalysis.FlagState;
16 import Analysis.TaskStateAnalysis.SafetyAnalysis;
17 import Analysis.OwnershipAnalysis.AllocationSite;
18 import Analysis.OwnershipAnalysis.OwnershipAnalysis;
19 import Analysis.OwnershipAnalysis.HeapRegionNode;
20 import Analysis.Prefetch.*;
21 import IR.ClassDescriptor;
23 import IR.FlagDescriptor;
24 import IR.MethodDescriptor;
26 import IR.TagVarDescriptor;
27 import IR.TaskDescriptor;
28 import IR.TypeDescriptor;
30 import IR.VarDescriptor;
31 import IR.Tree.DNFFlag;
32 import IR.Tree.DNFFlagAtom;
33 import IR.Tree.FlagExpressionNode;
34 import IR.Tree.TagExpressionList;
36 public class BuildCodeMultiCore extends BuildCode {
37 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 protected OwnershipAnalysis m_oa;
53 protected 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,
65 super(st, temptovar, typeutil, sa);
66 this.scheduling = scheduling;
67 this.coreNum = coreNum; // # of the active cores
68 this.tcoreNum = coreNum; // # of the cores setup by users
69 this.gcoreNum = gcoreNum; // # of the cores for gc if any
70 this.currentSchedule = null;
71 this.fsate2qnames = null;
72 this.startupcorenum = 0;
74 // sometimes there are extra cores then needed in scheduling
76 // currently, it is guaranteed that in scheduling, the corenum
77 // is started from 0 and continuous.
78 // MAY need modification here in the future when take hardware
79 // information into account.
80 if(this.scheduling.size() < this.coreNum) {
81 this.coreNum = this.scheduling.size();
85 this.m_aliasSets = null;
86 this.m_aliasFNTbl4Para = null;
87 this.m_aliasFNTbl = null;
88 this.m_aliaslocksTbl4FN = null;
91 public void setOwnershipAnalysis(OwnershipAnalysis m_oa) {
95 public void buildCode() {
96 /* Create output streams to write to */
97 PrintWriter outclassdefs=null;
98 PrintWriter outglobaldefs=null;
99 PrintWriter outglobaldefsprim=null;
100 PrintWriter outstructs=null;
101 PrintWriter outmethodheader=null;
102 PrintWriter outmethod=null;
103 PrintWriter outvirtual=null;
104 PrintWriter outtask=null;
105 PrintWriter outtaskdefs=null;
106 //PrintWriter outoptionalarrays=null;
107 //PrintWriter optionalheaders=null;
110 outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
111 outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
112 outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
113 outglobaldefs=new PrintWriter(new FileOutputStream(PREFIX+"globaldefs.h"), true);
114 outglobaldefsprim=new PrintWriter(new FileOutputStream(PREFIX+"globaldefsprim.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 /* Fix field safe symbols due to shadowing */
135 FieldShadow.handleFieldShadow(state);
137 /* Build the virtual dispatch tables */
139 buildVirtualTables(outvirtual);
141 /* Tag the methods that are invoked by static blocks */
142 tagMethodInvokedByStaticBlock();
144 /* Output includes */
145 outmethodheader.println("#ifndef METHODHEADERS_H");
146 outmethodheader.println("#define METHODHEADERS_H");
147 outmethodheader.println("#include \"structdefs.h\"");
149 outmethodheader.println("#include \"dstm.h\"");*/
151 /* Output Structures */
152 outputStructs(outstructs);
154 outglobaldefs.println("#ifndef __GLOBALDEF_H_");
155 outglobaldefs.println("#define __GLOBALDEF_H_");
156 outglobaldefs.println("");
157 outglobaldefs.println("struct global_defs_t {");
158 outglobaldefs.println(" int size;");
159 outglobaldefs.println(" void * next;");
161 outglobaldefsprim.println("#ifndef __GLOBALDEFPRIM_H_");
162 outglobaldefsprim.println("#define __GLOBALDEFPRIM_H_");
163 outglobaldefsprim.println("");
164 outglobaldefsprim.println("struct global_defsprim_t {");
166 // Output the C class declarations
167 // These could mutually reference each other
168 outclassdefs.println("#ifndef __CLASSDEF_H_");
169 outclassdefs.println("#define __CLASSDEF_H_");
170 outputClassDeclarations(outclassdefs, outglobaldefs, outglobaldefsprim);
172 // Output function prototypes and structures for parameters
173 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
174 int numclasses = this.state.numClasses();
175 while(it.hasNext()) {
176 ClassDescriptor cn=(ClassDescriptor)it.next();
177 generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs, outglobaldefsprim);
179 outclassdefs.println("#include \"globaldefs.h\"");
180 outclassdefs.println("#include \"globaldefsprim.h\"");
181 outclassdefs.println("#endif");
182 outclassdefs.close();
183 outglobaldefs.println("};");
184 outglobaldefs.println("");
185 outglobaldefs.println("extern struct global_defs_t * global_defs_p;");
186 outglobaldefs.println("#endif");
187 outglobaldefs.flush();
188 outglobaldefs.close();
190 outglobaldefsprim.println("};");
191 outglobaldefsprim.println("");
192 outglobaldefsprim.println("extern struct global_defsprim_t * global_defsprim_p;");
193 outglobaldefsprim.println("#endif");
194 outglobaldefsprim.flush();
195 outglobaldefsprim.close();
198 /* Map flags to integers */
199 /* The runtime keeps track of flags using these integers */
200 it=state.getClassSymbolTable().getDescriptorsIterator();
201 while(it.hasNext()) {
202 ClassDescriptor cn=(ClassDescriptor)it.next();
206 generateTaskStructs(outstructs, outmethodheader);
208 /* Outputs generic task structures if this is a task
210 outputTaskTypes(outtask);
213 /* Build the actual methods */
214 outputMethods(outmethod);
217 Iterator[] taskits = new Iterator[this.coreNum];
218 for(int i = 0; i < taskits.length; ++i) {
221 int[] numtasks = new int[this.coreNum];
222 int[][] numqueues = new int[this.coreNum][numclasses];
223 /* Output code for tasks */
224 for(int i = 0; i < this.scheduling.size(); ++i) {
225 this.currentSchedule = this.scheduling.elementAt(i);
226 outputTaskCode(outtaskdefs, outmethod, outtask, taskits, numtasks, numqueues);
229 // Output task descriptors
230 boolean comma = false;
231 outtaskdefs.println("struct parameterwrapper ** objectqueues[][NUMCLASSES] = {");
232 boolean needcomma = false;
233 for(int i = 0; i < numqueues.length ; ++i) {
235 outtaskdefs.println(",");
239 outtaskdefs.println("/* object queue array for core " + i + "*/");
240 outtaskdefs.print("{");
242 for(int j = 0; j < numclasses; ++j) {
244 outtaskdefs.println(",");
248 outtaskdefs.print(this.objqarrayprefix + j + "_core" + i);
250 outtaskdefs.print("}");
252 outtaskdefs.println("};");
254 outtaskdefs.println("int numqueues[][NUMCLASSES] = {");
255 for(int i = 0; i < numqueues.length; ++i) {
257 outtaskdefs.println(",");
261 int[] tmparray = numqueues[i];
263 outtaskdefs.print("{");
264 for(int j = 0; j < tmparray.length; ++j) {
266 outtaskdefs.print(",");
270 outtaskdefs.print(tmparray[j]);
272 outtaskdefs.print("}");
274 outtaskdefs.println("};");
276 /* parameter queue arrays for all the tasks*/
277 outtaskdefs.println("struct parameterwrapper *** paramqueues[] = {");
279 for(int i = 0; i < this.coreNum ; ++i) {
281 outtaskdefs.println(",");
285 outtaskdefs.println("/* parameter queue array for core " + i + "*/");
286 outtaskdefs.print(this.coreqarrayprefix + i);
288 outtaskdefs.println("};");
290 for(int i = 0; i < taskits.length; ++i) {
291 outtaskdefs.println("struct taskdescriptor * " + this.taskarrayprefix + i + "[]={");
292 Iterator taskit = taskits[i];
295 while(taskit.hasNext()) {
296 TaskDescriptor td=(TaskDescriptor)taskit.next();
300 outtaskdefs.println(",");
301 outtaskdefs.print("&" + this.taskprefix +td.getCoreSafeSymbol(i));
304 outtaskdefs.println();
305 outtaskdefs.println("};");
307 outtaskdefs.println("struct taskdescriptor ** taskarray[]= {");
309 for(int i = 0; i < taskits.length; ++i) {
311 outtaskdefs.println(",");
314 outtaskdefs.print(this.taskarrayprefix + i);
316 outtaskdefs.println("};");
318 outtaskdefs.print("int numtasks[]= {");
320 for(int i = 0; i < taskits.length; ++i) {
322 outtaskdefs.print(",");
325 outtaskdefs.print(numtasks[i]);
327 outtaskdefs.println("};");
328 outtaskdefs.println("int corenum=0;");
331 outtask.println("#endif");
333 /* Record maximum number of task parameters */
334 outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
335 /* Record maximum number of all types, i.e. length of classsize[] */
336 outstructs.println("#define NUMTYPES "+(state.numClasses() + state.numArrays() + state.numInterfaces()));
337 /* Record number of total cores */
338 outstructs.println("#define NUMCORES "+this.tcoreNum);
339 /* Record number of active cores */
340 outstructs.println("#define NUMCORESACTIVE "+this.coreNum); // this.coreNum
341 // can be reset by the scheduling analysis
342 /* Record number of garbage collection cores */
343 outstructs.println("#ifdef MULTICORE_GC");
344 outstructs.println("#define NUMCORES4GC "+this.gcoreNum);
345 outstructs.println("#endif");
346 /* Record number of core containing startup task */
347 outstructs.println("#define STARTUPCORE "+this.startupcorenum);
348 } //else if (state.main!=null) {
349 /* Generate main method */
350 // outputMainMethod(outmethod);
353 /* Generate information for task with optional parameters */
354 /*if (state.TASK&&state.OPTIONAL){
355 generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
356 outoptionalarrays.close();
359 /* Output structure definitions for repair tool */
360 /*if (state.structfile!=null) {
361 buildRepairStructs(outrepairstructs);
362 outrepairstructs.close();
366 outmethodheader.println("#endif");
367 outmethodheader.close();
369 outstructs.println("#endif");
373 /** This function outputs (1) structures that parameters are
374 * passed in (when PRECISE GC is enabled) and (2) function
375 * prototypes for the tasks */
377 protected void generateTaskStructs(PrintWriter output,
378 PrintWriter headersout) {
379 /* Cycle through tasks */
380 for(int i = 0; i < this.scheduling.size(); ++i) {
381 Schedule tmpschedule = this.scheduling.elementAt(i);
382 int num = tmpschedule.getCoreNum();
383 Iterator<TaskDescriptor> taskit = tmpschedule.getTasks().iterator();
385 while(taskit.hasNext()) {
386 /* Classify parameters */
387 TaskDescriptor task=taskit.next();
388 FlatMethod fm=state.getMethodFlat(task);
389 generateTempStructs(fm);
391 ParamsObject objectparams=(ParamsObject) paramstable.get(task);
392 TempObject objecttemps=(TempObject) tempstable.get(task);
394 /* Output parameter structure */
395 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
396 output.println("struct "+task.getCoreSafeSymbol(num)+"_params {");
397 output.println(" int size;");
398 output.println(" void * next;");
399 for(int j=0; j<objectparams.numPointers(); j++) {
400 TempDescriptor temp=objectparams.getPointer(j);
401 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
404 output.println("};\n");
405 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
406 maxtaskparams=objectparams.numPointers()+fm.numTags();
410 /* Output temp structure */
411 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
412 output.println("struct "+task.getCoreSafeSymbol(num)+"_locals {");
413 output.println(" int size;");
414 output.println(" void * next;");
415 for(int j=0; j<objecttemps.numPointers(); j++) {
416 TempDescriptor temp=objecttemps.getPointer(j);
417 if (temp.getType().isNull())
418 output.println(" void * "+temp.getSafeSymbol()+";");
419 else if(temp.getType().isTag())
420 output.println(" struct "+
421 (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
423 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
425 output.println("};\n");
428 /* Output task declaration */
429 headersout.print("void " + task.getCoreSafeSymbol(num)+"(");
431 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
432 headersout.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
434 headersout.print("void * parameterarray[]");
435 headersout.println(");\n");
441 /* This method outputs code for each task. */
443 protected void outputTaskCode(PrintWriter outtaskdefs,
444 PrintWriter outmethod,
449 /* Compile task based program */
450 outtaskdefs.println("#include \"task.h\"");
451 outtaskdefs.println("#include \"methodheaders.h\"");
453 /* Output object transfer queues into method.c*/
454 generateObjectTransQueues(outmethod);
456 //Vector[] qnames = new Vector[2];
457 int numclasses = numqueues[0].length;
458 Vector qnames[]= new Vector[numclasses];
459 for(int i = 0; i < qnames.length; ++i) {
462 Iterator<TaskDescriptor> taskit=this.currentSchedule.getTasks().iterator();
463 while(taskit.hasNext()) {
464 TaskDescriptor td=taskit.next();
465 FlatMethod fm=state.getMethodFlat(td);
466 generateTaskMethod(fm, outmethod);
467 generateTaskDescriptor(outtaskdefs, outtask, fm, td, qnames);
470 // generate queuearray for this core
471 int num = this.currentSchedule.getCoreNum();
472 boolean comma = false;
473 for(int i = 0; i < qnames.length; ++i) {
474 outtaskdefs.println("/* object queue array for class " + i + " on core " + num + "*/");
475 outtaskdefs.println("struct parameterwrapper * " + this.objqarrayprefix + i + "_core" + num + "[] = {");
477 Vector tmpvector = qnames[i];
478 if(tmpvector != null) {
479 for(int j = 0; j < tmpvector.size(); ++j) {
481 outtaskdefs.println(",");
485 outtaskdefs.print("&" + tmpvector.elementAt(j));
487 numqueues[num][i] = tmpvector.size();
489 numqueues[num][i] = 0;
491 outtaskdefs.println("};");
494 /* All the queues for tasks residing on this core*/
496 outtaskdefs.println("/* object queue array for tasks on core " + num + "*/");
497 outtaskdefs.println("struct parameterwrapper ** " + this.coreqarrayprefix + num + "[] = {");
498 taskit=this.currentSchedule.getTasks().iterator();
499 while(taskit.hasNext()) {
501 outtaskdefs.println(",");
505 TaskDescriptor td=taskit.next();
506 outtaskdefs.print(this.paramqarrayprefix + td.getCoreSafeSymbol(num));
508 outtaskdefs.println("};");
510 // record the iterator of tasks on this core
511 taskit=this.currentSchedule.getTasks().iterator();
512 taskits[num] = taskit;
513 numtasks[num] = this.currentSchedule.getTasks().size();
516 /** Prints out definitions for generic task structures */
517 protected void outputTaskTypes(PrintWriter outtask) {
518 outtask.println("#ifndef _TASK_H");
519 outtask.println("#define _TASK_H");
520 outtask.println("#include \"ObjectHash.h\"");
521 outtask.println("#include \"structdefs.h\"");
522 outtask.println("#include \"Queue.h\"");
523 outtask.println("#include <string.h>");
524 outtask.println("#include \"runtime_arch.h\"");
525 //outtask.println("#ifdef RAW");
526 //outtask.println("#include <raw.h>");
527 //outtask.println("#endif");
529 outtask.println("struct tagobjectiterator {");
530 outtask.println(" int istag; /* 0 if object iterator, 1 if tag iterator */");
531 outtask.println(" struct ObjectIterator it; /* Object iterator */");
532 outtask.println(" struct ObjectHash * objectset;");
533 outtask.println("#ifdef OPTIONAL");
534 outtask.println(" int failedstate;");
535 outtask.println("#endif");
536 outtask.println(" int slot;");
537 outtask.println(" int tagobjindex; /* Index for tag or object depending on use */");
538 outtask.println(" /*if tag we have an object binding */");
539 outtask.println(" int tagid;");
540 outtask.println(" int tagobjectslot;");
541 outtask.println(" /*if object, we may have one or more tag bindings */");
542 outtask.println(" int numtags;");
543 outtask.println(" int tagbindings[MAXTASKPARAMS-1]; /* list slots */");
544 outtask.println("};");
546 outtask.println("struct parameterwrapper {");
547 outtask.println(" //int type;");
548 outtask.println(" struct ObjectHash * objectset;");
549 outtask.println(" int numberofterms;");
550 outtask.println(" int * intarray;");
551 outtask.println(" int numbertags;");
552 outtask.println(" int * tagarray;");
553 outtask.println(" struct taskdescriptor * task;");
554 outtask.println(" int slot;");
555 outtask.println(" struct tagobjectiterator iterators[MAXTASKPARAMS-1];");
556 outtask.println("};");
558 outtask.println("extern struct parameterwrapper ** objectqueues[][NUMCLASSES];");
559 outtask.println("extern int numqueues[][NUMCLASSES];");
561 outtask.println("struct parameterdescriptor {");
562 outtask.println(" int type;");
563 outtask.println(" int numberterms;");
564 outtask.println(" int *intarray;");
565 outtask.println(" struct parameterwrapper * queue;");
566 outtask.println(" int numbertags;");
567 outtask.println(" int *tagarray;");
568 outtask.println("};");
570 outtask.println("struct taskdescriptor {");
571 outtask.println(" void * taskptr;");
572 outtask.println(" int numParameters;");
573 outtask.println(" int numTotal;");
574 outtask.println(" struct parameterdescriptor **descriptorarray;");
575 outtask.println(" char * name;");
576 outtask.println("};");
578 outtask.println("extern struct taskdescriptor ** taskarray[];");
579 outtask.println("extern int numtasks[];");
580 outtask.println("extern int corenum;"); // define corenum to identify different core
581 outtask.println("extern struct parameterwrapper *** paramqueues[];");
585 protected void generateObjectTransQueues(PrintWriter output) {
586 if(this.fsate2qnames == null) {
587 this.fsate2qnames = new Hashtable[this.coreNum];
588 for(int i = 0; i < this.fsate2qnames.length; ++i) {
589 this.fsate2qnames[i] = null;
592 int num = this.currentSchedule.getCoreNum();
593 assert(this.fsate2qnames[num] == null);
594 Hashtable<FlagState, String> flag2qname = new Hashtable<FlagState, String>();
595 this.fsate2qnames[num] = flag2qname;
596 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
597 if(targetCoreTbl != null) {
598 Object[] keys = targetCoreTbl.keySet().toArray();
600 output.println("/* Object transfer queues for core" + num + ".*/");
601 for(int i = 0; i < keys.length; ++i) {
602 FlagState tmpfstate = (FlagState)keys[i];
603 Object[] targetcores = targetCoreTbl.get(tmpfstate).toArray();
604 String queuename = this.otqueueprefix + tmpfstate.getClassDescriptor().getCoreSafeSymbol(num) + tmpfstate.getuid() + "___";
605 String queueins = queuename + "ins";
606 flag2qname.put(tmpfstate, queuename);
607 output.println("struct " + queuename + " {");
608 output.println(" int * cores;");
609 output.println(" int index;");
610 output.println(" int length;");
611 output.println("};");
612 output.print("int " + queuename + "cores[] = {");
613 for(int j = 0; j < targetcores.length; ++j) {
617 output.print(((Integer)targetcores[j]).intValue());
619 output.println("};");
620 output.println("struct " + queuename + " " + queueins + "= {");
621 output.println(/*".cores = " + */ queuename + "cores,");
622 output.println(/*".index = " + */ "0,");
623 output.println(/*".length = " +*/ targetcores.length + "};");
629 protected void generateTaskMethod(FlatMethod fm,
630 PrintWriter output) {
631 /*if (State.PRINTFLAT)
632 System.out.println(fm.printMethod());*/
633 TaskDescriptor task=fm.getTask();
634 assert(task != null);
635 int num = this.currentSchedule.getCoreNum();
637 //ParamsObject objectparams=(ParamsObject)paramstable.get(task);
638 generateTaskHeader(fm, task,output);
640 TempObject objecttemp=(TempObject) tempstable.get(task);
642 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
643 output.print(" struct "+task.getCoreSafeSymbol(num)+"_locals "+localsprefix+"={");
645 output.print(objecttemp.numPointers()+",");
646 output.print(paramsprefix);
647 for(int j=0; j<objecttemp.numPointers(); j++)
648 output.print(", NULL");
649 output.println("};");
652 for(int i=0; i<objecttemp.numPrimitives(); i++) {
653 TempDescriptor td=objecttemp.getPrimitive(i);
654 TypeDescriptor type=td.getType();
656 output.println(" void * "+td.getSafeSymbol()+";");
657 else if (state.MGC && type.isClass() && type.getClassDesc().isEnum()) {
658 output.println(" int " + td.getSafeSymbol()+";");
659 } else if (type.isClass()||type.isArray())
660 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
662 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
665 for(int i = 0; i < fm.numParameters(); ++i) {
666 TempDescriptor temp = fm.getParameter(i);
667 output.println(" int "+generateTempFlagName(fm, temp)+" = "+generateTemp(fm, temp)+
671 /* Assign labels to FlatNode's if necessary.*/
673 Hashtable<FlatNode, Integer> nodetolabel=assignLabels(fm, null);
675 /* Check to see if we need to do a GC if this is a
676 * multi-threaded program...*/
677 if(this.state.MULTICOREGC) {
678 output.println("if(gcflag) gc("+localsprefixaddr+");");
681 /* Create queues to store objects need to be transferred to other cores and their destination*/
682 //output.println(" struct Queue * totransobjqueue = createQueue();");
683 output.println(" clearQueue(totransobjqueue);");
684 output.println(" struct transObjInfo * tmpObjInfo = NULL;");
686 this.m_aliasSets = null;
687 this.m_aliasFNTbl4Para = null;
688 this.m_aliasFNTbl = null;
689 this.m_aliaslocksTbl4FN = null;
690 outputAliasLockCode(fm, output);
692 /* generate print information for RAW version */
693 output.println("#ifdef MULTICORE");
696 output.println("int tmpsum = 0;");
697 output.println("char * taskname = \"" + task.getSymbol() + "\";");
698 output.println("int tmplen = " + task.getSymbol().length() + ";");
699 output.println("int tmpindex = 1;");
700 output.println("for(;tmpindex < tmplen; tmpindex++) {");
701 output.println(" tmpsum = tmpsum * 10 + *(taskname + tmpindex) - '0';");
704 output.println("#ifdef RAWPATH");
706 output.println("BAMBOO_DEBUGPRINT(0xAAAA);");
707 output.println("BAMBOO_DEBUGPRINT_REG(tmpsum);");
709 //output.println("BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();");
710 output.println("printf(\"(%x,%x) Process %x(%d): task %s\\n\", udn_tile_coord_x(), udn_tile_coord_y(), corenum, corenum, \"" + task.getSymbol() + "\");");
711 //output.println("BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();");
713 //output.println("BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());");
714 output.println("#endif");
715 output.println("#ifdef DEBUG");
717 output.println("BAMBOO_DEBUGPRINT(0xAAAA);");
718 output.println("BAMBOO_DEBUGPRINT_REG(tmpsum);");
720 //output.println("BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();");
721 output.println("printf(\"(%x,%x) Process %x(%d): task %s\\n\", udn_tile_coord_x(), udn_tile_coord_y(), corenum, corenum, \"" + task.getSymbol() + "\");");
722 //output.println("BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();");
724 output.println("#endif");
728 output.println("#endif");
730 for(int i = 0; i < fm.numParameters(); ++i) {
731 TempDescriptor temp = fm.getParameter(i);
732 output.println(" ++" + generateTemp(fm, temp)+"->version;");
735 /* Do the actual code generation */
736 FlatNode current_node=null;
737 HashSet tovisit=new HashSet();
738 HashSet visited=new HashSet();
739 tovisit.add(fm.getNext(0));
740 while(current_node!=null||!tovisit.isEmpty()) {
741 if (current_node==null) {
742 current_node=(FlatNode)tovisit.iterator().next();
743 tovisit.remove(current_node);
745 visited.add(current_node);
746 if (nodetolabel.containsKey(current_node))
747 output.println("L"+nodetolabel.get(current_node)+":");
748 /*if (state.INSTRUCTIONFAILURE) {
749 if (state.THREAD||state.DSM) {
750 output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
753 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
755 if (current_node.numNext()==0) {
757 generateFlatNode(fm, current_node, output);
758 if (current_node.kind()!=FKind.FlatReturnNode) {
759 //output.println(" flushAll();");
760 output.println("#ifdef CACHEFLUSH");
761 output.println("BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();");
762 output.println("#ifdef DEBUG");
763 output.println("BAMBOO_DEBUGPRINT(0xec00);");
764 output.println("#endif");
765 output.println("BAMBOO_CACHE_FLUSH_ALL();");
766 output.println("#ifdef DEBUG");
767 output.println("BAMBOO_DEBUGPRINT(0xecff);");
768 output.println("#endif");
769 output.println("BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();");
770 output.println("#endif");
771 outputTransCode(output);
772 output.println(" return;");
775 } else if(current_node.numNext()==1) {
777 generateFlatNode(fm, current_node, output);
778 FlatNode nextnode=current_node.getNext(0);
779 if (visited.contains(nextnode)) {
780 output.println("goto L"+nodetolabel.get(nextnode)+";");
783 current_node=nextnode;
784 } else if (current_node.numNext()==2) {
787 generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
788 if (!visited.contains(current_node.getNext(1)))
789 tovisit.add(current_node.getNext(1));
790 if (visited.contains(current_node.getNext(0))) {
791 output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
794 current_node=current_node.getNext(0);
795 } else throw new Error();
798 output.println("}\n\n");
801 /** This method outputs TaskDescriptor information */
802 protected void generateTaskDescriptor(PrintWriter output,
807 int num = this.currentSchedule.getCoreNum();
809 output.println("/* TaskDescriptor information for task " + task.getSymbol() + " on core " + num + "*/");
811 for (int i=0; i<task.numParameters(); i++) {
812 VarDescriptor param_var=task.getParameter(i);
813 TypeDescriptor param_type=task.getParamType(i);
814 FlagExpressionNode param_flag=task.getFlag(param_var);
815 TagExpressionList param_tag=task.getTag(param_var);
818 if (param_flag==null) {
819 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
820 output.println("0x0, 0x0 };");
823 DNFFlag dflag=param_flag.getDNF();
824 dnfterms=dflag.size();
826 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
827 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
828 for(int j=0; j<dflag.size(); j++) {
831 Vector term=dflag.get(j);
834 for(int k=0; k<term.size(); k++) {
835 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
836 FlagDescriptor fd=dfa.getFlag();
837 boolean negated=dfa.getNegated();
838 int flagid=1<<((Integer)flags.get(fd)).intValue();
843 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
845 output.println("};");
848 output.println("int parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
849 //BUG...added next line to fix, test with any task program
851 for(int j=0; j<param_tag.numTags(); j++) {
854 /* for each tag we need */
855 /* which slot it is */
856 /* what type it is */
857 TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
858 TempDescriptor tmp=param_tag.getTemp(j);
859 int slot=fm.getTagInt(tmp);
860 output.println(slot+", "+state.getTagId(tvd.getTag()));
862 output.println("};");
864 // generate object queue for this parameter
865 String qname = this.objqueueprefix+i+"_"+task.getCoreSafeSymbol(num);
866 if(param_type.getClassDesc().getSymbol().equals("StartupObject")) {
867 this.startupcorenum = num;
869 if(qnames[param_type.getClassDesc().getId()] == null) {
870 qnames[param_type.getClassDesc().getId()] = new Vector();
872 qnames[param_type.getClassDesc().getId()].addElement(qname);
873 outtask.println("extern struct parameterwrapper " + qname + ";");
874 output.println("struct parameterwrapper " + qname + "={");
875 output.println(".objectset = 0,"); // objectset
876 output.println("/* number of DNF terms */ .numberofterms = "+dnfterms+","); // numberofterms
877 output.println(".intarray = parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
880 output.println("/* number of tags */ .numbertags = "+param_tag.numTags()+",");
882 output.println("/* number of tags */ .numbertags = 0,");
883 output.println(".tagarray = parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+","); // tagarray
884 output.println(".task = 0,"); // task
885 output.println(".slot = " + i + ","); // slot
887 output.println("};");
889 output.println("struct parameterdescriptor parameter_"+i+"_"+task.getCoreSafeSymbol(num)+"={");
890 output.println("/* type */"+param_type.getClassDesc().getId()+",");
891 output.println("/* number of DNF terms */"+dnfterms+",");
892 output.println("parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
893 output.println("&" + qname + ","); // queue
894 //BUG, added next line to fix and else statement...test
895 //with any task program
897 output.println("/* number of tags */"+param_tag.numTags()+",");
899 output.println("/* number of tags */ 0,");
900 output.println("parametertag_"+i+"_"+task.getCoreSafeSymbol(num)); // tagarray
901 output.println("};");
904 /* parameter queues for this task*/
905 output.println("struct parameterwrapper * " + this.paramqarrayprefix + task.getCoreSafeSymbol(num)+"[] = {");
906 for (int i=0; i<task.numParameters(); i++) {
909 output.print("&" + this.objqueueprefix + i + "_" + task.getCoreSafeSymbol(num));
911 output.println("};");
913 output.println("struct parameterdescriptor * parameterdescriptors_"+task.getCoreSafeSymbol(num)+"[] = {");
914 for (int i=0; i<task.numParameters(); i++) {
917 output.print("¶meter_"+i+"_"+task.getCoreSafeSymbol(num));
919 output.println("};");
921 output.println("struct taskdescriptor " + this.taskprefix + task.getCoreSafeSymbol(num) + "={");
922 output.println("&"+task.getCoreSafeSymbol(num)+",");
923 output.println("/* number of parameters */" +task.numParameters() + ",");
924 int numtotal=task.numParameters()+fm.numTags();
925 output.println("/* number total parameters */" +numtotal + ",");
926 output.println("parameterdescriptors_"+task.getCoreSafeSymbol(num)+",");
927 output.println("\""+task.getSymbol()+"\"");
928 output.println("};");
933 /** This method generates header information for the task
934 * referenced by the Descriptor des. */
936 protected void generateTaskHeader(FlatMethod fm,
938 PrintWriter output) {
940 ParamsObject objectparams=(ParamsObject)paramstable.get(des);
941 TaskDescriptor task=(TaskDescriptor) des;
943 int num = this.currentSchedule.getCoreNum();
944 //catch the constructor case
945 output.print("void ");
946 output.print(task.getCoreSafeSymbol(num)+"(");
948 boolean printcomma=false;
949 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
950 output.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
954 if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
956 output.println("void * parameterarray[]) {");
957 /* Unpack variables */
958 for(int i=0; i<objectparams.numPrimitives(); i++) {
959 TempDescriptor temp=objectparams.getPrimitive(i);
960 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
962 for(int i=0; i<fm.numTags(); i++) {
963 TempDescriptor temp=fm.getTag(i);
964 int offset=i+objectparams.numPrimitives();
965 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+i+"___=parameterarray["+offset+"];"); // add i to fix bugs of duplicate definition of tags
968 if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
969 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
970 } else output.println(") {");
973 protected void generateFlagOrAnd(FlatFlagActionNode ffan,
979 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
980 output.println("flagorandinit("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
982 int num = this.currentSchedule.getCoreNum();
983 ClassDescriptor cd = temp.getType().getClassDesc();
984 Vector<FlagState> initfstates = ffan.getInitFStates(cd);
985 for(int i = 0; i < initfstates.size(); ++i) {
986 FlagState tmpFState = initfstates.elementAt(i);
988 QueueInfo qinfo = outputqueues(tmpFState, num, output, false);
989 output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+
990 ", 0x"+Integer.toHexString(andmask)+", " + qinfo.qname +
991 ", " + qinfo.length + ");");
994 if(ffan.getTaskType()==FlatFlagActionNode.TASKEXIT) {
995 // generate codes for profiling, recording which task exit it is
996 output.println("#ifdef PROFILE");
997 output.println("setTaskExitIndex(" + ffan.getTaskExitIndex() + ");");
998 output.println("#endif");
1003 protected void generateObjectDistribute(FlatFlagActionNode ffan,
1005 TempDescriptor temp,
1006 PrintWriter output) {
1007 ClassDescriptor cd = temp.getType().getClassDesc();
1008 Vector<FlagState> initfstates = null;
1009 Vector[] targetFStates = null;
1010 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
1011 targetFStates = new Vector[1];
1012 targetFStates[0] = ffan.getTargetFStates4NewObj(cd);
1014 initfstates = ffan.getInitFStates(cd);
1015 targetFStates = new Vector[initfstates.size()];
1016 for(int i = 0; i < initfstates.size(); ++i) {
1017 FlagState fs = initfstates.elementAt(i);
1018 targetFStates[i] = ffan.getTargetFStates(fs);
1020 if(!fs.isSetmask()) {
1021 Hashtable flags=(Hashtable)flagorder.get(cd);
1024 Iterator it_flags = fs.getFlags();
1025 while(it_flags.hasNext()) {
1026 FlagDescriptor fd = (FlagDescriptor)it_flags.next();
1027 int flagid=1<<((Integer)flags.get(fd)).intValue();
1031 fs.setAndmask(andmask);
1032 fs.setCheckmask(checkmask);
1033 fs.setSetmask(true);
1037 boolean isolate = true; // check if this flagstate can associate to some task with multiple params which can
1038 // reside on multiple cores
1039 if((this.currentSchedule == null) && (fm.getMethod().getClassDesc().getSymbol().equals("ServerSocket"))) {
1040 // ServerSocket object will always reside on current core
1041 for(int j = 0; j < targetFStates.length; ++j) {
1042 if(initfstates != null) {
1043 FlagState fs = initfstates.elementAt(j);
1044 output.println("if(" + generateTempFlagName(fm, temp) + "&(0x" + Integer.toHexString(fs.getAndmask())
1045 + ")==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
1047 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
1048 for(int i = 0; i < tmpfstates.size(); ++i) {
1049 FlagState tmpFState = tmpfstates.elementAt(i);
1051 // may have bugs here
1052 output.println("/* reside on this core*");
1053 output.println("enqueueObject("+generateTemp(fm, temp)+", NULL, 0);");
1055 if(initfstates != null) {
1056 output.println("}");
1062 int num = this.currentSchedule.getCoreNum();
1063 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
1064 for(int j = 0; j < targetFStates.length; ++j) {
1065 FlagState fs = null;
1066 if(initfstates != null) {
1067 fs = initfstates.elementAt(j);
1068 output.println("if((" + generateTempFlagName(fm, temp) + "&(0x" + Integer.toHexString(fs.getAndmask())
1069 + "))==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
1071 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
1072 for(int i = 0; i < tmpfstates.size(); ++i) {
1073 FlagState tmpFState = tmpfstates.elementAt(i);
1075 if(this.currentSchedule.getAllyCoreTable() == null) {
1078 isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) ||
1079 (this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
1082 Vector<Integer> sendto = new Vector<Integer>();
1083 Queue<Integer> queue = null;
1084 if(targetCoreTbl != null) {
1085 queue = targetCoreTbl.get(tmpFState);
1087 if((queue != null) &&
1088 ((queue.size() != 1) ||
1089 ((queue.size() == 1) && (queue.element().intValue() != num)))) {
1090 // this object may be transferred to other cores
1091 String queuename = (String) this.fsate2qnames[num].get(tmpFState);
1092 String queueins = queuename + "ins";
1094 Object[] cores = queue.toArray();
1096 Integer targetcore = (Integer)cores[0];
1097 if(queue.size() > 1) {
1098 index = queueins + ".index";
1100 if(queue.size() > 1) {
1101 output.println("switch(" + queueins + ".index % " + queueins + ".length) {");
1102 for(int k = 0; k < cores.length; ++k) {
1103 output.println("case " + k + ":");
1104 targetcore = (Integer)cores[k];
1105 if(targetcore.intValue() == num) {
1106 output.println("/* reside on this core*/");
1108 output.println("{");
1109 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1110 output.println("enqueueObject("+generateTemp(fm, temp)+", " + qinfo.qname +
1111 ", " + qinfo.length + ");");
1112 output.println("}");
1116 output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1117 output.println("enqueueObject("+generateTemp(fm, temp)+", NULL, 0);");
1118 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1122 // Is it possible to decide the actual queues?
1123 output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1124 output.println("enqueueObject("+generateTemp(fm, temp)+", NULL, 0);");
1125 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1126 output.println("/* transfer to core " + targetcore.toString() + "*/");
1127 output.println("{");
1128 // enqueue this object and its destinations for later process
1129 // all the possible queues
1130 QueueInfo qinfo = null;
1131 TranObjInfo tmpinfo = new TranObjInfo();
1132 tmpinfo.name = generateTemp(fm, temp);
1133 tmpinfo.targetcore = targetcore;
1134 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1135 if(targetFS != null) {
1136 tmpinfo.fs = targetFS;
1138 tmpinfo.fs = tmpFState;
1140 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1141 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1142 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1143 output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1144 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1145 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1146 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1147 output.println("}");
1149 output.println("break;");
1151 output.println("}");
1155 // Is it possible to decide the actual queues?
1156 output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1157 output.println("enqueueObject("+generateTemp(fm, temp)+", NULL, 0);");
1158 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1159 output.println("/* transfer to core " + targetcore.toString() + "*/");
1160 output.println("{");
1161 // enqueue this object and its destinations for later process
1162 // all the possible queues
1163 QueueInfo qinfo = null;
1164 TranObjInfo tmpinfo = new TranObjInfo();
1165 tmpinfo.name = generateTemp(fm, temp);
1166 tmpinfo.targetcore = targetcore;
1167 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1168 if(targetFS != null) {
1169 tmpinfo.fs = targetFS;
1171 tmpinfo.fs = tmpFState;
1173 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1174 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1175 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1176 output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1177 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1178 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1179 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1180 output.println("}");
1182 output.println("/* increase index*/");
1183 output.println("++" + queueins + ".index;");
1185 // this object will reside on current core
1186 output.println("/* reside on this core*/");
1188 output.println("{");
1189 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1190 output.println("enqueueObject("+generateTemp(fm, temp)+", " + qinfo.qname +
1191 ", " + qinfo.length + ");");
1192 output.println("}");
1196 output.println("enqueueObject("+generateTemp(fm, temp)+", NULL, 0);");
1197 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1200 // codes for multi-params tasks
1202 // flagstate associated with some multi-params tasks
1203 // need to be send to other cores
1204 Vector<Integer> targetcores = this.currentSchedule.getAllyCores(tmpFState);
1205 output.println("/* send the shared object to possible queues on other cores*/");
1206 // TODO, temporary solution, send to mostly the first two
1207 int upperbound = targetcores.size() > 2? 2: targetcores.size();
1208 for(int k = 0; k < upperbound; ++k) {
1210 // add the information of exactly which queue
1211 int targetcore = targetcores.elementAt(k).intValue();
1212 if(!sendto.contains(targetcore)) {
1213 // previously not sended to this target core
1214 // enqueue this object and its destinations for later process
1215 output.println("{");
1216 // all the possible queues
1217 QueueInfo qinfo = null;
1218 TranObjInfo tmpinfo = new TranObjInfo();
1219 tmpinfo.name = generateTemp(fm, temp);
1220 tmpinfo.targetcore = targetcore;
1221 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1222 if(targetFS != null) {
1223 tmpinfo.fs = targetFS;
1225 tmpinfo.fs = tmpFState;
1227 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1228 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1229 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1230 output.println("tmpObjInfo->targetcore = "+targetcore+";");
1231 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1232 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1233 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1234 output.println("}");
1235 sendto.addElement(targetcore);
1241 if(initfstates != null) {
1242 output.println("}");
1247 protected QueueInfo outputqueues(FlagState tmpFState,
1250 boolean isEnqueue) {
1252 QueueInfo qinfo = new QueueInfo();
1253 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1254 output.println("struct parameterwrapper * " + qinfo.qname + "[] = {");
1255 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1256 Vector<TaskDescriptor> residetasks = this.currentSchedule.getTasks();
1257 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1258 Vector<Integer> indexes = new Vector<Integer>();
1259 boolean comma = false;
1261 while(it_edges.hasNext()) {
1262 FEdge fe = (FEdge)it_edges.next();
1263 TaskDescriptor td = fe.getTask();
1264 int paraindex = fe.getIndex();
1265 if((!isEnqueue) || (isEnqueue && residetasks.contains(td))) {
1266 if((!tasks.contains(td)) ||
1267 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1268 tasks.addElement(td);
1269 indexes.addElement(paraindex);
1271 output.println(",");
1275 output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
1280 output.println("};");
1284 protected QueueInfo outputtransqueues(FlagState tmpFState,
1286 PrintWriter output) {
1288 QueueInfo qinfo = new QueueInfo();
1289 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1290 output.println("int " + qinfo.qname + "_clone[] = {");
1291 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1292 Vector<TaskDescriptor> residetasks = this.scheduling.get(targetcore).getTasks();
1293 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1294 Vector<Integer> indexes = new Vector<Integer>();
1295 boolean comma = false;
1297 while(it_edges.hasNext()) {
1298 FEdge fe = (FEdge)it_edges.next();
1299 TaskDescriptor td = fe.getTask();
1300 int paraindex = fe.getIndex();
1301 if(residetasks.contains(td)) {
1302 if((!tasks.contains(td)) ||
1303 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1304 tasks.addElement(td);
1305 indexes.addElement(paraindex);
1307 output.println(",");
1311 output.print(residetasks.indexOf(td) + ", ");
1312 output.print(paraindex);
1317 output.println("};");
1318 output.println("int * " + qinfo.qname + " = RUNMALLOC(sizeof(int) * " + qinfo.length * 2 + ");");
1319 output.println("memcpy(" + qinfo.qname + ", (int *)" + qinfo.qname + "_clone, sizeof(int) * " + qinfo.length * 2 + ");");
1323 protected class QueueInfo {
1325 public String qname;
1328 protected String generateTempFlagName(FlatMethod fm,
1329 TempDescriptor td) {
1330 MethodDescriptor md=fm.getMethod();
1331 TaskDescriptor task=fm.getTask();
1332 TempObject objecttemps=(TempObject) tempstable.get(md!=null ? md : task);
1334 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1335 return td.getSafeSymbol() + "_oldflag";
1338 if (objecttemps.isLocalPtr(td)) {
1339 return localsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1342 if (objecttemps.isParamPtr(td)) {
1343 return paramsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1348 protected void outputTransCode(PrintWriter output) {
1349 output.println("while(0 == isEmpty(totransobjqueue)) {");
1350 output.println(" struct transObjInfo * totransobj = (struct transObjInfo *)(getItem(totransobjqueue));");
1351 output.println(" transferObject(totransobj);");
1352 output.println(" RUNFREE(totransobj->queues);");
1353 output.println(" RUNFREE(totransobj);");
1354 output.println("}");
1355 //output.println("freeQueue(totransobjqueue);");
1358 protected void outputAliasLockCode(FlatMethod fm,
1359 PrintWriter output) {
1360 if(this.m_oa == null) {
1363 TaskDescriptor td = fm.getTask();
1364 Object[] allocSites = this.m_oa.getFlaggedAllocationSitesReachableFromTask(td).toArray();
1365 Vector<Vector<Integer>> aliasSets = new Vector<Vector<Integer>>();
1366 Vector<Vector<FlatNew>> aliasFNSets = new Vector<Vector<FlatNew>>();
1367 Hashtable<Integer, Vector<FlatNew>> aliasFNTbl4Para = new Hashtable<Integer, Vector<FlatNew>>();
1368 Hashtable<FlatNew, Vector<FlatNew>> aliasFNTbl = new Hashtable<FlatNew, Vector<FlatNew>>();
1369 Set<HeapRegionNode> common;
1370 for( int i = 0; i < fm.numParameters(); ++i ) {
1371 // for the ith parameter check for aliases to all
1372 // higher numbered parameters
1373 aliasSets.add(null);
1374 for( int j = i + 1; j < fm.numParameters(); ++j ) {
1375 common = this.m_oa.createsPotentialAliases(td, i, j);
1376 if(!common.isEmpty()) {
1377 // ith parameter and jth parameter has alias, create lock to protect them
1378 if(aliasSets.elementAt(i) == null) {
1379 aliasSets.setElementAt(new Vector<Integer>(), i);
1381 aliasSets.elementAt(i).add(j);
1385 // for the ith parameter, check for aliases against
1386 // the set of allocation sites reachable from this
1388 aliasFNSets.add(null);
1389 for(int j = 0; j < allocSites.length; j++) {
1390 AllocationSite as = (AllocationSite)allocSites[j];
1391 common = this.m_oa.createsPotentialAliases(td, i, as);
1392 if( !common.isEmpty() ) {
1393 // ith parameter and allocationsite as has alias
1394 if(aliasFNSets.elementAt(i) == null) {
1395 aliasFNSets.setElementAt(new Vector<FlatNew>(), i);
1397 aliasFNSets.elementAt(i).add(as.getFlatNew());
1402 // for each allocation site check for aliases with
1403 // other allocation sites in the context of execution
1405 for( int i = 0; i < allocSites.length; ++i ) {
1406 AllocationSite as1 = (AllocationSite)allocSites[i];
1407 for(int j = i + 1; j < allocSites.length; j++) {
1408 AllocationSite as2 = (AllocationSite)allocSites[j];
1410 common = this.m_oa.createsPotentialAliases(td, as1, as2);
1411 if( !common.isEmpty() ) {
1412 // as1 and as2 has alias
1413 if(!aliasFNTbl.containsKey(as1.getFlatNew())) {
1414 aliasFNTbl.put(as1.getFlatNew(), new Vector<FlatNew>());
1416 if(!aliasFNTbl.get(as1.getFlatNew()).contains(as2.getFlatNew())) {
1417 aliasFNTbl.get(as1.getFlatNew()).add(as2.getFlatNew());
1423 // if FlatNew N1->N2->N3, we group N1, N2, N3 together
1424 Iterator<FlatNew> it = aliasFNTbl.keySet().iterator();
1425 Vector<FlatNew> visited = new Vector<FlatNew>();
1426 while(it.hasNext()) {
1427 FlatNew tmpfn = it.next();
1428 if(visited.contains(tmpfn)) {
1432 Queue<FlatNew> tovisit = new LinkedList<FlatNew>();
1433 Vector<FlatNew> tmpv = aliasFNTbl.get(tmpfn);
1438 for(int j = 0; j < tmpv.size(); j++) {
1439 tovisit.add(tmpv.elementAt(j));
1442 while(!tovisit.isEmpty()) {
1443 FlatNew fn = tovisit.poll();
1445 Vector<FlatNew> tmpset = aliasFNTbl.get(fn);
1446 if(tmpset != null) {
1447 // merge tmpset to the alias set of the ith parameter
1448 for(int j = 0; j < tmpset.size(); j++) {
1449 if(!tmpv.contains(tmpset.elementAt(j))) {
1450 tmpv.add(tmpset.elementAt(j));
1451 tovisit.add(tmpset.elementAt(j));
1454 aliasFNTbl.remove(fn);
1457 it = aliasFNTbl.keySet().iterator();
1460 // check alias between parameters and between parameter-flatnew
1461 for(int i = 0; i < aliasSets.size(); i++) {
1462 Queue<Integer> tovisit = new LinkedList<Integer>();
1463 Vector<Integer> tmpv = aliasSets.elementAt(i);
1468 for(int j = 0; j < tmpv.size(); j++) {
1469 tovisit.add(tmpv.elementAt(j));
1472 while(!tovisit.isEmpty()) {
1473 int index = tovisit.poll().intValue();
1474 Vector<Integer> tmpset = aliasSets.elementAt(index);
1475 if(tmpset != null) {
1476 // merge tmpset to the alias set of the ith parameter
1477 for(int j = 0; j < tmpset.size(); j++) {
1478 if(!tmpv.contains(tmpset.elementAt(j))) {
1479 tmpv.add(tmpset.elementAt(j));
1480 tovisit.add(tmpset.elementAt(j));
1483 aliasSets.setElementAt(null, index);
1486 Vector<FlatNew> tmpFNSet = aliasFNSets.elementAt(index);
1487 if(tmpFNSet != null) {
1488 // merge tmpFNSet to the aliasFNSet of the ith parameter
1489 if(aliasFNSets.elementAt(i) == null) {
1490 aliasFNSets.setElementAt(tmpFNSet, i);
1492 Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1493 for(int j = 0; j < tmpFNSet.size(); j++) {
1494 if(!tmpFNv.contains(tmpFNSet.elementAt(j))) {
1495 tmpFNv.add(tmpFNSet.elementAt(j));
1499 aliasFNSets.setElementAt(null, index);
1505 int numparalock = 0;
1506 Vector<Vector<Integer>> tmpaliasSets = new Vector<Vector<Integer>>();
1507 for(int i = 0; i < aliasSets.size(); i++) {
1508 Vector<Integer> tmpv = aliasSets.elementAt(i);
1511 tmpaliasSets.add(tmpv);
1515 Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1516 if(tmpFNv != null) {
1517 aliasFNTbl4Para.put(i, tmpFNv);
1523 numparalock = numlock;
1526 this.m_aliasSets = tmpaliasSets;
1527 aliasFNSets.clear();
1529 this.m_aliasFNTbl4Para = aliasFNTbl4Para;
1530 this.m_aliasFNTbl = aliasFNTbl;
1531 numlock += this.m_aliasFNTbl.size();
1535 output.println("int aliaslocks[" + numlock + "];");
1536 output.println("int tmpi = 0;");
1537 // associate locks with parameters
1539 for(int i = 0; i < this.m_aliasSets.size(); i++) {
1540 Vector<Integer> toadd = this.m_aliasSets.elementAt(i);
1542 output.println("int tmplen_" + lockindex + " = " + toadd.size());
1543 output.println("void * tmpptrs_" + lockindex + "[] = {");
1544 for(int j = 0; j < toadd.size(); j++) {
1545 int para = toadd.elementAt(j).intValue();
1546 output.print(generateTemp(fm, fm.getParameter(para)));
1547 if(j < toadd.size() - 1) {
1550 output.println("};");
1553 output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", tmplen_" + lockindex + ", lockRedirectTbl);");
1555 for(int j = 0; j < toadd.size(); j++) {
1556 int para = toadd.elementAt(j).intValue();
1557 output.println("addAliasLock(" + generateTemp(fm, fm.getParameter(para)) + ", aliaslocks[" + i + "]);");
1559 // check if this lock is also associated with any FlatNew nodes
1560 if(this.m_aliasFNTbl4Para.containsKey(toadd.elementAt(0))) {
1561 if(this.m_aliaslocksTbl4FN == null) {
1562 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1564 Vector<FlatNew> tmpv = this.m_aliasFNTbl4Para.get(toadd.elementAt(0));
1565 for(int j = 0; j < tmpv.size(); j++) {
1566 FlatNew fn = tmpv.elementAt(j);
1567 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1568 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1570 this.m_aliaslocksTbl4FN.get(fn).add(i);
1572 this.m_aliasFNTbl4Para.remove(toadd.elementAt(0));
1577 Object[] key = this.m_aliasFNTbl4Para.keySet().toArray();
1578 for(int i = 0; i < key.length; i++) {
1579 int para = ((Integer)key[i]).intValue();
1581 output.println("void * tmpptrs_" + lockindex + "[] = {" + generateTemp(fm, fm.getParameter(para)) + "};");
1582 output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", 1, lockRedirectTbl);");
1584 output.println("addAliasLock(" + generateTemp(fm, fm.getParameter(para)) + ", aliaslocks[" + lockindex + "]);");
1585 Vector<FlatNew> tmpv = this.m_aliasFNTbl4Para.get(para);
1586 for(int j = 0; j < tmpv.size(); j++) {
1587 FlatNew fn = tmpv.elementAt(j);
1588 if(this.m_aliaslocksTbl4FN == null) {
1589 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1591 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1592 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1594 this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
1599 // check m_aliasFNTbl for locks associated with FlatNew nodes
1600 Object[] FNkey = this.m_aliasFNTbl.keySet().toArray();
1601 for(int i = 0; i < FNkey.length; i++) {
1602 FlatNew fn = (FlatNew)FNkey[i];
1603 Vector<FlatNew> tmpv = this.m_aliasFNTbl.get(fn);
1605 output.println("aliaslocks[tmpi++] = (int)(RUNMALLOC(sizeof(int)));");
1607 if(this.m_aliaslocksTbl4FN == null) {
1608 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1610 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1611 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1613 this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
1614 for(int j = 0; j < tmpv.size(); j++) {
1615 FlatNew tfn = tmpv.elementAt(j);
1616 if(!this.m_aliaslocksTbl4FN.containsKey(tfn)) {
1617 this.m_aliaslocksTbl4FN.put(tfn, new Vector<Integer>());
1619 this.m_aliaslocksTbl4FN.get(tfn).add(lockindex);
1626 protected void generateFlatReturnNode(FlatMethod fm,
1628 PrintWriter output) {
1629 if (frn.getReturnTemp()!=null) {
1630 if (frn.getReturnTemp().getType().isPtr())
1631 output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp())+";");
1633 output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
1635 if(fm.getTask() != null) {
1636 output.println("#ifdef CACHEFLUSH");
1637 output.println("BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();");
1638 output.println("#ifdef DEBUG");
1639 output.println("BAMBOO_DEBUGPRINT(0xec00);");
1640 output.println("#endif");
1641 output.println("BAMBOO_CACHE_FLUSH_ALL();");
1642 output.println("#ifdef DEBUG");
1643 output.println("BAMBOO_DEBUGPRINT(0xecff);");
1644 output.println("#endif");
1645 output.println("BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();");
1646 output.println("#endif");
1647 outputTransCode(output);
1649 output.println("return;");
1653 protected void generateFlatNew(FlatMethod fm,
1655 PrintWriter output) {
1656 if (fn.getType().isArray()) {
1657 int arrayid = state.getArrayNumber(fn.getType())
1658 + state.numClasses();
1659 if (fn.isGlobal()) {
1660 output.println(generateTemp(fm, fn.getDst())
1661 + "=allocate_newarrayglobal(trans, " + arrayid + ", "
1662 + generateTemp(fm, fn.getSize()) + ");");
1663 } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1664 output.println(generateTemp(fm, fn.getDst())
1665 + "=allocate_newarray(&" + localsprefix + ", "
1666 + arrayid + ", " + generateTemp(fm, fn.getSize())
1669 output.println(generateTemp(fm, fn.getDst())
1670 + "=allocate_newarray(" + arrayid + ", "
1671 + generateTemp(fm, fn.getSize()) + ");");
1674 if (fn.isGlobal()) {
1675 output.println(generateTemp(fm, fn.getDst())
1676 + "=allocate_newglobal(trans, "
1677 + fn.getType().getClassDesc().getId() + ");");
1678 } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1679 output.println(generateTemp(fm, fn.getDst())
1680 + "=allocate_new(&" + localsprefix + ", "
1681 + fn.getType().getClassDesc().getId() + ");");
1683 output.println(generateTemp(fm, fn.getDst())
1685 + fn.getType().getClassDesc().getId() + ");");
1688 // create alias lock if necessary
1689 if((this.m_aliaslocksTbl4FN != null) && (this.m_aliaslocksTbl4FN.containsKey(fn))) {
1690 Vector<Integer> tmpv = this.m_aliaslocksTbl4FN.get(fn);
1691 for(int i = 0; i < tmpv.size(); i++) {
1692 output.println("addAliasLock(" + generateTemp(fm, fn.getDst()) + ", aliaslocks[" + tmpv.elementAt(i).intValue() + "]);");
1695 // generate codes for profiling, recording how many new objects are created
1696 if(!fn.getType().isArray() &&
1697 (fn.getType().getClassDesc() != null)
1698 && (fn.getType().getClassDesc().hasFlags())) {
1699 output.println("#ifdef PROFILE");
1700 output.println("addNewObjInfo(\"" + fn.getType().getClassDesc().getSymbol() + "\");");
1701 output.println("#endif");
1707 public int targetcore;
1708 public FlagState fs;
1711 protected boolean contains(Vector<TranObjInfo> sendto,
1713 if(sendto.size() == 0) {
1716 for(int i = 0; i < sendto.size(); i++) {
1717 TranObjInfo tmp = sendto.elementAt(i);
1718 if(!tmp.name.equals(t.name)) {
1721 if(tmp.targetcore != t.targetcore) {
1724 if(tmp.fs != t.fs) {