Fixed variable dynamic source bookkeeping bug, regression test runs for single and...
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
index 6c4bc13d9570ff7e22320db932e71b4e5a0f7acf..9c24aa680a3ee83ca2c5645a87da79b704fdfac0 100644 (file)
@@ -286,6 +286,7 @@ public class BuildCode {
     outmethod.println("  int i;");
 
     if (state.MLP) {
+      //outmethod.println("  pthread_once( &mlpOnceObj, mlpInitOncePerThread );");
       outmethod.println("  workScheduleInit( "+state.MLP_NUMCORES+", invokeSESEmethod );");
     }
 
@@ -594,7 +595,7 @@ public class BuildCode {
       } else {
         outclassdefs.println("  int version;");
         outclassdefs.println("  int * lock;");  // lock entry for this obj
-        outclassdefs.println("  void * mutex;");  
+        outclassdefs.println("  int mutex;");  
         outclassdefs.println("  int lockcount;");
         if(state.MULTICOREGC) {
           outclassdefs.println("  int marked;");
@@ -1303,13 +1304,13 @@ public class BuildCode {
       if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) {
        classdefout.println("  void * flagptr;");
       } else if (state.MULTICORE) {
-        if(state.MULTICOREGC) {
-          classdefout.println("  int marked;");
-        }
        classdefout.println("  int version;");
     classdefout.println("  int * lock;");  // lock entry for this obj
-    classdefout.println("  void * mutex;");  
+    classdefout.println("  int mutex;");  
     classdefout.println("  int lockcount;");
+    if(state.MULTICOREGC) {
+      classdefout.println("  int marked;");
+    }
       }
       if (state.OPTIONAL) {
        classdefout.println("  int numfses;");
@@ -1656,6 +1657,32 @@ public class BuildCode {
        output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
     }
 
+
+    if( state.MLP ) {      
+      if( fm.getNext(0) instanceof FlatSESEEnterNode ) {
+       FlatSESEEnterNode callerSESEplaceholder = (FlatSESEEnterNode) fm.getNext( 0 );
+       if( callerSESEplaceholder != mlpa.getMainSESE() ) {
+         // declare variables for naming static SESE's
+         output.println("   /* static SESE names */");
+         Iterator<SESEandAgePair> pItr = callerSESEplaceholder.getNeededStaticNames().iterator();
+         while( pItr.hasNext() ) {
+           SESEandAgePair p = pItr.next();
+           output.println("   void* "+p+";");
+         }
+
+         // declare variables for tracking dynamic sources
+         output.println("   /* dynamic variable sources */");
+         Iterator<TempDescriptor> dynSrcItr = callerSESEplaceholder.getDynamicVarSet().iterator();
+         while( dynSrcItr.hasNext() ) {
+           TempDescriptor dynSrcVar = dynSrcItr.next();
+           output.println("   void* "+dynSrcVar+"_srcSESE;");
+           output.println("   int   "+dynSrcVar+"_srcOffset;");
+         }    
+       }
+      }
+    }
+
+
     /* Check to see if we need to do a GC if this is a
      * multi-threaded program...*/
 
@@ -1679,7 +1706,7 @@ public class BuildCode {
 
 
   protected void initializeSESE( FlatSESEEnterNode fsen ) {
-    
+
     FlatMethod       fm = fsen.getfmEnclosing();
     MethodDescriptor md = fm.getMethod();
     ClassDescriptor  cn = md.getClassDesc();
@@ -1727,10 +1754,11 @@ public class BuildCode {
       for(int i=0; i<writes.length; i++) {
        TempDescriptor temp=writes[i];
        TypeDescriptor type=temp.getType();
-       if (type.isPtr()&&GENERATEPRECISEGC)
+       if (type.isPtr()&&GENERATEPRECISEGC) {
          objecttemps.addPtr(temp);
-       else
+       } else {
          objecttemps.addPrim(temp);
+       }
       }
     }
   }
@@ -1743,24 +1771,22 @@ public class BuildCode {
                                     ) {
 
     ParamsObject objectparams = (ParamsObject) paramstable.get( fsen.getmdBogus() );
-    
-    Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
-    inSetAndOutSet.addAll( fsen.getInVarSet() );
-    inSetAndOutSet.addAll( fsen.getOutVarSet() );
-
-    Set<TempDescriptor> inSetAndOutSetPrims = new HashSet<TempDescriptor>();
-
-    Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
-    while( itr.hasNext() ) {
-      TempDescriptor temp = itr.next();
-      TypeDescriptor type = temp.getType();
-      if( !type.isPtr() ) {
-       inSetAndOutSetPrims.add( temp );
-      }
-    }
-            
+                
     TempObject objecttemps = (TempObject) tempstable.get( fsen.getmdBogus() );
     
+    // generate locals structure
+    outputStructs.println("struct "+fsen.getcdEnclosing().getSafeSymbol()+fsen.getmdBogus().getSafeSymbol()+"_"+fsen.getmdBogus().getSafeMethodDescriptor()+"_locals {");
+    outputStructs.println("  INTPTR size;");
+    outputStructs.println("  void * next;");
+    for(int i=0; i<objecttemps.numPointers(); i++) {
+      TempDescriptor temp=objecttemps.getPointer(i);
+      if (temp.getType().isNull())
+        outputStructs.println("  void * "+temp.getSafeSymbol()+";");
+      else
+        outputStructs.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
+    }
+    outputStructs.println("};\n");
+
     
     // generate the SESE record structure
     outputStructs.println(fsen.getSESErecordName()+" {");
@@ -1783,7 +1809,30 @@ public class BuildCode {
       outputStructs.println("  "+srcPair.getSESE().getSESErecordName()+"* "+srcPair+";");
     }    
 
+    // DYNAMIC stuff needs a source SESE ptr and offset
+    Iterator<TempDescriptor> itrDynInVars = fsen.getDynamicInVarSet().iterator();
+    while( itrDynInVars.hasNext() ) {
+      TempDescriptor dynInVar = itrDynInVars.next();
+      outputStructs.println("  void* "+dynInVar+"_srcSESE;");
+      outputStructs.println("  int   "+dynInVar+"_srcOffset;");
+    }    
+
     // space for all in and out set primitives
+    Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
+    inSetAndOutSet.addAll( fsen.getInVarSet() );
+    inSetAndOutSet.addAll( fsen.getOutVarSet() );
+
+    Set<TempDescriptor> inSetAndOutSetPrims = new HashSet<TempDescriptor>();
+
+    Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
+    while( itr.hasNext() ) {
+      TempDescriptor temp = itr.next();
+      TypeDescriptor type = temp.getType();
+      if( !type.isPtr() ) {
+       inSetAndOutSetPrims.add( temp );
+      }
+    }
+
     Iterator<TempDescriptor> itrPrims = inSetAndOutSetPrims.iterator();
     while( itrPrims.hasNext() ) {
       TempDescriptor temp = itrPrims.next();
@@ -1801,26 +1850,14 @@ public class BuildCode {
     
     outputStructs.println("};\n");
 
-    // generate locals structure
-    outputStructs.println("struct "+fsen.getcdEnclosing().getSafeSymbol()+fsen.getmdBogus().getSafeSymbol()+"_"+fsen.getmdBogus().getSafeMethodDescriptor()+"_locals {");
-    outputStructs.println("  INTPTR size;");
-    outputStructs.println("  void * next;");
-    for(int i=0; i<objecttemps.numPointers(); i++) {
-      TempDescriptor temp=objecttemps.getPointer(i);
-      if (temp.getType().isNull())
-        outputStructs.println("  void * "+temp.getSafeSymbol()+";");
-      else
-        outputStructs.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
-    }
-    outputStructs.println("};\n");
     
-
     // write method declaration to header file
     outputMethHead.print("void ");
     outputMethHead.print(fsen.getSESEmethodName()+"(");
     outputMethHead.print(fsen.getSESErecordName()+"* "+paramsprefix);
     outputMethHead.println(");\n");
 
+
     generateFlatMethodSESE( fsen.getfmBogus(), 
                            fsen.getcdEnclosing(), 
                            fsen, 
@@ -1853,6 +1890,7 @@ public class BuildCode {
       output.println("};");
     }
 
+    output.println("   /* regular local primitives */");
     for(int i=0; i<objecttemp.numPrimitives(); i++) {
       TempDescriptor td=objecttemp.getPrimitive(i);
       TypeDescriptor type=td.getType();
@@ -1865,15 +1903,26 @@ public class BuildCode {
     }
 
 
-    // declare variables for naming SESE's
+    // declare variables for naming static SESE's
+    output.println("   /* static SESE names */");
     Iterator<SESEandAgePair> pItr = fsen.getNeededStaticNames().iterator();
     while( pItr.hasNext() ) {
       SESEandAgePair p = pItr.next();
       output.println("   void* "+p+";");
     }
 
+    // declare variables for tracking dynamic sources
+    output.println("   /* dynamic variable sources */");
+    Iterator<TempDescriptor> dynSrcItr = fsen.getDynamicVarSet().iterator();
+    while( dynSrcItr.hasNext() ) {
+      TempDescriptor dynSrcVar = dynSrcItr.next();
+      output.println("   void* "+dynSrcVar+"_srcSESE;");
+      output.println("   int   "+dynSrcVar+"_srcOffset;");
+    }    
+
     // declare local temps for in-set primitives, and if it is
     // a ready-source variable, get the value from the record
+    output.println("   /* local temps for in-set primitives */");
     Iterator<TempDescriptor> itrInSet = fsen.getInVarSet().iterator();
     while( itrInSet.hasNext() ) {
       TempDescriptor temp = itrInSet.next();
@@ -1887,6 +1936,18 @@ public class BuildCode {
       }
     }    
 
+    // declare local temps for out-set primitives if its not already
+    // in the in-set, and it's value will get written so no problem
+    output.println("   /* local temp for out-set prim, not already in the in-set */");
+    Iterator<TempDescriptor> itrOutSet = fsen.getOutVarSet().iterator();
+    while( itrOutSet.hasNext() ) {
+      TempDescriptor temp = itrOutSet.next();
+      TypeDescriptor type = temp.getType();
+      if( !type.isPtr() && !fsen.getInVarSet().contains( temp ) ) {
+       output.println("   "+type+" "+temp+";");       
+      }
+    }    
+
     // copy in-set into place, ready vars were already 
     // copied when the SESE was issued
     Iterator<TempDescriptor> tempItr;
@@ -1894,30 +1955,63 @@ public class BuildCode {
     // static vars are from a known SESE
     tempItr = fsen.getStaticInVarSet().iterator();
     while( tempItr.hasNext() ) {
-      TempDescriptor      temp = tempItr.next();
-      TypeDescriptor      type = temp.getType();
-      VariableSourceToken vst  = fsen.getStaticInVarSrc( temp );
+      TempDescriptor temp = tempItr.next();
+      VariableSourceToken vst = fsen.getStaticInVarSrc( temp );
+      SESEandAgePair srcPair = new SESEandAgePair( vst.getSESE(), vst.getAge() );
+      
+      // can't grab something from this source until it is done
+      output.println("   {");
+      output.println("     SESEcommon* com = (SESEcommon*)"+paramsprefix+"->"+srcPair+";" );
+      output.println("     pthread_mutex_lock( &(com->lock) );");
+      output.println("     while( com->doneExecuting == FALSE ) {");
+      output.println("       pthread_cond_wait( &(com->doneCond), &(com->lock) );");
+      output.println("     }");
+      output.println("     pthread_mutex_unlock( &(com->lock) );");
+
+      output.println("     "+generateTemp( fsen.getfmBogus(), temp, null )+
+                    " = "+paramsprefix+"->"+srcPair+"->"+vst.getAddrVar()+";");
 
-      String to;
-      String size;
-      if( type.isPtr() ) {
-       to = "(void*) ";
-       size = "sizeof ";
+      output.println("   }");
+    }
+
+    // dynamic vars come from an SESE and src
+    tempItr = fsen.getDynamicInVarSet().iterator();
+    while( tempItr.hasNext() ) {
+      TempDescriptor temp = tempItr.next();
+      TypeDescriptor type = temp.getType();
+      
+      // go grab it from the SESE source
+      output.println("   if( "+paramsprefix+"->"+temp+"_srcSESE != NULL ) {");
+
+      // gotta wait until the source is done
+      output.println("     SESEcommon* com = (SESEcommon*)"+paramsprefix+"->"+temp+"_srcSESE;" );
+      output.println("     pthread_mutex_lock( &(com->lock) );");
+      output.println("     while( com->doneExecuting == FALSE ) {");
+      output.println("       pthread_cond_wait( &(com->doneCond), &(com->lock) );");
+      output.println("     }");
+      output.println("     pthread_mutex_unlock( &(com->lock) );");
+
+      String typeStr;
+      if( type.isNull() ) {
+       typeStr = "void*";
+      } else if( type.isClass() || type.isArray() ) {
+       typeStr = "struct "+type.getSafeSymbol()+"*";
       } else {
-       //to = "(void*) &("+temp.getSafeSymbol()+")";
-       to = temp.getSafeSymbol();
-       size = "sizeof( "+temp.getSafeSymbol()+" )";
+       typeStr = type.getSafeSymbol();
       }
-
-      SESEandAgePair srcPair = new SESEandAgePair( vst.getSESE(), vst.getAge() );
-      //String from = "(void*) &("+paramsprefix+"->"+srcPair+"->"+vst.getAddrVar()+")";
-      String from = paramsprefix+"->"+srcPair+"->"+vst.getAddrVar();
       
-      //output.println("     memcpy( "+to+", "+from+", "+size+" );");
-      output.println("     "+to+" = "+from+";");
+      output.println("     "+generateTemp( fsen.getfmBogus(), temp, null )+
+                    " = *(("+typeStr+"*) ("+
+                    paramsprefix+"->"+temp+"_srcSESE + "+
+                    paramsprefix+"->"+temp+"_srcOffset));");
+
+      // or if the source was our parent, its in the record to grab
+      output.println("   } else {");
+      output.println("     "+generateTemp( fsen.getfmBogus(), temp, null )+
+                          " = "+paramsprefix+"->"+temp+";");
+      output.println("   }");
     }
 
-
     // Check to see if we need to do a GC if this is a
     // multi-threaded program...    
     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
@@ -1931,9 +2025,11 @@ public class BuildCode {
       }
     }    
 
-    HashSet<FlatNode> exitset=new HashSet<FlatNode>();
-    exitset.add(seseExit);
+    // initialize thread-local var to a non-zero, invalid address
+    output.println("   seseCaller = (SESEcommon*) 0x2;");
 
+    HashSet<FlatNode> exitset=new HashSet<FlatNode>();
+    exitset.add(seseExit);    
 
     generateCode(fsen.getNext(0), fm, null, exitset, output, true);
     
@@ -1965,6 +2061,12 @@ public class BuildCode {
       outmethod.println(    "    /* "+fsen.getPrettyIdentifier()+" */");
       outmethod.println(    "    case "+fsen.getIdentifier()+":");
       outmethod.println(    "      "+fsen.getSESEmethodName()+"( seseRecord );");  
+      
+      if( fsen.equals( mlpa.getMainSESE() ) ) {
+       outmethod.println(  "      /* work scheduler works forever, explicitly exit */");
+       outmethod.println(  "      exit( 0 );");
+      }
+
       outmethod.println(    "      break;");
       outmethod.println(    "");
     }
@@ -2045,13 +2147,24 @@ public class BuildCode {
            output.println("primitives->"+tmp.getSafeSymbol()+"="+tmp.getSafeSymbol()+";");
          }
        }
+       if (state.MLP && stopset!=null) {
+         assert first.getPrev( 0 ) instanceof FlatSESEEnterNode;
+         assert current_node       instanceof FlatSESEExitNode;
+         FlatSESEEnterNode fsen = (FlatSESEEnterNode) first.getPrev( 0 );
+         FlatSESEExitNode  fsxn = (FlatSESEExitNode)  current_node;
+         assert fsen.getFlatExit().equals( fsxn );
+         assert fsxn.getFlatEnter().equals( fsen );
+       }
        if (current_node.kind()!=FKind.FlatReturnNode) {
          output.println("   return;");
        }
        current_node=null;
       } else if(current_node.numNext()==1) {
        FlatNode nextnode;
-       if (state.MLP && current_node.kind()==FKind.FlatSESEEnterNode) {
+       if (state.MLP && 
+           current_node.kind()==FKind.FlatSESEEnterNode && 
+           !((FlatSESEEnterNode)current_node).getIsCallerSESEplaceholder()
+          ) {
          FlatSESEEnterNode fsen = (FlatSESEEnterNode)current_node;
          generateFlatNode(fm, lb, current_node, output);
          nextnode=fsen.getFlatExit().getNext(0);
@@ -2240,6 +2353,8 @@ public class BuildCode {
       CodePlan cp = mlpa.getCodePlan( fn );
       if( cp != null ) {               
        
+       FlatSESEEnterNode currentSESE = cp.getCurrentSESE();
+       
        // for each sese and age pair that this parent statement
        // must stall on, take that child's stall semaphore, the
        // copying of values comes after the statement
@@ -2251,7 +2366,14 @@ public class BuildCode {
 
          output.println("   {");
          output.println("     SESEcommon* common = (SESEcommon*) "+p+";");
-         output.println("     psem_take( &(common->stallSem) );");
+
+         output.println("     pthread_mutex_lock( &(common->lock) );");
+         output.println("     while( common->doneExecuting == FALSE ) {");
+         output.println("       pthread_cond_wait( &(common->doneCond), &(common->lock) );");
+         output.println("     }");
+         output.println("     pthread_mutex_unlock( &(common->lock) );");
+                 
+         //output.println("     psem_take( &(common->stallSem) );");
 
          // copy things we might have stalled for        
          output.println("     "+p.getSESE().getSESErecordName()+"* child = ("+
@@ -2260,15 +2382,63 @@ public class BuildCode {
          Iterator<TempDescriptor> tdItr = cp.getCopySet( vst ).iterator();
          while( tdItr.hasNext() ) {
            TempDescriptor td = tdItr.next();
-
-           output.println("       "+td.getSafeSymbol()+" = child->"+
-                                    vst.getAddrVar().getSafeSymbol()+";");
-           //output.println("printf(\"copied %d into "+td.getSafeSymbol()+" from "+vst.getAddrVar().getSafeSymbol()+
-           //"\\n\", "+td.getSafeSymbol()+" );");
+           FlatMethod fmContext;
+           if( currentSESE.getIsCallerSESEplaceholder() ) {
+             fmContext = currentSESE.getfmEnclosing();
+           } else {
+             fmContext = currentSESE.getfmBogus();
+           }
+           output.println("       "+generateTemp( fmContext, td, null )+
+                          " = child->"+vst.getAddrVar().getSafeSymbol()+";");
          }
 
          output.println("   }");
        }
+       
+       // for each variable with a dynamic source, stall just for that variable
+       Iterator<TempDescriptor> dynItr = cp.getDynamicStallSet().iterator();
+       while( dynItr.hasNext() ) {
+         TempDescriptor dynVar = dynItr.next();
+
+         // only stall if the dynamic source is not yourself, denoted by src==NULL
+         // otherwise the dynamic write nodes will have the local var up-to-date
+         output.println("   {");
+         output.println("     if( "+dynVar+"_srcSESE != NULL ) {");
+         output.println("       SESEcommon* common = (SESEcommon*) "+dynVar+"_srcSESE;");
+         output.println("       psem_take( &(common->stallSem) );");
+
+         FlatMethod fmContext;
+         if( currentSESE.getIsCallerSESEplaceholder() ) {
+           fmContext = currentSESE.getfmEnclosing();
+         } else {
+           fmContext = currentSESE.getfmBogus();
+         }
+         output.println("       "+generateTemp( fmContext, dynVar, null )+
+                        " = *(("+dynVar.getType()+"*) ("+
+                        dynVar+"_srcSESE + "+dynVar+"_srcOffset));");
+         
+         output.println("     }");
+         output.println("   }");
+       }
+
+       // for each assignment of a variable to rhs that has a dynamic source,
+       // copy the dynamic sources
+       Iterator dynAssignItr = cp.getDynAssigns().entrySet().iterator();
+       while( dynAssignItr.hasNext() ) {
+         Map.Entry      me  = (Map.Entry)      dynAssignItr.next();
+         TempDescriptor lhs = (TempDescriptor) me.getKey();
+         TempDescriptor rhs = (TempDescriptor) me.getValue();
+         output.println("   "+lhs+"_srcSESE   = "+rhs+"_srcSESE;");
+         output.println("   "+lhs+"_srcOffset = "+rhs+"_srcOffset;");
+       }
+
+       // for each lhs that is dynamic from a non-dynamic source, set the
+       // dynamic source vars to the current SESE
+       dynItr = cp.getDynAssignCurr().iterator();
+       while( dynItr.hasNext() ) {
+         TempDescriptor dynVar = dynItr.next();
+         output.println("   "+dynVar+"_srcSESE = NULL;");
+       }
       }     
     }
 
@@ -2292,6 +2462,10 @@ public class BuildCode {
     case FKind.FlatSESEExitNode:
       generateFlatSESEExitNode(fm, lb, (FlatSESEExitNode)fn, output);
       break;
+      
+    case FKind.FlatWriteDynamicVarNode:
+      generateFlatWriteDynamicVarNode(fm, lb, (FlatWriteDynamicVarNode)fn, output);
+      break;
 
     case FKind.FlatGlobalConvNode:
       generateFlatGlobalConvNode(fm, lb, (FlatGlobalConvNode) fn, output);
@@ -2387,17 +2561,6 @@ public class BuildCode {
       CodePlan cp = mlpa.getCodePlan( fn );
 
       if( cp != null ) {     
-
-       /*
-       Set<VariableSourceToken> writeDynamic = cp.getWriteToDynamicSrc();      
-       if( writeDynamic != null ) {
-         Iterator<VariableSourceToken> vstItr = writeDynamic.iterator();
-         while( vstItr.hasNext() ) {
-           VariableSourceToken vst = vstItr.next();
-           
-         }
-       }
-       */
       }
     }    
   }
@@ -2734,61 +2897,100 @@ public class BuildCode {
                                         FlatSESEEnterNode fsen, 
                                         PrintWriter output 
                                       ) {
+
+    // if MLP flag is off, okay that SESE nodes are in IR graph, 
+    // just skip over them and code generates exactly the same
     if( !state.MLP ) {
-      // SESE nodes can be parsed for normal compilation, just skip over them
       return;
     }    
 
+    // there may be an SESE in an unreachable method, skip over
+    if( !mlpa.getAllSESEs().contains( fsen ) ) {
+      return;
+    }
+
+    // also, if we have encountered a placeholder, just skip it
+    if( fsen.getIsCallerSESEplaceholder() ) {
+      return;
+    }
+
     output.println("   {");
 
+    // set up the parent
+    if( fsen == mlpa.getMainSESE() ) {
+      output.println("     SESEcommon* parentCommon = NULL;");
+    } else {
+      if( fsen.getParent() == null ) {
+       System.out.println( "in "+fm+", "+fsen+" has null parent" );
+      }
+      assert fsen.getParent() != null;
+      if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
+       output.println("     SESEcommon* parentCommon = &("+paramsprefix+"->common);");
+      } else {
+       //output.println("     SESEcommon* parentCommon = (SESEcommon*) peekItem( seseCallStack );");
+       output.println("     SESEcommon* parentCommon = seseCaller;");
+      }
+    }
+
+    // before doing anything, lock your own record and increment the running children
+    if( fsen != mlpa.getMainSESE() ) {      
+      output.println("     pthread_mutex_lock( &(parentCommon->lock) );");
+      output.println("     ++(parentCommon->numRunningChildren);");
+      output.println("     pthread_mutex_unlock( &(parentCommon->lock) );");      
+    }
+
     // just allocate the space for this record
     output.println("     "+fsen.getSESErecordName()+"* seseToIssue = ("+
                           fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+
                           fsen.getSESErecordName()+" ) );");
 
+    // and keep the thread-local sese stack up to date
+    //output.println("     addNewItem( seseCallStack, (void*) seseToIssue);");
+
     // fill in common data
     output.println("     seseToIssue->common.classID = "+fsen.getIdentifier()+";");
     output.println("     psem_init( &(seseToIssue->common.stallSem) );");
 
-    // before potentially adding this SESE to other forwarding lists,
-    //  create it's lock and take it immediately
-    output.println("     pthread_mutex_init( &(seseToIssue->common.lock), NULL );");
-    output.println("     pthread_mutex_lock( &(seseToIssue->common.lock) );");
-
     output.println("     seseToIssue->common.forwardList = createQueue();");
     output.println("     seseToIssue->common.unresolvedDependencies = 0;");
+    output.println("     pthread_cond_init( &(seseToIssue->common.doneCond), NULL );");
     output.println("     seseToIssue->common.doneExecuting = FALSE;");    
+    output.println("     pthread_cond_init( &(seseToIssue->common.runningChildrenCond), NULL );");
+    output.println("     seseToIssue->common.numRunningChildren = 0;");
+    output.println("     seseToIssue->common.parent = parentCommon;");
 
     // all READY in-vars should be copied now and be done with it
     Iterator<TempDescriptor> tempItr = fsen.getReadyInVarSet().iterator();
     while( tempItr.hasNext() ) {
       TempDescriptor temp = tempItr.next();
-      TypeDescriptor type = temp.getType();
 
-      // if we are root (no parent) or the source of the in-var is in 
-      // the in or out set, we know it is in the params structure, 
-      // otherwise its a method-local variable
-      String from;
-      if( fsen.getParent() == null ||
-         fsen.getParent().getInVarSet().contains( temp ) ||
-         fsen.getParent().getOutVarSet().contains( temp ) 
-       ) {
-       //from = "(void*) &("+paramsprefix+"->"+temp.getSafeSymbol()+")";
-       from = paramsprefix+"->"+temp.getSafeSymbol();
+      // when we are issuing the main SESE or an SESE with placeholder
+      // caller SESE as parent, generate temp child child's eclosing method,
+      // otherwise use the parent's enclosing method as the context
+      boolean useParentContext = false;
+
+      if( fsen != mlpa.getMainSESE() ) {
+       assert fsen.getParent() != null;
+       if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
+         useParentContext = true;
+       }
+      }
+
+      if( useParentContext ) {
+       output.println("     seseToIssue->"+temp+" = "+
+                      generateTemp( fsen.getParent().getfmBogus(), temp, null )+";");   
       } else {
-       from = temp.getSafeSymbol();
+       output.println("     seseToIssue->"+temp+" = "+
+                      generateTemp( fsen.getfmEnclosing(), temp, null )+";");
       }
-   
-      //String to   = "(void*) &(seseToIssue->"+temp.getSafeSymbol()+")";
-      String to   = "seseToIssue->"+temp.getSafeSymbol();
-      String size = "sizeof( seseToIssue->"+temp.getSafeSymbol()+" )";
-      
-      //output.println("     memcpy( "+to+", "+from+", "+size+" );");
-      output.println("     "+to+" = "+from+";");
     }
 
-    if( fsen != mlpa.getRootSESE() ) {
+    // before potentially adding this SESE to other forwarding lists,
+    //  create it's lock and take it immediately
+    output.println("     pthread_mutex_init( &(seseToIssue->common.lock), NULL );");
+    output.println("     pthread_mutex_lock( &(seseToIssue->common.lock) );");
 
+    if( fsen != mlpa.getMainSESE() ) {
       // count up outstanding dependencies, static first, then dynamic
       Iterator<SESEandAgePair> staticSrcsItr = fsen.getStaticInVarSrcs().iterator();
       while( staticSrcsItr.hasNext() ) {
@@ -2801,8 +3003,10 @@ public class BuildCode {
        output.println("         printf( \"This shouldnt already be here\\n\");");
        output.println("         exit( -1 );");
        output.println("       }");
-       output.println("       addNewItem( src->forwardList, seseToIssue );");
-       output.println("       ++(seseToIssue->common.unresolvedDependencies);");
+       output.println("       if( !src->doneExecuting ) {");
+       output.println("         addNewItem( src->forwardList, seseToIssue );");
+       output.println("         ++(seseToIssue->common.unresolvedDependencies);");
+       output.println("       }");
        output.println("       pthread_mutex_unlock( &(src->lock) );");
        output.println("     }");
 
@@ -2810,16 +3014,69 @@ public class BuildCode {
        // to pass the static name to the child's record
        output.println("     seseToIssue->"+srcPair+" = "+srcPair+";");
       }
+
+      // dynamic sources might already be accounted for in the static list,
+      // so only add them to forwarding lists if they're not already there
+      Iterator<TempDescriptor> dynVarsItr = fsen.getDynamicInVarSet().iterator();
+      while( dynVarsItr.hasNext() ) {
+       TempDescriptor dynInVar = dynVarsItr.next();
+       output.println("     {");
+       output.println("       SESEcommon* src = (SESEcommon*)"+dynInVar+"_srcSESE;");
+
+       // the dynamic source is NULL if it comes from your own space--you can't pass
+       // the address off to the new child, because you're not done executing and
+       // might change the variable, so copy it right now
+       output.println("       if( src != NULL ) {");
+       output.println("         pthread_mutex_lock( &(src->lock) );");
+       output.println("         if( isEmpty( src->forwardList ) ||");
+       output.println("             seseToIssue != peekItem( src->forwardList ) ) {");
+       output.println("           if( !src->doneExecuting ) {");
+       output.println("             addNewItem( src->forwardList, seseToIssue );");
+       output.println("             ++(seseToIssue->common.unresolvedDependencies);");
+       output.println("           }");
+       output.println("         }");
+       output.println("         pthread_mutex_unlock( &(src->lock) );");       
+       output.println("         seseToIssue->"+dynInVar+"_srcOffset = "+dynInVar+"_srcOffset;");
+       output.println("       } else {");
+
+       boolean useParentContext = false;
+       if( fsen != mlpa.getMainSESE() ) {
+         assert fsen.getParent() != null;
+         if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
+           useParentContext = true;
+         }
+       }       
+       if( useParentContext ) {
+         output.println("         seseToIssue->"+dynInVar+" = "+
+                        generateTemp( fsen.getParent().getfmBogus(), dynInVar, null )+";");
+       } else {
+         output.println("         seseToIssue->"+dynInVar+" = "+
+                        generateTemp( fsen.getfmEnclosing(), dynInVar, null )+";");
+       }
+       
+       output.println("       }");
+       output.println("     }");
+       
+       // even if the value is already copied, make sure your NULL source
+       // gets passed so child knows it already has the dynamic value
+       output.println("     seseToIssue->"+dynInVar+"_srcSESE = "+dynInVar+"_srcSESE;");
+      }
       
       // maintain pointers for for finding dynamic SESE 
-      // instances from static names
-      for( int i = fsen.getOldestAgeToTrack(); i > 0; --i ) {
-       SESEandAgePair p1 = new SESEandAgePair( fsen, i   );
-       SESEandAgePair p2 = new SESEandAgePair( fsen, i-1 );
-       output.println("     "+p1+" = "+p2+";");
-      }
+      // instances from static names      
       SESEandAgePair p = new SESEandAgePair( fsen, 0 );
-      output.println("     "+p+" = seseToIssue;");
+      if(  fsen.getParent() != null && 
+          //!fsen.getParent().getIsCallerSESEplaceholder() &&
+          fsen.getParent().getNeededStaticNames().contains( p ) 
+       ) {       
+
+       for( int i = fsen.getOldestAgeToTrack(); i > 0; --i ) {
+         SESEandAgePair p1 = new SESEandAgePair( fsen, i   );
+         SESEandAgePair p2 = new SESEandAgePair( fsen, i-1 );
+         output.println("     "+p1+" = "+p2+";");
+       }      
+       output.println("     "+p+" = seseToIssue;");
+      }
     }
 
     // if there were no outstanding dependencies, issue here
@@ -2839,13 +3096,35 @@ public class BuildCode {
                                        FlatSESEExitNode fsexn, 
                                        PrintWriter output
                                      ) {
+
+    // if MLP flag is off, okay that SESE nodes are in IR graph, 
+    // just skip over them and code generates exactly the same 
     if( !state.MLP ) {
-      // SESE nodes can be parsed for normal compilation, just skip over them
       return;
     }
 
+    // there may be an SESE in an unreachable method, skip over
+    if( !mlpa.getAllSESEs().contains( fsexn.getFlatEnter() ) ) {
+      return;
+    }
+
+    // also, if we have encountered a placeholder, just jump it
+    if( fsexn.getFlatEnter().getIsCallerSESEplaceholder() ) {
+      return;
+    }
+
+    output.println("   /* SESE exiting */");
+
     String com = paramsprefix+"->common";
 
+    // this SESE cannot be done until all of its children are done
+    // so grab your own lock with the condition variable for watching
+    // that the number of your running children is greater than zero    
+    output.println("   pthread_mutex_lock( &("+com+".lock) );");
+    output.println("   while( "+com+".numRunningChildren > 0 ) {");
+    output.println("     pthread_cond_wait( &("+com+".runningChildrenCond), &("+com+".lock) );");
+    output.println("   }");
+
     // copy out-set from local temps into the sese record
     Iterator<TempDescriptor> itr = fsexn.getFlatEnter().getOutVarSet().iterator();
     while( itr.hasNext() ) {
@@ -2856,8 +3135,8 @@ public class BuildCode {
     }    
     
     // mark yourself done, your SESE data is now read-only
-    output.println("   pthread_mutex_lock( &("+com+".lock) );");
     output.println("   "+com+".doneExecuting = TRUE;");
+    output.println("   pthread_cond_signal( &("+com+".doneCond) );");
     output.println("   pthread_mutex_unlock( &("+com+".lock) );");
 
     // decrement dependency count for all SESE's on your forwarding list
@@ -2872,10 +3151,74 @@ public class BuildCode {
     output.println("   }");
     
     // if parent is stalling on you, let them know you're done
-    if( fsexn.getFlatEnter() != mlpa.getRootSESE() ) {
-      output.println("     psem_give( &("+paramsprefix+"->common.stallSem) );");
+    if( fsexn.getFlatEnter() != mlpa.getMainSESE() ) {
+      output.println("   psem_give( &("+paramsprefix+"->common.stallSem) );");
+    }
+
+    // last of all, decrement your parent's number of running children    
+    output.println("   if( "+paramsprefix+"->common.parent != NULL ) {");
+    output.println("     pthread_mutex_lock( &("+paramsprefix+"->common.parent->lock) );");
+    output.println("     --("+paramsprefix+"->common.parent->numRunningChildren);");
+    output.println("     pthread_cond_signal( &("+paramsprefix+"->common.parent->runningChildrenCond) );");
+    output.println("     pthread_mutex_unlock( &("+paramsprefix+"->common.parent->lock) );");
+    output.println("   }");    
+
+    // this is a thread-only variable that can be handled when critical sese-to-sese
+    // data has been taken care of--set sese pointer to remember self over method
+    // calls to a non-zero, invalid address
+    output.println("   seseCaller = (SESEcommon*) 0x1;");    
+  }
+
+  public void generateFlatWriteDynamicVarNode( FlatMethod fm,  
+                                              LocalityBinding lb, 
+                                              FlatWriteDynamicVarNode fwdvn,
+                                              PrintWriter output
+                                            ) {
+    if( !state.MLP ) {
+      // should node should not be in an IR graph if the
+      // MLP flag is not set
+      throw new Error("Unexpected presence of FlatWriteDynamicVarNode");
     }
+       
+    Hashtable<TempDescriptor, VariableSourceToken> writeDynamic = 
+      fwdvn.getVar2src();
+
+    assert writeDynamic != null;
+
+    Iterator wdItr = writeDynamic.entrySet().iterator();
+    while( wdItr.hasNext() ) {
+      Map.Entry           me     = (Map.Entry)           wdItr.next();
+      TempDescriptor      refVar = (TempDescriptor)      me.getKey();
+      VariableSourceToken vst    = (VariableSourceToken) me.getValue();
+      
+      FlatSESEEnterNode current = fwdvn.getEnclosingSESE();
+
+      // only do this if the variable in question should be tracked,
+      // meaning that it was explicitly added to the dynamic var set
+      if( !current.getDynamicVarSet().contains( vst.getAddrVar() ) ) {
+       continue;
+      }
+
+      SESEandAgePair instance = new SESEandAgePair( vst.getSESE(), vst.getAge() );      
+
+      output.println("   {");
+
+      if( current.equals( vst.getSESE() ) ) {
+       // if the src comes from this SESE, it's a method local variable,
+       // mark src pointer NULL to signify that the var is up-to-date
+       output.println("     "+vst.getAddrVar()+"_srcSESE = NULL;");
+
+      } else {
+       // otherwise we track where it will come from
+       output.println("     "+vst.getAddrVar()+"_srcSESE = "+instance+";");    
+       output.println("     "+vst.getAddrVar()+"_srcOffset = (int) &((("+
+                      vst.getSESE().getSESErecordName()+"*)0)->"+vst.getAddrVar()+");");
+      }
+
+      output.println("   }");
+    }  
   }
+
   
   private void generateFlatCheckNode(FlatMethod fm,  LocalityBinding lb, FlatCheckNode fcn, PrintWriter output) {
     if (state.CONSCHECK) {
@@ -2902,6 +3245,11 @@ public class BuildCode {
   }
 
   private void generateFlatCall(FlatMethod fm, LocalityBinding lb, FlatCall fc, PrintWriter output) {
+
+    if( state.MLP && !nonSESEpass ) {
+      output.println("     seseCaller = (SESEcommon*)"+paramsprefix+";");
+    }
+
     MethodDescriptor md=fc.getMethod();
     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? locality.getBinding(lb, fc) : md);
     ClassDescriptor cn=md.getClassDesc();
@@ -3000,7 +3348,7 @@ public class BuildCode {
       needcomma=true;
     }
 
-    if (!GENERATEPRECISEGC) {
+    if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
       if (fc.getThis()!=null) {
        TypeDescriptor ptd=md.getThis().getType();
        if (needcomma)
@@ -3173,7 +3521,7 @@ public class BuildCode {
        /* Link object into list */
        String revertptr=generateTemp(fm, reverttable.get(lb),lb);
        output.println(revertptr+"=revertlist;");
-       if (GENERATEPRECISEGC)
+       if (GENERATEPRECISEGC || this.state.MULTICOREGC)
          output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
        else
          output.println("COPY_OBJ("+dst+");");
@@ -3201,7 +3549,7 @@ public class BuildCode {
        String dst=generateTemp(fm, fsfn.getDst(),lb);
        output.println("if(!"+dst+"->"+localcopystr+") {");
        /* Link object into list */
-       if (GENERATEPRECISEGC)
+       if (GENERATEPRECISEGC || this.state.MULTICOREGC)
          output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
        else
          output.println("COPY_OBJ("+dst+");");
@@ -3321,7 +3669,7 @@ public class BuildCode {
        /* Link object into list */
        String revertptr=generateTemp(fm, reverttable.get(lb),lb);
        output.println(revertptr+"=revertlist;");
-       if ((GENERATEPRECISEGC))
+       if ((GENERATEPRECISEGC) || this.state.MULTICOREGC)
         output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
        else
          output.println("COPY_OBJ("+dst+");");
@@ -3343,7 +3691,7 @@ public class BuildCode {
        String dst=generateTemp(fm, fsen.getDst(),lb);
        output.println("if(!"+dst+"->"+localcopystr+") {");
        /* Link object into list */
-       if (GENERATEPRECISEGC)
+       if (GENERATEPRECISEGC || this.state.MULTICOREGC)
          output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
        else
          output.println("COPY_OBJ("+dst+");");
@@ -3554,12 +3902,6 @@ public class BuildCode {
     } else
       output.print(task.getSafeSymbol()+"(");
     
-    /*
-    if (addSESErecord) {
-      output.print("SESErecord* currentSESE, ");
-    }
-    */
-
     boolean printcomma=false;
     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
       if (md!=null) {
@@ -3585,7 +3927,7 @@ public class BuildCode {
          output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
       }
       output.println(") {");
-    } else if (!GENERATEPRECISEGC) {
+    } else if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
       /* Imprecise Task */
       output.println("void * parameterarray[]) {");
       /* Unpack variables */