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;
40 Schedule currentSchedule;
41 Hashtable[] fsate2qnames;
42 String objqarrayprefix= "objqueuearray4class";
43 String objqueueprefix = "objqueue4parameter_";
44 String paramqarrayprefix = "paramqueuearray4task";
45 String coreqarrayprefix = "paramqueuearrays_core";
46 String taskprefix = "task_";
47 String taskarrayprefix = "taskarray_core";
48 String otqueueprefix = "___otqueue";
49 int startupcorenum; // record the core containing startup task, suppose only one core can hava startup object
51 private OwnershipAnalysis m_oa;
52 private Vector<Vector<Integer>> m_aliasSets;
53 Hashtable<Integer, Vector<FlatNew>> m_aliasFNTbl4Para;
54 Hashtable<FlatNew, Vector<FlatNew>> m_aliasFNTbl;
55 Hashtable<FlatNew, Vector<Integer>> m_aliaslocksTbl4FN;
57 public BuildCodeMultiCore(State st,
61 Vector<Schedule> scheduling,
63 PrefetchAnalysis pa) {
64 super(st, temptovar, typeutil, sa, pa);
65 this.scheduling = scheduling;
66 this.coreNum = coreNum;
67 this.currentSchedule = null;
68 this.fsate2qnames = null;
69 this.startupcorenum = 0;
71 // sometimes there are extra cores then needed in scheduling
73 // currently, it is guaranteed that in scheduling, the corenum
74 // is started from 0 and continuous.
75 // MAY need modification here in the future when take hardware
76 // information into account.
77 if(this.scheduling.size() < this.coreNum) {
78 this.coreNum = this.scheduling.size();
82 this.m_aliasSets = null;
83 this.m_aliasFNTbl4Para = null;
84 this.m_aliasFNTbl = null;
85 this.m_aliaslocksTbl4FN = null;
88 public void setOwnershipAnalysis(OwnershipAnalysis m_oa) {
92 public void buildCode() {
93 /* Create output streams to write to */
94 PrintWriter outclassdefs=null;
95 PrintWriter outstructs=null;
96 PrintWriter outmethodheader=null;
97 PrintWriter outmethod=null;
98 PrintWriter outvirtual=null;
99 PrintWriter outtask=null;
100 PrintWriter outtaskdefs=null;
101 //PrintWriter outoptionalarrays=null;
102 //PrintWriter optionalheaders=null;
105 outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
106 outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
107 outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
108 outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
109 outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
111 outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
112 outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
115 outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
116 optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
119 /*if (state.structfile!=null) {
120 outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
122 } catch (Exception e) {
127 /* Build the virtual dispatch tables */
128 super.buildVirtualTables(outvirtual);
130 /* Output includes */
131 outmethodheader.println("#ifndef METHODHEADERS_H");
132 outmethodheader.println("#define METHODHEADERS_H");
133 outmethodheader.println("#include \"structdefs.h\"");
135 outmethodheader.println("#include \"dstm.h\"");*/
137 /* Output Structures */
138 super.outputStructs(outstructs);
140 // Output the C class declarations
141 // These could mutually reference each other
142 super.outputClassDeclarations(outclassdefs);
144 // Output function prototypes and structures for parameters
145 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
147 while(it.hasNext()) {
149 ClassDescriptor cn=(ClassDescriptor)it.next();
150 super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
152 outclassdefs.close();
155 /* Map flags to integers */
156 /* The runtime keeps track of flags using these integers */
157 it=state.getClassSymbolTable().getDescriptorsIterator();
158 while(it.hasNext()) {
159 ClassDescriptor cn=(ClassDescriptor)it.next();
163 generateTaskStructs(outstructs, outmethodheader);
165 /* Outputs generic task structures if this is a task
167 outputTaskTypes(outtask);
170 /* Build the actual methods */
171 super.outputMethods(outmethod);
174 Iterator[] taskits = new Iterator[this.coreNum];
175 for(int i = 0; i < taskits.length; ++i) {
178 int[] numtasks = new int[this.coreNum];
179 int[][] numqueues = new int[this.coreNum][numclasses];
180 /* Output code for tasks */
181 for(int i = 0; i < this.scheduling.size(); ++i) {
182 this.currentSchedule = this.scheduling.elementAt(i);
183 outputTaskCode(outtaskdefs, outmethod, outtask, taskits, numtasks, numqueues);
186 // Output task descriptors
187 boolean comma = false;
188 outtaskdefs.println("struct parameterwrapper ** objectqueues[][NUMCLASSES] = {");
189 boolean needcomma = false;
190 for(int i = 0; i < numqueues.length ; ++i) {
192 outtaskdefs.println(",");
196 outtaskdefs.println("/* object queue array for core " + i + "*/");
197 outtaskdefs.print("{");
199 for(int j = 0; j < numclasses; ++j) {
201 outtaskdefs.println(",");
205 outtaskdefs.print(this.objqarrayprefix + j + "_core" + i);
207 outtaskdefs.print("}");
209 outtaskdefs.println("};");
211 outtaskdefs.println("int numqueues[][NUMCLASSES] = {");
212 for(int i = 0; i < numqueues.length; ++i) {
214 outtaskdefs.println(",");
218 int[] tmparray = numqueues[i];
220 outtaskdefs.print("{");
221 for(int j = 0; j < tmparray.length; ++j) {
223 outtaskdefs.print(",");
227 outtaskdefs.print(tmparray[j]);
229 outtaskdefs.print("}");
231 outtaskdefs.println("};");
233 /* parameter queue arrays for all the tasks*/
234 outtaskdefs.println("struct parameterwrapper *** paramqueues[] = {");
236 for(int i = 0; i < this.coreNum ; ++i) {
238 outtaskdefs.println(",");
242 outtaskdefs.println("/* parameter queue array for core " + i + "*/");
243 outtaskdefs.print(this.coreqarrayprefix + i);
245 outtaskdefs.println("};");
247 for(int i = 0; i < taskits.length; ++i) {
248 outtaskdefs.println("struct taskdescriptor * " + this.taskarrayprefix + i + "[]={");
249 Iterator taskit = taskits[i];
252 while(taskit.hasNext()) {
253 TaskDescriptor td=(TaskDescriptor)taskit.next();
257 outtaskdefs.println(",");
258 outtaskdefs.print("&" + this.taskprefix +td.getCoreSafeSymbol(i));
261 outtaskdefs.println();
262 outtaskdefs.println("};");
264 outtaskdefs.println("struct taskdescriptor ** taskarray[]= {");
266 for(int i = 0; i < taskits.length; ++i) {
268 outtaskdefs.println(",");
271 outtaskdefs.print(this.taskarrayprefix + i);
273 outtaskdefs.println("};");
275 outtaskdefs.print("int numtasks[]= {");
277 for(int i = 0; i < taskits.length; ++i) {
279 outtaskdefs.print(",");
282 outtaskdefs.print(numtasks[i]);
284 outtaskdefs.println("};");
285 outtaskdefs.println("int corenum=0;");
288 outtask.println("#endif");
290 /* Record maximum number of task parameters */
291 outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
292 /* Record maximum number of all types, i.e. length of classsize[] */
293 outstructs.println("#define NUMTYPES "+(state.numClasses() + state.numArrays()));
294 /* Record number of cores */
295 outstructs.println("#define NUMCORES "+this.coreNum);
296 /* Record number of core containing startup task */
297 outstructs.println("#define STARTUPCORE "+this.startupcorenum);
298 } //else if (state.main!=null) {
299 /* Generate main method */
300 // outputMainMethod(outmethod);
303 /* Generate information for task with optional parameters */
304 /*if (state.TASK&&state.OPTIONAL){
305 generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
306 outoptionalarrays.close();
309 /* Output structure definitions for repair tool */
310 /*if (state.structfile!=null) {
311 buildRepairStructs(outrepairstructs);
312 outrepairstructs.close();
316 outmethodheader.println("#endif");
317 outmethodheader.close();
319 outstructs.println("#endif");
323 /** This function outputs (1) structures that parameters are
324 * passed in (when PRECISE GC is enabled) and (2) function
325 * prototypes for the tasks */
327 private void generateTaskStructs(PrintWriter output,
328 PrintWriter headersout) {
329 /* Cycle through tasks */
330 for(int i = 0; i < this.scheduling.size(); ++i) {
331 Schedule tmpschedule = this.scheduling.elementAt(i);
332 int num = tmpschedule.getCoreNum();
333 Iterator<TaskDescriptor> taskit = tmpschedule.getTasks().iterator();
335 while(taskit.hasNext()) {
336 /* Classify parameters */
337 TaskDescriptor task=taskit.next();
338 FlatMethod fm=state.getMethodFlat(task);
339 super.generateTempStructs(fm, null);
341 ParamsObject objectparams=(ParamsObject) paramstable.get(task);
342 TempObject objecttemps=(TempObject) tempstable.get(task);
344 /* Output parameter structure */
345 if (GENERATEPRECISEGC) {
346 output.println("struct "+task.getCoreSafeSymbol(num)+"_params {");
347 output.println(" int size;");
348 output.println(" void * next;");
349 for(int j=0; j<objectparams.numPointers(); j++) {
350 TempDescriptor temp=objectparams.getPointer(j);
351 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
354 output.println("};\n");
355 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
356 maxtaskparams=objectparams.numPointers()+fm.numTags();
360 /* Output temp structure */
361 if (GENERATEPRECISEGC) {
362 output.println("struct "+task.getCoreSafeSymbol(num)+"_locals {");
363 output.println(" int size;");
364 output.println(" void * next;");
365 for(int j=0; j<objecttemps.numPointers(); j++) {
366 TempDescriptor temp=objecttemps.getPointer(j);
367 if (temp.getType().isNull())
368 output.println(" void * "+temp.getSafeSymbol()+";");
369 else if(temp.getType().isTag())
370 output.println(" struct "+
371 (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
373 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
375 output.println("};\n");
378 /* Output task declaration */
379 headersout.print("void " + task.getCoreSafeSymbol(num)+"(");
381 if (GENERATEPRECISEGC) {
382 headersout.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
384 headersout.print("void * parameterarray[]");
385 headersout.println(");\n");
391 /* This method outputs code for each task. */
393 private void outputTaskCode(PrintWriter outtaskdefs,
394 PrintWriter outmethod,
399 /* Compile task based program */
400 outtaskdefs.println("#include \"task.h\"");
401 outtaskdefs.println("#include \"methodheaders.h\"");
403 /* Output object transfer queues into method.c*/
404 generateObjectTransQueues(outmethod);
406 //Vector[] qnames = new Vector[2];
407 int numclasses = numqueues[0].length;
408 Vector qnames[]= new Vector[numclasses];
409 for(int i = 0; i < qnames.length; ++i) {
412 Iterator<TaskDescriptor> taskit=this.currentSchedule.getTasks().iterator();
413 while(taskit.hasNext()) {
414 TaskDescriptor td=taskit.next();
415 FlatMethod fm=state.getMethodFlat(td);
416 generateTaskMethod(fm, null, outmethod);
417 generateTaskDescriptor(outtaskdefs, outtask, fm, td, qnames);
420 // generate queuearray for this core
421 int num = this.currentSchedule.getCoreNum();
422 boolean comma = false;
423 for(int i = 0; i < qnames.length; ++i) {
424 outtaskdefs.println("/* object queue array for class " + i + " on core " + num + "*/");
425 outtaskdefs.println("struct parameterwrapper * " + this.objqarrayprefix + i + "_core" + num + "[] = {");
427 Vector tmpvector = qnames[i];
428 if(tmpvector != null) {
429 for(int j = 0; j < tmpvector.size(); ++j) {
431 outtaskdefs.println(",");
435 outtaskdefs.print("&" + tmpvector.elementAt(j));
437 numqueues[num][i] = tmpvector.size();
439 numqueues[num][i] = 0;
441 outtaskdefs.println("};");
444 /* All the queues for tasks residing on this core*/
446 outtaskdefs.println("/* object queue array for tasks on core " + num + "*/");
447 outtaskdefs.println("struct parameterwrapper ** " + this.coreqarrayprefix + num + "[] = {");
448 taskit=this.currentSchedule.getTasks().iterator();
449 while(taskit.hasNext()) {
451 outtaskdefs.println(",");
455 TaskDescriptor td=taskit.next();
456 outtaskdefs.print(this.paramqarrayprefix + td.getCoreSafeSymbol(num));
458 outtaskdefs.println("};");
460 // record the iterator of tasks on this core
461 taskit=this.currentSchedule.getTasks().iterator();
462 taskits[num] = taskit;
463 numtasks[num] = this.currentSchedule.getTasks().size();
466 /** Prints out definitions for generic task structures */
467 private void outputTaskTypes(PrintWriter outtask) {
468 outtask.println("#ifndef _TASK_H");
469 outtask.println("#define _TASK_H");
470 outtask.println("#include \"ObjectHash.h\"");
471 outtask.println("#include \"structdefs.h\"");
472 outtask.println("#include \"Queue.h\"");
473 outtask.println("#include <string.h>");
474 outtask.println("#include \"runtime_arch.h\"");
475 //outtask.println("#ifdef RAW");
476 //outtask.println("#include <raw.h>");
477 //outtask.println("#endif");
479 outtask.println("struct tagobjectiterator {");
480 outtask.println(" int istag; /* 0 if object iterator, 1 if tag iterator */");
481 outtask.println(" struct ObjectIterator it; /* Object iterator */");
482 outtask.println(" struct ObjectHash * objectset;");
483 outtask.println("#ifdef OPTIONAL");
484 outtask.println(" int failedstate;");
485 outtask.println("#endif");
486 outtask.println(" int slot;");
487 outtask.println(" int tagobjindex; /* Index for tag or object depending on use */");
488 outtask.println(" /*if tag we have an object binding */");
489 outtask.println(" int tagid;");
490 outtask.println(" int tagobjectslot;");
491 outtask.println(" /*if object, we may have one or more tag bindings */");
492 outtask.println(" int numtags;");
493 outtask.println(" int tagbindings[MAXTASKPARAMS-1]; /* list slots */");
494 outtask.println("};");
496 outtask.println("struct parameterwrapper {");
497 outtask.println(" //int type;");
498 outtask.println(" struct ObjectHash * objectset;");
499 outtask.println(" int numberofterms;");
500 outtask.println(" int * intarray;");
501 outtask.println(" int numbertags;");
502 outtask.println(" int * tagarray;");
503 outtask.println(" struct taskdescriptor * task;");
504 outtask.println(" int slot;");
505 outtask.println(" struct tagobjectiterator iterators[MAXTASKPARAMS-1];");
506 outtask.println("};");
508 outtask.println("extern struct parameterwrapper ** objectqueues[][NUMCLASSES];");
509 outtask.println("extern int numqueues[][NUMCLASSES];");
511 outtask.println("struct parameterdescriptor {");
512 outtask.println(" int type;");
513 outtask.println(" int numberterms;");
514 outtask.println(" int *intarray;");
515 outtask.println(" struct parameterwrapper * queue;");
516 outtask.println(" int numbertags;");
517 outtask.println(" int *tagarray;");
518 outtask.println("};");
520 outtask.println("struct taskdescriptor {");
521 outtask.println(" void * taskptr;");
522 outtask.println(" int numParameters;");
523 outtask.println(" int numTotal;");
524 outtask.println(" struct parameterdescriptor **descriptorarray;");
525 outtask.println(" char * name;");
526 outtask.println("};");
528 outtask.println("extern struct taskdescriptor ** taskarray[];");
529 outtask.println("extern int numtasks[];");
530 outtask.println("extern int corenum;"); // define corenum to identify different core
531 outtask.println("extern struct parameterwrapper *** paramqueues[];");
535 private void generateObjectTransQueues(PrintWriter output) {
536 if(this.fsate2qnames == null) {
537 this.fsate2qnames = new Hashtable[this.coreNum];
538 for(int i = 0; i < this.fsate2qnames.length; ++i) {
539 this.fsate2qnames[i] = null;
542 int num = this.currentSchedule.getCoreNum();
543 assert(this.fsate2qnames[num] == null);
544 Hashtable<FlagState, String> flag2qname = new Hashtable<FlagState, String>();
545 this.fsate2qnames[num] = flag2qname;
546 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
547 if(targetCoreTbl != null) {
548 Object[] keys = targetCoreTbl.keySet().toArray();
550 output.println("/* Object transfer queues for core" + num + ".*/");
551 for(int i = 0; i < keys.length; ++i) {
552 FlagState tmpfstate = (FlagState)keys[i];
553 Object[] targetcores = targetCoreTbl.get(tmpfstate).toArray();
554 String queuename = this.otqueueprefix + tmpfstate.getClassDescriptor().getCoreSafeSymbol(num) + tmpfstate.getuid() + "___";
555 String queueins = queuename + "ins";
556 flag2qname.put(tmpfstate, queuename);
557 output.println("struct " + queuename + " {");
558 output.println(" int * cores;");
559 output.println(" int index;");
560 output.println(" int length;");
561 output.println("};");
562 output.print("int " + queuename + "cores[] = {");
563 for(int j = 0; j < targetcores.length; ++j) {
567 output.print(((Integer)targetcores[j]).intValue());
569 output.println("};");
570 output.println("struct " + queuename + " " + queueins + "= {");
571 output.println(/*".cores = " + */ queuename + "cores,");
572 output.println(/*".index = " + */ "0,");
573 output.println(/*".length = " +*/ targetcores.length + "};");
579 private void generateTaskMethod(FlatMethod fm,
581 PrintWriter output) {
582 /*if (State.PRINTFLAT)
583 System.out.println(fm.printMethod());*/
584 TaskDescriptor task=fm.getTask();
585 assert(task != null);
586 int num = this.currentSchedule.getCoreNum();
588 //ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:task);
589 generateTaskHeader(fm, lb, task,output);
590 TempObject objecttemp=(TempObject) tempstable.get(lb!=null ? lb : task);
591 /*if (state.DSM&&lb.getHasAtomic()) {
592 output.println("transrecord_t * trans;");
595 if (GENERATEPRECISEGC) {
596 output.print(" struct "+task.getCoreSafeSymbol(num)+"_locals "+localsprefix+"={");
598 output.print(objecttemp.numPointers()+",");
599 output.print(paramsprefix);
600 for(int j=0; j<objecttemp.numPointers(); j++)
601 output.print(", NULL");
602 output.println("};");
605 for(int i=0; i<objecttemp.numPrimitives(); i++) {
606 TempDescriptor td=objecttemp.getPrimitive(i);
607 TypeDescriptor type=td.getType();
609 output.println(" void * "+td.getSafeSymbol()+";");
610 else if (type.isClass()||type.isArray())
611 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
613 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
616 for(int i = 0; i < fm.numParameters(); ++i) {
617 TempDescriptor temp = fm.getParameter(i);
618 output.println(" int "+generateTempFlagName(fm, temp, lb)+" = "+super.generateTemp(fm, temp, lb)+
622 /* Assign labels to FlatNode's if necessary.*/
624 Hashtable<FlatNode, Integer> nodetolabel=super.assignLabels(fm);
626 /* Check to see if we need to do a GC if this is a
627 * multi-threaded program...*/
629 /*if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) {
630 if (state.DSM&&lb.isAtomic())
631 output.println("checkcollect2(&"+localsprefix+",trans);");
633 output.println("checkcollect(&"+localsprefix+");");
636 /* Create queues to store objects need to be transferred to other cores and their destination*/
637 output.println(" struct Queue * totransobjqueue = createQueue();");
638 output.println(" struct transObjInfo * tmpObjInfo = NULL;");
640 this.m_aliasSets = null;
641 this.m_aliasFNTbl4Para = null;
642 this.m_aliasFNTbl = null;
643 this.m_aliaslocksTbl4FN = null;
644 outputAliasLockCode(fm, lb, output);
646 /* generate print information for RAW version */
647 output.println("#ifdef MULTICORE");
650 output.println("int tmpsum = 0;");
651 output.println("char * taskname = \"" + task.getSymbol() + "\";");
652 output.println("int tmplen = " + task.getSymbol().length() + ";");
653 output.println("int tmpindex = 1;");
654 output.println("for(;tmpindex < tmplen; tmpindex++) {");
655 output.println(" tmpsum = tmpsum * 10 + *(taskname + tmpindex) - '0';");
658 output.println("#ifdef RAWPATH");
660 output.println("BAMBOO_DEBUGPRINT(0xAAAA);");
661 output.println("BAMBOO_DEBUGPRINT_REG(tmpsum);");
663 output.println("BAMBOO_START_CRITICAL_SECTION();");
664 output.println("tprintf(\"Process %x(%d): task %s\\n\", corenum, corenum, \"" + task.getSymbol() + "\");");
665 output.println("BAMBOO_CLOSE_CRITICAL_SECTION();");
667 //output.println("BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());");
668 output.println("#endif");
669 output.println("#ifdef DEBUG");
671 output.println("BAMBOO_DEBUGPRINT(0xAAAA);");
672 output.println("BAMBOO_DEBUGPRINT_REG(tmpsum);");
674 output.println("BAMBOO_START_CRITICAL_SECTION();");
675 output.println("tprintf(\"Process %x(%d): task %s\\n\", corenum, corenum, \"" + task.getSymbol() + "\");");
676 output.println("BAMBOO_CLOSE_CRITICAL_SECTION();");
678 output.println("#endif");
682 output.println("#endif");
684 for(int i = 0; i < fm.numParameters(); ++i) {
685 TempDescriptor temp = fm.getParameter(i);
686 output.println(" ++" + super.generateTemp(fm, temp, lb)+"->version;");
689 /* Do the actual code generation */
690 FlatNode current_node=null;
691 HashSet tovisit=new HashSet();
692 HashSet visited=new HashSet();
693 tovisit.add(fm.getNext(0));
694 while(current_node!=null||!tovisit.isEmpty()) {
695 if (current_node==null) {
696 current_node=(FlatNode)tovisit.iterator().next();
697 tovisit.remove(current_node);
699 visited.add(current_node);
700 if (nodetolabel.containsKey(current_node))
701 output.println("L"+nodetolabel.get(current_node)+":");
702 /*if (state.INSTRUCTIONFAILURE) {
703 if (state.THREAD||state.DSM) {
704 output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
707 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
709 if (current_node.numNext()==0) {
711 super.generateFlatNode(fm, lb, current_node, output);
712 if (current_node.kind()!=FKind.FlatReturnNode) {
713 //output.println(" flushAll();");
714 output.println("#ifdef CACHEFLUSH");
715 output.println("BAMBOO_START_CRITICAL_SECTION();");
716 output.println("#ifdef DEBUG");
717 output.println("BAMBOO_DEBUGPRINT(0xec00);");
718 output.println("#endif");
719 output.println("BAMBOO_CACHE_FLUSH_ALL();");
720 output.println("#ifdef DEBUG");
721 output.println("BAMBOO_DEBUGPRINT(0xecff);");
722 output.println("#endif");
723 output.println("BAMBOO_CLOSE_CRITICAL_SECTION();");
724 output.println("#endif");
725 outputTransCode(output);
726 output.println(" return;");
729 } else if(current_node.numNext()==1) {
731 super.generateFlatNode(fm, lb, current_node, output);
732 FlatNode nextnode=current_node.getNext(0);
733 if (visited.contains(nextnode)) {
734 output.println("goto L"+nodetolabel.get(nextnode)+";");
737 current_node=nextnode;
738 } else if (current_node.numNext()==2) {
741 super.generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
742 if (!visited.contains(current_node.getNext(1)))
743 tovisit.add(current_node.getNext(1));
744 if (visited.contains(current_node.getNext(0))) {
745 output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
748 current_node=current_node.getNext(0);
749 } else throw new Error();
752 output.println("}\n\n");
755 /** This method outputs TaskDescriptor information */
756 private void generateTaskDescriptor(PrintWriter output,
761 int num = this.currentSchedule.getCoreNum();
763 output.println("/* TaskDescriptor information for task " + task.getSymbol() + " on core " + num + "*/");
765 for (int i=0; i<task.numParameters(); i++) {
766 VarDescriptor param_var=task.getParameter(i);
767 TypeDescriptor param_type=task.getParamType(i);
768 FlagExpressionNode param_flag=task.getFlag(param_var);
769 TagExpressionList param_tag=task.getTag(param_var);
772 if (param_flag==null) {
773 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
774 output.println("0x0, 0x0 };");
777 DNFFlag dflag=param_flag.getDNF();
778 dnfterms=dflag.size();
780 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
781 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
782 for(int j=0; j<dflag.size(); j++) {
785 Vector term=dflag.get(j);
788 for(int k=0; k<term.size(); k++) {
789 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
790 FlagDescriptor fd=dfa.getFlag();
791 boolean negated=dfa.getNegated();
792 int flagid=1<<((Integer)flags.get(fd)).intValue();
797 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
799 output.println("};");
802 output.println("int parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
803 //BUG...added next line to fix, test with any task program
805 for(int j=0; j<param_tag.numTags(); j++) {
808 /* for each tag we need */
809 /* which slot it is */
810 /* what type it is */
811 TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
812 TempDescriptor tmp=param_tag.getTemp(j);
813 int slot=fm.getTagInt(tmp);
814 output.println(slot+", "+state.getTagId(tvd.getTag()));
816 output.println("};");
818 // generate object queue for this parameter
819 String qname = this.objqueueprefix+i+"_"+task.getCoreSafeSymbol(num);
820 if(param_type.getClassDesc().getSymbol().equals("StartupObject")) {
821 this.startupcorenum = num;
823 if(qnames[param_type.getClassDesc().getId()] == null) {
824 qnames[param_type.getClassDesc().getId()] = new Vector();
826 qnames[param_type.getClassDesc().getId()].addElement(qname);
827 outtask.println("extern struct parameterwrapper " + qname + ";");
828 output.println("struct parameterwrapper " + qname + "={");
829 output.println(".objectset = 0,"); // objectset
830 output.println("/* number of DNF terms */ .numberofterms = "+dnfterms+","); // numberofterms
831 output.println(".intarray = parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
834 output.println("/* number of tags */ .numbertags = "+param_tag.numTags()+",");
836 output.println("/* number of tags */ .numbertags = 0,");
837 output.println(".tagarray = parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+","); // tagarray
838 output.println(".task = 0,"); // task
839 output.println(".slot = " + i + ","); // slot
841 output.println("};");
843 output.println("struct parameterdescriptor parameter_"+i+"_"+task.getCoreSafeSymbol(num)+"={");
844 output.println("/* type */"+param_type.getClassDesc().getId()+",");
845 output.println("/* number of DNF terms */"+dnfterms+",");
846 output.println("parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
847 output.println("&" + qname + ","); // queue
848 //BUG, added next line to fix and else statement...test
849 //with any task program
851 output.println("/* number of tags */"+param_tag.numTags()+",");
853 output.println("/* number of tags */ 0,");
854 output.println("parametertag_"+i+"_"+task.getCoreSafeSymbol(num)); // tagarray
855 output.println("};");
858 /* parameter queues for this task*/
859 output.println("struct parameterwrapper * " + this.paramqarrayprefix + task.getCoreSafeSymbol(num)+"[] = {");
860 for (int i=0; i<task.numParameters(); i++) {
863 output.print("&" + this.objqueueprefix + i + "_" + task.getCoreSafeSymbol(num));
865 output.println("};");
867 output.println("struct parameterdescriptor * parameterdescriptors_"+task.getCoreSafeSymbol(num)+"[] = {");
868 for (int i=0; i<task.numParameters(); i++) {
871 output.print("¶meter_"+i+"_"+task.getCoreSafeSymbol(num));
873 output.println("};");
875 output.println("struct taskdescriptor " + this.taskprefix + task.getCoreSafeSymbol(num) + "={");
876 output.println("&"+task.getCoreSafeSymbol(num)+",");
877 output.println("/* number of parameters */" +task.numParameters() + ",");
878 int numtotal=task.numParameters()+fm.numTags();
879 output.println("/* number total parameters */" +numtotal + ",");
880 output.println("parameterdescriptors_"+task.getCoreSafeSymbol(num)+",");
881 output.println("\""+task.getSymbol()+"\"");
882 output.println("};");
887 /** This method generates header information for the task
888 * referenced by the Descriptor des. */
890 private void generateTaskHeader(FlatMethod fm,
893 PrintWriter output) {
895 ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : des);
896 TaskDescriptor task=(TaskDescriptor) des;
898 int num = this.currentSchedule.getCoreNum();
899 //catch the constructor case
900 output.print("void ");
901 output.print(task.getCoreSafeSymbol(num)+"(");
903 boolean printcomma=false;
904 if (GENERATEPRECISEGC) {
905 output.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
909 /*if (state.DSM&&lb.isAtomic()) {
912 output.print("transrecord_t * trans");
916 if (!GENERATEPRECISEGC) {
918 output.println("void * parameterarray[]) {");
919 /* Unpack variables */
920 for(int i=0; i<objectparams.numPrimitives(); i++) {
921 TempDescriptor temp=objectparams.getPrimitive(i);
922 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
924 for(int i=0; i<fm.numTags(); i++) {
925 TempDescriptor temp=fm.getTag(i);
926 int offset=i+objectparams.numPrimitives();
927 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+i+"___=parameterarray["+offset+"];"); // add i to fix bugs of duplicate definition of tags
930 if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
931 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
932 } else output.println(") {");
935 protected void generateFlagOrAnd(FlatFlagActionNode ffan,
942 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
943 output.println("flagorandinit("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
945 int num = this.currentSchedule.getCoreNum();
946 ClassDescriptor cd = temp.getType().getClassDesc();
947 Vector<FlagState> initfstates = ffan.getInitFStates(cd);
948 for(int i = 0; i < initfstates.size(); ++i) {
949 FlagState tmpFState = initfstates.elementAt(i);
951 QueueInfo qinfo = outputqueues(tmpFState, num, output, false);
952 output.println("flagorand("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+
953 ", 0x"+Integer.toHexString(andmask)+", " + qinfo.qname +
954 ", " + qinfo.length + ");");
957 if(ffan.getTaskType()==FlatFlagActionNode.TASKEXIT) {
958 // generate codes for profiling, recording which task exit it is
959 output.println("#ifdef PROFILE");
960 output.println("setTaskExitIndex(" + ffan.getTaskExitIndex() + ");");
961 output.println("#endif");
966 protected void generateObjectDistribute(FlatFlagActionNode ffan,
970 PrintWriter output) {
971 ClassDescriptor cd = temp.getType().getClassDesc();
972 Vector<FlagState> initfstates = null;
973 Vector[] targetFStates = null;
974 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
975 targetFStates = new Vector[1];
976 targetFStates[0] = ffan.getTargetFStates4NewObj(cd);
978 initfstates = ffan.getInitFStates(cd);
979 targetFStates = new Vector[initfstates.size()];
980 for(int i = 0; i < initfstates.size(); ++i) {
981 FlagState fs = initfstates.elementAt(i);
982 targetFStates[i] = ffan.getTargetFStates(fs);
984 if(!fs.isSetmask()) {
985 Hashtable flags=(Hashtable)flagorder.get(cd);
988 Iterator it_flags = fs.getFlags();
989 while(it_flags.hasNext()) {
990 FlagDescriptor fd = (FlagDescriptor)it_flags.next();
991 int flagid=1<<((Integer)flags.get(fd)).intValue();
995 fs.setAndmask(andmask);
996 fs.setCheckmask(checkmask);
1001 boolean isolate = true; // check if this flagstate can associate to some task with multiple params which can
1002 // reside on multiple cores
1003 if((this.currentSchedule == null) && (fm.getMethod().getClassDesc().getSymbol().equals("ServerSocket"))) {
1004 // ServerSocket object will always reside on current core
1005 for(int j = 0; j < targetFStates.length; ++j) {
1006 if(initfstates != null) {
1007 FlagState fs = initfstates.elementAt(j);
1008 output.println("if(" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
1009 + ")==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
1011 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
1012 for(int i = 0; i < tmpfstates.size(); ++i) {
1013 FlagState tmpFState = tmpfstates.elementAt(i);
1015 // may have bugs here
1016 output.println("/* reside on this core*");
1017 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1019 if(initfstates != null) {
1020 output.println("}");
1026 int num = this.currentSchedule.getCoreNum();
1027 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
1028 for(int j = 0; j < targetFStates.length; ++j) {
1029 FlagState fs = null;
1030 if(initfstates != null) {
1031 fs = initfstates.elementAt(j);
1032 output.println("if((" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
1033 + "))==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
1035 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
1036 for(int i = 0; i < tmpfstates.size(); ++i) {
1037 FlagState tmpFState = tmpfstates.elementAt(i);
1039 if(this.currentSchedule.getAllyCoreTable() == null) {
1042 isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) ||
1043 (this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
1045 /* no longler use the isolate flag in object structure
1047 // indentify this object as a shared object
1048 // isolate flag is initially set as 1, once this flag is set as 0, it is never reset to 1, i.e. once an object
1049 // is shared, it maybe shared all the time afterwards
1050 output.println("if(" + super.generateTemp(fm, temp, lb) + "->isolate == 1) {");
1051 output.println(" " + super.generateTemp(fm, temp, lb) + "->isolate = 0;");
1052 output.println(" " + super.generateTemp(fm, temp, lb) + "->original = (struct ___Object___ *)" + super.generateTemp(fm, temp, lb) + ";");
1053 output.println("}");
1057 Vector<Integer> sendto = new Vector<Integer>();
1058 Queue<Integer> queue = null;
1059 if(targetCoreTbl != null) {
1060 queue = targetCoreTbl.get(tmpFState);
1062 if((queue != null) &&
1063 ((queue.size() != 1) ||
1064 ((queue.size() == 1) && (queue.element().intValue() != num)))) {
1065 // this object may be transferred to other cores
1066 String queuename = (String) this.fsate2qnames[num].get(tmpFState);
1067 String queueins = queuename + "ins";
1069 Object[] cores = queue.toArray();
1071 Integer targetcore = (Integer)cores[0];
1072 if(queue.size() > 1) {
1073 index = queueins + ".index";
1075 if(queue.size() > 1) {
1076 output.println("switch(" + queueins + ".index % " + queueins + ".length) {");
1077 for(int k = 0; k < cores.length; ++k) {
1078 output.println("case " + k + ":");
1079 targetcore = (Integer)cores[k];
1080 if(targetcore.intValue() == num) {
1081 output.println("/* reside on this core*/");
1083 output.println("{");
1084 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1085 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1086 ", " + qinfo.length + ");");
1087 output.println("}");
1091 output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1092 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1093 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1097 // Is it possible to decide the actual queues?
1098 output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1099 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1100 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1101 output.println("/* transfer to core " + targetcore.toString() + "*/");
1102 output.println("{");
1103 // enqueue this object and its destinations for later process
1104 // all the possible queues
1105 QueueInfo qinfo = null;
1106 TranObjInfo tmpinfo = new TranObjInfo();
1107 tmpinfo.name = super.generateTemp(fm, temp, lb);
1108 tmpinfo.targetcore = targetcore;
1109 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1110 if(targetFS != null) {
1111 tmpinfo.fs = targetFS;
1113 tmpinfo.fs = tmpFState;
1115 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1116 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1117 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1118 output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1119 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1120 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1121 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1122 output.println("}");
1124 output.println("break;");
1126 output.println("}");
1130 // Is it possible to decide the actual queues?
1131 output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1132 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1133 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1134 output.println("/* transfer to core " + targetcore.toString() + "*/");
1135 output.println("{");
1136 // enqueue this object and its destinations for later process
1137 // all the possible queues
1138 QueueInfo qinfo = null;
1139 TranObjInfo tmpinfo = new TranObjInfo();
1140 tmpinfo.name = super.generateTemp(fm, temp, lb);
1141 tmpinfo.targetcore = targetcore;
1142 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1143 if(targetFS != null) {
1144 tmpinfo.fs = targetFS;
1146 tmpinfo.fs = tmpFState;
1148 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1149 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1150 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1151 output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1152 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1153 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1154 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1155 output.println("}");
1157 output.println("/* increase index*/");
1158 output.println("++" + queueins + ".index;");
1160 // this object will reside on current core
1161 output.println("/* reside on this core*/");
1163 output.println("{");
1164 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1165 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1166 ", " + qinfo.length + ");");
1167 output.println("}");
1171 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1172 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1175 // codes for multi-params tasks
1177 // flagstate associated with some multi-params tasks
1178 // need to be send to other cores
1179 Vector<Integer> targetcores = this.currentSchedule.getAllyCores(tmpFState);
1180 output.println("/* send the shared object to possible queues on other cores*/");
1181 // TODO, temporary solution, send to mostly the first two
1182 int upperbound = targetcores.size() > 2? 2: targetcores.size();
1183 for(int k = 0; k < upperbound; ++k) {
1185 // add the information of exactly which queue
1186 int targetcore = targetcores.elementAt(k).intValue();
1187 if(!sendto.contains(targetcore)) {
1188 // previously not sended to this target core
1189 // enqueue this object and its destinations for later process
1190 output.println("{");
1191 // all the possible queues
1192 QueueInfo qinfo = null;
1193 TranObjInfo tmpinfo = new TranObjInfo();
1194 tmpinfo.name = super.generateTemp(fm, temp, lb);
1195 tmpinfo.targetcore = targetcore;
1196 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1197 if(targetFS != null) {
1198 tmpinfo.fs = targetFS;
1200 tmpinfo.fs = tmpFState;
1202 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1203 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1204 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1205 output.println("tmpObjInfo->targetcore = "+targetcore+";");
1206 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1207 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1208 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1209 output.println("}");
1210 sendto.addElement(targetcore);
1216 if(initfstates != null) {
1217 output.println("}");
1222 private QueueInfo outputqueues(FlagState tmpFState,
1225 boolean isEnqueue) {
1227 QueueInfo qinfo = new QueueInfo();
1228 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1229 output.println("struct parameterwrapper * " + qinfo.qname + "[] = {");
1230 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1231 Vector<TaskDescriptor> residetasks = this.currentSchedule.getTasks();
1232 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1233 Vector<Integer> indexes = new Vector<Integer>();
1234 boolean comma = false;
1236 while(it_edges.hasNext()) {
1237 FEdge fe = (FEdge)it_edges.next();
1238 TaskDescriptor td = fe.getTask();
1239 int paraindex = fe.getIndex();
1240 if((!isEnqueue) || (isEnqueue && residetasks.contains(td))) {
1241 if((!tasks.contains(td)) ||
1242 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1243 tasks.addElement(td);
1244 indexes.addElement(paraindex);
1246 output.println(",");
1250 output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
1255 output.println("};");
1259 private QueueInfo outputtransqueues(FlagState tmpFState,
1261 PrintWriter output) {
1263 QueueInfo qinfo = new QueueInfo();
1264 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1265 output.println("int " + qinfo.qname + "_clone[] = {");
1266 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1267 Vector<TaskDescriptor> residetasks = this.scheduling.get(targetcore).getTasks();
1268 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1269 Vector<Integer> indexes = new Vector<Integer>();
1270 boolean comma = false;
1272 while(it_edges.hasNext()) {
1273 FEdge fe = (FEdge)it_edges.next();
1274 TaskDescriptor td = fe.getTask();
1275 int paraindex = fe.getIndex();
1276 if(residetasks.contains(td)) {
1277 if((!tasks.contains(td)) ||
1278 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1279 tasks.addElement(td);
1280 indexes.addElement(paraindex);
1282 output.println(",");
1286 output.print(residetasks.indexOf(td) + ", ");
1287 output.print(paraindex);
1292 output.println("};");
1293 output.println("int * " + qinfo.qname + " = RUNMALLOC(sizeof(int) * " + qinfo.length * 2 + ");");
1294 output.println("memcpy(" + qinfo.qname + ", (int *)" + qinfo.qname + "_clone, sizeof(int) * " + qinfo.length * 2 + ");");
1298 private class QueueInfo {
1300 public String qname;
1303 private String generateTempFlagName(FlatMethod fm,
1305 LocalityBinding lb) {
1306 MethodDescriptor md=fm.getMethod();
1307 TaskDescriptor task=fm.getTask();
1308 TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
1310 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1311 return td.getSafeSymbol() + "_oldflag";
1314 if (objecttemps.isLocalPtr(td)) {
1315 return localsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1318 if (objecttemps.isParamPtr(td)) {
1319 return paramsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1324 protected void outputTransCode(PrintWriter output) {
1325 output.println("while(0 == isEmpty(totransobjqueue)) {");
1326 output.println(" struct transObjInfo * totransobj = (struct transObjInfo *)(getItem(totransobjqueue));");
1327 output.println(" transferObject(totransobj);");
1328 output.println(" RUNFREE(totransobj->queues);");
1329 output.println(" RUNFREE(totransobj);");
1330 output.println("}");
1331 output.println("freeQueue(totransobjqueue);");
1334 protected void outputAliasLockCode(FlatMethod fm,
1336 PrintWriter output) {
1337 if(this.m_oa == null) {
1340 TaskDescriptor td = fm.getTask();
1341 Object[] allocSites = this.m_oa.getFlaggedAllocationSitesReachableFromTask(td).toArray();
1342 Vector<Vector<Integer>> aliasSets = new Vector<Vector<Integer>>();
1343 Vector<Vector<FlatNew>> aliasFNSets = new Vector<Vector<FlatNew>>();
1344 Hashtable<Integer, Vector<FlatNew>> aliasFNTbl4Para = new Hashtable<Integer, Vector<FlatNew>>();
1345 Hashtable<FlatNew, Vector<FlatNew>> aliasFNTbl = new Hashtable<FlatNew, Vector<FlatNew>>();
1346 Set<HeapRegionNode> common;
1347 for( int i = 0; i < fm.numParameters(); ++i ) {
1348 // for the ith parameter check for aliases to all
1349 // higher numbered parameters
1350 aliasSets.add(null);
1351 for( int j = i + 1; j < fm.numParameters(); ++j ) {
1352 common = this.m_oa.createsPotentialAliases(td, i, j);
1353 if(!common.isEmpty()) {
1354 // ith parameter and jth parameter has alias, create lock to protect them
1355 if(aliasSets.elementAt(i) == null) {
1356 aliasSets.setElementAt(new Vector<Integer>(), i);
1358 aliasSets.elementAt(i).add(j);
1362 // for the ith parameter, check for aliases against
1363 // the set of allocation sites reachable from this
1365 aliasFNSets.add(null);
1366 for(int j = 0; j < allocSites.length; j++) {
1367 AllocationSite as = (AllocationSite)allocSites[j];
1368 common = this.m_oa.createsPotentialAliases(td, i, as);
1369 if( !common.isEmpty() ) {
1370 // ith parameter and allocationsite as has alias
1371 if(aliasFNSets.elementAt(i) == null) {
1372 aliasFNSets.setElementAt(new Vector<FlatNew>(), i);
1374 aliasFNSets.elementAt(i).add(as.getFlatNew());
1379 // for each allocation site check for aliases with
1380 // other allocation sites in the context of execution
1382 for( int i = 0; i < allocSites.length; ++i ) {
1383 AllocationSite as1 = (AllocationSite)allocSites[i];
1384 for(int j = i + 1; j < allocSites.length; j++) {
1385 AllocationSite as2 = (AllocationSite)allocSites[j];
1387 common = this.m_oa.createsPotentialAliases(td, as1, as2);
1388 if( !common.isEmpty() ) {
1389 // as1 and as2 has alias
1390 if(!aliasFNTbl.containsKey(as1.getFlatNew())) {
1391 aliasFNTbl.put(as1.getFlatNew(), new Vector<FlatNew>());
1393 if(!aliasFNTbl.get(as1.getFlatNew()).contains(as2.getFlatNew())) {
1394 aliasFNTbl.get(as1.getFlatNew()).add(as2.getFlatNew());
1400 // if FlatNew N1->N2->N3, we group N1, N2, N3 together
1401 Iterator<FlatNew> it = aliasFNTbl.keySet().iterator();
1402 Vector<FlatNew> visited = new Vector<FlatNew>();
1403 while(it.hasNext()) {
1404 FlatNew tmpfn = it.next();
1405 if(visited.contains(tmpfn)) {
1409 Queue<FlatNew> tovisit = new LinkedList<FlatNew>();
1410 Vector<FlatNew> tmpv = aliasFNTbl.get(tmpfn);
1415 for(int j = 0; j < tmpv.size(); j++) {
1416 tovisit.add(tmpv.elementAt(j));
1419 while(!tovisit.isEmpty()) {
1420 FlatNew fn = tovisit.poll();
1422 Vector<FlatNew> tmpset = aliasFNTbl.get(fn);
1423 if(tmpset != null) {
1424 // merge tmpset to the alias set of the ith parameter
1425 for(int j = 0; j < tmpset.size(); j++) {
1426 if(!tmpv.contains(tmpset.elementAt(j))) {
1427 tmpv.add(tmpset.elementAt(j));
1428 tovisit.add(tmpset.elementAt(j));
1431 aliasFNTbl.remove(fn);
1434 it = aliasFNTbl.keySet().iterator();
1437 // check alias between parameters and between parameter-flatnew
1438 for(int i = 0; i < aliasSets.size(); i++) {
1439 Queue<Integer> tovisit = new LinkedList<Integer>();
1440 Vector<Integer> tmpv = aliasSets.elementAt(i);
1445 for(int j = 0; j < tmpv.size(); j++) {
1446 tovisit.add(tmpv.elementAt(j));
1449 while(!tovisit.isEmpty()) {
1450 int index = tovisit.poll().intValue();
1451 Vector<Integer> tmpset = aliasSets.elementAt(index);
1452 if(tmpset != null) {
1453 // merge tmpset to the alias set of the ith parameter
1454 for(int j = 0; j < tmpset.size(); j++) {
1455 if(!tmpv.contains(tmpset.elementAt(j))) {
1456 tmpv.add(tmpset.elementAt(j));
1457 tovisit.add(tmpset.elementAt(j));
1460 aliasSets.setElementAt(null, index);
1463 Vector<FlatNew> tmpFNSet = aliasFNSets.elementAt(index);
1464 if(tmpFNSet != null) {
1465 // merge tmpFNSet to the aliasFNSet of the ith parameter
1466 if(aliasFNSets.elementAt(i) == null) {
1467 aliasFNSets.setElementAt(tmpFNSet, i);
1469 Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1470 for(int j = 0; j < tmpFNSet.size(); j++) {
1471 if(!tmpFNv.contains(tmpFNSet.elementAt(j))) {
1472 tmpFNv.add(tmpFNSet.elementAt(j));
1476 aliasFNSets.setElementAt(null, index);
1482 int numparalock = 0;
1483 Vector<Vector<Integer>> tmpaliasSets = new Vector<Vector<Integer>>();
1484 for(int i = 0; i < aliasSets.size(); i++) {
1485 Vector<Integer> tmpv = aliasSets.elementAt(i);
1488 tmpaliasSets.add(tmpv);
1492 Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1493 if(tmpFNv != null) {
1494 aliasFNTbl4Para.put(i, tmpFNv);
1500 numparalock = numlock;
1503 this.m_aliasSets = tmpaliasSets;
1504 tmpaliasSets.clear();
1505 tmpaliasSets = null;
1506 aliasFNSets.clear();
1508 this.m_aliasFNTbl4Para = aliasFNTbl4Para;
1509 this.m_aliasFNTbl = aliasFNTbl;
1510 numlock += this.m_aliasFNTbl.size();
1514 output.println("int aliaslocks[" + numlock + "];");
1515 output.println("int tmpi = 0;");
1516 // associate locks with parameters
1518 for(int i = 0; i < this.m_aliasSets.size(); i++) {
1519 Vector<Integer> toadd = this.m_aliasSets.elementAt(i);
1521 output.print("int tmplen_" + lockindex + " = 0;");
1522 output.println("void * tmpptrs_" + lockindex + "[] = {");
1523 for(int j = 0; j < toadd.size(); j++) {
1524 int para = toadd.elementAt(j).intValue();
1525 output.print(super.generateTemp(fm, fm.getParameter(para), lb));
1526 if(j < toadd.size() - 1) {
1529 output.println("};");
1532 output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", tmplen_" + lockindex + ", lockRedirectTbl);");
1534 for(int j = 0; j < toadd.size(); j++) {
1535 int para = toadd.elementAt(j).intValue();
1536 output.println("addAliasLock(" + super.generateTemp(fm, fm.getParameter(para), lb) + ", aliaslocks[" + i + "]);");
1538 // check if this lock is also associated with any FlatNew nodes
1539 if(this.m_aliasFNTbl4Para.containsKey(toadd.elementAt(0))) {
1540 if(this.m_aliaslocksTbl4FN == null) {
1541 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1543 Vector<FlatNew> tmpv = this.m_aliasFNTbl4Para.get(toadd.elementAt(0));
1544 for(int j = 0; j < tmpv.size(); j++) {
1545 FlatNew fn = tmpv.elementAt(j);
1546 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1547 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1549 this.m_aliaslocksTbl4FN.get(fn).add(i);
1551 this.m_aliasFNTbl4Para.remove(toadd.elementAt(0));
1556 Object[] key = this.m_aliasFNTbl4Para.keySet().toArray();
1557 for(int i = 0; i < key.length; i++) {
1558 int para = ((Integer)key[i]).intValue();
1560 output.println("void * tmpptrs_" + lockindex + "[] = {" + super.generateTemp(fm, fm.getParameter(para), lb) + "};");
1561 output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", 1, lockRedirectTbl);");
1563 output.println("addAliasLock(" + super.generateTemp(fm, fm.getParameter(para), lb) + ", aliaslocks[" + lockindex + "]);");
1564 Vector<FlatNew> tmpv = this.m_aliasFNTbl4Para.get(para);
1565 for(int j = 0; j < tmpv.size(); j++) {
1566 FlatNew fn = tmpv.elementAt(j);
1567 if(this.m_aliaslocksTbl4FN == null) {
1568 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1570 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1571 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1573 this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
1578 // check m_aliasFNTbl for locks associated with FlatNew nodes
1579 Object[] FNkey = this.m_aliasFNTbl.keySet().toArray();
1580 for(int i = 0; i < FNkey.length; i++) {
1581 FlatNew fn = (FlatNew)FNkey[i];
1582 Vector<FlatNew> tmpv = this.m_aliasFNTbl.get(fn);
1584 output.println("aliaslocks[tmpi++] = (int)(RUNMALLOC(sizeof(int)));");
1586 if(this.m_aliaslocksTbl4FN == null) {
1587 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1589 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1590 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1592 this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
1593 for(int j = 0; j < tmpv.size(); j++) {
1594 FlatNew tfn = tmpv.elementAt(j);
1595 if(!this.m_aliaslocksTbl4FN.containsKey(tfn)) {
1596 this.m_aliaslocksTbl4FN.put(tfn, new Vector<Integer>());
1598 this.m_aliaslocksTbl4FN.get(tfn).add(lockindex);
1605 protected void generateFlatReturnNode(FlatMethod fm,
1608 PrintWriter output) {
1609 if (frn.getReturnTemp()!=null) {
1610 if (frn.getReturnTemp().getType().isPtr())
1611 output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1613 output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1615 if(fm.getTask() != null) {
1616 output.println("#ifdef CACHEFLUSH");
1617 output.println("BAMBOO_START_CRITICAL_SECTION();");
1618 output.println("#ifdef DEBUG");
1619 output.println("BAMBOO_DEBUGPRINT(0xec00);");
1620 output.println("#endif");
1621 output.println("BAMBOO_CACHE_FLUSH_ALL();");
1622 output.println("#ifdef DEBUG");
1623 output.println("BAMBOO_DEBUGPRINT(0xecff);");
1624 output.println("#endif");
1625 output.println("BAMBOO_CLOSE_CRITICAL_SECTION();");
1626 output.println("#endif");
1627 outputTransCode(output);
1629 output.println("return;");
1633 protected void generateFlatNew(FlatMethod fm,
1636 PrintWriter output) {
1637 if (state.DSM && locality.getAtomic(lb).get(fn).intValue() > 0
1638 && !fn.isGlobal()) {
1639 // Stash pointer in case of GC
1640 String revertptr = super.generateTemp(fm, reverttable.get(lb), lb);
1641 output.println(revertptr + "=trans->revertlist;");
1643 if (fn.getType().isArray()) {
1644 int arrayid = state.getArrayNumber(fn.getType())
1645 + state.numClasses();
1646 if (fn.isGlobal()) {
1647 output.println(super.generateTemp(fm, fn.getDst(), lb)
1648 + "=allocate_newarrayglobal(trans, " + arrayid + ", "
1649 + super.generateTemp(fm, fn.getSize(), lb) + ");");
1650 } else if (GENERATEPRECISEGC) {
1651 output.println(super.generateTemp(fm, fn.getDst(), lb)
1652 + "=allocate_newarray(&" + localsprefix + ", "
1653 + arrayid + ", " + super.generateTemp(fm, fn.getSize(), lb)
1656 output.println(super.generateTemp(fm, fn.getDst(), lb)
1657 + "=allocate_newarray(" + arrayid + ", "
1658 + super.generateTemp(fm, fn.getSize(), lb) + ");");
1661 if (fn.isGlobal()) {
1662 output.println(super.generateTemp(fm, fn.getDst(), lb)
1663 + "=allocate_newglobal(trans, "
1664 + fn.getType().getClassDesc().getId() + ");");
1665 } else if (GENERATEPRECISEGC) {
1666 output.println(super.generateTemp(fm, fn.getDst(), lb)
1667 + "=allocate_new(&" + localsprefix + ", "
1668 + fn.getType().getClassDesc().getId() + ");");
1670 output.println(super.generateTemp(fm, fn.getDst(), lb)
1672 + fn.getType().getClassDesc().getId() + ");");
1675 if (state.DSM && locality.getAtomic(lb).get(fn).intValue() > 0
1676 && !fn.isGlobal()) {
1677 String revertptr = super.generateTemp(fm, reverttable.get(lb), lb);
1678 output.println("trans->revertlist=" + revertptr + ";");
1680 // create alias lock if necessary
1681 if((this.m_aliaslocksTbl4FN != null) && (this.m_aliaslocksTbl4FN.containsKey(fn))) {
1682 Vector<Integer> tmpv = this.m_aliaslocksTbl4FN.get(fn);
1683 for(int i = 0; i < tmpv.size(); i++) {
1684 output.println("addAliasLock(" + super.generateTemp(fm, fn.getDst(), lb) + ", aliaslocks[" + tmpv.elementAt(i).intValue() + "]);");
1687 // generate codes for profiling, recording how many new objects are created
1688 if(!fn.getType().isArray() &&
1689 (fn.getType().getClassDesc() != null)
1690 && (fn.getType().getClassDesc().hasFlags())) {
1691 output.println("#ifdef PROFILE");
1692 output.println("addNewObjInfo(\"" + fn.getType().getClassDesc().getSymbol() + "\");");
1693 output.println("#endif");
1699 public int targetcore;
1700 public FlagState fs;
1703 private boolean contains(Vector<TranObjInfo> sendto,
1705 if(sendto.size() == 0) {
1708 for(int i = 0; i < sendto.size(); i++) {
1709 TranObjInfo tmp = sendto.elementAt(i);
1710 if(!tmp.name.equals(t.name)) {
1713 if(tmp.targetcore != t.targetcore) {
1716 if(tmp.fs != t.fs) {