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.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;
39 Schedule currentSchedule;
40 Hashtable[] fsate2qnames;
41 String objqarrayprefix= "objqueuearray4class";
42 String objqueueprefix = "objqueue4parameter_";
43 String paramqarrayprefix = "paramqueuearray4task";
44 String coreqarrayprefix = "paramqueuearrays_core";
45 String taskprefix = "task_";
46 String taskarrayprefix = "taskarray_core";
47 String otqueueprefix = "___otqueue";
48 int startupcorenum; // record the core containing startup task, suppose only one core can hava startup object
50 private OwnershipAnalysis m_oa;
51 private Vector<Vector<Integer>> m_aliasSets;
52 Hashtable<Integer, Vector<FlatNew>> m_aliasFNTbl4Para;
53 Hashtable<FlatNew, Vector<FlatNew>> m_aliasFNTbl;
54 Hashtable<FlatNew, Vector<Integer>> m_aliaslocksTbl4FN;
56 public BuildCodeMultiCore(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, Vector<Schedule> scheduling, int coreNum, PrefetchAnalysis pa) {
57 super(st, temptovar, typeutil, sa, pa);
58 this.scheduling = scheduling;
59 this.coreNum = coreNum;
60 this.currentSchedule = null;
61 this.fsate2qnames = null;
62 this.startupcorenum = 0;
64 // sometimes there are extra cores then needed in scheduling
66 // currently, it is guaranteed that in scheduling, the corenum
67 // is started from 0 and continuous.
68 // MAY need modification here in the future when take hardware
69 // information into account.
70 if(this.scheduling.size() < this.coreNum) {
71 this.coreNum = this.scheduling.size();
75 this.m_aliasSets = null;
76 this.m_aliasFNTbl4Para = null;
77 this.m_aliasFNTbl = null;
78 this.m_aliaslocksTbl4FN = null;
81 public void setOwnershipAnalysis(OwnershipAnalysis m_oa) {
85 public void buildCode() {
86 /* Create output streams to write to */
87 PrintWriter outclassdefs=null;
88 PrintWriter outstructs=null;
89 PrintWriter outmethodheader=null;
90 PrintWriter outmethod=null;
91 PrintWriter outvirtual=null;
92 PrintWriter outtask=null;
93 PrintWriter outtaskdefs=null;
94 //PrintWriter outoptionalarrays=null;
95 //PrintWriter optionalheaders=null;
98 outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
99 outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
100 outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
101 outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
102 outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
104 outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
105 outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
108 outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
109 optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
112 /*if (state.structfile!=null) {
113 outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
115 } catch (Exception e) {
120 /* Build the virtual dispatch tables */
121 super.buildVirtualTables(outvirtual);
123 /* Output includes */
124 outmethodheader.println("#ifndef METHODHEADERS_H");
125 outmethodheader.println("#define METHODHEADERS_H");
126 outmethodheader.println("#include \"structdefs.h\"");
128 outmethodheader.println("#include \"dstm.h\"");*/
130 /* Output Structures */
131 super.outputStructs(outstructs);
133 // Output the C class declarations
134 // These could mutually reference each other
135 super.outputClassDeclarations(outclassdefs);
137 // Output function prototypes and structures for parameters
138 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
140 while(it.hasNext()) {
142 ClassDescriptor cn=(ClassDescriptor)it.next();
143 super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
145 outclassdefs.close();
148 /* Map flags to integers */
149 /* The runtime keeps track of flags using these integers */
150 it=state.getClassSymbolTable().getDescriptorsIterator();
151 while(it.hasNext()) {
152 ClassDescriptor cn=(ClassDescriptor)it.next();
156 generateTaskStructs(outstructs, outmethodheader);
158 /* Outputs generic task structures if this is a task
160 outputTaskTypes(outtask);
163 /* Build the actual methods */
164 super.outputMethods(outmethod);
167 Iterator[] taskits = new Iterator[this.coreNum];
168 for(int i = 0; i < taskits.length; ++i) {
171 int[] numtasks = new int[this.coreNum];
172 int[][] numqueues = new int[this.coreNum][numclasses];
173 /* Output code for tasks */
174 for(int i = 0; i < this.scheduling.size(); ++i) {
175 this.currentSchedule = this.scheduling.elementAt(i);
176 outputTaskCode(outtaskdefs, outmethod, outtask, taskits, numtasks, numqueues);
179 // Output task descriptors
180 boolean comma = false;
181 outtaskdefs.println("struct parameterwrapper ** objectqueues[][NUMCLASSES] = {");
182 boolean needcomma = false;
183 for(int i = 0; i < numqueues.length ; ++i) {
185 outtaskdefs.println(",");
189 outtaskdefs.println("/* object queue array for core " + i + "*/");
190 outtaskdefs.print("{");
192 for(int j = 0; j < numclasses; ++j) {
194 outtaskdefs.println(",");
198 outtaskdefs.print(this.objqarrayprefix + j + "_core" + i);
200 outtaskdefs.print("}");
202 outtaskdefs.println("};");
204 outtaskdefs.println("int numqueues[][NUMCLASSES] = {");
205 for(int i = 0; i < numqueues.length; ++i) {
207 outtaskdefs.println(",");
211 int[] tmparray = numqueues[i];
213 outtaskdefs.print("{");
214 for(int j = 0; j < tmparray.length; ++j) {
216 outtaskdefs.print(",");
220 outtaskdefs.print(tmparray[j]);
222 outtaskdefs.print("}");
224 outtaskdefs.println("};");
226 /* parameter queue arrays for all the tasks*/
227 outtaskdefs.println("struct parameterwrapper *** paramqueues[] = {");
229 for(int i = 0; i < this.coreNum ; ++i) {
231 outtaskdefs.println(",");
235 outtaskdefs.println("/* parameter queue array for core " + i + "*/");
236 outtaskdefs.print(this.coreqarrayprefix + i);
238 outtaskdefs.println("};");
240 for(int i = 0; i < taskits.length; ++i) {
241 outtaskdefs.println("struct taskdescriptor * " + this.taskarrayprefix + i + "[]={");
242 Iterator taskit = taskits[i];
245 while(taskit.hasNext()) {
246 TaskDescriptor td=(TaskDescriptor)taskit.next();
250 outtaskdefs.println(",");
251 outtaskdefs.print("&" + this.taskprefix +td.getCoreSafeSymbol(i));
254 outtaskdefs.println();
255 outtaskdefs.println("};");
257 outtaskdefs.println("struct taskdescriptor ** taskarray[]= {");
259 for(int i = 0; i < taskits.length; ++i) {
261 outtaskdefs.println(",");
264 outtaskdefs.print(this.taskarrayprefix + i);
266 outtaskdefs.println("};");
268 outtaskdefs.print("int numtasks[]= {");
270 for(int i = 0; i < taskits.length; ++i) {
272 outtaskdefs.print(",");
275 outtaskdefs.print(numtasks[i]);
277 outtaskdefs.println("};");
278 outtaskdefs.println("int corenum=0;");
281 outtask.println("#endif");
283 /* Record maximum number of task parameters */
284 outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
285 /* Record maximum number of all types, i.e. length of classsize[] */
286 outstructs.println("#define NUMTYPES "+(state.numClasses() + state.numArrays()));
287 /* Record number of cores */
288 outstructs.println("#define NUMCORES "+this.coreNum);
289 /* Record number of core containing startup task */
290 outstructs.println("#define STARTUPCORE "+this.startupcorenum);
291 } //else if (state.main!=null) {
292 /* Generate main method */
293 // outputMainMethod(outmethod);
296 /* Generate information for task with optional parameters */
297 /*if (state.TASK&&state.OPTIONAL){
298 generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
299 outoptionalarrays.close();
302 /* Output structure definitions for repair tool */
303 /*if (state.structfile!=null) {
304 buildRepairStructs(outrepairstructs);
305 outrepairstructs.close();
309 outmethodheader.println("#endif");
310 outmethodheader.close();
312 outstructs.println("#endif");
316 /** This function outputs (1) structures that parameters are
317 * passed in (when PRECISE GC is enabled) and (2) function
318 * prototypes for the tasks */
320 private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
321 /* Cycle through tasks */
322 for(int i = 0; i < this.scheduling.size(); ++i) {
323 Schedule tmpschedule = this.scheduling.elementAt(i);
324 int num = tmpschedule.getCoreNum();
325 Iterator<TaskDescriptor> taskit = tmpschedule.getTasks().iterator();
327 while(taskit.hasNext()) {
328 /* Classify parameters */
329 TaskDescriptor task=taskit.next();
330 FlatMethod fm=state.getMethodFlat(task);
331 super.generateTempStructs(fm, null);
333 ParamsObject objectparams=(ParamsObject) paramstable.get(task);
334 TempObject objecttemps=(TempObject) tempstable.get(task);
336 /* Output parameter structure */
337 if (GENERATEPRECISEGC) {
338 output.println("struct "+task.getCoreSafeSymbol(num)+"_params {");
339 output.println(" int size;");
340 output.println(" void * next;");
341 for(int j=0; j<objectparams.numPointers(); j++) {
342 TempDescriptor temp=objectparams.getPointer(j);
343 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
346 output.println("};\n");
347 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
348 maxtaskparams=objectparams.numPointers()+fm.numTags();
352 /* Output temp structure */
353 if (GENERATEPRECISEGC) {
354 output.println("struct "+task.getCoreSafeSymbol(num)+"_locals {");
355 output.println(" int size;");
356 output.println(" void * next;");
357 for(int j=0; j<objecttemps.numPointers(); j++) {
358 TempDescriptor temp=objecttemps.getPointer(j);
359 if (temp.getType().isNull())
360 output.println(" void * "+temp.getSafeSymbol()+";");
361 else if(temp.getType().isTag())
362 output.println(" struct "+
363 (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
365 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
367 output.println("};\n");
370 /* Output task declaration */
371 headersout.print("void " + task.getCoreSafeSymbol(num)+"(");
373 if (GENERATEPRECISEGC) {
374 headersout.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
376 headersout.print("void * parameterarray[]");
377 headersout.println(");\n");
383 /* This method outputs code for each task. */
385 private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod, PrintWriter outtask, Iterator[] taskits, int[] numtasks,
387 /* Compile task based program */
388 outtaskdefs.println("#include \"task.h\"");
389 outtaskdefs.println("#include \"methodheaders.h\"");
391 /* Output object transfer queues into method.c*/
392 generateObjectTransQueues(outmethod);
394 //Vector[] qnames = new Vector[2];
395 int numclasses = numqueues[0].length;
396 Vector qnames[]= new Vector[numclasses];
397 for(int i = 0; i < qnames.length; ++i) {
400 Iterator<TaskDescriptor> taskit=this.currentSchedule.getTasks().iterator();
401 while(taskit.hasNext()) {
402 TaskDescriptor td=taskit.next();
403 FlatMethod fm=state.getMethodFlat(td);
404 generateTaskMethod(fm, null, outmethod);
405 generateTaskDescriptor(outtaskdefs, outtask, fm, td, qnames);
408 // generate queuearray for this core
409 int num = this.currentSchedule.getCoreNum();
410 boolean comma = false;
411 for(int i = 0; i < qnames.length; ++i) {
412 outtaskdefs.println("/* object queue array for class " + i + " on core " + num + "*/");
413 outtaskdefs.println("struct parameterwrapper * " + this.objqarrayprefix + i + "_core" + num + "[] = {");
415 Vector tmpvector = qnames[i];
416 if(tmpvector != null) {
417 for(int j = 0; j < tmpvector.size(); ++j) {
419 outtaskdefs.println(",");
423 outtaskdefs.print("&" + tmpvector.elementAt(j));
425 numqueues[num][i] = tmpvector.size();
427 numqueues[num][i] = 0;
429 outtaskdefs.println("};");
432 /* All the queues for tasks residing on this core*/
434 outtaskdefs.println("/* object queue array for tasks on core " + num + "*/");
435 outtaskdefs.println("struct parameterwrapper ** " + this.coreqarrayprefix + num + "[] = {");
436 taskit=this.currentSchedule.getTasks().iterator();
437 while(taskit.hasNext()) {
439 outtaskdefs.println(",");
443 TaskDescriptor td=taskit.next();
444 outtaskdefs.print(this.paramqarrayprefix + td.getCoreSafeSymbol(num));
446 outtaskdefs.println("};");
448 // record the iterator of tasks on this core
449 taskit=this.currentSchedule.getTasks().iterator();
450 taskits[num] = taskit;
451 numtasks[num] = this.currentSchedule.getTasks().size();
454 /** Prints out definitions for generic task structures */
455 private void outputTaskTypes(PrintWriter outtask) {
456 outtask.println("#ifndef _TASK_H");
457 outtask.println("#define _TASK_H");
458 outtask.println("#include \"ObjectHash.h\"");
459 outtask.println("#include \"structdefs.h\"");
460 outtask.println("#include \"Queue.h\"");
461 outtask.println("#include <string.h>");
462 outtask.println("#ifdef RAW");
463 outtask.println("#include <raw.h>");
464 outtask.println("#endif");
466 outtask.println("struct tagobjectiterator {");
467 outtask.println(" int istag; /* 0 if object iterator, 1 if tag iterator */");
468 outtask.println(" struct ObjectIterator it; /* Object iterator */");
469 outtask.println(" struct ObjectHash * objectset;");
470 outtask.println("#ifdef OPTIONAL");
471 outtask.println(" int failedstate;");
472 outtask.println("#endif");
473 outtask.println(" int slot;");
474 outtask.println(" int tagobjindex; /* Index for tag or object depending on use */");
475 outtask.println(" /*if tag we have an object binding */");
476 outtask.println(" int tagid;");
477 outtask.println(" int tagobjectslot;");
478 outtask.println(" /*if object, we may have one or more tag bindings */");
479 outtask.println(" int numtags;");
480 outtask.println(" int tagbindings[MAXTASKPARAMS-1]; /* list slots */");
481 outtask.println("};");
483 outtask.println("struct parameterwrapper {");
484 outtask.println(" //int type;");
485 outtask.println(" struct ObjectHash * objectset;");
486 outtask.println(" int numberofterms;");
487 outtask.println(" int * intarray;");
488 outtask.println(" int numbertags;");
489 outtask.println(" int * tagarray;");
490 outtask.println(" struct taskdescriptor * task;");
491 outtask.println(" int slot;");
492 outtask.println(" struct tagobjectiterator iterators[MAXTASKPARAMS-1];");
493 outtask.println("};");
495 outtask.println("extern struct parameterwrapper ** objectqueues[][NUMCLASSES];");
496 outtask.println("extern int numqueues[][NUMCLASSES];");
498 outtask.println("struct parameterdescriptor {");
499 outtask.println(" int type;");
500 outtask.println(" int numberterms;");
501 outtask.println(" int *intarray;");
502 outtask.println(" struct parameterwrapper * queue;");
503 outtask.println(" int numbertags;");
504 outtask.println(" int *tagarray;");
505 outtask.println("};");
507 outtask.println("struct taskdescriptor {");
508 outtask.println(" void * taskptr;");
509 outtask.println(" int numParameters;");
510 outtask.println(" int numTotal;");
511 outtask.println(" struct parameterdescriptor **descriptorarray;");
512 outtask.println(" char * name;");
513 outtask.println("};");
515 outtask.println("extern struct taskdescriptor ** taskarray[];");
516 outtask.println("extern int numtasks[];");
517 outtask.println("extern int corenum;"); // define corenum to identify different core
518 outtask.println("extern struct parameterwrapper *** paramqueues[];");
522 private void generateObjectTransQueues(PrintWriter output) {
523 if(this.fsate2qnames == null) {
524 this.fsate2qnames = new Hashtable[this.coreNum];
525 for(int i = 0; i < this.fsate2qnames.length; ++i) {
526 this.fsate2qnames[i] = null;
529 int num = this.currentSchedule.getCoreNum();
530 assert(this.fsate2qnames[num] == null);
531 Hashtable<FlagState, String> flag2qname = new Hashtable<FlagState, String>();
532 this.fsate2qnames[num] = flag2qname;
533 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
534 if(targetCoreTbl != null) {
535 Object[] keys = targetCoreTbl.keySet().toArray();
537 output.println("/* Object transfer queues for core" + num + ".*/");
538 for(int i = 0; i < keys.length; ++i) {
539 FlagState tmpfstate = (FlagState)keys[i];
540 Object[] targetcores = targetCoreTbl.get(tmpfstate).toArray();
541 String queuename = this.otqueueprefix + tmpfstate.getClassDescriptor().getCoreSafeSymbol(num) + tmpfstate.getuid() + "___";
542 String queueins = queuename + "ins";
543 flag2qname.put(tmpfstate, queuename);
544 output.println("struct " + queuename + " {");
545 output.println(" int * cores;");
546 output.println(" int index;");
547 output.println(" int length;");
548 output.println("};");
549 output.print("int " + queuename + "cores[] = {");
550 for(int j = 0; j < targetcores.length; ++j) {
554 output.print(((Integer)targetcores[j]).intValue());
556 output.println("};");
557 output.println("struct " + queuename + " " + queueins + "= {");
558 output.println(/*".cores = " + */ queuename + "cores,");
559 output.println(/*".index = " + */ "0,");
560 output.println(/*".length = " +*/ targetcores.length + "};");
566 private void generateTaskMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
567 /*if (State.PRINTFLAT)
568 System.out.println(fm.printMethod());*/
569 TaskDescriptor task=fm.getTask();
570 assert(task != null);
571 int num = this.currentSchedule.getCoreNum();
573 //ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:task);
574 generateTaskHeader(fm, lb, task,output);
575 TempObject objecttemp=(TempObject) tempstable.get(lb!=null ? lb : task);
576 /*if (state.DSM&&lb.getHasAtomic()) {
577 output.println("transrecord_t * trans;");
580 if (GENERATEPRECISEGC) {
581 output.print(" struct "+task.getCoreSafeSymbol(num)+"_locals "+localsprefix+"={");
583 output.print(objecttemp.numPointers()+",");
584 output.print(paramsprefix);
585 for(int j=0; j<objecttemp.numPointers(); j++)
586 output.print(", NULL");
587 output.println("};");
590 for(int i=0; i<objecttemp.numPrimitives(); i++) {
591 TempDescriptor td=objecttemp.getPrimitive(i);
592 TypeDescriptor type=td.getType();
594 output.println(" void * "+td.getSafeSymbol()+";");
595 else if (type.isClass()||type.isArray())
596 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
598 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
601 for(int i = 0; i < fm.numParameters(); ++i) {
602 TempDescriptor temp = fm.getParameter(i);
603 output.println(" int "+generateTempFlagName(fm, temp, lb)+" = "+super.generateTemp(fm, temp, lb)+
607 /* Assign labels to FlatNode's if necessary.*/
609 Hashtable<FlatNode, Integer> nodetolabel=super.assignLabels(fm);
611 /* Check to see if we need to do a GC if this is a
612 * multi-threaded program...*/
614 /*if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) {
615 if (state.DSM&&lb.isAtomic())
616 output.println("checkcollect2(&"+localsprefix+",trans);");
618 output.println("checkcollect(&"+localsprefix+");");
621 /* Create queues to store objects need to be transferred to other cores and their destination*/
622 output.println(" struct Queue * totransobjqueue = createQueue();");
623 output.println(" struct transObjInfo * tmpObjInfo = NULL;");
625 this.m_aliasSets = null;
626 this.m_aliasFNTbl4Para = null;
627 this.m_aliasFNTbl = null;
628 this.m_aliaslocksTbl4FN = null;
629 outputAliasLockCode(fm, lb, output);
631 /* generate print information for RAW version */
632 output.println("#ifdef RAW");
634 output.println("int tmpsum = 0;");
635 output.println("char * taskname = \"" + task.getSymbol() + "\";");
636 output.println("int tmplen = " + task.getSymbol().length() + ";");
637 output.println("int tmpindex = 1;");
638 output.println("for(;tmpindex < tmplen; tmpindex++) {");
639 output.println(" tmpsum = tmpsum * 10 + *(taskname + tmpindex) - '0';");
641 output.println("#ifdef RAWPATH");
642 output.println("raw_test_pass(0xAAAA);");
643 output.println("raw_test_pass_reg(tmpsum);");
644 //output.println("raw_test_pass(raw_get_cycle());");
645 output.println("#endif");
646 output.println("#ifdef RAWDEBUG");
647 output.println("raw_test_pass(0xAAAA);");
648 output.println("raw_test_pass_reg(tmpsum);");
649 output.println("#endif");
651 output.println("#endif");
653 for(int i = 0; i < fm.numParameters(); ++i) {
654 TempDescriptor temp = fm.getParameter(i);
655 output.println(" ++" + super.generateTemp(fm, temp, lb)+"->version;");
658 /* Do the actual code generation */
659 FlatNode current_node=null;
660 HashSet tovisit=new HashSet();
661 HashSet visited=new HashSet();
662 tovisit.add(fm.getNext(0));
663 while(current_node!=null||!tovisit.isEmpty()) {
664 if (current_node==null) {
665 current_node=(FlatNode)tovisit.iterator().next();
666 tovisit.remove(current_node);
668 visited.add(current_node);
669 if (nodetolabel.containsKey(current_node))
670 output.println("L"+nodetolabel.get(current_node)+":");
671 /*if (state.INSTRUCTIONFAILURE) {
672 if (state.THREAD||state.DSM) {
673 output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
676 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
678 if (current_node.numNext()==0) {
680 super.generateFlatNode(fm, lb, current_node, output);
681 if (current_node.kind()!=FKind.FlatReturnNode) {
682 //output.println(" flushAll();");
683 output.println("#ifdef RAWCACHEFLUSH");
684 output.println("raw_user_interrupts_off();");
685 output.println("#ifdef RAWDEBUG");
686 output.println("raw_test_pass(0xec00);");
687 output.println("#endif");
688 output.println("raw_flush_entire_cache();");
689 output.println("#ifdef RAWDEBUG");
690 output.println("raw_test_pass(0xecff);");
691 output.println("#endif");
692 output.println("raw_user_interrupts_on();");
693 output.println("#endif");
694 outputTransCode(output);
695 output.println(" return;");
698 } else if(current_node.numNext()==1) {
700 super.generateFlatNode(fm, lb, current_node, output);
701 FlatNode nextnode=current_node.getNext(0);
702 if (visited.contains(nextnode)) {
703 output.println("goto L"+nodetolabel.get(nextnode)+";");
706 current_node=nextnode;
707 } else if (current_node.numNext()==2) {
710 super.generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
711 if (!visited.contains(current_node.getNext(1)))
712 tovisit.add(current_node.getNext(1));
713 if (visited.contains(current_node.getNext(0))) {
714 output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
717 current_node=current_node.getNext(0);
718 } else throw new Error();
721 output.println("}\n\n");
724 /** This method outputs TaskDescriptor information */
725 private void generateTaskDescriptor(PrintWriter output, PrintWriter outtask, FlatMethod fm, TaskDescriptor task, Vector[] qnames) {
726 int num = this.currentSchedule.getCoreNum();
728 output.println("/* TaskDescriptor information for task " + task.getSymbol() + " on core " + num + "*/");
730 for (int i=0; i<task.numParameters(); i++) {
731 VarDescriptor param_var=task.getParameter(i);
732 TypeDescriptor param_type=task.getParamType(i);
733 FlagExpressionNode param_flag=task.getFlag(param_var);
734 TagExpressionList param_tag=task.getTag(param_var);
737 if (param_flag==null) {
738 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
739 output.println("0x0, 0x0 };");
742 DNFFlag dflag=param_flag.getDNF();
743 dnfterms=dflag.size();
745 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
746 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
747 for(int j=0; j<dflag.size(); j++) {
750 Vector term=dflag.get(j);
753 for(int k=0; k<term.size(); k++) {
754 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
755 FlagDescriptor fd=dfa.getFlag();
756 boolean negated=dfa.getNegated();
757 int flagid=1<<((Integer)flags.get(fd)).intValue();
762 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
764 output.println("};");
767 output.println("int parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
768 //BUG...added next line to fix, test with any task program
770 for(int j=0; j<param_tag.numTags(); j++) {
773 /* for each tag we need */
774 /* which slot it is */
775 /* what type it is */
776 TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
777 TempDescriptor tmp=param_tag.getTemp(j);
778 int slot=fm.getTagInt(tmp);
779 output.println(slot+", "+state.getTagId(tvd.getTag()));
781 output.println("};");
783 // generate object queue for this parameter
784 String qname = this.objqueueprefix+i+"_"+task.getCoreSafeSymbol(num);
785 if(param_type.getClassDesc().getSymbol().equals("StartupObject")) {
786 this.startupcorenum = num;
788 if(qnames[param_type.getClassDesc().getId()] == null) {
789 qnames[param_type.getClassDesc().getId()] = new Vector();
791 qnames[param_type.getClassDesc().getId()].addElement(qname);
792 outtask.println("extern struct parameterwrapper " + qname + ";");
793 output.println("struct parameterwrapper " + qname + "={");
794 output.println(".objectset = 0,"); // objectset
795 output.println("/* number of DNF terms */ .numberofterms = "+dnfterms+","); // numberofterms
796 output.println(".intarray = parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
799 output.println("/* number of tags */ .numbertags = "+param_tag.numTags()+",");
801 output.println("/* number of tags */ .numbertags = 0,");
802 output.println(".tagarray = parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+","); // tagarray
803 output.println(".task = 0,"); // task
804 output.println(".slot = " + i + ","); // slot
806 output.println("};");
808 output.println("struct parameterdescriptor parameter_"+i+"_"+task.getCoreSafeSymbol(num)+"={");
809 output.println("/* type */"+param_type.getClassDesc().getId()+",");
810 output.println("/* number of DNF terms */"+dnfterms+",");
811 output.println("parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
812 output.println("&" + qname + ","); // queue
813 //BUG, added next line to fix and else statement...test
814 //with any task program
816 output.println("/* number of tags */"+param_tag.numTags()+",");
818 output.println("/* number of tags */ 0,");
819 output.println("parametertag_"+i+"_"+task.getCoreSafeSymbol(num)); // tagarray
820 output.println("};");
823 /* parameter queues for this task*/
824 output.println("struct parameterwrapper * " + this.paramqarrayprefix + task.getCoreSafeSymbol(num)+"[] = {");
825 for (int i=0; i<task.numParameters(); i++) {
828 output.print("&" + this.objqueueprefix + i + "_" + task.getCoreSafeSymbol(num));
830 output.println("};");
832 output.println("struct parameterdescriptor * parameterdescriptors_"+task.getCoreSafeSymbol(num)+"[] = {");
833 for (int i=0; i<task.numParameters(); i++) {
836 output.print("¶meter_"+i+"_"+task.getCoreSafeSymbol(num));
838 output.println("};");
840 output.println("struct taskdescriptor " + this.taskprefix + task.getCoreSafeSymbol(num) + "={");
841 output.println("&"+task.getCoreSafeSymbol(num)+",");
842 output.println("/* number of parameters */" +task.numParameters() + ",");
843 int numtotal=task.numParameters()+fm.numTags();
844 output.println("/* number total parameters */" +numtotal + ",");
845 output.println("parameterdescriptors_"+task.getCoreSafeSymbol(num)+",");
846 output.println("\""+task.getSymbol()+"\"");
847 output.println("};");
852 /** This method generates header information for the task
853 * referenced by the Descriptor des. */
855 private void generateTaskHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
857 ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : des);
858 TaskDescriptor task=(TaskDescriptor) des;
860 int num = this.currentSchedule.getCoreNum();
861 //catch the constructor case
862 output.print("void ");
863 output.print(task.getCoreSafeSymbol(num)+"(");
865 boolean printcomma=false;
866 if (GENERATEPRECISEGC) {
867 output.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
871 /*if (state.DSM&&lb.isAtomic()) {
874 output.print("transrecord_t * trans");
878 if (!GENERATEPRECISEGC) {
880 output.println("void * parameterarray[]) {");
881 /* Unpack variables */
882 for(int i=0; i<objectparams.numPrimitives(); i++) {
883 TempDescriptor temp=objectparams.getPrimitive(i);
884 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
886 for(int i=0; i<fm.numTags(); i++) {
887 TempDescriptor temp=fm.getTag(i);
888 int offset=i+objectparams.numPrimitives();
889 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+i+"___=parameterarray["+offset+"];"); // add i to fix bugs of duplicate definition of tags
892 if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
893 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
894 } else output.println(") {");
897 protected void generateFlagOrAnd(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp,
898 PrintWriter output, int ormask, int andmask) {
899 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
900 output.println("flagorandinit("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
902 int num = this.currentSchedule.getCoreNum();
903 ClassDescriptor cd = temp.getType().getClassDesc();
904 Vector<FlagState> initfstates = ffan.getInitFStates(cd);
905 for(int i = 0; i < initfstates.size(); ++i) {
906 FlagState tmpFState = initfstates.elementAt(i);
908 QueueInfo qinfo = outputqueues(tmpFState, num, output, false);
909 output.println("flagorand("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+
910 ", 0x"+Integer.toHexString(andmask)+", " + qinfo.qname +
911 ", " + qinfo.length + ");");
914 if(ffan.getTaskType()==FlatFlagActionNode.TASKEXIT) {
915 // generate codes for profiling, recording which task exit it is
916 output.println("#ifdef RAWPROFILE");
917 output.println("setTaskExitIndex(" + ffan.getTaskExitIndex() + ");");
918 output.println("#endif");
923 protected void generateObjectDistribute(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp,
924 PrintWriter output) {
925 ClassDescriptor cd = temp.getType().getClassDesc();
926 Vector<FlagState> initfstates = null;
927 Vector[] targetFStates = null;
928 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
929 targetFStates = new Vector[1];
930 targetFStates[0] = ffan.getTargetFStates4NewObj(cd);
932 initfstates = ffan.getInitFStates(cd);
933 targetFStates = new Vector[initfstates.size()];
934 for(int i = 0; i < initfstates.size(); ++i) {
935 FlagState fs = initfstates.elementAt(i);
936 targetFStates[i] = ffan.getTargetFStates(fs);
938 if(!fs.isSetmask()) {
939 Hashtable flags=(Hashtable)flagorder.get(cd);
942 Iterator it_flags = fs.getFlags();
943 while(it_flags.hasNext()) {
944 FlagDescriptor fd = (FlagDescriptor)it_flags.next();
945 int flagid=1<<((Integer)flags.get(fd)).intValue();
949 fs.setAndmask(andmask);
950 fs.setCheckmask(checkmask);
955 boolean isolate = true; // check if this flagstate can associate to some task with multiple params which can
956 // reside on multiple cores
957 if((this.currentSchedule == null) && (fm.getMethod().getClassDesc().getSymbol().equals("ServerSocket"))) {
958 // ServerSocket object will always reside on current core
959 for(int j = 0; j < targetFStates.length; ++j) {
960 if(initfstates != null) {
961 FlagState fs = initfstates.elementAt(j);
962 output.println("if(" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
963 + ")==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
965 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
966 for(int i = 0; i < tmpfstates.size(); ++i) {
967 FlagState tmpFState = tmpfstates.elementAt(i);
969 // may have bugs here
970 output.println("/* reside on this core*");
971 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
973 if(initfstates != null) {
980 int num = this.currentSchedule.getCoreNum();
981 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
982 for(int j = 0; j < targetFStates.length; ++j) {
984 if(initfstates != null) {
985 fs = initfstates.elementAt(j);
986 output.println("if((" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
987 + "))==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
989 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
990 for(int i = 0; i < tmpfstates.size(); ++i) {
991 FlagState tmpFState = tmpfstates.elementAt(i);
993 if(this.currentSchedule.getAllyCoreTable() == null) {
996 isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) ||
997 (this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
1000 // indentify this object as a shared object
1001 // 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
1002 // is shared, it maybe shared all the time afterwards
1003 output.println("if(" + super.generateTemp(fm, temp, lb) + "->isolate == 1) {");
1004 output.println(" " + super.generateTemp(fm, temp, lb) + "->isolate = 0;");
1005 output.println(" " + super.generateTemp(fm, temp, lb) + "->original = (struct ___Object___ *)" + super.generateTemp(fm, temp, lb) + ";");
1006 output.println("}");
1009 Vector<TranObjInfo> sendto = new Vector<TranObjInfo>();
1010 Queue<Integer> queue = null;
1011 if(targetCoreTbl != null) {
1012 queue = targetCoreTbl.get(tmpFState);
1014 if((queue != null) &&
1015 ((queue.size() != 1) ||
1016 ((queue.size() == 1) && (queue.element().intValue() != num)))) {
1017 // this object may be transferred to other cores
1018 String queuename = (String) this.fsate2qnames[num].get(tmpFState);
1019 String queueins = queuename + "ins";
1021 Object[] cores = queue.toArray();
1023 Integer targetcore = (Integer)cores[0];
1024 if(queue.size() > 1) {
1025 index = queueins + ".index";
1027 if(queue.size() > 1) {
1028 output.println("switch(" + queueins + ".index % " + queueins + ".length) {");
1029 for(int k = 0; k < cores.length; ++k) {
1030 output.println("case " + k + ":");
1031 targetcore = (Integer)cores[k];
1032 if(targetcore.intValue() == num) {
1033 output.println("/* reside on this core*/");
1035 output.println("{");
1036 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1037 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1038 ", " + qinfo.length + ");");
1039 output.println("}");
1043 output.println("/* possibly needed by multi-parameter tasks on this core*/");
1044 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1049 // Is it possible to decide the actual queues?
1050 output.println("/* possibly needed by multi-parameter tasks on this core*/");
1051 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1053 output.println("/* transfer to core " + targetcore.toString() + "*/");
1054 output.println("{");
1055 // enqueue this object and its destinations for later process
1056 // all the possible queues
1057 QueueInfo qinfo = null;
1058 TranObjInfo tmpinfo = new TranObjInfo();
1059 tmpinfo.name = super.generateTemp(fm, temp, lb);
1060 tmpinfo.targetcore = targetcore;
1061 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1062 if(targetFS != null) {
1063 tmpinfo.fs = targetFS;
1065 tmpinfo.fs = tmpFState;
1067 if(!contains(sendto, tmpinfo)) {
1068 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1069 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1070 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1071 output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1072 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1073 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1074 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1075 sendto.add(tmpinfo);
1077 output.println("}");
1079 output.println("break;");
1081 output.println("}");
1085 // Is it possible to decide the actual queues?
1086 output.println("/* possibly needed by multi-parameter tasks on this core*/");
1087 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1089 output.println("/* transfer to core " + targetcore.toString() + "*/");
1090 output.println("{");
1091 // enqueue this object and its destinations for later process
1092 // all the possible queues
1093 QueueInfo qinfo = null;
1094 TranObjInfo tmpinfo = new TranObjInfo();
1095 tmpinfo.name = super.generateTemp(fm, temp, lb);
1096 tmpinfo.targetcore = targetcore;
1097 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1098 if(targetFS != null) {
1099 tmpinfo.fs = targetFS;
1101 tmpinfo.fs = tmpFState;
1103 if(!contains(sendto, tmpinfo)) {
1104 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1105 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1106 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1107 output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1108 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1109 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1110 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1111 sendto.add(tmpinfo);
1113 output.println("}");
1115 output.println("/* increase index*/");
1116 output.println("++" + queueins + ".index;");
1118 // this object will reside on current core
1119 output.println("/* reside on this core*/");
1121 output.println("{");
1122 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1123 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1124 ", " + qinfo.length + ");");
1125 output.println("}");
1129 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1133 // codes for multi-params tasks
1135 // flagstate associated with some multi-params tasks
1136 // need to be send to other cores
1137 Vector<Integer> targetcores = this.currentSchedule.getAllyCores(tmpFState);
1138 output.println("/* send the shared object to possible queues on other cores*/");
1139 for(int k = 0; k < targetcores.size(); ++k) {
1141 // add the information of exactly which queue
1142 //if(!sendto.contains(targetcores.elementAt(i))) {
1143 // previously not sended to this target core
1144 // enqueue this object and its destinations for later process
1145 output.println("{");
1146 // all the possible queues
1147 QueueInfo qinfo = null;
1148 TranObjInfo tmpinfo = new TranObjInfo();
1149 tmpinfo.name = super.generateTemp(fm, temp, lb);
1150 tmpinfo.targetcore = targetcores.elementAt(i);
1151 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1152 if(targetFS != null) {
1153 tmpinfo.fs = targetFS;
1155 tmpinfo.fs = tmpFState;
1157 if(!contains(sendto, tmpinfo)) {
1158 qinfo = outputtransqueues(tmpinfo.fs, targetcores.elementAt(i), output);
1159 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1160 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1161 output.println("tmpObjInfo->targetcore = "+targetcores.elementAt(i).toString()+";");
1162 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1163 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1164 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1165 sendto.add(tmpinfo);
1167 output.println("}");
1173 if(initfstates != null) {
1174 output.println("}");
1179 private QueueInfo outputqueues(FlagState tmpFState, int num, PrintWriter output, boolean isEnqueue) {
1181 QueueInfo qinfo = new QueueInfo();
1182 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1183 output.println("struct parameterwrapper * " + qinfo.qname + "[] = {");
1184 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1185 Vector<TaskDescriptor> residetasks = this.currentSchedule.getTasks();
1186 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1187 Vector<Integer> indexes = new Vector<Integer>();
1188 boolean comma = false;
1190 while(it_edges.hasNext()) {
1191 FEdge fe = (FEdge)it_edges.next();
1192 TaskDescriptor td = fe.getTask();
1193 int paraindex = fe.getIndex();
1194 if((!isEnqueue) || (isEnqueue && residetasks.contains(td))) {
1195 if((!tasks.contains(td)) ||
1196 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1197 tasks.addElement(td);
1198 indexes.addElement(paraindex);
1200 output.println(",");
1204 output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
1209 output.println("};");
1213 private QueueInfo outputtransqueues(FlagState tmpFState, int targetcore, PrintWriter output) {
1215 QueueInfo qinfo = new QueueInfo();
1216 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1217 output.println("int " + qinfo.qname + "_clone[] = {");
1218 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1219 Vector<TaskDescriptor> residetasks = this.scheduling.get(targetcore).getTasks();
1220 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1221 Vector<Integer> indexes = new Vector<Integer>();
1222 boolean comma = false;
1224 while(it_edges.hasNext()) {
1225 FEdge fe = (FEdge)it_edges.next();
1226 TaskDescriptor td = fe.getTask();
1227 int paraindex = fe.getIndex();
1228 if(residetasks.contains(td)) {
1229 if((!tasks.contains(td)) ||
1230 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1231 tasks.addElement(td);
1232 indexes.addElement(paraindex);
1234 output.println(",");
1238 output.print(residetasks.indexOf(td) + ", ");
1239 output.print(paraindex);
1244 output.println("};");
1245 output.println("int * " + qinfo.qname + " = RUNMALLOC(sizeof(int) * " + qinfo.length * 2 + ");");
1246 output.println("memcpy(" + qinfo.qname + ", (int *)" + qinfo.qname + "_clone, sizeof(int) * " + qinfo.length * 2 + ");");
1250 private class QueueInfo {
1252 public String qname;
1255 private String generateTempFlagName(FlatMethod fm, TempDescriptor td, LocalityBinding lb) {
1256 MethodDescriptor md=fm.getMethod();
1257 TaskDescriptor task=fm.getTask();
1258 TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
1260 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1261 return td.getSafeSymbol() + "_oldflag";
1264 if (objecttemps.isLocalPtr(td)) {
1265 return localsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1268 if (objecttemps.isParamPtr(td)) {
1269 return paramsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1274 protected void outputTransCode(PrintWriter output) {
1275 output.println("while(0 == isEmpty(totransobjqueue)) {");
1276 output.println(" struct transObjInfo * totransobj = (struct transObjInfo *)(getItem(totransobjqueue));");
1277 output.println(" transferObject(totransobj);");
1278 output.println(" RUNFREE(totransobj->queues);");
1279 output.println(" RUNFREE(totransobj);");
1280 output.println("}");
1281 output.println("freeQueue(totransobjqueue);");
1284 protected void outputAliasLockCode(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
1285 if(this.m_oa == null) {
1288 TaskDescriptor td = fm.getTask();
1289 Object[] allocSites = this.m_oa.getFlaggedAllocationSitesReachableFromTask(td).toArray();
1290 Vector<Vector<Integer>> aliasSets = new Vector<Vector<Integer>>();
1291 Vector<Vector<FlatNew>> aliasFNSets = new Vector<Vector<FlatNew>>();
1292 Hashtable<Integer, Vector<FlatNew>> aliasFNTbl4Para = new Hashtable<Integer, Vector<FlatNew>>();
1293 Hashtable<FlatNew, Vector<FlatNew>> aliasFNTbl = new Hashtable<FlatNew, Vector<FlatNew>>();
1294 for( int i = 0; i < fm.numParameters(); ++i ) {
1295 // for the ith parameter check for aliases to all
1296 // higher numbered parameters
1297 aliasSets.add(null);
1298 for( int j = i + 1; j < fm.numParameters(); ++j ) {
1299 if(this.m_oa.createsPotentialAliases(td, i, j)) {
1300 // ith parameter and jth parameter has alias, create lock to protect them
1301 if(aliasSets.elementAt(i) == null) {
1302 aliasSets.setElementAt(new Vector<Integer>(), i);
1304 aliasSets.elementAt(i).add(j);
1308 // for the ith parameter, check for aliases against
1309 // the set of allocation sites reachable from this
1311 aliasFNSets.add(null);
1312 for(int j = 0; j < allocSites.length; j++) {
1313 AllocationSite as = (AllocationSite)allocSites[j];
1314 if( this.m_oa.createsPotentialAliases(td, i, as) ) {
1315 // ith parameter and allocationsite as has alias
1316 if(aliasFNSets.elementAt(i) == null) {
1317 aliasFNSets.setElementAt(new Vector<FlatNew>(), i);
1319 aliasFNSets.elementAt(i).add(as.getFlatNew());
1324 // for each allocation site check for aliases with
1325 // other allocation sites in the context of execution
1327 for( int i = 0; i < allocSites.length; ++i ) {
1328 AllocationSite as1 = (AllocationSite)allocSites[i];
1329 for(int j = i + 1; j < allocSites.length; j++) {
1330 AllocationSite as2 = (AllocationSite)allocSites[j];
1332 if( this.m_oa.createsPotentialAliases(td, as1, as2) ) {
1333 // as1 and as2 has alias
1334 if(!aliasFNTbl.contains(as1.getFlatNew())) {
1335 aliasFNTbl.put(as1.getFlatNew(), new Vector<FlatNew>());
1337 if(!aliasFNTbl.get(as1.getFlatNew()).contains(as2.getFlatNew())) {
1338 aliasFNTbl.get(as1.getFlatNew()).add(as2.getFlatNew());
1344 // if FlatNew N1->N2->N3, we group N1, N2, N3 together
1345 Iterator<FlatNew> it = aliasFNTbl.keySet().iterator();
1346 Vector<FlatNew> visited = new Vector<FlatNew>();
1347 while(it.hasNext()) {
1348 FlatNew tmpfn = it.next();
1349 if(visited.contains(tmpfn)) {
1353 Queue<FlatNew> tovisit = new LinkedList<FlatNew>();
1354 Vector<FlatNew> tmpv = aliasFNTbl.get(tmpfn);
1359 for(int j = 0; j < tmpv.size(); j++) {
1360 tovisit.add(tmpv.elementAt(j));
1363 while(!tovisit.isEmpty()) {
1364 FlatNew fn = tovisit.poll();
1366 Vector<FlatNew> tmpset = aliasFNTbl.get(fn);
1367 if(tmpset != null) {
1368 // merge tmpset to the alias set of the ith parameter
1369 for(int j = 0; j < tmpset.size(); j++) {
1370 if(!tmpv.contains(tmpset.elementAt(j))) {
1371 tmpv.add(tmpset.elementAt(j));
1372 tovisit.add(tmpset.elementAt(j));
1375 aliasFNTbl.remove(fn);
1378 it = aliasFNTbl.keySet().iterator();
1381 // check alias between parameters and between parameter-flatnew
1382 for(int i = 0; i < aliasSets.size(); i++) {
1383 Queue<Integer> tovisit = new LinkedList<Integer>();
1384 Vector<Integer> tmpv = aliasSets.elementAt(i);
1389 for(int j = 0; j < tmpv.size(); j++) {
1390 tovisit.add(tmpv.elementAt(j));
1393 while(!tovisit.isEmpty()) {
1394 int index = tovisit.poll().intValue();
1395 Vector<Integer> tmpset = aliasSets.elementAt(index);
1396 if(tmpset != null) {
1397 // merge tmpset to the alias set of the ith parameter
1398 for(int j = 0; j < tmpset.size(); j++) {
1399 if(!tmpv.contains(tmpset.elementAt(j))) {
1400 tmpv.add(tmpset.elementAt(j));
1401 tovisit.add(tmpset.elementAt(j));
1404 aliasSets.setElementAt(null, index);
1407 Vector<FlatNew> tmpFNSet = aliasFNSets.elementAt(index);
1408 if(tmpFNSet != null) {
1409 // merge tmpFNSet to the aliasFNSet of the ith parameter
1410 if(aliasFNSets.elementAt(i) == null) {
1411 aliasFNSets.setElementAt(tmpFNSet, i);
1413 Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1414 for(int j = 0; j < tmpFNSet.size(); j++) {
1415 if(!tmpFNv.contains(tmpFNSet.elementAt(j))) {
1416 tmpFNv.add(tmpFNSet.elementAt(j));
1420 aliasFNSets.setElementAt(null, index);
1426 int numparalock = 0;
1427 Vector<Vector<Integer>> tmpaliasSets = new Vector<Vector<Integer>>();
1428 for(int i = 0; i < aliasSets.size(); i++) {
1429 Vector<Integer> tmpv = aliasSets.elementAt(i);
1432 tmpaliasSets.add(tmpv);
1436 Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1437 if(tmpFNv != null) {
1438 aliasFNTbl4Para.put(i, tmpFNv);
1444 numparalock = numlock;
1447 this.m_aliasSets = tmpaliasSets;
1448 tmpaliasSets.clear();
1449 tmpaliasSets = null;
1450 aliasFNSets.clear();
1452 this.m_aliasFNTbl4Para = aliasFNTbl4Para;
1453 this.m_aliasFNTbl = aliasFNTbl;
1454 numlock += this.m_aliasFNTbl.size();
1458 output.println("int aliaslocks[" + numlock + "];");
1459 output.println("int tmpi = 0;");
1460 // associate locks with parameters
1462 for(int i = 0; i < this.m_aliasSets.size(); i++) {
1463 Vector<Integer> toadd = this.m_aliasSets.elementAt(i);
1465 output.print("int tmplen_" + lockindex + " = 0;");
1466 output.println("void * tmpptrs_" + lockindex + "[] = {");
1467 for(int j = 0; j < toadd.size(); j++) {
1468 int para = toadd.elementAt(j).intValue();
1469 output.print(super.generateTemp(fm, fm.getParameter(para), lb));
1470 if(j < toadd.size() - 1) {
1473 output.println("};");
1476 output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", tmplen_" + lockindex + ", lockRedirectTbl);");
1478 for(int j = 0; j < toadd.size(); j++) {
1479 int para = toadd.elementAt(j).intValue();
1480 output.println("addAliasLock(" + super.generateTemp(fm, fm.getParameter(para), lb) + ", aliaslocks[" + i + "]);");
1482 // check if this lock is also associated with any FlatNew nodes
1483 if(this.m_aliasFNTbl4Para.contains(toadd.elementAt(0))) {
1484 if(this.m_aliaslocksTbl4FN == null) {
1485 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1487 Vector<FlatNew> tmpv = this.m_aliasFNTbl4Para.get(toadd.elementAt(0));
1488 for(int j = 0; j < tmpv.size(); j++) {
1489 FlatNew fn = tmpv.elementAt(j);
1490 if(!this.m_aliaslocksTbl4FN.contains(fn)) {
1491 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1493 this.m_aliaslocksTbl4FN.get(fn).add(i);
1495 this.m_aliasFNTbl4Para.remove(toadd.elementAt(0));
1500 Object[] key = this.m_aliasFNTbl4Para.keySet().toArray();
1501 for(int i = 0; i < key.length; i++) {
1502 int para = ((Integer)key[i]).intValue();
1504 output.println("void * tmpptrs_" + lockindex + "[] = {" + super.generateTemp(fm, fm.getParameter(para), lb) + "};");
1505 output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", 1, lockRedirectTbl);");
1507 output.println("addAliasLock(" + super.generateTemp(fm, fm.getParameter(para), lb) + ", aliaslocks[" + lockindex + "]);");
1508 Vector<FlatNew> tmpv = this.m_aliasFNTbl4Para.get(para);
1509 for(int j = 0; j < tmpv.size(); j++) {
1510 FlatNew fn = tmpv.elementAt(j);
1511 if(this.m_aliaslocksTbl4FN == null) {
1512 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1514 if(!this.m_aliaslocksTbl4FN.contains(fn)) {
1515 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1517 this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
1522 // check m_aliasFNTbl for locks associated with FlatNew nodes
1523 Object[] FNkey = this.m_aliasFNTbl.keySet().toArray();
1524 for(int i = 0; i < FNkey.length; i++) {
1525 FlatNew fn = (FlatNew)FNkey[i];
1526 Vector<FlatNew> tmpv = this.m_aliasFNTbl.get(fn);
1528 output.println("aliaslocks[tmpi++] = (int)(RUNMALLOC(sizeof(int)));");
1530 if(this.m_aliaslocksTbl4FN == null) {
1531 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1533 if(!this.m_aliaslocksTbl4FN.contains(fn)) {
1534 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1536 this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
1537 for(int j = 0; j < tmpv.size(); j++) {
1538 FlatNew tfn = tmpv.elementAt(j);
1539 if(!this.m_aliaslocksTbl4FN.contains(tfn)) {
1540 this.m_aliaslocksTbl4FN.put(tfn, new Vector<Integer>());
1542 this.m_aliaslocksTbl4FN.get(tfn).add(lockindex);
1549 protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
1550 if (frn.getReturnTemp()!=null) {
1551 if (frn.getReturnTemp().getType().isPtr())
1552 output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1554 output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1556 if(fm.getTask() != null) {
1557 output.println("#ifdef RAWCACHEFLUSH");
1558 output.println("raw_user_interrupts_off();");
1559 output.println("#ifdef RAWDEBUG");
1560 output.println("raw_test_pass(0xec00);");
1561 output.println("#endif");
1562 output.println("raw_flush_entire_cache();");
1563 output.println("#ifdef RAWDEBUG");
1564 output.println("raw_test_pass(0xecff);");
1565 output.println("#endif");
1566 output.println("raw_user_interrupts_on();");
1567 output.println("#endif");
1568 outputTransCode(output);
1570 output.println("return;");
1574 protected void generateFlatNew(FlatMethod fm, LocalityBinding lb, FlatNew fn,
1575 PrintWriter output) {
1576 if (state.DSM && locality.getAtomic(lb).get(fn).intValue() > 0
1577 && !fn.isGlobal()) {
1578 // Stash pointer in case of GC
1579 String revertptr = super.generateTemp(fm, reverttable.get(lb), lb);
1580 output.println(revertptr + "=trans->revertlist;");
1582 if (fn.getType().isArray()) {
1583 int arrayid = state.getArrayNumber(fn.getType())
1584 + state.numClasses();
1585 if (fn.isGlobal()) {
1586 output.println(super.generateTemp(fm, fn.getDst(), lb)
1587 + "=allocate_newarrayglobal(trans, " + arrayid + ", "
1588 + super.generateTemp(fm, fn.getSize(), lb) + ");");
1589 } else if (GENERATEPRECISEGC) {
1590 output.println(super.generateTemp(fm, fn.getDst(), lb)
1591 + "=allocate_newarray(&" + localsprefix + ", "
1592 + arrayid + ", " + super.generateTemp(fm, fn.getSize(), lb)
1595 output.println(super.generateTemp(fm, fn.getDst(), lb)
1596 + "=allocate_newarray(" + arrayid + ", "
1597 + super.generateTemp(fm, fn.getSize(), lb) + ");");
1600 if (fn.isGlobal()) {
1601 output.println(super.generateTemp(fm, fn.getDst(), lb)
1602 + "=allocate_newglobal(trans, "
1603 + fn.getType().getClassDesc().getId() + ");");
1604 } else if (GENERATEPRECISEGC) {
1605 output.println(super.generateTemp(fm, fn.getDst(), lb)
1606 + "=allocate_new(&" + localsprefix + ", "
1607 + fn.getType().getClassDesc().getId() + ");");
1609 output.println(super.generateTemp(fm, fn.getDst(), lb)
1611 + fn.getType().getClassDesc().getId() + ");");
1614 if (state.DSM && locality.getAtomic(lb).get(fn).intValue() > 0
1615 && !fn.isGlobal()) {
1616 String revertptr = super.generateTemp(fm, reverttable.get(lb), lb);
1617 output.println("trans->revertlist=" + revertptr + ";");
1619 // create alias lock if necessary
1620 if((this.m_aliaslocksTbl4FN != null) && (this.m_aliaslocksTbl4FN.contains(fn))) {
1621 Vector<Integer> tmpv = this.m_aliaslocksTbl4FN.get(fn);
1622 for(int i = 0; i < tmpv.size(); i++) {
1623 output.println("addAliasLock(" + super.generateTemp(fm, fn.getDst(), lb) + ", aliaslocks[" + tmpv.elementAt(i).intValue() + "]);");
1626 // generate codes for profiling, recording how many new objects are created
1627 if(!fn.getType().isArray() &&
1628 (fn.getType().getClassDesc() != null)
1629 && (fn.getType().getClassDesc().hasFlags())) {
1630 output.println("#ifdef RAWPROFILE");
1631 output.println("addNewObjInfo(\"" + fn.getType().getClassDesc().getSymbol() + "\");");
1632 output.println("#endif");
1638 public int targetcore;
1639 public FlagState fs;
1642 private boolean contains(Vector<TranObjInfo> sendto, TranObjInfo t) {
1643 if(sendto.size() == 0) {
1646 for(int i = 0; i < sendto.size(); i++) {
1647 TranObjInfo tmp = sendto.elementAt(i);
1648 if(!tmp.name.equals(t.name)) {
1651 if(tmp.targetcore != t.targetcore) {
1654 if(tmp.fs != t.fs) {