9 import Analysis.TaskStateAnalysis.*;
10 import Analysis.CallGraph.*;
11 import Analysis.Disjoint.*;
12 import Analysis.OoOJava.*;
13 import Analysis.Loops.*;
14 import Analysis.Locality.*;
18 public class BuildOoOJavaCode extends BuildCode {
22 String maxTaskRecSizeStr="__maxTaskRecSize___";
26 "sprintf(errmsg, \"MLP error at %s:%d\", __FILE__, __LINE__); "+
27 "perror(errmsg); exit(-1); }";
29 RuntimeConflictResolver rcr = null;
31 public BuildOoOJavaCode(State st,
35 OoOJavaAnalysis oooa, CallGraph callgraph
37 super( st, temptovar, typeutil, sa, callgraph);
43 protected void additionalIncludesMethodsHeader(PrintWriter outmethodheader) {
45 outmethodheader.println("#include <stdlib.h>");
46 outmethodheader.println("#include <stdio.h>");
47 outmethodheader.println("#include <string.h>");
48 outmethodheader.println("#include \"mlp_runtime.h\"");
49 outmethodheader.println("#include \"psemaphore.h\"");
50 outmethodheader.println("#include \"memPool.h\"");
53 outmethodheader.println("#include \"rcr_runtime.h\"");
56 // spit out a global to inform all worker threads what
57 // the maximum size is for any task record
58 outmethodheader.println("extern int "+maxTaskRecSizeStr+";");
62 protected void preCodeGenInitialization() {
64 // have to initialize some SESE compiler data before
65 // analyzing normal methods, which must happen before
66 // generating SESE internal code
68 Iterator<FlatSESEEnterNode> seseit = oooa.getAllSESEs().iterator();
70 while( seseit.hasNext() ) {
71 FlatSESEEnterNode fsen = seseit.next();
75 //TODO signal the object that will report errors
78 rcr = new RuntimeConflictResolver(PREFIX,
81 System.out.println("Runtime Conflict Resolver started.");
82 } catch (FileNotFoundException e) {
83 System.out.println("Runtime Conflict Resolver could not create output file.");
89 protected void initializeSESE(FlatSESEEnterNode fsen) {
91 FlatMethod fm = fsen.getfmEnclosing();
92 MethodDescriptor md = fm.getMethod();
93 ClassDescriptor cn = md.getClassDesc();
95 // Creates bogus method descriptor to index into tables
96 Modifiers modBogus = new Modifiers();
97 MethodDescriptor mdBogus =
98 new MethodDescriptor(modBogus,
99 new TypeDescriptor(TypeDescriptor.VOID),
100 "sese_"+fsen.getPrettyIdentifier()+fsen.getIdentifier()
103 mdBogus.setClassDesc(fsen.getcdEnclosing() );
104 FlatMethod fmBogus = new FlatMethod(mdBogus, null);
105 fsen.setfmBogus(fmBogus);
106 fsen.setmdBogus(mdBogus);
108 Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
109 inSetAndOutSet.addAll(fsen.getInVarSet() );
110 inSetAndOutSet.addAll(fsen.getOutVarSet() );
112 // Build paramsobj for bogus method descriptor
113 ParamsObject objectparams = new ParamsObject(mdBogus, tag++);
114 paramstable.put(mdBogus, objectparams);
116 Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
117 while( itr.hasNext() ) {
118 TempDescriptor temp = itr.next();
119 TypeDescriptor type = temp.getType();
121 objectparams.addPtr(temp);
123 objectparams.addPrim(temp);
127 // Build normal temp object for bogus method descriptor
128 TempObject objecttemps = new TempObject(objectparams, mdBogus, tag++);
129 tempstable.put(mdBogus, objecttemps);
131 for( Iterator nodeit = fsen.getNodeSet().iterator(); nodeit.hasNext(); ) {
132 FlatNode fn = (FlatNode)nodeit.next();
133 TempDescriptor[] writes = fn.writesTemps();
135 for( int i = 0; i < writes.length; i++ ) {
136 TempDescriptor temp = writes[i];
137 TypeDescriptor type = temp.getType();
140 objecttemps.addPtr(temp);
142 objecttemps.addPrim(temp);
149 protected void postCodeGenCleanUp() {
152 System.out.println("Runtime Conflict Resolver Done.");
157 protected void additionalCodeGen(PrintWriter outmethodheader,
158 PrintWriter outstructs,
159 PrintWriter outmethod) {
161 // Output function prototypes and structures for SESE's and code
163 // spit out a global to inform all worker threads with
164 // the maximum size is for any task record
165 outmethod.println("int "+maxTaskRecSizeStr+" = 0;");
167 // first generate code for each sese's internals
168 Iterator<FlatSESEEnterNode> seseit;
169 seseit = oooa.getAllSESEs().iterator();
171 while( seseit.hasNext() ) {
172 FlatSESEEnterNode fsen = seseit.next();
173 generateMethodSESE(fsen, outstructs, outmethodheader, outmethod);
176 // then write the invokeSESE switch to decouple scheduler
177 // from having to do unique details of sese invocation
178 generateSESEinvocationMethod(outmethodheader, outmethod);
182 protected void additionalCodeAtTopOfMain(PrintWriter outmethod) {
184 // do a calculation to determine which task record
185 // is the largest, store that as a global value for
186 // allocating records
187 Iterator<FlatSESEEnterNode> seseit = oooa.getAllSESEs().iterator();
188 while( seseit.hasNext() ) {
189 FlatSESEEnterNode fsen = seseit.next();
190 outmethod.println("if( sizeof( "+fsen.getSESErecordName()+
191 " ) > "+maxTaskRecSizeStr+
192 " ) { "+maxTaskRecSizeStr+
193 " = sizeof( "+fsen.getSESErecordName()+
197 outmethod.println(" runningSESE = NULL;");
199 outmethod.println(" workScheduleInit( "+state.OOO_NUMCORES+", invokeSESEmethod );");
201 //initializes data structures needed for the RCR traverser
202 if( state.RCR && rcr != null ) {
203 outmethod.println(" initializeStructsRCR();");
204 outmethod.println(" createAndFillMasterHashStructureArray();");
209 protected void additionalCodeAtBottomOfMain(PrintWriter outmethod) {
210 outmethod.println(" workScheduleBegin();");
214 protected void additionalIncludesMethodsImplementation(PrintWriter outmethod) {
215 outmethod.println("#include <stdlib.h>");
216 outmethod.println("#include <stdio.h>");
217 outmethod.println("#include \"mlp_runtime.h\"");
218 outmethod.println("#include \"psemaphore.h\"");
221 outmethod.println("#include \"trqueue.h\"");
222 outmethod.println("#include \"RuntimeConflictResolver.h\"");
223 outmethod.println("#include \"rcr_runtime.h\"");
224 outmethod.println("#include \"hashStructure.h\"");
229 protected void additionalIncludesStructsHeader(PrintWriter outstructs) {
230 outstructs.println("#include \"mlp_runtime.h\"");
231 outstructs.println("#include \"psemaphore.h\"");
233 outstructs.println("#include \"rcr_runtime.h\"");
238 protected void additionalClassObjectFields(PrintWriter outclassdefs) {
239 outclassdefs.println(" int oid;");
240 outclassdefs.println(" int allocsite;");
244 protected void additionalCodeAtTopMethodsImplementation(PrintWriter outmethod) {
245 outmethod.print("extern __thread int oid;\n");
246 outmethod.print("extern int oidIncrement;\n");
250 protected void additionalCodeAtTopFlatMethodBody(PrintWriter output, FlatMethod fm) {
252 // declare variables for naming static and dynamic SESE's
253 ContextTaskNames context = oooa.getContextTaskNames(fm);
255 output.println(" /* static SESE names */");
256 Iterator<SESEandAgePair> pItr = context.getNeededStaticNames().iterator();
257 while( pItr.hasNext() ) {
258 SESEandAgePair pair = pItr.next();
259 output.println(" void* "+pair+" = NULL;");
262 output.println(" /* dynamic variable sources */");
263 Iterator<TempDescriptor> dynSrcItr = context.getDynamicVarSet().iterator();
264 while( dynSrcItr.hasNext() ) {
265 TempDescriptor dynSrcVar = dynSrcItr.next();
266 output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;");
267 output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;");
271 // eom - set up related allocation sites's waiting queues
272 // TODO: we have to do a table-based thing here...
273 // jjenista, I THINK WE LOSE THIS ALTOGETHER!
275 FlatSESEEnterNode callerSESEplaceholder = (FlatSESEEnterNode) fm.getNext( 0 );
276 if(callerSESEplaceholder!= oooa.getMainSESE()){
277 Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(callerSESEplaceholder);
278 if (graph != null && graph.hasConflictEdge()) {
279 output.println(" // set up waiting queues ");
280 output.println(" int numMemoryQueue=0;");
281 output.println(" int memoryQueueItemID=0;");
282 Set<Analysis.OoOJava.SESELock> lockSet = oooa.getLockMappings(graph);
283 System.out.println("#lockSet="+lockSet.hashCode());
284 System.out.println("lockset="+lockSet);
285 for (Iterator iterator = lockSet.iterator(); iterator.hasNext();) {
286 Analysis.OoOJava.SESELock seseLock = (Analysis.OoOJava.SESELock) iterator.next();
287 System.out.println("id="+seseLock.getID());
288 System.out.println("#="+seseLock);
290 System.out.println("size="+lockSet.size());
291 if (lockSet.size() > 0) {
292 output.println(" numMemoryQueue=" + lockSet.size() + ";");
293 output.println(" runningSESE->numMemoryQueue=numMemoryQueue;");
294 output.println(" runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);");
303 protected void generateMethodSESE(FlatSESEEnterNode fsen,
304 PrintWriter outputStructs,
305 PrintWriter outputMethHead,
306 PrintWriter outputMethods) {
308 ParamsObject objectparams = (ParamsObject) paramstable.get(fsen.getmdBogus() );
309 TempObject objecttemps = (TempObject) tempstable.get(fsen.getmdBogus() );
311 // generate locals structure
312 outputStructs.println("struct "+
313 fsen.getcdEnclosing().getSafeSymbol()+
314 fsen.getmdBogus().getSafeSymbol()+"_"+
315 fsen.getmdBogus().getSafeMethodDescriptor()+
318 outputStructs.println(" int size;");
319 outputStructs.println(" void * next;");
321 for(int i=0; i<objecttemps.numPointers(); i++) {
322 TempDescriptor temp=objecttemps.getPointer(i);
324 if (temp.getType().isNull())
325 outputStructs.println(" void * "+temp.getSafeSymbol()+";");
327 outputStructs.println(" struct "+
328 temp.getType().getSafeSymbol()+" * "+
329 temp.getSafeSymbol()+";");
331 outputStructs.println("};\n");
334 // divide in-set and out-set into objects and primitives to prep
335 // for the record generation just below
336 Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
337 inSetAndOutSet.addAll(fsen.getInVarSet() );
338 inSetAndOutSet.addAll(fsen.getOutVarSet() );
340 Set<TempDescriptor> inSetAndOutSetObjs = new HashSet<TempDescriptor>();
341 Set<TempDescriptor> inSetAndOutSetPrims = new HashSet<TempDescriptor>();
343 Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
344 while( itr.hasNext() ) {
345 TempDescriptor temp = itr.next();
346 TypeDescriptor type = temp.getType();
348 inSetAndOutSetObjs.add(temp);
350 inSetAndOutSetPrims.add(temp);
355 // generate the SESE record structure
356 outputStructs.println(fsen.getSESErecordName()+" {");
358 // data common to any SESE, and it must be placed first so
359 // a module that doesn't know what kind of SESE record this
360 // is can cast the pointer to a common struct
361 outputStructs.println(" SESEcommon common;");
363 // then garbage list stuff
364 outputStructs.println(" /* next is in-set and out-set objects that look like a garbage list */");
365 outputStructs.println(" int size;");
366 outputStructs.println(" void * next;");
368 // I think that the set of TempDescriptors inSetAndOutSetObjs
369 // calculated above should match the pointer object params
370 // used in the following code, but let's just leave the working
371 // implementation unless there is actually a problem...
373 Vector<TempDescriptor> inset=fsen.getInVarsForDynamicCoarseConflictResolution();
374 for(int i=0; i<inset.size(); i++) {
375 TempDescriptor temp=inset.get(i);
376 if (temp.getType().isNull())
377 outputStructs.println(" void * "+temp.getSafeSymbol()+
378 "; /* in-or-out-set obj in gl */");
380 outputStructs.println(" struct "+temp.getType().getSafeSymbol()+" * "+
381 temp.getSafeSymbol()+"; /* in-or-out-set obj in gl */");
384 for(int i=0; i<objectparams.numPointers(); i++) {
385 TempDescriptor temp=objectparams.getPointer(i);
386 if (!inset.contains(temp)) {
387 if (temp.getType().isNull())
388 outputStructs.println(" void * "+temp.getSafeSymbol()+
389 "; /* in-or-out-set obj in gl */");
391 outputStructs.println(" struct "+temp.getType().getSafeSymbol()+" * "+
392 temp.getSafeSymbol()+"; /* in-or-out-set obj in gl */");
396 outputStructs.println(" /* next is primitives for in-set and out-set and dynamic tracking */");
398 Iterator<TempDescriptor> itrPrims = inSetAndOutSetPrims.iterator();
399 while( itrPrims.hasNext() ) {
400 TempDescriptor temp = itrPrims.next();
401 TypeDescriptor type = temp.getType();
402 if(type.isPrimitive()) {
403 outputStructs.println(" "+temp.getType().getSafeSymbol()+" "+
404 temp.getSafeSymbol()+"; /* in-set or out-set primitive */");
408 // note that the sese record pointer will be added below, just primitive part of tracking here
409 Iterator<TempDescriptor> itrDynInVars = fsen.getDynamicInVarSet().iterator();
410 while( itrDynInVars.hasNext() ) {
411 TempDescriptor dynInVar = itrDynInVars.next();
412 outputStructs.println(" INTPTR "+dynInVar+"_srcOffset; /* dynamic tracking primitive */");
416 outputStructs.println(" /* everything after this should be pointers to an SESE record */");
418 // other half of info for dynamic tracking, the SESE record pointer
419 itrDynInVars = fsen.getDynamicInVarSet().iterator();
420 while( itrDynInVars.hasNext() ) {
421 TempDescriptor dynInVar = itrDynInVars.next();
422 String depRecField = dynInVar+"_srcSESE";
423 outputStructs.println(" SESEcommon* "+depRecField+";");
424 addingDepRecField(fsen, depRecField);
427 // statically known sese sources are record pointers, too
428 Iterator<SESEandAgePair> itrStaticInVarSrcs = fsen.getStaticInVarSrcs().iterator();
429 while( itrStaticInVarSrcs.hasNext() ) {
430 SESEandAgePair srcPair = itrStaticInVarSrcs.next();
431 outputStructs.println(" "+srcPair.getSESE().getSESErecordName()+"* "+srcPair+";");
432 addingDepRecField(fsen, srcPair.toString());
436 if (inset.size()!=0) {
437 outputStructs.println("struct rcrRecord rcrRecords["+inset.size()+"];");
441 if( fsen.getFirstDepRecField() != null ) {
442 outputStructs.println(" /* compiler believes first dependent SESE record field above is: "+
443 fsen.getFirstDepRecField()+" */");
445 outputStructs.println("};\n");
448 // write method declaration to header file
449 outputMethHead.print("void ");
450 outputMethHead.print(fsen.getSESEmethodName()+"(");
451 outputMethHead.print(fsen.getSESErecordName()+"* "+paramsprefix);
452 outputMethHead.println(");\n");
455 generateFlatMethodSESE(fsen.getfmBogus(),
456 fsen.getcdEnclosing(),
462 // used when generating the specific SESE record struct
463 // to remember the FIRST field name of sese records
464 // that the current SESE depends on--we need to know the
465 // offset to the first one for garbage collection
466 protected void addingDepRecField(FlatSESEEnterNode fsen,
468 if( fsen.getFirstDepRecField() == null ) {
469 fsen.setFirstDepRecField(field);
471 fsen.incNumDepRecs();
475 private void generateFlatMethodSESE(FlatMethod fm,
477 FlatSESEEnterNode fsen,
478 FlatSESEExitNode seseExit,
482 MethodDescriptor md = fm.getMethod();
484 output.print("void ");
485 output.print(fsen.getSESEmethodName()+"(");
486 output.print(fsen.getSESErecordName()+"* "+paramsprefix);
487 output.println("){\n");
490 TempObject objecttemp=(TempObject) tempstable.get(md);
492 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
493 output.print(" struct "+
495 md.getSafeSymbol()+"_"+
496 md.getSafeMethodDescriptor()+
497 "_locals "+localsprefix+"={");
498 output.print(objecttemp.numPointers()+",");
499 output.print("&(((SESEcommon*)(___params___))[1])");
500 for(int j=0; j<objecttemp.numPointers(); j++)
501 output.print(", NULL");
502 output.println("};");
505 output.println(" /* regular local primitives */");
506 for(int i=0; i<objecttemp.numPrimitives(); i++) {
507 TempDescriptor td=objecttemp.getPrimitive(i);
508 TypeDescriptor type=td.getType();
510 output.println(" void * "+td.getSafeSymbol()+";");
511 else if (type.isClass()||type.isArray())
512 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
514 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
518 // declare variables for naming static and dynamic SESE's
519 ContextTaskNames context = oooa.getContextTaskNames(fsen);
521 output.println(" /* static SESE names */");
522 Iterator<SESEandAgePair> pItr = context.getNeededStaticNames().iterator();
523 while( pItr.hasNext() ) {
524 SESEandAgePair pair = pItr.next();
525 output.println(" SESEcommon* "+pair+" = NULL;");
528 // declare variables for tracking dynamic sources
529 output.println(" /* dynamic variable sources */");
530 Iterator<TempDescriptor> dynSrcItr = context.getDynamicVarSet().iterator();
531 while( dynSrcItr.hasNext() ) {
532 TempDescriptor dynSrcVar = dynSrcItr.next();
533 output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;");
534 output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;");
538 // declare local temps for in-set primitives, and if it is
539 // a ready-source variable, get the value from the record
540 output.println(" /* local temps for in-set primitives */");
541 Iterator<TempDescriptor> itrInSet = fsen.getInVarSet().iterator();
542 while( itrInSet.hasNext() ) {
543 TempDescriptor temp = itrInSet.next();
544 TypeDescriptor type = temp.getType();
545 if( !type.isPtr() ) {
546 if( fsen.getReadyInVarSet().contains(temp) ) {
547 output.println(" "+type+" "+temp+" = "+paramsprefix+"->"+temp+";");
549 output.println(" "+type+" "+temp+";");
554 // declare local temps for out-set primitives if its not already
555 // in the in-set, and it's value will get written so no problem
556 output.println(" /* local temp for out-set prim, not already in the in-set */");
557 Iterator<TempDescriptor> itrOutSet = fsen.getOutVarSet().iterator();
558 while( itrOutSet.hasNext() ) {
559 TempDescriptor temp = itrOutSet.next();
560 TypeDescriptor type = temp.getType();
561 if( !type.isPtr() && !fsen.getInVarSet().contains(temp) ) {
562 output.println(" "+type+" "+temp+";");
567 // initialize thread-local var to a the task's record, which is fused
568 // with the param list
570 output.println(" // code of this task's body should use this to access the running task record");
571 output.println(" runningSESE = &(___params___->common);");
572 output.println(" childSESE = 0;");
576 // eom - setup memory queue
577 output.println(" // set up memory queues ");
578 output.println(" int numMemoryQueue=0;");
579 output.println(" int memoryQueueItemID=0;");
580 Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(fsen);
581 if( graph != null && graph.hasConflictEdge() ) {
582 output.println(" {");
583 Set<Analysis.OoOJava.SESELock> lockSet = oooa.getLockMappings(graph);
584 System.out.println("#lockSet="+lockSet);
585 if( lockSet.size() > 0 ) {
586 output.println(" numMemoryQueue=" + lockSet.size() + ";");
587 output.println(" runningSESE->numMemoryQueue=numMemoryQueue;");
588 output.println(" runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);");
591 output.println(" }");
595 // set up a task's mem pool to recycle the allocation of children tasks
596 // don't bother if the task never has children (a leaf task)
597 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
598 output.println("/////////////////////////////////////////////");
599 output.println("//");
600 output.println("// TODO: use poolcreate to make one record pool");
601 output.println("// per WORKER THREAD and never destroy it...");
602 output.println("//");
603 output.println("/////////////////////////////////////////////");
604 if( !fsen.getIsLeafSESE() ) {
605 output.println(" runningSESE->taskRecordMemPool = poolcreate( "+
606 maxTaskRecSizeStr+", freshTaskRecordInitializer );");
607 if (state.RCR && !rcr.hasEmptyTraversers(fsen)) {
608 output.println(" createTR();");
609 output.println(" runningSESE->allHashStructures=TRqueue->allHashStructures;");
612 // make it clear we purposefully did not initialize this
613 output.println(" runningSESE->taskRecordMemPool = (MemPool*)0x7;");
615 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
618 // copy in-set into place, ready vars were already
619 // copied when the SESE was issued
620 Iterator<TempDescriptor> tempItr;
622 // static vars are from a known SESE
623 output.println(" // copy variables from static sources");
624 tempItr = fsen.getStaticInVarSet().iterator();
625 while( tempItr.hasNext() ) {
626 TempDescriptor temp = tempItr.next();
627 VariableSourceToken vst = fsen.getStaticInVarSrc(temp);
628 SESEandAgePair srcPair = new SESEandAgePair(vst.getSESE(), vst.getAge() );
629 output.println(" "+generateTemp(fsen.getfmBogus(), temp)+
630 " = "+paramsprefix+"->"+srcPair+"->"+vst.getAddrVar()+";");
633 output.println(" // decrement references to static sources");
634 for( Iterator<SESEandAgePair> pairItr = fsen.getStaticInVarSrcs().iterator(); pairItr.hasNext(); ) {
635 SESEandAgePair srcPair = pairItr.next();
636 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
637 output.println(" {");
638 output.println(" SESEcommon* src = &("+paramsprefix+"->"+srcPair+"->common);");
639 output.println(" RELEASE_REFERENCE_TO( src );");
640 output.println(" }");
641 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
645 // dynamic vars come from an SESE and src
646 output.println(" // copy variables from dynamic sources");
647 tempItr = fsen.getDynamicInVarSet().iterator();
648 while( tempItr.hasNext() ) {
649 TempDescriptor temp = tempItr.next();
650 TypeDescriptor type = temp.getType();
652 // go grab it from the SESE source
653 output.println(" if( "+paramsprefix+"->"+temp+"_srcSESE != NULL ) {");
656 if( type.isNull() ) {
658 } else if( type.isClass() || type.isArray() ) {
659 typeStr = "struct "+type.getSafeSymbol()+"*";
661 typeStr = type.getSafeSymbol();
664 output.println(" "+generateTemp(fsen.getfmBogus(), temp)+
665 " = *(("+typeStr+"*) ((void*)"+
666 paramsprefix+"->"+temp+"_srcSESE + "+
667 paramsprefix+"->"+temp+"_srcOffset));");
669 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
670 output.println(" SESEcommon* src = "+paramsprefix+"->"+temp+"_srcSESE;");
671 output.println(" RELEASE_REFERENCE_TO( src );");
672 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
674 // or if the source was our parent, its already in our record to grab
675 output.println(" } else {");
676 output.println(" "+generateTemp(fsen.getfmBogus(), temp)+
677 " = "+paramsprefix+"->"+temp+";");
678 output.println(" }");
681 // Check to see if we need to do a GC if this is a
682 // multi-threaded program...
683 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
684 output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
685 //Don't bother if we aren't in recursive methods...The loops case will catch it
686 // if (callgraph.getAllMethods(md).contains(md)) {
687 // if(this.state.MULTICOREGC) {
688 // output.println("if(gcflag) gc("+localsprefixaddr+");");
690 // output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
695 if( state.COREPROF ) {
696 output.println("#ifdef CP_EVENTID_TASKEXECUTE");
697 output.println(" CP_LOGEVENT( CP_EVENTID_TASKEXECUTE, CP_EVENTTYPE_BEGIN );");
698 output.println("#endif");
701 HashSet<FlatNode> exitset=new HashSet<FlatNode>();
702 exitset.add(seseExit);
703 generateCode(fsen.getNext(0), fm, exitset, output);
704 output.println("}\n\n");
708 // when a new mlp thread is created for an issued SESE, it is started
709 // by running this method which blocks on a cond variable until
710 // it is allowed to transition to execute. Then a case statement
711 // allows it to invoke the method with the proper SESE body, and after
712 // exiting the SESE method, executes proper SESE exit code before the
713 // thread can be destroyed
714 private void generateSESEinvocationMethod(PrintWriter outmethodheader,
715 PrintWriter outmethod
718 outmethodheader.println("void* invokeSESEmethod( void* seseRecord );");
719 outmethod.println("void* invokeSESEmethod( void* seseRecord ) {");
720 outmethod.println(" int status;");
721 outmethod.println(" char errmsg[128];");
723 // generate a case for each SESE class that can be invoked
724 outmethod.println(" switch( ((SESEcommon*)seseRecord)->classID ) {");
725 outmethod.println(" ");
726 Iterator<FlatSESEEnterNode> seseit;
727 seseit = oooa.getAllSESEs().iterator();
729 while( seseit.hasNext() ) {
730 FlatSESEEnterNode fsen = seseit.next();
732 outmethod.println(" /* "+fsen.getPrettyIdentifier()+" */");
733 outmethod.println(" case "+fsen.getIdentifier()+":");
734 outmethod.println(" "+fsen.getSESEmethodName()+"( seseRecord );");
736 if( fsen.getIsMainSESE() ) {
737 outmethod.println(" workScheduleExit();");
740 outmethod.println(" break;");
741 outmethod.println("");
744 // default case should never be taken, error out
745 outmethod.println(" default:");
746 outmethod.println(" printf(\"Error: unknown SESE class ID in invoke method.\\n\");");
747 outmethod.println(" exit(-30);");
748 outmethod.println(" break;");
749 outmethod.println(" }");
750 outmethod.println(" return NULL;");
751 outmethod.println("}\n\n");
756 protected void stallMEMRCR(FlatMethod fm,
758 Set<WaitingElement> waitingElementSet, PrintWriter output) {
759 output.println("// stall on parent's stall sites ");
760 output.println(" {");
761 output.println(" REntry* rentry;");
762 output.println(" // stallrecord sometimes is used as a task record for instance ");
763 output.println(" // when you call RELEASE_REFERENCE_TO on a stall record.");
764 output.println(" // so the parent field must be initialized.");
765 output.println(" SESEstall * stallrecord=(SESEstall *) poolalloc(runningSESE->taskRecordMemPool);");
766 output.println(" stallrecord->common.parent=runningSESE;");
767 output.println(" stallrecord->common.unresolvedDependencies=10000;");
768 output.println(" stallrecord->common.rcrstatus=1;");
769 output.println(" stallrecord->common.offsetToParamRecords=(INTPTR) & (((SESEstall *)0)->rcrRecords);");
770 output.println(" stallrecord->common.refCount = 3;");
771 output.println(" int localCount=10000;");
772 output.println(" stallrecord->rcrRecords[0].index=0;");
773 output.println(" stallrecord->rcrRecords[0].flag=0;");
774 output.println(" stallrecord->rcrRecords[0].next=NULL;");
775 output.println(" stallrecord->common.parentsStallSem=&runningSESEstallSem;");
776 output.println(" psem_reset( &runningSESEstallSem);");
777 output.println(" stallrecord->tag=runningSESEstallSem.tag;");
779 TempDescriptor stalltd=null;
780 for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext(); ) {
781 WaitingElement waitingElement =(WaitingElement) iterator.next();
782 if (waitingElement.getStatus() >= ConflictNode.COARSE) {
783 output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["
784 + waitingElement.getQueueID() + "]," + waitingElement.getStatus()
785 + ", (SESEcommon *) stallrecord, 1LL);");
787 throw new Error("Fine-grained conflict: This should not happen in RCR");
789 output.println(" rentry->queue=runningSESE->memoryQueueArray["
790 + waitingElement.getQueueID() + "];");
791 output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["
792 + waitingElement.getQueueID() + "],rentry)==NOTREADY) {");
793 output.println(" localCount--;");
794 output.println(" }");
795 output.println("#if defined(RCR)&&!defined(OOO_DISABLE_TASKMEMPOOL)");
796 output.println(" else poolfreeinto(runningSESE->memoryQueueArray["+
797 waitingElement.getQueueID()+
798 "]->rentrypool, rentry);");
799 output.println("#endif");
801 stalltd=waitingElement.getTempDesc();
802 } else if (stalltd!=waitingElement.getTempDesc()) {
803 throw new Error("Multiple temp descriptors at stall site"+stalltd+"!="+waitingElement.getTempDesc());
807 //did all of the course grained stuff
808 output.println(" if(!atomic_sub_and_test(localCount, &(stallrecord->common.unresolvedDependencies))) {");
809 //have to do fine-grained work also
810 output.println(" stallrecord->___obj___=(struct ___Object___ *)"
811 + generateTemp(fm, stalltd) + ";");
812 output.println(" stallrecord->common.classID=-"
813 + rcr.getTraverserID(stalltd, fn) + ";");
815 output.println(" enqueueTR(TRqueue, (void *)stallrecord);");
817 if (state.COREPROF) {
818 output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
820 .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );");
821 output.println("#endif");
824 output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
826 if (state.COREPROF) {
827 output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
829 .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );");
830 output.println("#endif");
833 output.println(" } else {"); //exit if condition
834 //release traversers reference if we didn't use traverser
835 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
836 output.println(" RELEASE_REFERENCES_TO((SESEcommon *)stallrecord, 2);");
837 output.println("#endif");
838 output.println(" }");
839 //release our reference to stall record
840 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
841 output.println(" RELEASE_REFERENCE_TO((SESEcommon *)stallrecord);");
842 output.println("#endif");
843 output.println(" }"); //exit block
847 protected void additionalCodePreNode(FlatMethod fm,
849 PrintWriter output) {
850 // insert pre-node actions from the code plan
852 CodePlan cp = oooa.getCodePlan(fn);
856 // the current task for a code plan is either the
857 // locally-defined enclosing task, or the caller proxy task.
858 // When it is the caller proxy, it is possible to ask what are
859 // all the possible tasks that the proxy might stand for
860 FlatSESEEnterNode currentSESE = cp.getCurrentSESE();
862 FlatMethod fmContext;
863 if( currentSESE.getIsCallerProxySESE() ) {
864 fmContext = oooa.getContainingFlatMethod(fn);
866 fmContext = currentSESE.getfmBogus();
869 ContextTaskNames contextTaskNames;
870 if( currentSESE.getIsCallerProxySESE() ) {
871 contextTaskNames = oooa.getContextTaskNames(oooa.getContainingFlatMethod(fn) );
873 contextTaskNames = oooa.getContextTaskNames(currentSESE);
876 // for each sese and age pair that this parent statement
877 // must stall on, take that child's stall semaphore, the
878 // copying of values comes after the statement
879 Iterator<VariableSourceToken> vstItr = cp.getStallTokens().iterator();
880 while( vstItr.hasNext() ) {
881 VariableSourceToken vst = vstItr.next();
883 SESEandAgePair pair = new SESEandAgePair(vst.getSESE(), vst.getAge() );
885 output.println(" {");
887 pair.getSESE().getSESErecordName()+"* child = ("+
888 pair.getSESE().getSESErecordName()+"*) "+pair+";");
890 output.println(" SESEcommon* childCom = (SESEcommon*) "+pair+";");
892 if( state.COREPROF ) {
893 output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
894 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );");
895 output.println("#endif");
898 output.println(" pthread_mutex_lock( &(childCom->lock) );");
899 output.println(" if( childCom->doneExecuting == FALSE ) {");
900 output.println(" psem_reset( &runningSESEstallSem );");
901 output.println(" childCom->parentsStallSem = &runningSESEstallSem;");
902 output.println(" pthread_mutex_unlock( &(childCom->lock) );");
903 output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
904 output.println(" } else {");
905 output.println(" pthread_mutex_unlock( &(childCom->lock) );");
906 output.println(" }");
908 // copy things we might have stalled for
909 Iterator<TempDescriptor> tdItr = cp.getCopySet(vst).iterator();
910 while( tdItr.hasNext() ) {
911 TempDescriptor td = tdItr.next();
912 output.println(" "+generateTemp(fmContext, td)+
913 " = child->"+vst.getAddrVar().getSafeSymbol()+";");
916 if( state.COREPROF ) {
917 output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
918 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );");
919 output.println("#endif");
922 output.println(" }");
925 // for each variable with a dynamic source, stall just for that variable
926 Iterator<TempDescriptor> dynItr = cp.getDynamicStallSet().iterator();
927 while( dynItr.hasNext() ) {
928 TempDescriptor dynVar = dynItr.next();
930 // only stall if the dynamic source is not yourself, denoted by src==NULL
931 // otherwise the dynamic write nodes will have the local var up-to-date
932 output.println(" {");
933 output.println(" if( "+dynVar+"_srcSESE != NULL ) {");
935 output.println(" SESEcommon* childCom = (SESEcommon*) "+dynVar+"_srcSESE;");
937 if( state.COREPROF ) {
938 output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
939 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );");
940 output.println("#endif");
943 output.println(" pthread_mutex_lock( &(childCom->lock) );");
944 output.println(" if( childCom->doneExecuting == FALSE ) {");
945 output.println(" psem_reset( &runningSESEstallSem );");
946 output.println(" childCom->parentsStallSem = &runningSESEstallSem;");
947 output.println(" pthread_mutex_unlock( &(childCom->lock) );");
948 output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
949 output.println(" } else {");
950 output.println(" pthread_mutex_unlock( &(childCom->lock) );");
951 output.println(" }");
953 TypeDescriptor type = dynVar.getType();
955 if( type.isNull() ) {
957 } else if( type.isClass() || type.isArray() ) {
958 typeStr = "struct "+type.getSafeSymbol()+"*";
960 typeStr = type.getSafeSymbol();
963 output.println(" "+generateTemp(fmContext, dynVar)+
964 " = *(("+typeStr+"*) ((void*)"+
965 dynVar+"_srcSESE + "+dynVar+"_srcOffset));");
967 if( state.COREPROF ) {
968 output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
969 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );");
970 output.println("#endif");
973 output.println(" }");
974 output.println(" }");
977 // for each assignment of a variable to rhs that has a dynamic source,
978 // copy the dynamic sources
979 Iterator dynAssignItr = cp.getDynAssigns().entrySet().iterator();
980 while( dynAssignItr.hasNext() ) {
981 Map.Entry me = (Map.Entry)dynAssignItr.next();
982 TempDescriptor lhs = (TempDescriptor) me.getKey();
983 TempDescriptor rhs = (TempDescriptor) me.getValue();
985 output.println(" {");
986 output.println(" SESEcommon* oldSrc = "+lhs+"_srcSESE;");
988 output.println(" "+lhs+"_srcSESE = "+rhs+"_srcSESE;");
989 output.println(" "+lhs+"_srcOffset = "+rhs+"_srcOffset;");
991 // no matter what we did above, track reference count of whatever
992 // this variable pointed to, do release last in case we're just
993 // copying the same value in because 1->2->1 is safe but ref count
994 // 1->0->1 has a window where it looks like it should be free'd
995 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
996 output.println(" if( "+rhs+"_srcSESE != NULL ) {");
997 output.println(" ADD_REFERENCE_TO( "+rhs+"_srcSESE );");
998 output.println(" }");
999 output.println(" if( oldSrc != NULL ) {");
1000 output.println(" RELEASE_REFERENCE_TO( oldSrc );");
1001 output.println(" }");
1002 output.println(" }");
1003 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
1006 // for each lhs that is dynamic from a non-dynamic source, set the
1007 // dynamic source vars to the current SESE
1008 dynItr = cp.getDynAssignCurr().iterator();
1009 while( dynItr.hasNext() ) {
1010 TempDescriptor dynVar = dynItr.next();
1012 assert contextTaskNames.getDynamicVarSet().contains(dynVar);
1014 // first release a reference to current record
1015 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1016 output.println(" if( "+dynVar+"_srcSESE != NULL ) {");
1017 output.println(" RELEASE_REFERENCE_TO( oldSrc );");
1018 output.println(" }");
1019 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
1021 output.println(" "+dynVar+"_srcSESE = NULL;");
1025 // handling stall site, consider that one of several tasks might be
1026 // executing, so create a switch on task ID, because waiting elements
1027 // generated by this stall site should be inserted into possibly a
1028 // different memory queue index, depending on which task type it is
1029 // update: only generate the switch statement if there is at least
1030 // one non-empty case that will go in it!
1031 boolean atLeastOneCase = false;
1033 // create a case for each class of task that might be executing
1034 Iterator<FlatSESEEnterNode> taskItr = oooa.getPossibleExecutingRBlocks(fn).iterator();
1035 while( taskItr.hasNext() ) {
1036 FlatSESEEnterNode parent = taskItr.next();
1037 ConflictGraph graph = oooa.getConflictGraph(parent);
1039 if( graph == null ) {
1043 Set<SESELock> seseLockSet = oooa.getLockMappings(graph);
1044 Set<WaitingElement> waitingElementSet = graph.getStallSiteWaitingElementSet(fn, seseLockSet);
1046 if( waitingElementSet.size() == 0 ) {
1050 // TODO: THIS STRATEGY CAN BE OPTIMIZED EVEN FURTHER, IF THERE
1051 // IS EXACTLY ONE CASE, DON'T GENERATE A SWITCH AT ALL
1052 if( atLeastOneCase == false ) {
1053 atLeastOneCase = true;
1054 output.println(" // potential stall site ");
1055 output.println(" switch( runningSESE->classID ) {");
1058 output.println(" case "+parent.getIdentifier()+": {");
1061 stallMEMRCR(fm, fn, waitingElementSet, output);
1064 output.println(" REntry* rentry;");
1066 for( Iterator iterator = waitingElementSet.iterator(); iterator.hasNext(); ) {
1067 WaitingElement waitingElement = (WaitingElement) iterator.next();
1069 if (waitingElement.getStatus() >= ConflictNode.COARSE) {
1070 output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["
1071 + waitingElement.getQueueID() + "]," + waitingElement.getStatus()
1072 + ", runningSESE);");
1074 output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["
1075 + waitingElement.getQueueID() + "]," + waitingElement.getStatus()
1076 + ", runningSESE, (void*)&"
1077 + generateTemp(fm, waitingElement.getTempDesc()) + ");");
1079 output.println(" rentry->parentStallSem=&runningSESEstallSem;");
1080 output.println(" psem_reset( &runningSESEstallSem);");
1081 output.println(" rentry->tag=runningSESEstallSem.tag;");
1082 output.println(" rentry->queue=runningSESE->memoryQueueArray["
1083 + waitingElement.getQueueID() + "];");
1084 output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["
1085 + waitingElement.getQueueID() + "],rentry)==NOTREADY){");
1086 if (state.COREPROF) {
1087 output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
1088 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );");
1089 output.println("#endif");
1092 output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
1094 if (state.COREPROF) {
1095 output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
1096 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );");
1097 output.println("#endif");
1099 output.println(" } ");
1103 output.println(" } break; // end case "+parent.getIdentifier());
1106 if( atLeastOneCase ) {
1107 output.println(" } // end stall site switch");
1113 protected void additionalCodePostNode(FlatMethod fm,
1115 PrintWriter output) {
1117 // insert post-node actions from the code-plan (none right now...)
1121 public void generateFlatSESEEnterNode(FlatMethod fm,
1122 FlatSESEEnterNode fsen,
1123 PrintWriter output) {
1125 // there may be an SESE in an unreachable method, skip over
1126 if( !oooa.getAllSESEs().contains(fsen) ) {
1130 // assert we are never generating code for the caller proxy
1131 // it should only appear in analysis results
1132 assert !fsen.getIsCallerProxySESE();
1135 output.println(" { // issue new task instance");
1137 if( state.COREPROF ) {
1138 output.println("#ifdef CP_EVENTID_TASKDISPATCH");
1139 output.println(" CP_LOGEVENT( CP_EVENTID_TASKDISPATCH, CP_EVENTTYPE_BEGIN );");
1140 output.println("#endif");
1144 // before doing anything, lock your own record and increment the running children
1145 if( !fsen.getIsMainSESE() ) {
1146 output.println(" childSESE++;");
1149 // allocate the space for this record
1150 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1152 output.println("#ifdef CP_EVENTID_POOLALLOC");
1153 output.println(" CP_LOGEVENT( CP_EVENTID_POOLALLOC, CP_EVENTTYPE_BEGIN );");
1154 output.println("#endif");
1155 if( !fsen.getIsMainSESE() ) {
1157 fsen.getSESErecordName()+"* seseToIssue = ("+
1158 fsen.getSESErecordName()+"*) poolalloc( runningSESE->taskRecordMemPool );");
1159 output.println(" CHECK_RECORD( seseToIssue );");
1162 fsen.getSESErecordName()+"* seseToIssue = ("+
1163 fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+
1164 fsen.getSESErecordName()+" ) );");
1166 output.println("#ifdef CP_EVENTID_POOLALLOC");
1167 output.println(" CP_LOGEVENT( CP_EVENTID_POOLALLOC, CP_EVENTTYPE_END );");
1168 output.println("#endif");
1170 output.println("#else // OOO_DISABLE_TASKMEMPOOL");
1172 fsen.getSESErecordName()+"* seseToIssue = ("+
1173 fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+
1174 fsen.getSESErecordName()+" ) );");
1175 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
1178 // set up the SESE in-set and out-set objects, which look
1179 // like a garbage list
1180 output.println(" struct garbagelist * gl= (struct garbagelist *)&(((SESEcommon*)(seseToIssue))[1]);");
1181 output.println(" gl->size="+calculateSizeOfSESEParamList(fsen)+";");
1182 output.println(" gl->next = NULL;");
1183 output.println(" seseToIssue->common.rentryIdx=0;");
1186 //flag the SESE status as 1...it will be reset
1187 output.println(" seseToIssue->common.rcrstatus=1;");
1190 // there are pointers to SESE records the newly-issued SESE
1191 // will use to get values it depends on them for--how many
1192 // are there, and what is the offset from the total SESE
1193 // record to the first dependent record pointer?
1194 output.println(" seseToIssue->common.numDependentSESErecords="+
1195 fsen.getNumDepRecs()+";");
1197 // we only need this (and it will only compile) when the number of dependent
1198 // SESE records is non-zero
1199 if( fsen.getFirstDepRecField() != null ) {
1200 output.println(" seseToIssue->common.offsetToDepSESErecords=(INTPTR)sizeof("+
1201 fsen.getSESErecordName()+") - (INTPTR)&((("+
1202 fsen.getSESErecordName()+"*)0)->"+fsen.getFirstDepRecField()+");"
1207 fsen.getInVarsForDynamicCoarseConflictResolution().size() > 0
1209 output.println(" seseToIssue->common.offsetToParamRecords=(INTPTR) & ((("+
1210 fsen.getSESErecordName()+"*)0)->rcrRecords);");
1213 // fill in common data
1214 output.println(" int localCount=0;");
1215 output.println(" seseToIssue->common.classID = "+fsen.getIdentifier()+";");
1216 output.println(" seseToIssue->common.unresolvedDependencies = 10000;");
1217 output.println(" seseToIssue->common.parentsStallSem = NULL;");
1218 output.println(" initQueue(&seseToIssue->common.forwardList);");
1219 output.println(" seseToIssue->common.doneExecuting = FALSE;");
1220 output.println(" seseToIssue->common.numRunningChildren = 0;");
1221 output.println("#ifdef OOO_DISABLE_TASKMEMPOOL");
1222 output.println(" pthread_cond_init( &(seseToIssue->common.runningChildrenCond), NULL );");
1223 output.println("#endif");
1224 output.println(" seseToIssue->common.parent = runningSESE;");
1225 // start with refCount = 2, one being the count that the child itself
1226 // will decrement when it retires, to say it is done using its own
1227 // record, and the other count is for the parent that will remember
1228 // the static name of this new child below
1230 // if we're using RCR, ref count is 3 because the traverser has
1232 if( !fsen.getIsMainSESE() && fsen.getInVarsForDynamicCoarseConflictResolution().size()>0) {
1233 output.println(" seseToIssue->common.refCount = 10003;");
1235 output.println(" seseToIssue->common.refCount = 10002;");
1237 output.println(" int refCount=10000;");
1239 output.println(" seseToIssue->common.refCount = 2;");
1242 // all READY in-vars should be copied now and be done with it
1243 Iterator<TempDescriptor> tempItr = fsen.getReadyInVarSet().iterator();
1244 while( tempItr.hasNext() ) {
1245 TempDescriptor temp = tempItr.next();
1247 // determine whether this new task instance is in a method context,
1248 // or within the body of another task
1249 assert !fsen.getIsCallerProxySESE();
1250 FlatSESEEnterNode parent = fsen.getLocalParent();
1251 if( parent != null && !parent.getIsCallerProxySESE() ) {
1252 output.println(" seseToIssue->"+temp+" = "+
1253 generateTemp(parent.getfmBogus(), temp)+";");
1255 output.println(" seseToIssue->"+temp+" = "+
1256 generateTemp(fsen.getfmEnclosing(), temp)+";");
1260 // before potentially adding this SESE to other forwarding lists,
1262 output.println("#ifdef OOO_DISABLE_TASKMEMPOOL");
1263 output.println(" pthread_mutex_init( &(seseToIssue->common.lock), NULL );");
1264 output.println("#endif");
1266 if( !fsen.getIsMainSESE() ) {
1267 // count up outstanding dependencies, static first, then dynamic
1268 Iterator<SESEandAgePair> staticSrcsItr = fsen.getStaticInVarSrcs().iterator();
1269 while( staticSrcsItr.hasNext() ) {
1270 SESEandAgePair srcPair = staticSrcsItr.next();
1271 output.println(" {");
1272 output.println(" SESEcommon* src = (SESEcommon*)"+srcPair+";");
1273 output.println(" pthread_mutex_lock( &(src->lock) );");
1274 // FORWARD TODO - ...what? make it a chain of arrays instead of true linked-list?
1275 output.println(" if( !src->doneExecuting ) {");
1276 output.println(" addNewItem( &src->forwardList, seseToIssue );");
1277 output.println(" ++(localCount);");
1278 output.println(" }");
1279 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1280 output.println(" ADD_REFERENCE_TO( src );");
1281 output.println("#endif");
1282 output.println(" pthread_mutex_unlock( &(src->lock) );");
1283 output.println(" }");
1285 // whether or not it is an outstanding dependency, make sure
1286 // to pass the static name to the child's record
1287 output.println(" seseToIssue->"+srcPair+" = "+
1288 "("+srcPair.getSESE().getSESErecordName()+"*)"+
1292 // dynamic sources might already be accounted for in the static list,
1293 // so only add them to forwarding lists if they're not already there
1294 Iterator<TempDescriptor> dynVarsItr = fsen.getDynamicInVarSet().iterator();
1295 while( dynVarsItr.hasNext() ) {
1296 TempDescriptor dynInVar = dynVarsItr.next();
1297 output.println(" {");
1298 output.println(" SESEcommon* src = (SESEcommon*)"+dynInVar+"_srcSESE;");
1300 // the dynamic source is NULL if it comes from your own space--you can't pass
1301 // the address off to the new child, because you're not done executing and
1302 // might change the variable, so copy it right now
1303 output.println(" if( src != NULL ) {");
1304 output.println(" pthread_mutex_lock( &(src->lock) );");
1308 output.println(" if( isEmpty( &src->forwardList ) ||");
1309 output.println(" seseToIssue != peekItem( &src->forwardList ) ) {");
1310 output.println(" if( !src->doneExecuting ) {");
1311 output.println(" addNewItem( &src->forwardList, seseToIssue );");
1312 output.println(" ++(localCount);");
1313 output.println(" }");
1314 output.println(" }");
1315 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1316 output.println(" ADD_REFERENCE_TO( src );");
1317 output.println("#endif");
1318 output.println(" pthread_mutex_unlock( &(src->lock) );");
1319 output.println(" seseToIssue->"+dynInVar+"_srcOffset = "+dynInVar+"_srcOffset;");
1320 output.println(" } else {");
1323 // determine whether this new task instance is in a method context,
1324 // or within the body of another task
1325 assert !fsen.getIsCallerProxySESE();
1326 FlatSESEEnterNode parent = fsen.getLocalParent();
1327 if( parent != null && !parent.getIsCallerProxySESE() ) {
1328 output.println(" seseToIssue->"+dynInVar+" = "+
1329 generateTemp(parent.getfmBogus(), dynInVar)+";");
1331 output.println(" seseToIssue->"+dynInVar+" = "+
1332 generateTemp(fsen.getfmEnclosing(), dynInVar)+";");
1335 output.println(" }");
1336 output.println(" }");
1338 // even if the value is already copied, make sure your NULL source
1339 // gets passed so child knows it already has the dynamic value
1340 output.println(" seseToIssue->"+dynInVar+"_srcSESE = "+dynInVar+"_srcSESE;");
1344 // maintain pointers for finding dynamic SESE
1345 // instances from static names, do a shuffle as instances age
1346 // and also release references that have become too old
1347 if( !fsen.getIsMainSESE() ) {
1349 FlatSESEEnterNode currentSESE = fsen.getLocalParent();
1351 ContextTaskNames contextTaskNames;
1352 if( currentSESE == null ) {
1353 contextTaskNames = oooa.getContextTaskNames(oooa.getContainingFlatMethod(fsen) );
1355 contextTaskNames = oooa.getContextTaskNames(currentSESE);
1358 SESEandAgePair pairNewest = new SESEandAgePair(fsen, 0);
1359 SESEandAgePair pairOldest = new SESEandAgePair(fsen, fsen.getOldestAgeToTrack() );
1360 if( contextTaskNames.getNeededStaticNames().contains(pairNewest) ) {
1361 output.println(" {");
1362 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1363 output.println(" SESEcommon* oldest = "+pairOldest+";");
1364 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
1366 for( int i = fsen.getOldestAgeToTrack(); i > 0; --i ) {
1367 SESEandAgePair pair1 = new SESEandAgePair(fsen, i);
1368 SESEandAgePair pair2 = new SESEandAgePair(fsen, i-1);
1369 output.println(" "+pair1+" = "+pair2+";");
1371 output.println(" "+pairNewest+" = &(seseToIssue->common);");
1373 // no need to add a reference to whatever is the newest record, because
1374 // we initialized seseToIssue->refCount to *2*
1375 // but release a reference to whatever was the oldest BEFORE the shift
1376 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1377 output.println(" if( oldest != NULL ) {");
1378 output.println(" RELEASE_REFERENCE_TO( oldest );");
1379 output.println(" }");
1380 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
1381 output.println(" }");
1387 //////////////////////
1388 // count up memory conflict dependencies,
1389 ///////////////////////
1390 if( !fsen.getIsMainSESE() ) {
1392 if( state.COREPROF ) {
1393 output.println("#ifdef CP_EVENTID_PREPAREMEMQ");
1394 output.println(" CP_LOGEVENT( CP_EVENTID_PREPAREMEMQ, CP_EVENTTYPE_BEGIN );");
1395 output.println("#endif");
1399 dispatchMEMRC(fm, fsen, output);
1402 // there may be several task types that can get to this
1403 // program point (issue this new task) so create a switch
1404 // based on task ID, each type of task has a different index
1405 // scheme for its memory queue's, and the cases here drop the
1406 // new task instance in the right bucket
1407 boolean atLeastOneCase = false;
1409 // create a case for each class of task that might be executing
1410 Iterator<FlatSESEEnterNode> taskItr = oooa.getPossibleExecutingRBlocks(fsen).iterator();
1411 while( taskItr.hasNext() ) {
1412 FlatSESEEnterNode parent = taskItr.next();
1413 ConflictGraph graph = oooa.getConflictGraph(parent);
1415 if( graph == null || !graph.hasConflictEdge() ) {
1419 Set<SESELock> seseLockSet = oooa.getLockMappings(graph);
1421 SESEWaitingQueue seseWaitingQueue =
1422 graph.getWaitingElementSetBySESEID(fsen.getIdentifier(), seseLockSet);
1424 if( seseWaitingQueue.getWaitingElementSize() == 0 ) {
1428 if( atLeastOneCase == false ) {
1429 atLeastOneCase = true;
1430 output.println(" // add new task instance to current task's memory queues if needed ");
1431 output.println(" switch( runningSESE->classID ) {");
1434 output.println(" case "+parent.getIdentifier()+": {");
1435 output.println(" REntry* rentry=NULL;");
1436 output.println(" INTPTR* pointer=NULL;");
1437 output.println(" seseToIssue->common.rentryIdx=0;");
1439 Set<Integer> queueIDSet=seseWaitingQueue.getQueueIDSet();
1440 for (Iterator iterator = queueIDSet.iterator(); iterator.hasNext(); ) {
1441 Integer key = (Integer) iterator.next();
1442 int queueID=key.intValue();
1443 Set<WaitingElement> waitingQueueSet =
1444 seseWaitingQueue.getWaitingElementSet(queueID);
1445 int enqueueType=seseWaitingQueue.getType(queueID);
1446 if(enqueueType==SESEWaitingQueue.EXCEPTION) {
1447 output.println(" INITIALIZEBUF(runningSESE->memoryQueueArray[" + queueID+ "]);");
1449 for (Iterator iterator2 = waitingQueueSet.iterator(); iterator2.hasNext(); ) {
1450 WaitingElement waitingElement
1451 = (WaitingElement) iterator2.next();
1452 if (waitingElement.getStatus() >= ConflictNode.COARSE) {
1453 output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1454 + waitingElement.getStatus()
1455 + ", &(seseToIssue->common));");
1457 TempDescriptor td = waitingElement.getTempDesc();
1458 // decide whether waiting element is dynamic or static
1459 if (fsen.getDynamicInVarSet().contains(td)) {
1460 // dynamic in-var case
1461 output.println(" pointer=seseToIssue->"
1462 + waitingElement.getDynID()
1463 + "_srcSESE+seseToIssue->"
1464 + waitingElement.getDynID()
1466 output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1467 + waitingElement.getStatus()
1468 + ", &(seseToIssue->common), pointer );");
1469 } else if (fsen.getStaticInVarSet().contains(td)) {
1470 // static in-var case
1471 VariableSourceToken vst = fsen.getStaticInVarSrc(td);
1474 String srcId = "SESE_" + vst.getSESE().getPrettyIdentifier()
1475 + vst.getSESE().getIdentifier()
1476 + "_" + vst.getAge();
1477 output.println(" pointer=(void*)&seseToIssue->"
1483 output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1484 + waitingElement.getStatus()
1485 + ", &(seseToIssue->common), pointer );");
1488 output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1489 + waitingElement.getStatus()
1490 + ", &(seseToIssue->common), (void*)&seseToIssue->"
1491 + waitingElement.getDynID()
1495 output.println(" rentry->queue=runningSESE->memoryQueueArray["
1496 + waitingElement.getQueueID()
1499 if(enqueueType==SESEWaitingQueue.NORMAL) {
1500 output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;");
1501 output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["
1502 + waitingElement.getQueueID()
1503 + "],rentry)==NOTREADY) {");
1504 output.println(" localCount++;");
1505 output.println(" }");
1507 output.println(" ADDRENTRYTOBUF(runningSESE->memoryQueueArray[" + waitingElement.getQueueID() + "],rentry);");
1510 if(enqueueType!=SESEWaitingQueue.NORMAL) {
1511 output.println(" localCount+=RESOLVEBUF(runningSESE->memoryQueueArray["
1512 + queueID+ "],&seseToIssue->common);");
1515 output.println(" } break; // end case "+parent.getIdentifier());
1519 if( atLeastOneCase ) {
1520 output.println(" } // end stall site switch");
1524 if( state.COREPROF ) {
1525 output.println("#ifdef CP_EVENTID_PREPAREMEMQ");
1526 output.println(" CP_LOGEVENT( CP_EVENTID_PREPAREMEMQ, CP_EVENTTYPE_END );");
1527 output.println("#endif");
1531 // Enqueue Task Record
1533 if( fsen != oooa.getMainSESE() && fsen.getInVarsForDynamicCoarseConflictResolution().size()>0) {
1534 output.println(" enqueueTR(TRqueue, (void *)seseToIssue);");
1538 // if there were no outstanding dependencies, issue here
1539 output.println(" if( atomic_sub_and_test(10000-localCount,&(seseToIssue->common.unresolvedDependencies) ) ) {");
1540 output.println(" workScheduleSubmit( (void*)seseToIssue );");
1541 output.println(" }");
1545 if( state.COREPROF ) {
1546 output.println("#ifdef CP_EVENTID_TASKDISPATCH");
1547 output.println(" CP_LOGEVENT( CP_EVENTID_TASKDISPATCH, CP_EVENTTYPE_END );");
1548 output.println("#endif");
1551 output.println(" } // end task issue");
1555 void dispatchMEMRC(FlatMethod fm,
1556 FlatSESEEnterNode newChild,
1557 PrintWriter output) {
1558 // what we need to do here is create RCR records for the
1559 // new task and insert it into the appropriate parent queues
1560 // IF NEEDED!!!!!!!!
1561 assert newChild.getParents().size() > 0;
1563 output.println(" switch( runningSESE->classID ) {");
1565 Iterator<FlatSESEEnterNode> pItr = newChild.getParents().iterator();
1566 while( pItr.hasNext() ) {
1568 FlatSESEEnterNode parent = pItr.next();
1569 ConflictGraph graph = oooa.getConflictGraph(parent);
1571 if( graph != null && graph.hasConflictEdge() ) {
1572 Set<SESELock> seseLockSet = oooa.getLockMappings(graph);
1573 SESEWaitingQueue seseWaitingQueue=graph.getWaitingElementSetBySESEID(newChild.getIdentifier(), seseLockSet);
1574 if(seseWaitingQueue.getWaitingElementSize()>0) {
1576 output.println(" /* "+parent.getPrettyIdentifier()+" */");
1577 output.println(" case "+parent.getIdentifier()+": {");
1579 output.println(" REntry* rentry=NULL;");
1580 output.println(" INTPTR* pointer=NULL;");
1581 output.println(" seseToIssue->common.rentryIdx=0;");
1582 Vector<TempDescriptor> invars=newChild.getInVarsForDynamicCoarseConflictResolution();
1583 //System.out.println(fm.getMethod()+"["+invars+"]");
1585 Vector<Long> queuetovar=new Vector<Long>();
1587 for(int i=0; i<invars.size(); i++) {
1588 TempDescriptor td=invars.get(i);
1589 Set<WaitingElement> weset=seseWaitingQueue.getWaitingElementSet(td);
1591 //TODO FIX MEEEEE!!!!
1592 //Weset is sometimes null which breaks the following code and
1593 //we don't know what weset = null means. For now, we bail when it's null
1594 //until we find out what to do....
1595 // if(weset == null) {
1598 //UPDATE: This hack DOES NOT FIX IT!.
1603 Set<Integer> queueSet=new HashSet<Integer>();
1604 for (Iterator iterator = weset.iterator(); iterator.hasNext(); ) {
1605 WaitingElement we = (WaitingElement) iterator.next();
1606 Integer queueID=new Integer(we.getQueueID());
1607 if(!queueSet.contains(queueID)) {
1609 queueSet.add(queueID);
1613 output.println(" seseToIssue->rcrRecords["+i+"].flag="+numqueues+";");
1614 output.println(" seseToIssue->rcrRecords["+i+"].index=0;");
1615 output.println(" seseToIssue->rcrRecords["+i+"].next=NULL;");
1616 output.println(" int dispCount"+i+"=0;");
1618 for (Iterator<WaitingElement> wtit = weset.iterator(); wtit.hasNext(); ) {
1619 WaitingElement waitingElement = wtit.next();
1620 int queueID = waitingElement.getQueueID();
1621 if (queueID >= queuetovar.size())
1622 queuetovar.setSize(queueID + 1);
1623 Long l = queuetovar.get(queueID);
1624 long val = (l != null)?l.longValue():0;
1625 val = val | (1 << i);
1626 queuetovar.set(queueID, new Long(val));
1630 HashSet generatedqueueentry=new HashSet();
1631 for(int i=0; i<invars.size(); i++) {
1632 TempDescriptor td=invars.get(i);
1633 Set<WaitingElement> weset=seseWaitingQueue.getWaitingElementSet(td);
1637 //TODO FIX MEEEEE!!!!
1638 //Weset is sometimes null which breaks the following code and
1639 //we don't know what weset = null means. For now, we bail when it's null
1640 //until we find out what to do....
1641 // if(weset == null) {
1644 //UPDATE: This hack DOES NOT FIX IT!.
1648 for(Iterator<WaitingElement> wtit=weset.iterator(); wtit.hasNext(); ) {
1649 WaitingElement waitingElement=wtit.next();
1650 int queueID=waitingElement.getQueueID();
1652 if(waitingElement.isBogus()) {
1656 if (generatedqueueentry.contains(queueID))
1659 generatedqueueentry.add(queueID);
1661 assert(waitingElement.getStatus()>=ConflictNode.COARSE);
1662 long mask=queuetovar.get(queueID);
1663 output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "]," + waitingElement.getStatus() + ", &(seseToIssue->common), "+mask+"LL);");
1664 output.println(" rentry->count=2;");
1665 output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;");
1666 output.println(" rentry->queue=runningSESE->memoryQueueArray[" + waitingElement.getQueueID()+"];");
1668 output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "],rentry)==READY) {");
1669 for(int j=0; mask!=0; j++) {
1671 output.println(" dispCount"+j+"++;");
1674 output.println(" } else ");
1675 output.println(" refCount--;");
1678 if (newChild.getDynamicInVarSet().contains(td)) {
1679 // dynamic in-var case
1680 //output.println(" pointer=seseToIssue->"+waitingElement.getDynID()+
1681 // "_srcSESE+seseToIssue->"+waitingElement.getDynID()+
1683 //output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+
1684 // ", &(seseToIssue->common), pointer );");
1687 for(int i=0; i<invars.size(); i++) {
1688 output.println(" if(!dispCount"+i+" || !atomic_sub_and_test(dispCount"+i+",&(seseToIssue->rcrRecords["+i+"].flag)))");
1689 output.println(" localCount++;");
1691 output.println(" } break;");
1696 output.println(" } // end switch");
1698 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1699 output.println(" RELEASE_REFERENCES_TO((SESEcommon *)seseToIssue, refCount);");
1700 output.println("#endif");
1704 public void generateFlatSESEExitNode(FlatMethod fm,
1705 FlatSESEExitNode fsexn,
1706 PrintWriter output) {
1708 // get the enter node for this exit that has meta data embedded
1709 FlatSESEEnterNode fsen = fsexn.getFlatEnter();
1711 // there may be an SESE in an unreachable method, skip over
1712 if( !oooa.getAllSESEs().contains(fsen) ) {
1716 // assert we are never generating code for the caller proxy
1717 // it should only appear in analysis results
1718 assert !fsen.getIsCallerProxySESE();
1721 if( state.COREPROF ) {
1722 output.println("#ifdef CP_EVENTID_TASKEXECUTE");
1723 output.println(" CP_LOGEVENT( CP_EVENTID_TASKEXECUTE, CP_EVENTTYPE_END );");
1724 output.println("#endif");
1727 output.println(" /* SESE exiting */");
1729 if( state.COREPROF ) {
1730 output.println("#ifdef CP_EVENTID_TASKRETIRE");
1731 output.println(" CP_LOGEVENT( CP_EVENTID_TASKRETIRE, CP_EVENTTYPE_BEGIN );");
1732 output.println("#endif");
1736 // this SESE cannot be done until all of its children are done
1737 // so grab your own lock with the condition variable for watching
1738 // that the number of your running children is greater than zero
1739 output.println(" atomic_add(childSESE, &runningSESE->numRunningChildren);");
1740 output.println(" pthread_mutex_lock( &(runningSESE->lock) );");
1741 output.println(" if( runningSESE->numRunningChildren > 0 ) {");
1742 output.println(" stopforgc( (struct garbagelist *)&___locals___ );");
1743 output.println(" do {");
1744 output.println(" pthread_cond_wait( &(runningSESE->runningChildrenCond), &(runningSESE->lock) );");
1745 output.println(" } while( runningSESE->numRunningChildren > 0 );");
1746 output.println(" restartaftergc();");
1747 output.println(" }");
1751 ////////////////////////////////////////
1752 // go through all out-vars and determine where to get them
1753 ////////////////////////////////////////
1754 output.println(" // copy ready out-set primitive variables from locals into record");
1755 Iterator<TempDescriptor> itr = fsen.getReadyOutVarSet().iterator();
1756 while( itr.hasNext() ) {
1757 TempDescriptor temp = itr.next();
1759 // only have to do this for primitives, non-arrays
1761 temp.getType().isPrimitive() && !temp.getType().isArray()
1767 String from = generateTemp(fsen.getfmBogus(), temp);
1769 output.println(" "+paramsprefix+
1770 "->"+temp.getSafeSymbol()+
1774 // static vars are from a known SESE
1775 Iterator<TempDescriptor> tempItr;
1776 output.println(" // copy out-set from static sources");
1777 tempItr = fsen.getStaticOutVarSet().iterator();
1778 while( tempItr.hasNext() ) {
1779 TempDescriptor temp = tempItr.next();
1780 VariableSourceToken vst = fsen.getStaticOutVarSrc(temp);
1781 SESEandAgePair srcPair = new SESEandAgePair(vst.getSESE(), vst.getAge() );
1782 output.println(" "+paramsprefix+
1783 "->"+temp.getSafeSymbol()+
1784 " = "+paramsprefix+"->"+srcPair+"->"+vst.getAddrVar()+";");
1787 //output.println(" // decrement references to static sources");
1788 //for( Iterator<SESEandAgePair> pairItr = fsen.getStaticOutVarSrcs().iterator(); pairItr.hasNext(); ) {
1789 // SESEandAgePair srcPair = pairItr.next();
1790 // output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1791 // output.println(" {");
1792 // output.println(" SESEcommon* src = &("+paramsprefix+"->"+srcPair+"->common);");
1793 // output.println(" RELEASE_REFERENCE_TO( src );");
1794 // output.println(" }");
1795 // output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1798 output.println(" // copy out-set from dynamic sources");
1799 tempItr = fsen.getDynamicOutVarSet().iterator();
1800 while( tempItr.hasNext() ) {
1801 TempDescriptor temp = tempItr.next();
1802 TypeDescriptor type = temp.getType();
1804 // go grab it from the SESE source, when the source is NULL it is
1805 // this exiting task, so nothing to do!
1806 output.println(" if( "+temp+"_srcSESE != NULL ) {");
1808 output.println(" "+paramsprefix+
1809 "->"+temp.getSafeSymbol()+
1810 " = *(void**)( (void*)"+
1812 temp+"_srcOffset);");
1814 //output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1815 //output.println(" SESEcommon* src = "+paramsprefix+"->"+temp+"_srcSESE;");
1816 //output.println(" RELEASE_REFERENCE_TO( src );");
1817 //output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1819 output.println(" }");
1825 // mark yourself done, your task data is now read-only
1826 output.println(" runningSESE->doneExecuting = TRUE;");
1828 // if parent is stalling on you, let them know you're done
1829 if( !fsen.getIsMainSESE() ) {
1830 output.println(" if( runningSESE->parentsStallSem != NULL ) {");
1831 output.println(" psem_give( runningSESE->parentsStallSem );");
1832 output.println(" }");
1835 output.println(" pthread_mutex_unlock( &(runningSESE->lock) );");
1837 // decrement dependency count for all SESE's on your forwarding list
1840 output.println(" while( !isEmpty( &runningSESE->forwardList ) ) {");
1841 output.println(" SESEcommon* consumer = (SESEcommon*) getItem( &runningSESE->forwardList );");
1845 output.println(" if(consumer->rentryIdx>0){");
1846 output.println(" // resolved null pointer");
1847 output.println(" int idx;");
1848 output.println(" for(idx=0;idx<consumer->rentryIdx;idx++){");
1849 output.println(" resolvePointer(consumer->rentryArray[idx]);");
1850 output.println(" }");
1851 output.println(" }");
1854 output.println(" if( atomic_sub_and_test( 1, &(consumer->unresolvedDependencies) ) ){");
1855 output.println(" workScheduleSubmit( (void*)consumer );");
1856 output.println(" }");
1857 output.println(" }");
1860 // clean up its lock element from waiting queue, and decrement dependency count for next SESE block
1861 if( !fsen.getIsMainSESE() ) {
1863 output.println(" /* check memory dependency*/");
1864 output.println(" {");
1865 output.println(" int idx;");
1866 output.println(" for(idx=0;idx<___params___->common.rentryIdx;idx++){");
1867 output.println(" REntry* re=___params___->common.rentryArray[idx];");
1868 output.println(" RETIRERENTRY(re->queue,re);");
1869 output.println(" }");
1870 output.println(" }");
1873 Vector<TempDescriptor> inset=fsen.getInVarsForDynamicCoarseConflictResolution();
1874 if (state.RCR && inset.size() > 0) {
1875 /* Make sure the running SESE is finished */
1876 output.println(" if (unlikely(runningSESE->rcrstatus!=0)) {");
1877 output.println(" if(CAS(&runningSESE->rcrstatus,1,0)==2) {");
1878 output.println(" while(runningSESE->rcrstatus) {");
1879 output.println(" BARRIER();");
1880 output.println(" sched_yield();");
1881 output.println(" }");
1882 output.println(" }");
1883 output.println(" }");
1884 output.println("{");
1885 output.println(" int idx,idx2;");
1887 output.println(" struct rcrRecord *rec;");
1888 output.println(" struct Hashtable_rcr ** hashstruct=runningSESE->parent->allHashStructures;");
1890 for (int i = 0; i < inset.size(); i++) {
1891 output.println(" rec=&" + paramsprefix + "->rcrRecords[" + i + "];");
1892 output.println(" while(rec!=NULL) {");
1893 output.println(" for(idx2=0;idx2<rec->index;idx2++) {");
1895 int weaklyConnectedComponentIndex = rcr.getWeakID(inset.get(i), fsen);
1897 output.println(" rcr_RETIREHASHTABLE(hashstruct[" + weaklyConnectedComponentIndex
1898 + "],&(___params___->common), rec->array[idx2], (BinItem_rcr *) rec->ptrarray[idx2]);");
1900 output.println(" }"); // exit idx2 for loop
1901 output.println(" rec=rec->next;");
1902 output.println(" }"); // exit rec while loop
1904 output.println("}");
1908 // a task has variables to track static/dynamic instances
1909 // that serve as sources, release the parent's ref of each
1910 // non-null var of these types
1911 output.println(" // releasing static SESEs");
1912 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1914 ContextTaskNames contextTaskNames = oooa.getContextTaskNames(fsen);
1916 Iterator<SESEandAgePair> pItr = contextTaskNames.getNeededStaticNames().iterator();
1917 while( pItr.hasNext() ) {
1918 SESEandAgePair pair = pItr.next();
1919 output.println(" if( "+pair+" != NULL ) {");
1920 output.println(" RELEASE_REFERENCE_TO( "+pair+" );");
1921 output.println(" }");
1923 output.println(" // releasing dynamic variable sources");
1924 Iterator<TempDescriptor> dynSrcItr = contextTaskNames.getDynamicVarSet().iterator();
1925 while( dynSrcItr.hasNext() ) {
1926 TempDescriptor dynSrcVar = dynSrcItr.next();
1927 output.println(" if( "+dynSrcVar+"_srcSESE != NULL ) {");
1928 output.println(" RELEASE_REFERENCE_TO( "+dynSrcVar+"_srcSESE );");
1929 output.println(" }");
1932 // destroy this task's mempool if it is not a leaf task
1933 if( !fsen.getIsLeafSESE() ) {
1934 output.println(" pooldestroy( runningSESE->taskRecordMemPool );");
1935 if (state.RCR && fsen.getInVarsForDynamicCoarseConflictResolution().size() > 0 ) {
1936 output.println(" returnTR();");
1939 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
1942 output.println("{");
1943 output.println("SESEcommon *myparent=runningSESE->parent;");
1945 // if this is not the Main sese (which has no parent) then return
1946 // THIS task's record to the PARENT'S task record pool, and only if
1947 // the reference count is now zero
1948 if( !fsen.getIsMainSESE() ) {
1949 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1950 output.println(" RELEASE_REFERENCE_TO( runningSESE );");
1951 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
1953 // the main task has no parent, just free its record
1954 output.println(" mlpFreeSESErecord( runningSESE );");
1958 // last of all, decrement your parent's number of running children
1959 output.println(" if( myparent != NULL ) {");
1960 output.println(" if( atomic_sub_and_test( 1, &(myparent->numRunningChildren) ) ) {");
1961 output.println(" pthread_mutex_lock ( &(myparent->lock) );");
1962 output.println(" pthread_cond_signal ( &(myparent->runningChildrenCond) );");
1963 output.println(" pthread_mutex_unlock( &(myparent->lock) );");
1964 output.println(" }");
1965 output.println(" }");
1967 output.println("}");
1969 // as this thread is wrapping up the task, make sure the thread-local var
1970 // for the currently running task record references an invalid task
1971 output.println(" runningSESE = (SESEcommon*) 0x1;");
1973 if( state.COREPROF ) {
1974 output.println("#ifdef CP_EVENTID_TASKRETIRE");
1975 output.println(" CP_LOGEVENT( CP_EVENTID_TASKRETIRE, CP_EVENTTYPE_END );");
1976 output.println("#endif");
1981 public void generateFlatWriteDynamicVarNode(FlatMethod fm,
1982 FlatWriteDynamicVarNode fwdvn,
1986 Hashtable<TempDescriptor, VSTWrapper> writeDynamic = fwdvn.getVar2src();
1988 assert writeDynamic != null;
1990 Iterator wdItr = writeDynamic.entrySet().iterator();
1991 while( wdItr.hasNext() ) {
1992 Map.Entry me = (Map.Entry)wdItr.next();
1993 TempDescriptor refVar = (TempDescriptor) me.getKey();
1994 VSTWrapper vstW = (VSTWrapper) me.getValue();
1995 VariableSourceToken vst = vstW.vst;
1997 output.println(" {");
1998 output.println(" SESEcommon* oldSrc = "+refVar+"_srcSESE;");
2001 // if there is no given source, this variable is ready so
2002 // mark src pointer NULL to signify that the var is up-to-date
2003 output.println(" "+refVar+"_srcSESE = NULL;");
2005 // otherwise we track where it will come from
2006 SESEandAgePair instance = new SESEandAgePair(vst.getSESE(), vst.getAge() );
2007 output.println(" "+refVar+"_srcSESE = "+instance+";");
2008 output.println(" "+refVar+"_srcOffset = (INTPTR) &((("+
2009 vst.getSESE().getSESErecordName()+"*)0)->"+vst.getAddrVar()+");");
2012 // no matter what we did above, track reference count of whatever
2013 // this variable pointed to, do release last in case we're just
2014 // copying the same value in because 1->2->1 is safe but ref count
2015 // 1->0->1 has a window where it looks like it should be free'd
2016 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
2017 output.println(" if( "+refVar+"_srcSESE != NULL ) {");
2018 output.println(" ADD_REFERENCE_TO( "+refVar+"_srcSESE );");
2019 output.println(" }");
2020 output.println(" if( oldSrc != NULL ) {");
2021 output.println(" RELEASE_REFERENCE_TO( oldSrc );");
2022 output.println(" }");
2023 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
2025 output.println(" }");
2030 protected void generateFlatNew(FlatMethod fm,
2032 PrintWriter output) {
2034 if( fn.getType().isArray() ) {
2035 int arrayid = state.getArrayNumber(fn.getType() )+state.numClasses();
2037 if( GENERATEPRECISEGC ) {
2038 output.println(generateTemp(fm, fn.getDst())+
2039 "=allocate_newarray_mlp("+localsprefixaddr+
2040 ", "+arrayid+", "+generateTemp(fm, fn.getSize())+
2042 oooa.getDisjointAnalysis().getAllocationSiteFromFlatNew(fn).getUniqueAllocSiteID()+
2044 output.println(" oid += oidIncrement;");
2046 output.println(generateTemp(fm, fn.getDst())+
2047 "=allocate_newarray("+arrayid+
2048 ", "+generateTemp(fm, fn.getSize())+
2054 if( GENERATEPRECISEGC ) {
2055 output.println(generateTemp(fm, fn.getDst())+
2056 "=allocate_new_mlp("+localsprefixaddr+
2057 ", "+fn.getType().getClassDesc().getId()+
2059 oooa.getDisjointAnalysis().getAllocationSiteFromFlatNew(fn).getUniqueAllocSiteID()+
2061 output.println(" oid += oidIncrement;");
2063 output.println(generateTemp(fm, fn.getDst())+
2064 "=allocate_new("+fn.getType().getClassDesc().getId()+
2071 private int calculateSizeOfSESEParamList(FlatSESEEnterNode fsen) {
2073 Set<TempDescriptor> tdSet=new HashSet<TempDescriptor>();
2075 for (Iterator iterator = fsen.getInVarSet().iterator(); iterator.hasNext(); ) {
2076 TempDescriptor tempDescriptor = (TempDescriptor) iterator.next();
2077 if(!tempDescriptor.getType().isPrimitive() || tempDescriptor.getType().isArray()) {
2078 tdSet.add(tempDescriptor);
2082 for (Iterator iterator = fsen.getOutVarSet().iterator(); iterator.hasNext(); ) {
2083 TempDescriptor tempDescriptor = (TempDescriptor) iterator.next();
2084 if(!tempDescriptor.getType().isPrimitive() || tempDescriptor.getType().isArray()) {
2085 tdSet.add(tempDescriptor);
2089 return tdSet.size();
2093 private String calculateSizeOfSESEParamSize(FlatSESEEnterNode fsen) {
2094 HashMap <String,Integer> map=new HashMap();
2095 HashSet <TempDescriptor> processed=new HashSet<TempDescriptor>();
2098 // space for all in and out set primitives
2099 Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
2100 inSetAndOutSet.addAll(fsen.getInVarSet() );
2101 inSetAndOutSet.addAll(fsen.getOutVarSet() );
2103 Set<TempDescriptor> inSetAndOutSetPrims = new HashSet<TempDescriptor>();
2105 Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
2106 while( itr.hasNext() ) {
2107 TempDescriptor temp = itr.next();
2108 TypeDescriptor type = temp.getType();
2109 if( !type.isPtr() ) {
2110 inSetAndOutSetPrims.add(temp);
2114 Iterator<TempDescriptor> itrPrims = inSetAndOutSetPrims.iterator();
2115 while( itrPrims.hasNext() ) {
2116 TempDescriptor temp = itrPrims.next();
2117 TypeDescriptor type = temp.getType();
2118 if(type.isPrimitive()) {
2119 Integer count=map.get(type.getSymbol());
2121 count=new Integer(1);
2122 map.put(type.getSymbol(), count);
2124 map.put(type.getSymbol(), new Integer(count.intValue()+1));
2129 Set<String> keySet=map.keySet();
2130 for (Iterator iterator = keySet.iterator(); iterator.hasNext(); ) {
2131 String key = (String) iterator.next();
2132 rtr+="+sizeof("+key+")*"+map.get(key);