Fixed variable dynamic source bookkeeping bug, regression test runs for single and...
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
index 2b2c9c703757bf1c65f7b7669e918a2bf943b6af..9c24aa680a3ee83ca2c5645a87da79b704fdfac0 100644 (file)
@@ -1,4 +1,5 @@
 package IR.Flat;
+import IR.Tree.Modifiers;
 import IR.Tree.FlagExpressionNode;
 import IR.Tree.DNFFlag;
 import IR.Tree.DNFFlagAtom;
@@ -18,8 +19,16 @@ import Analysis.TaskStateAnalysis.TaskIndex;
 import Analysis.Locality.LocalityAnalysis;
 import Analysis.Locality.LocalityBinding;
 import Analysis.Locality.DiscoverConflicts;
+import Analysis.Locality.DelayComputation;
+import Analysis.CallGraph.CallGraph;
 import Analysis.Prefetch.*;
 import Analysis.Loops.WriteBarrier;
+import Analysis.Loops.GlobalFieldType;
+import Analysis.Locality.TypeAnalysis;
+import Analysis.MLP.MLPAnalysis;
+import Analysis.MLP.VariableSourceToken;
+import Analysis.MLP.CodePlan;
+import Analysis.MLP.SESEandAgePair;
 
 public class BuildCode {
   State state;
@@ -30,6 +39,8 @@ public class BuildCode {
   Hashtable flagorder;
   int tag=0;
   String localsprefix="___locals___";
+  String localsprefixaddr="&"+localsprefix;
+  String localsprefixderef=localsprefix+".";
   String fcrevert="___fcrevert___";
   String paramsprefix="___params___";
   String oidstr="___nextobject___";
@@ -50,26 +61,37 @@ public class BuildCode {
   Hashtable<LocalityBinding, Hashtable<TempDescriptor, TempDescriptor>> backuptable;
   SafetyAnalysis sa;
   PrefetchAnalysis pa;
-  HashSet<FlatSESEEnterNode> setSESEtoGen;
+  MLPAnalysis mlpa;
+  String mlperrstr = "if(status != 0) { "+
+    "sprintf(errmsg, \"MLP error at %s:%d\", __FILE__, __LINE__); "+
+    "perror(errmsg); exit(-1); }";
   boolean nonSESEpass=true;
   WriteBarrier wb;
   DiscoverConflicts dc;
-
+  DiscoverConflicts recorddc;
+  DelayComputation delaycomp;
+  CallGraph callgraph;
 
   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa) {
-    this(st, temptovar, typeutil, null, sa, pa);
+    this(st, temptovar, typeutil, null, sa, pa, null);
+  }
+
+  public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa, MLPAnalysis mlpa) {
+    this(st, temptovar, typeutil, null, sa, pa, mlpa);
   }
 
-  public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, PrefetchAnalysis pa) {
-    this(st, temptovar, typeutil, locality, null, pa);
+  public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, PrefetchAnalysis pa, MLPAnalysis mlpa) {
+    this(st, temptovar, typeutil, locality, null, pa, mlpa);
   }
 
-  public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, SafetyAnalysis sa, PrefetchAnalysis pa) {
+  public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, SafetyAnalysis sa, PrefetchAnalysis pa, MLPAnalysis mlpa) {
     this.sa=sa;
     this.pa=pa;
+    this.mlpa=mlpa;
     state=st;
+    callgraph=new CallGraph(state);
     if (state.SINGLETM)
-       oidstr="___objlocation___";
+      oidstr="___objlocation___";
     this.temptovar=temptovar;
     paramstable=new Hashtable();
     tempstable=new Hashtable();
@@ -84,11 +106,20 @@ public class BuildCode {
       this.wb=new WriteBarrier(locality, st);
     }
     if (state.SINGLETM&&state.DCOPTS) {
-      this.dc=new DiscoverConflicts(locality, st);
+      TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
+      this.dc=new DiscoverConflicts(locality, st, typeanalysis, null);
       dc.doAnalysis();
     }
-
-    setSESEtoGen = new HashSet<FlatSESEEnterNode>();
+    if (state.DELAYCOMP) {
+      //TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
+      TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
+      GlobalFieldType gft=new GlobalFieldType(callgraph, st, typeutil.getMain());
+      delaycomp=new DelayComputation(locality, st, typeanalysis, gft);
+      delaycomp.doAnalysis();
+      dc=delaycomp.getConflicts();
+      recorddc=new DiscoverConflicts(locality, st, typeanalysis, delaycomp.getCannotDelayMap(), true, true, null);
+      recorddc.doAnalysis();
+    }
   }
 
   /** The buildCode method outputs C code for all the methods.  The Flat
@@ -139,12 +170,21 @@ public class BuildCode {
     outmethodheader.println("#include \"structdefs.h\"");
     if (state.DSM)
       outmethodheader.println("#include \"dstm.h\"");
-    if (state.SINGLETM)
+    if (state.SINGLETM) {
       outmethodheader.println("#include \"tm.h\"");
+      outmethodheader.println("#include \"delaycomp.h\"");
+    }
     if (state.ABORTREADERS) {
       outmethodheader.println("#include \"abortreaders.h\"");
       outmethodheader.println("#include <setjmp.h>");
     }
+    if (state.MLP) {
+      outmethodheader.println("#include <stdlib.h>");
+      outmethodheader.println("#include <stdio.h>");
+      outmethodheader.println("#include <string.h>");
+      outmethodheader.println("#include \"mlp_runtime.h\"");
+      outmethodheader.println("#include \"psemaphore.h\"");
+    }
 
     /* Output Structures */
     outputStructs(outstructs);
@@ -177,18 +217,32 @@ public class BuildCode {
       outputTaskTypes(outtask);
     }
 
+    if( state.MLP ) {
+      // have to initialize some SESE compiler data before
+      // analyzing normal methods, which must happen before
+      // generating SESE internal code
+      for(Iterator<FlatSESEEnterNode> seseit=mlpa.getAllSESEs().iterator();seseit.hasNext();) {
+       FlatSESEEnterNode fsen = seseit.next();
+       initializeSESE( fsen );
+      }
+    }
+
     /* Build the actual methods */
     outputMethods(outmethod);
 
+    // Output function prototypes and structures for SESE's and code
     if( state.MLP ) {
       nonSESEpass = false;
-      while( !setSESEtoGen.isEmpty() ) {
-       FlatSESEEnterNode fsen = setSESEtoGen.iterator().next();
-       setSESEtoGen.remove( fsen );
-       generateMethodSESE( fsen, fsen.getEnclosingFlatMeth(), null, outmethod );
+
+      // first generate code for each sese's internals
+      for(Iterator<FlatSESEEnterNode> seseit=mlpa.getAllSESEs().iterator();seseit.hasNext();) {
+       FlatSESEEnterNode fsen = seseit.next();
+       generateMethodSESE(fsen, null, outstructs, outmethodheader, outmethod);
       }
-    } else {
-      assert setSESEtoGen.isEmpty();
+
+      // then write the invokeSESE switch to decouple scheduler
+      // from having to do unique details of sese invocation
+      generateSESEinvocationMethod(outmethodheader, outmethod);
     }
 
     if (state.TASK) {
@@ -230,23 +284,29 @@ public class BuildCode {
   private void outputMainMethod(PrintWriter outmethod) {
     outmethod.println("int main(int argc, const char *argv[]) {");
     outmethod.println("  int i;");
+
+    if (state.MLP) {
+      //outmethod.println("  pthread_once( &mlpOnceObj, mlpInitOncePerThread );");
+      outmethod.println("  workScheduleInit( "+state.MLP_NUMCORES+", invokeSESEmethod );");
+    }
+
     if (state.DSM) {
-       outmethod.println("#ifdef TRANSSTATS \n");
-       outmethod.println("handle();\n");
-       outmethod.println("#endif\n");
+      outmethod.println("#ifdef TRANSSTATS \n");
+      outmethod.println("handle();\n");
+      outmethod.println("#endif\n");
     }
     if (state.THREAD||state.DSM||state.SINGLETM) {
       outmethod.println("initializethreads();");
     }
     if (state.DSM) {
       outmethod.println("if (dstmStartup(argv[1])) {");
-      if (GENERATEPRECISEGC) {
+      if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
        outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-2);");
       } else {
        outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-2);");
       }
     } else {
-      if (GENERATEPRECISEGC) {
+      if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
        outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
       } else {
        outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
@@ -257,7 +317,7 @@ public class BuildCode {
     } else
       outmethod.println("  for(i=1;i<argc;i++) {");
     outmethod.println("    int length=strlen(argv[i]);");
-    if (GENERATEPRECISEGC) {
+    if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
       outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
     } else {
       outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
@@ -268,12 +328,11 @@ public class BuildCode {
       outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
     outmethod.println("  }");
 
-
     MethodDescriptor md=typeutil.getMain();
     ClassDescriptor cd=typeutil.getMainClass();
 
     outmethod.println("   {");
-    if (GENERATEPRECISEGC) {
+    if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
       if (state.DSM||state.SINGLETM) {
        outmethod.print("       struct "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
       } else
@@ -305,28 +364,37 @@ public class BuildCode {
     if (state.DSM||state.SINGLETM) {
       outmethod.println("#ifdef TRANSSTATS \n");
       outmethod.println("printf(\"******  Transaction Stats   ******\\n\");");
-      outmethod.println("printf(\"numTransAbort= %d\\n\", numTransAbort);");
       outmethod.println("printf(\"numTransCommit= %d\\n\", numTransCommit);");
+      outmethod.println("printf(\"numTransAbort= %d\\n\", numTransAbort);");
       outmethod.println("printf(\"nSoftAbort= %d\\n\", nSoftAbort);");
       if (state.DSM) {
-         outmethod.println("printf(\"nchashSearch= %d\\n\", nchashSearch);");
-         outmethod.println("printf(\"nmhashSearch= %d\\n\", nmhashSearch);");
-         outmethod.println("printf(\"nprehashSearch= %d\\n\", nprehashSearch);");
-         outmethod.println("printf(\"nRemoteReadSend= %d\\n\", nRemoteSend);");
-         outmethod.println("printf(\"bytesSent= %d\\n\", bytesSent);");
-         outmethod.println("printf(\"bytesRecv= %d\\n\", bytesRecv);");
+       outmethod.println("printf(\"nchashSearch= %d\\n\", nchashSearch);");
+       outmethod.println("printf(\"nmhashSearch= %d\\n\", nmhashSearch);");
+       outmethod.println("printf(\"nprehashSearch= %d\\n\", nprehashSearch);");
+       outmethod.println("printf(\"nRemoteReadSend= %d\\n\", nRemoteSend);");
+       outmethod.println("printf(\"bytesSent= %d\\n\", bytesSent);");
+       outmethod.println("printf(\"bytesRecv= %d\\n\", bytesRecv);");
       } else if (state.SINGLETM) {
-         outmethod.println("printf(\"nSoftAbortAbort= %d\\n\", nSoftAbortAbort);");
-         outmethod.println("printf(\"nSoftAbortCommit= %d\\n\", nSoftAbortCommit);");
+       outmethod.println("printf(\"nSoftAbortAbort= %d\\n\", nSoftAbortAbort);");
+       outmethod.println("printf(\"nSoftAbortCommit= %d\\n\", nSoftAbortCommit);");
+       outmethod.println("#ifdef STMSTATS\n");
+       outmethod.println("for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {\n");
+       outmethod.println("  printf(\"typesCausingAbort[%2d] numaccess= %5d numabort= %3d\\n\", i, typesCausingAbort[i].numaccess, typesCausingAbort[i].numabort);\n");
+       outmethod.println("}\n");
+       outmethod.println("#endif\n");
+       outmethod.println("fflush(stdout);");
       }
       outmethod.println("#endif\n");
     }
 
     if (state.THREAD||state.SINGLETM)
-       outmethod.println("pthread_exit(NULL);");
+      outmethod.println("pthread_exit(NULL);");
 
-    outmethod.println("}");
+    if (state.MLP) {
+      outmethod.println("  workScheduleBegin();");
+    }
 
+    outmethod.println("}");
   }
 
   /* This method outputs code for each task. */
@@ -374,10 +442,12 @@ public class BuildCode {
       outmethod.println("#include \"localobjects.h\"");
     }
     if (state.FASTCHECK) {
-      outmethod.println("#include \"localobjects.h\"");      
+      outmethod.println("#include \"localobjects.h\"");
     }
     if(state.MULTICORE) {
       outmethod.println("#include \"task.h\"");
+         outmethod.println("#include \"multicoreruntime.h\"");
+         outmethod.println("#include \"runtime_arch.h\"");
     }
     if (state.THREAD||state.DSM||state.SINGLETM)
       outmethod.println("#include <thread.h>");
@@ -388,9 +458,13 @@ public class BuildCode {
       outmethod.println("#include \"checkers.h\"");
     }
     if (state.MLP) {
+      outmethod.println("#include <stdlib.h>");
+      outmethod.println("#include <stdio.h>");
       outmethod.println("#include \"mlp_runtime.h\"");
+      outmethod.println("#include \"psemaphore.h\"");
     }
 
+
     //Store the sizes of classes & array elements
     generateSizeArray(outmethod);
 
@@ -439,6 +513,10 @@ public class BuildCode {
     outstructs.println("#define INTPTR int");
     outstructs.println("#endif");
     outstructs.println("#endif");
+    if( state.MLP ) {
+      outstructs.println("#include \"mlp_runtime.h\"");
+      outstructs.println("#include \"psemaphore.h\"");
+    }
 
     /* Output #defines that the runtime uses to determine type
      * numbers for various objects it needs */
@@ -472,6 +550,8 @@ public class BuildCode {
                        (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
 
     outstructs.println("#define NUMCLASSES "+state.numClasses());
+    int totalClassSize = state.numClasses() + state.numArrays();
+    outstructs.println("#define TOTALNUMCLASSANDARRAY "+ totalClassSize);
     if (state.TASK) {
       outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
       outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
@@ -513,11 +593,13 @@ public class BuildCode {
       if(!state.MULTICORE) {
        outclassdefs.println("  void * flagptr;");
       } else {
-       outclassdefs.println("  int isolate;");        // indicate if this object is shared or not
-       outclassdefs.println("  int version;");
-       outclassdefs.println("  struct ___Object___ * original;");
-       //outclassdefs.println("  int numlocks;");        // array for locks
-       outclassdefs.println("  int * lock;");
+        outclassdefs.println("  int version;");
+        outclassdefs.println("  int * lock;");  // lock entry for this obj
+        outclassdefs.println("  int mutex;");  
+        outclassdefs.println("  int lockcount;");
+        if(state.MULTICOREGC) {
+          outclassdefs.println("  int marked;");
+        }
       }
       if(state.OPTIONAL) {
        outclassdefs.println("  int numfses;");
@@ -526,6 +608,9 @@ public class BuildCode {
     }
     printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
 
+    if (state.ARRAYPAD)
+      outclassdefs.println("  int paddingforarray;");
+
     outclassdefs.println("  int ___length___;");
     outclassdefs.println("};\n");
     outclassdefs.println("extern int classsize[];");
@@ -809,34 +894,29 @@ public class BuildCode {
     outclassdefs.print("extern int numTransCommit;\n");
     outclassdefs.print("extern int nSoftAbort;\n");
     if (state.DSM) {
-       outclassdefs.print("extern int nchashSearch;\n");
-       outclassdefs.print("extern int nmhashSearch;\n");
-       outclassdefs.print("extern int nprehashSearch;\n");
-       outclassdefs.print("extern int nRemoteSend;\n");
-       outclassdefs.print("extern int bytesSent;\n");
-       outclassdefs.print("extern int bytesRecv;\n");
-       outclassdefs.print("extern void handle();\n");
+      outclassdefs.print("extern int nchashSearch;\n");
+      outclassdefs.print("extern int nmhashSearch;\n");
+      outclassdefs.print("extern int nprehashSearch;\n");
+      outclassdefs.print("extern int nRemoteSend;\n");
+      outclassdefs.print("extern int bytesSent;\n");
+      outclassdefs.print("extern int bytesRecv;\n");
+      outclassdefs.print("extern void handle();\n");
     } else if (state.SINGLETM) {
-       outclassdefs.println("extern int nSoftAbortAbort;");
-       outclassdefs.println("extern int nSoftAbortCommit;");
+      outclassdefs.println("extern int nSoftAbortAbort;");
+      outclassdefs.println("extern int nSoftAbortCommit;");
+      outclassdefs.println("#ifdef STMSTATS\n");
+      outclassdefs.println("extern objtypestat_t typesCausingAbort[];");
+      outclassdefs.println("#endif\n");
     }
     outclassdefs.print("#endif\n");
     outclassdefs.print("int numprefetchsites = " + pa.prefetchsiteid + ";\n");
 
-    outclassdefs.print("int classsize[]={");
     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
     cdarray=new ClassDescriptor[state.numClasses()];
     while(it.hasNext()) {
       ClassDescriptor cd=(ClassDescriptor)it.next();
       cdarray[cd.getId()]=cd;
     }
-    boolean needcomma=false;
-    for(int i=0; i<state.numClasses(); i++) {
-      if (needcomma)
-       outclassdefs.print(", ");
-      outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");
-      needcomma=true;
-    }
 
     arraytable=new TypeDescriptor[state.numArrays()];
 
@@ -847,6 +927,34 @@ public class BuildCode {
       arraytable[id]=td;
     }
 
+
+
+    /* Print out types */
+    outclassdefs.println("/* ");
+    for(int i=0; i<state.numClasses(); i++) {
+      ClassDescriptor cd=cdarray[i];
+      outclassdefs.println(cd +"  "+i);
+    }
+
+    for(int i=0; i<state.numArrays(); i++) {
+      TypeDescriptor arraytd=arraytable[i];
+      outclassdefs.println(arraytd.toPrettyString() +"  "+(i+state.numClasses()));
+    }
+
+    outclassdefs.println("*/");
+
+
+    outclassdefs.print("int classsize[]={");
+
+    boolean needcomma=false;
+    for(int i=0; i<state.numClasses(); i++) {
+      if (needcomma)
+       outclassdefs.print(", ");
+      outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");
+      needcomma=true;
+    }
+
+
     for(int i=0; i<state.numArrays(); i++) {
       if (needcomma)
        outclassdefs.print(", ");
@@ -860,10 +968,10 @@ public class BuildCode {
 
     outclassdefs.println("};");
 
-    ClassDescriptor objectclass=typeutil.getClass(TypeUtil.ObjectClass);    
+    ClassDescriptor objectclass=typeutil.getClass(TypeUtil.ObjectClass);
     needcomma=false;
     outclassdefs.print("int typearray[]={");
-    for(int i=0;i<state.numClasses();i++) {
+    for(int i=0; i<state.numClasses(); i++) {
       ClassDescriptor cd=cdarray[i];
       ClassDescriptor supercd=cd.getSuperDesc();
       if (needcomma)
@@ -875,7 +983,7 @@ public class BuildCode {
       needcomma=true;
     }
 
-    for(int i=0;i<state.numArrays();i++) {
+    for(int i=0; i<state.numArrays(); i++) {
       TypeDescriptor arraytd=arraytable[i];
       ClassDescriptor arraycd=arraytd.getClassDesc();
       if (arraycd==null) {
@@ -903,13 +1011,13 @@ public class BuildCode {
       needcomma=true;
     }
 
-    outclassdefs.println("};");    
+    outclassdefs.println("};");
 
     needcomma=false;
 
 
     outclassdefs.print("int typearray2[]={");
-    for(int i=0;i<state.numArrays();i++) {
+    for(int i=0; i<state.numArrays(); i++) {
       TypeDescriptor arraytd=arraytable[i];
       ClassDescriptor arraycd=arraytd.getClassDesc();
       if (arraycd==null) {
@@ -922,7 +1030,7 @@ public class BuildCode {
       ClassDescriptor cd=arraycd.getSuperDesc();
       int level=arraytd.getArrayCount()-1;
       int type=-1;
-      for(;level>0;level--) {
+      for(; level>0; level--) {
        TypeDescriptor supertd=new TypeDescriptor(objectclass);
        supertd.setArrayCount(level);
        type=state.getArrayNumber(supertd);
@@ -952,8 +1060,7 @@ public class BuildCode {
     if (lb!=null) {
       paramstable.put(lb, objectparams);
       backuptable.put(lb, new Hashtable<TempDescriptor, TempDescriptor>());
-    }
-    else if (md!=null)
+    } else if (md!=null)
       paramstable.put(md, objectparams);
     else
       paramstable.put(task, objectparams);
@@ -961,7 +1068,7 @@ public class BuildCode {
     for(int i=0; i<fm.numParameters(); i++) {
       TempDescriptor temp=fm.getParameter(i);
       TypeDescriptor type=temp.getType();
-      if (type.isPtr()&&GENERATEPRECISEGC)
+      if (type.isPtr()&&((GENERATEPRECISEGC) || (this.state.MULTICOREGC)))
        objectparams.addPtr(temp);
       else
        objectparams.addPrim(temp);
@@ -972,7 +1079,7 @@ public class BuildCode {
 
     for(int i=0; i<fm.numTags(); i++) {
       TempDescriptor temp=fm.getTag(i);
-      if (GENERATEPRECISEGC)
+      if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
        objectparams.addPtr(temp);
       else
        objectparams.addPrim(temp);
@@ -992,7 +1099,7 @@ 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) || (this.state.MULTICOREGC)))
          objecttemps.addPtr(temp);
        else
          objecttemps.addPrim(temp);
@@ -1007,7 +1114,7 @@ public class BuildCode {
       for(Iterator<TempDescriptor> tmpit=backuptable.get(lb).values().iterator(); tmpit.hasNext();) {
        TempDescriptor tmp=tmpit.next();
        TypeDescriptor type=tmp.getType();
-       if (type.isPtr()&&GENERATEPRECISEGC)
+       if (type.isPtr()&&((GENERATEPRECISEGC) || (this.state.MULTICOREGC)))
          objecttemps.addPtr(tmp);
        else
          objecttemps.addPrim(tmp);
@@ -1015,7 +1122,7 @@ public class BuildCode {
       /* Create temp to hold revert table */
       if (state.DSM&&(lb.getHasAtomic()||lb.isAtomic())) {
        TempDescriptor reverttmp=new TempDescriptor("revertlist", typeutil.getClass(TypeUtil.ObjectClass));
-       if (GENERATEPRECISEGC)
+       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
          objecttemps.addPtr(reverttmp);
        else
          objecttemps.addPrim(reverttmp);
@@ -1126,14 +1233,10 @@ public class BuildCode {
     if (!fieldorder.containsKey(cn)) {
       Vector fields=new Vector();
       fieldorder.put(cn,fields);
-      if (sp==null&&!state.TASK) {
-       fields.add(cn.getFieldTable().get("cachedCode"));
-      }
-      Iterator fieldit=cn.getFields();
-      while(fieldit.hasNext()) {
-       FieldDescriptor fd=(FieldDescriptor)fieldit.next();
-       if ((sp==null||!sp.getFieldTable().contains(fd.getSymbol()))&&
-           (!fd.getSymbol().equals("cachedCode")||state.TASK))
+      Vector fieldvec=cn.getFieldVec();
+      for(int i=0;i<fieldvec.size();i++) {
+       FieldDescriptor fd=(FieldDescriptor)fieldvec.get(i);
+       if ((sp==null||!sp.getFieldTable().contains(fd.getSymbol())))
          fields.add(fd);
       }
     }
@@ -1201,11 +1304,13 @@ public class BuildCode {
       if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) {
        classdefout.println("  void * flagptr;");
       } else if (state.MULTICORE) {
-       classdefout.println("  int isolate;");        // indicate if this object is shared or not
        classdefout.println("  int version;");
-       classdefout.println("  struct ___Object___ * original;");
-       //classdefout.println("  int numlocks;");        // array for locks
-       classdefout.println("  int * lock;");
+    classdefout.println("  int * lock;");  // lock entry for this obj
+    classdefout.println("  int mutex;");  
+    classdefout.println("  int lockcount;");
+    if(state.MULTICOREGC) {
+      classdefout.println("  int marked;");
+    }
       }
       if (state.OPTIONAL) {
        classdefout.println("  int numfses;");
@@ -1254,7 +1359,7 @@ public class BuildCode {
 
   private void generateMethodParam(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter output) {
     /* Output parameter structure */
-    if (GENERATEPRECISEGC) {
+    if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
       ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null ? lb : md);
       if ((state.DSM||state.SINGLETM)&&lb!=null)
        output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
@@ -1270,7 +1375,6 @@ public class BuildCode {
     }
   }
 
-
   private void generateMethod(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter headersout, PrintWriter output) {
     FlatMethod fm=state.getMethodFlat(md);
     generateTempStructs(fm, lb);
@@ -1281,7 +1385,7 @@ public class BuildCode {
     generateMethodParam(cn, md, lb, output);
 
     /* Output temp structure */
-    if (GENERATEPRECISEGC) {
+    if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
       if (state.DSM||state.SINGLETM)
        output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
       else
@@ -1321,7 +1425,7 @@ public class BuildCode {
       headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
     }
     boolean printcomma=false;
-    if (GENERATEPRECISEGC) {
+    if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
       if (state.DSM||state.SINGLETM) {
        headersout.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
       } else
@@ -1362,7 +1466,7 @@ public class BuildCode {
       TempObject objecttemps=(TempObject) tempstable.get(task);
 
       /* Output parameter structure */
-      if (GENERATEPRECISEGC) {
+      if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
        output.println("struct "+task.getSafeSymbol()+"_params {");
 
        output.println("  INTPTR size;");
@@ -1379,7 +1483,7 @@ public class BuildCode {
       }
 
       /* Output temp structure */
-      if (GENERATEPRECISEGC) {
+      if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
        output.println("struct "+task.getSafeSymbol()+"_locals {");
        output.println("  INTPTR size;");
        output.println("  void * next;");
@@ -1400,7 +1504,7 @@ public class BuildCode {
       headersout.print("void " + task.getSafeSymbol()+"(");
 
       boolean printcomma=false;
-      if (GENERATEPRECISEGC) {
+      if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
        headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
       } else
        headersout.print("void * parameterarray[]");
@@ -1410,20 +1514,124 @@ public class BuildCode {
 
   /***** Generate code for FlatMethod fm. *****/
 
+  Hashtable<FlatAtomicEnterNode, AtomicRecord> atomicmethodmap;
+  static int atomicmethodcount=0;
+
   private void generateFlatMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
     if (State.PRINTFLAT)
       System.out.println(fm.printMethod());
     MethodDescriptor md=fm.getMethod();
-
     TaskDescriptor task=fm.getTask();
-
     ClassDescriptor cn=md!=null ? md.getClassDesc() : null;
-
     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : md!=null ? md : task);
+
+    HashSet<AtomicRecord> arset=null;
+
+    if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) {
+      //create map
+      if (atomicmethodmap==null)
+       atomicmethodmap=new Hashtable<FlatAtomicEnterNode, AtomicRecord>();
+
+      //fix these so we get right strings for local variables
+      localsprefixaddr=localsprefix;
+      localsprefixderef=localsprefix+"->";
+      arset=new HashSet<AtomicRecord>();
+      
+      //Generate commit methods here
+      for(Iterator<FlatNode> fnit=fm.getNodeSet().iterator();fnit.hasNext();) {
+       FlatNode fn=fnit.next();
+       if (fn.kind()==FKind.FlatAtomicEnterNode&&
+           locality.getAtomic(lb).get(fn.getPrev(0)).intValue()==0) {
+         //We have an atomic enter
+         FlatAtomicEnterNode faen=(FlatAtomicEnterNode) fn;
+         Set<FlatNode> exitset=faen.getExits();
+         //generate header
+         String methodname=md.getSymbol()+(atomicmethodcount++);
+         AtomicRecord ar=new AtomicRecord();
+         ar.name=methodname;
+         arset.add(ar);
+
+         atomicmethodmap.put(faen, ar);
+
+         //build data structure declaration
+         output.println("struct atomicprimitives_"+methodname+" {");
+
+         Set<FlatNode> recordset=delaycomp.livecode(lb);
+         Set<TempDescriptor> liveinto=delaycomp.liveinto(lb, faen, recordset);
+         Set<TempDescriptor> liveout=delaycomp.liveout(lb, faen);
+         Set<TempDescriptor> liveoutvirtualread=delaycomp.liveoutvirtualread(lb, faen);
+         ar.livein=liveinto;
+         ar.reallivein=new HashSet(liveinto);
+         ar.liveout=liveout;
+         ar.liveoutvirtualread=liveoutvirtualread;
+
+         for(Iterator<TempDescriptor> it=liveinto.iterator(); it.hasNext();) {
+           TempDescriptor tmp=it.next();
+           //remove the pointers
+           if (tmp.getType().isPtr()) {
+             it.remove();
+           } else {
+             //let's print it here
+             output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+";");
+           }
+         }
+         for(Iterator<TempDescriptor> it=liveout.iterator(); it.hasNext();) {
+           TempDescriptor tmp=it.next();
+           //remove the pointers
+           if (tmp.getType().isPtr()) {
+             it.remove();
+           } else if (!liveinto.contains(tmp)) {
+             //let's print it here
+             output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+";");
+           }
+         }
+         output.println("};");
+
+         //print out method name
+         output.println("void "+methodname+"(struct "+ cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix+", struct "+ cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals *"+localsprefix+", struct atomicprimitives_"+methodname+" * primitives) {");
+         //build code for commit method
+         
+         //first define local primitives
+         Set<TempDescriptor> alltemps=delaycomp.alltemps(lb, faen, recordset);
+         for(Iterator<TempDescriptor> tmpit=alltemps.iterator();tmpit.hasNext();) {
+           TempDescriptor tmp=tmpit.next();
+           if (!tmp.getType().isPtr()) {
+             if (liveinto.contains(tmp)||liveoutvirtualread.contains(tmp)) {
+               //read from live into set
+               output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+"=primitives->"+tmp.getSafeSymbol()+";");
+             } else {
+               //just define
+               output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+";");
+             }
+           }
+         }
+         //turn off write barrier generation
+         wb.turnoff();
+         state.SINGLETM=false;
+         generateCode(faen, fm, lb, exitset, output, false);
+         state.SINGLETM=true;
+         //turn on write barrier generation
+         wb.turnon();
+         output.println("}\n\n");
+       }
+      }
+    }
+    //redefine these back to normal
+
+    localsprefixaddr="&"+localsprefix;
+    localsprefixderef=localsprefix+".";
+
     generateHeader(fm, lb, md!=null ? md : task,output);
     TempObject objecttemp=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
 
-    if (GENERATEPRECISEGC) {
+    if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) {
+      for(Iterator<AtomicRecord> arit=arset.iterator();arit.hasNext();) {
+       AtomicRecord ar=arit.next();
+       output.println("struct atomicprimitives_"+ar.name+" primitives_"+ar.name+";");
+      }
+    }
+
+    if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
       if (md!=null&&(state.DSM||state.SINGLETM))
        output.print("   struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
       else if (md!=null&&!(state.DSM||state.SINGLETM))
@@ -1449,129 +1657,632 @@ 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...*/
 
-    if ((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC) {
-      if (state.DSM&&lb.isAtomic())
-       output.println("if (needtocollect) checkcollect2(&"+localsprefix+");");
-      else
-      output.println("if (needtocollect) checkcollect(&"+localsprefix+");");
+    if (((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC) 
+        || this.state.MULTICOREGC) {
+      //Don't bother if we aren't in recursive methods...The loops case will catch it
+      if (callgraph.getAllMethods(md).contains(md)) {
+       if (state.DSM&&lb.isAtomic())
+         output.println("if (needtocollect) checkcollect2("+localsprefixaddr+");");
+       else if (this.state.MULTICOREGC) {
+      output.println("if(gcflag) gc("+localsprefixaddr+");");
+    } else
+         output.println("if (needtocollect) checkcollect("+localsprefixaddr+");");
+      }
     }
 
-    generateCode( fm.getNext(0), fm, lb, null, output );
+    generateCode(fm.getNext(0), fm, lb, null, output, true);
 
     output.println("}\n\n");
   }
 
 
-  protected void generateMethodSESE( FlatSESEEnterNode fsen,
-                                    FlatMethod fm, 
-                                    LocalityBinding lb,
-                                    PrintWriter output ) {
-
-    //output.println( "void _SESE"+fsen.getPrettyIdentifier()+
-      //" {\n" );
-    //generateCode( fsen.getNext(0), fm, lb, fsen.getFlatExit(), output );
-    //output.println( "}\n\n" );
+  protected void initializeSESE( FlatSESEEnterNode fsen ) {
 
-    /*
-    output.println("struct sese"+faen.getPrettyIdentifier()+"in {");
-    Iterator<TempDescriptor> itr = faen.getInVarSet().iterator();
+    FlatMethod       fm = fsen.getfmEnclosing();
+    MethodDescriptor md = fm.getMethod();
+    ClassDescriptor  cn = md.getClassDesc();
+    
+        
+    // Creates bogus method descriptor to index into tables
+    Modifiers modBogus = new Modifiers();
+    MethodDescriptor mdBogus = 
+      new MethodDescriptor( modBogus, 
+                           new TypeDescriptor( TypeDescriptor.VOID ), 
+                           "sese_"+fsen.getPrettyIdentifier()+fsen.getIdentifier()
+                           );
+    
+    mdBogus.setClassDesc( fsen.getcdEnclosing() );
+    FlatMethod fmBogus = new FlatMethod( mdBogus, null );
+    fsen.setfmBogus( fmBogus );
+    fsen.setmdBogus( mdBogus );
+
+    Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
+    inSetAndOutSet.addAll( fsen.getInVarSet() );
+    inSetAndOutSet.addAll( fsen.getOutVarSet() );
+
+    // Build paramsobj for bogus method descriptor
+    ParamsObject objectparams = new ParamsObject( mdBogus, tag++ );
+    paramstable.put( mdBogus, objectparams );
+    
+    Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
     while( itr.hasNext() ) {
-      TempDescriptor td = itr.next();
-      output.println("  "+td+";");
+      TempDescriptor temp = itr.next();
+      TypeDescriptor type = temp.getType();
+      if( type.isPtr() ) {
+       objectparams.addPtr( temp );
+      } else {
+       objectparams.addPrim( temp );
+      }
     }
-    output.println("}");
+        
+    // Build normal temp object for bogus method descriptor
+    TempObject objecttemps = new TempObject( objectparams, mdBogus, tag++ );
+    tempstable.put( mdBogus, objecttemps );
+    
+    for(Iterator nodeit=fsen.getNodeSet().iterator(); nodeit.hasNext();) {
+      FlatNode fn=(FlatNode)nodeit.next();
+      TempDescriptor[] writes=fn.writesTemps();
+      for(int i=0; i<writes.length; i++) {
+       TempDescriptor temp=writes[i];
+       TypeDescriptor type=temp.getType();
+       if (type.isPtr()&&GENERATEPRECISEGC) {
+         objecttemps.addPtr(temp);
+       } else {
+         objecttemps.addPrim(temp);
+       }
+      }
+    }
+  }
+
+  protected void generateMethodSESE(FlatSESEEnterNode fsen,
+                                    LocalityBinding lb,
+                                    PrintWriter outputStructs,
+                                    PrintWriter outputMethHead,
+                                    PrintWriter outputMethods
+                                    ) {
 
-    output.println("struct sese"+faen.getPrettyIdentifier()+"out {");
-    itr = faen.getOutVarSet().iterator();
+    ParamsObject objectparams = (ParamsObject) paramstable.get( fsen.getmdBogus() );
+                
+    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()+" {");
+    
+    // data common to any SESE, and it must be placed first so
+    // a module that doesn't know what kind of SESE record this
+    // is can cast the pointer to a common struct
+    outputStructs.println("  SESEcommon common;");
+
+    // then garbage list stuff
+    outputStructs.println("  INTPTR size;");
+    outputStructs.println("  void * next;");
+
+    // in-set source tracking
+    // in-vars that are READY come from parent, don't need anything
+    // stuff STATIC needs a custom SESE pointer for each age pair
+    Iterator<SESEandAgePair> itrStaticInVarSrcs = fsen.getStaticInVarSrcs().iterator();
+    while( itrStaticInVarSrcs.hasNext() ) {
+      SESEandAgePair srcPair = itrStaticInVarSrcs.next();
+      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 td = itr.next();
-      output.println("  "+td+";");
+      TempDescriptor temp = itr.next();
+      TypeDescriptor type = temp.getType();
+      if( !type.isPtr() ) {
+       inSetAndOutSetPrims.add( temp );
+      }
     }
-    output.println("}");
-    */
 
+    Iterator<TempDescriptor> itrPrims = inSetAndOutSetPrims.iterator();
+    while( itrPrims.hasNext() ) {
+      TempDescriptor temp = itrPrims.next();
+      TypeDescriptor type = temp.getType();
+      outputStructs.println("  "+temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol()+";");
+    }
+
+    for(int i=0; i<objectparams.numPointers(); i++) {
+      TempDescriptor temp=objectparams.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, 
+                           fsen.getFlatExit(), 
+                           outputMethods );
   }
 
+  private void generateFlatMethodSESE(FlatMethod fm, 
+                                      ClassDescriptor cn, 
+                                      FlatSESEEnterNode fsen, 
+                                      FlatSESEExitNode  seseExit, 
+                                      PrintWriter output
+                                      ) {
+
+    MethodDescriptor md=fm.getMethod();
 
-  protected void generateCode( FlatNode first,
-                              FlatMethod fm, 
-                              LocalityBinding lb,
-                              FlatSESEExitNode stop,
-                              PrintWriter output ) {
+    output.print("void ");
+    output.print(fsen.getSESEmethodName()+"(");
+    output.print(fsen.getSESErecordName()+"* "+paramsprefix);
+    output.println("){\n");
 
-    /* Assign labels to FlatNode's if necessary.*/
-    Hashtable<FlatNode, Integer> nodetolabel=assignLabels(first);
+    TempObject objecttemp=(TempObject) tempstable.get(md);
+
+    if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+      output.print("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
+      output.print(objecttemp.numPointers()+",");
+      output.print("(void*) &("+paramsprefix+"->size)");
+      for(int j=0; j<objecttemp.numPointers(); j++)
+       output.print(", NULL");
+      output.println("};");
+    }
+
+    output.println("   /* regular local primitives */");
+    for(int i=0; i<objecttemp.numPrimitives(); i++) {
+      TempDescriptor td=objecttemp.getPrimitive(i);
+      TypeDescriptor type=td.getType();
+      if (type.isNull())
+       output.println("   void * "+td.getSafeSymbol()+";");
+      else if (type.isClass()||type.isArray())
+       output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
+      else
+       output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
+    }
+
+
+    // 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();
+      TypeDescriptor type = temp.getType();
+      if( !type.isPtr() ) {
+       if( fsen.getReadyInVarSet().contains( temp ) ) {
+         output.println("   "+type+" "+temp+" = "+paramsprefix+"->"+temp+";");
+       } else {
+         output.println("   "+type+" "+temp+";");
+       }
+      }
+    }    
+
+    // 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;
+
+    // static vars are from a known SESE
+    tempItr = fsen.getStaticInVarSet().iterator();
+    while( tempItr.hasNext() ) {
+      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()+";");
+
+      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 {
+       typeStr = type.getSafeSymbol();
+      }
+      
+      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)) {
+      //Don't bother if we aren't in recursive methods...The loops case will catch it
+      if (callgraph.getAllMethods(md).contains(md)) {
+        if(this.state.MULTICOREGC) {
+          output.println("if(gcflag) gc("+localsprefixaddr+");");
+        } else {
+          output.println("if (needtocollect) checkcollect("+localsprefixaddr+");");
+        }
+      }
+    }    
+
+    // 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);
+    
+    output.println("}\n\n");
+  }
+
+
+  // when a new mlp thread is created for an issued SESE, it is started
+  // by running this method which blocks on a cond variable until
+  // it is allowed to transition to execute.  Then a case statement
+  // allows it to invoke the method with the proper SESE body, and after
+  // exiting the SESE method, executes proper SESE exit code before the
+  // thread can be destroyed
+  private void generateSESEinvocationMethod(PrintWriter outmethodheader,
+                                            PrintWriter outmethod
+                                            ) {
+
+    outmethodheader.println("void* invokeSESEmethod( void* seseRecord );");
+    outmethod.println(      "void* invokeSESEmethod( void* seseRecord ) {");
+    outmethod.println(      "  int status;");
+    outmethod.println(      "  char errmsg[128];");
+
+    // generate a case for each SESE class that can be invoked
+    outmethod.println(      "  switch( *((int*)seseRecord) ) {");
+    outmethod.println(      "    ");
+    for(Iterator<FlatSESEEnterNode> seseit=mlpa.getAllSESEs().iterator();seseit.hasNext();) {
+      FlatSESEEnterNode fsen = seseit.next();
+
+      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(    "");
+    }
+
+    // default case should never be taken, error out
+    outmethod.println(      "    default:");
+    outmethod.println(      "      printf(\"Error: unknown SESE class ID in invoke method.\\n\");");
+    outmethod.println(      "      exit(-30);");
+    outmethod.println(      "      break;");
+    outmethod.println(      "  }");
+    outmethod.println(      "  return NULL;");
+    outmethod.println(      "}\n\n");
+  }
+
+
+  protected void generateCode(FlatNode first,
+                              FlatMethod fm,
+                              LocalityBinding lb,
+                             Set<FlatNode> stopset,
+                              PrintWriter output, boolean firstpass) {
+
+    /* Assign labels to FlatNode's if necessary.*/
+    Hashtable<FlatNode, Integer> nodetolabel=assignLabels(first, stopset);
+
+    Set<FlatNode> storeset=null;
+    HashSet<FlatNode> genset=null;
+    Set<FlatNode> unionset=null;
+
+    if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) {
+      storeset=delaycomp.livecode(lb);
+      genset=new HashSet<FlatNode>();
+      if (firstpass) {
+       genset.addAll(delaycomp.getCannotDelay(lb));
+       genset.addAll(delaycomp.getOther(lb));
+      } else {
+       genset.addAll(delaycomp.getNotReady(lb));
+      }
+      unionset=new HashSet<FlatNode>();
+      unionset.addAll(storeset);
+      unionset.addAll(genset);
+    }
+    
     /* Do the actual code generation */
     FlatNode current_node=null;
     HashSet tovisit=new HashSet();
     HashSet visited=new HashSet();
-    tovisit.add(first);
+    if (!firstpass)
+      tovisit.add(first.getNext(0));
+    else
+      tovisit.add(first);
     while(current_node!=null||!tovisit.isEmpty()) {
       if (current_node==null) {
        current_node=(FlatNode)tovisit.iterator().next();
        tovisit.remove(current_node);
-      } else if (tovisit.contains(current_node)){
-         tovisit.remove(current_node);
+      } else if (tovisit.contains(current_node)) {
+       tovisit.remove(current_node);
       }
-      if(current_node==stop) { return; }
       visited.add(current_node);
-      if (nodetolabel.containsKey(current_node))
+      if (nodetolabel.containsKey(current_node)) {
        output.println("L"+nodetolabel.get(current_node)+":");
+      }
       if (state.INSTRUCTIONFAILURE) {
        if (state.THREAD||state.DSM||state.SINGLETM) {
          output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
        } else
          output.println("if ((--instructioncount)==0) injectinstructionfailure();");
       }
-      if (current_node.numNext()==0) {
+      if (current_node.numNext()==0||stopset!=null&&stopset.contains(current_node)) {
        output.print("   ");
-       generateFlatNode(fm, lb, current_node, output);
+       if (!state.DELAYCOMP||firstpass) {
+         generateFlatNode(fm, lb, current_node, output);
+       } else {
+         //store primitive variables in out set
+         AtomicRecord ar=atomicmethodmap.get((FlatAtomicEnterNode)first);
+         Set<TempDescriptor> liveout=ar.liveout;
+         for(Iterator<TempDescriptor> tmpit=liveout.iterator();tmpit.hasNext();) {
+           TempDescriptor tmp=tmpit.next();
+           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;
-         if( nonSESEpass ) {
-           setSESEtoGen.add(fsen);
-           fsen.setEnclosingFlatMeth(fm);
-         }
+         generateFlatNode(fm, lb, current_node, output);
          nextnode=fsen.getFlatExit().getNext(0);
+       } else if (state.DELAYCOMP) {
+         boolean specialprimitive=false;
+         //skip literals...no need to add extra overhead
+         if (storeset!=null&&storeset.contains(current_node)&&current_node.kind()==FKind.FlatLiteralNode) {
+           TypeDescriptor typedesc=((FlatLiteralNode)current_node).getType();
+           if (!typedesc.isClass()&&!typedesc.isArray()) {
+             specialprimitive=true;
+           }
+         }
+
+         if (genset==null||genset.contains(current_node)||specialprimitive)
+           generateFlatNode(fm, lb, current_node, output);
+         if (storeset!=null&&storeset.contains(current_node)&&!specialprimitive) {
+           TempDescriptor wrtmp=current_node.writesTemps()[0];
+           if (firstpass) {
+             //need to store value written by previous node
+             if (wrtmp.getType().isPtr()) {
+               //only lock the objects that may actually need locking
+               if (recorddc.getNeedTrans(lb, current_node)) {
+                 output.println("STOREPTR("+generateTemp(fm, wrtmp,lb)+");");
+               } else {
+                 output.println("STOREPTRNOLOCK("+generateTemp(fm, wrtmp,lb)+");");
+               }
+             } else {
+               output.println("STORE"+wrtmp.getType().getSafeDescriptor()+"("+generateTemp(fm, wrtmp, lb)+");");
+             }
+           } else {
+             //need to read value read by previous node
+             if (wrtmp.getType().isPtr()) {
+               output.println("RESTOREPTR("+generateTemp(fm, wrtmp,lb)+");");
+             } else {
+               output.println("RESTORE"+wrtmp.getType().getSafeDescriptor()+"("+generateTemp(fm, wrtmp, lb)+");");             
+             }
+           }
+         }
+         nextnode=current_node.getNext(0);
        } else {
          output.print("   ");
-         generateFlatNode(fm, lb, current_node, output);       
+         generateFlatNode(fm, lb, current_node, output);
          nextnode=current_node.getNext(0);
        }
        if (visited.contains(nextnode)) {
          output.println("goto L"+nodetolabel.get(nextnode)+";");
          current_node=null;
-       } else
+       } else 
          current_node=nextnode;
       } else if (current_node.numNext()==2) {
        /* Branch */
-       output.print("   ");
-       generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
-       if (!visited.contains(current_node.getNext(1)))
-         tovisit.add(current_node.getNext(1));
-       if (visited.contains(current_node.getNext(0))) {
-         output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
-         current_node=null;
-       } else
-         current_node=current_node.getNext(0);
+       if (state.DELAYCOMP) {
+         boolean computeside=false;
+         if (firstpass) {
+           //need to record which way it should go
+           if (genset==null||genset.contains(current_node)) {
+             if (storeset!=null&&storeset.contains(current_node)) {
+               //need to store which way branch goes
+               generateStoreFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
+             } else
+               generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
+           } else {
+             //which side to execute
+             computeside=true;
+           }
+         } else {
+           if (genset.contains(current_node)) {
+             generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);             
+           } else if (storeset.contains(current_node)) {
+             //need to do branch
+             output.println("RESTOREANDBRANCH(L"+nodetolabel.get(current_node.getNext(1))+");");
+           } else {
+             //which side to execute
+             computeside=true;
+           }
+         }
+         if (computeside) {
+           Set<FlatNode> leftset=DelayComputation.getNext(current_node, 0, unionset, lb,locality, true);
+           int branch=0;
+           if (leftset.size()==0)
+             branch=1;
+           if (visited.contains(current_node.getNext(branch))) {
+             //already visited -- build jump
+             output.println("goto L"+nodetolabel.get(current_node.getNext(branch))+";");
+             current_node=null;
+           } else {
+             current_node=current_node.getNext(branch);
+           }
+         } else {
+           if (!visited.contains(current_node.getNext(1)))
+             tovisit.add(current_node.getNext(1));
+           if (visited.contains(current_node.getNext(0))) {
+             output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
+             current_node=null;
+           } else 
+             current_node=current_node.getNext(0);
+         }
+       } else {
+         output.print("   ");  
+         generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
+         if (!visited.contains(current_node.getNext(1)))
+           tovisit.add(current_node.getNext(1));
+         if (visited.contains(current_node.getNext(0))) {
+           output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
+           current_node=null;
+         } else 
+           current_node=current_node.getNext(0);
+       }
       } else throw new Error();
     }
   }
 
-
   /** This method assigns labels to FlatNodes */
-
   protected Hashtable<FlatNode, Integer> assignLabels(FlatNode first) {
+    return assignLabels(first, null);
+  }
+
+  protected Hashtable<FlatNode, Integer> assignLabels(FlatNode first, Set<FlatNode> lastset) {
     HashSet tovisit=new HashSet();
     HashSet visited=new HashSet();
     int labelindex=0;
@@ -1585,8 +2296,17 @@ public class BuildCode {
       FlatNode fn=(FlatNode)tovisit.iterator().next();
       tovisit.remove(fn);
       visited.add(fn);
+
+
+      if(lastset!=null&&lastset.contains(fn)) {
+       // if last is not null and matches, don't go 
+       // any further for assigning labels
+       continue;
+      }
+
       for(int i=0; i<fn.numNext(); i++) {
        FlatNode nn=fn.getNext(i);
+
        if(i>0) {
          //1) Edge >1 of node
          nodetolabel.put(nn,new Integer(labelindex++));
@@ -1608,126 +2328,241 @@ public class BuildCode {
     MethodDescriptor md=fm.getMethod();
     TaskDescriptor task=fm.getTask();
     TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
+
     if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
       //System.out.println("generateTemp returns " + td.getSafeSymbol());
       return td.getSafeSymbol();
     }
 
     if (objecttemps.isLocalPtr(td)) {
-      return localsprefix+"."+td.getSafeSymbol();
+      return localsprefixderef+td.getSafeSymbol();
     }
 
     if (objecttemps.isParamPtr(td)) {
       return paramsprefix+"->"+td.getSafeSymbol();
     }
+
     throw new Error();
   }
 
   protected void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) {
+
+    // insert pre-node actions from the code plan
+    if( state.MLP ) {
+      
+      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
+       Iterator<VariableSourceToken> vstItr = cp.getStallTokens().iterator();
+       while( vstItr.hasNext() ) {
+         VariableSourceToken vst = vstItr.next();
+
+         SESEandAgePair p = new SESEandAgePair( vst.getSESE(), vst.getAge() );
+
+         output.println("   {");
+         output.println("     SESEcommon* common = (SESEcommon*) "+p+";");
+
+         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 = ("+
+                                p.getSESE().getSESErecordName()+"*) "+p+";");
+         
+         Iterator<TempDescriptor> tdItr = cp.getCopySet( vst ).iterator();
+         while( tdItr.hasNext() ) {
+           TempDescriptor td = tdItr.next();
+           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;");
+       }
+      }     
+    }
+
     switch(fn.kind()) {
     case FKind.FlatAtomicEnterNode:
       generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output);
-      return;
+      break;
 
     case FKind.FlatAtomicExitNode:
       generateFlatAtomicExitNode(fm, lb, (FlatAtomicExitNode) fn, output);
-      return;
+      break;
 
     case FKind.FlatInstanceOfNode:
       generateFlatInstanceOfNode(fm, lb, (FlatInstanceOfNode)fn, output);
-      return;
+      break;
 
     case FKind.FlatSESEEnterNode:
-      assert !state.MLP;
-      return;
+      generateFlatSESEEnterNode(fm, lb, (FlatSESEEnterNode)fn, output);
+      break;
 
     case FKind.FlatSESEExitNode:
-      assert !state.MLP;
-      return;
+      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);
-      return;
+      break;
 
     case FKind.FlatTagDeclaration:
       generateFlatTagDeclaration(fm, lb, (FlatTagDeclaration) fn,output);
-      return;
+      break;
 
     case FKind.FlatCall:
       generateFlatCall(fm, lb, (FlatCall) fn,output);
-      return;
+      break;
 
     case FKind.FlatFieldNode:
       generateFlatFieldNode(fm, lb, (FlatFieldNode) fn,output);
-      return;
+      break;
 
     case FKind.FlatElementNode:
       generateFlatElementNode(fm, lb, (FlatElementNode) fn,output);
-      return;
+      break;
 
     case FKind.FlatSetElementNode:
       generateFlatSetElementNode(fm, lb, (FlatSetElementNode) fn,output);
-      return;
+      break;
 
     case FKind.FlatSetFieldNode:
       generateFlatSetFieldNode(fm, lb, (FlatSetFieldNode) fn,output);
-      return;
+      break;
 
     case FKind.FlatNew:
       generateFlatNew(fm, lb, (FlatNew) fn,output);
-      return;
+      break;
 
     case FKind.FlatOpNode:
       generateFlatOpNode(fm, lb, (FlatOpNode) fn,output);
-      return;
+      break;
 
     case FKind.FlatCastNode:
       generateFlatCastNode(fm, lb, (FlatCastNode) fn,output);
-      return;
+      break;
 
     case FKind.FlatLiteralNode:
       generateFlatLiteralNode(fm, lb, (FlatLiteralNode) fn,output);
-      return;
+      break;
 
     case FKind.FlatReturnNode:
       generateFlatReturnNode(fm, lb, (FlatReturnNode) fn,output);
-      return;
+      break;
 
     case FKind.FlatNop:
       output.println("/* nop */");
-      return;
+      break;
 
     case FKind.FlatExit:
       output.println("/* exit */");
-      return;
+      break;
 
     case FKind.FlatBackEdge:
-      if ((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC) {
+      if (((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC)
+          || (this.state.MULTICOREGC)) {
        if(state.DSM&&locality.getAtomic(lb).get(fn).intValue()>0) {
-         output.println("if (needtocollect) checkcollect2(&"+localsprefix+");");
-       } else
-       output.println("if (needtocollect) checkcollect(&"+localsprefix+");");
+         output.println("if (needtocollect) checkcollect2("+localsprefixaddr+");");
+       } else if(this.state.MULTICOREGC) {
+      output.println("if (gcflag) gc("+localsprefixaddr+");");
+    } else
+         output.println("if (needtocollect) checkcollect("+localsprefixaddr+");");
       } else
        output.println("/* nop */");
-      return;
+      break;
 
     case FKind.FlatCheckNode:
       generateFlatCheckNode(fm, lb, (FlatCheckNode) fn, output);
-      return;
+      break;
 
     case FKind.FlatFlagActionNode:
       generateFlatFlagActionNode(fm, lb, (FlatFlagActionNode) fn, output);
-      return;
+      break;
 
     case FKind.FlatPrefetchNode:
       generateFlatPrefetchNode(fm,lb, (FlatPrefetchNode) fn, output);
-      return;
+      break;
 
     case FKind.FlatOffsetNode:
       generateFlatOffsetNode(fm, lb, (FlatOffsetNode)fn, output);
-      return;
+      break;
+
+    default:
+      throw new Error();
     }
-    throw new Error();
+
+    // insert post-node actions from the code-plan    
+    if( state.MLP ) {
+      CodePlan cp = mlpa.getCodePlan( fn );
+
+      if( cp != null ) {     
+      }
+    }    
   }
 
   public void generateFlatOffsetNode(FlatMethod fm, LocalityBinding lb, FlatOffsetNode fofn, PrintWriter output) {
@@ -1859,7 +2694,7 @@ public class BuildCode {
        for(int j=0; j<id.tddesc.size(); j++) {
          indexcheck+=generateTemp(fm, id.getTempDescAt(j), lb)+"+";
        }
-       indexcheck+=id.offset+")>=0)&&(tmpindex<((struct ArrayObject *)prefptr)->___length___)";
+       indexcheck+=id.offset+")>=0)&(tmpindex<((struct ArrayObject *)prefptr)->___length___)";
 
        if (!teststr.equals(""))
          teststr+="&&";
@@ -1909,17 +2744,24 @@ public class BuildCode {
       return;
     /* Have to generate flat globalconv */
     if (fgcn.getMakePtr()) {
-       if (state.DSM) {
-           output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", (unsigned int) "+generateTemp(fm, fgcn.getSrc(),lb)+");");
-       } else {
-           output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+");");
+      if (state.DSM) {
+       output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", (unsigned int) "+generateTemp(fm, fgcn.getSrc(),lb)+");");
+      } else {
+       if ((dc==null)||!state.READSET&&dc.getNeedTrans(lb, fgcn)||state.READSET&&dc.getNeedWriteTrans(lb, fgcn)) {
+         //need to do translation
+         output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+", (void *)("+localsprefixaddr+"));");
+       } else if (state.READSET&&dc.getNeedTrans(lb, fgcn)) {
+         output.println("TRANSREADRD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+");");
        }
+      }
     } else {
       /* Need to convert to OID */
-      if (fgcn.doConvert()) {
-       output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
-      } else {
-       output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=NULL;");
+      if ((dc==null)||dc.getNeedSrcTrans(lb,fgcn)) {
+       if (fgcn.doConvert()||(delaycomp!=null&&atomicmethodmap.get(fgcn.getAtomicEnter()).reallivein.contains(fgcn.getSrc()))) {
+         output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
+       } else {
+         output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=NULL;");
+       }
       }
     }
   }
@@ -1931,7 +2773,7 @@ public class BuildCode {
     } else {
       type=fion.getType().getClassDesc().getId();
     }
-    
+
     if (fion.getType().getSymbol().equals(TypeUtil.ObjectClass))
       output.println(generateTemp(fm, fion.getDst(), lb)+"=1;");
     else
@@ -1940,14 +2782,37 @@ public class BuildCode {
 
   public void generateFlatAtomicEnterNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) {
     /* Check to see if we need to generate code for this atomic */
-    if (locality==null||locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
+    if (locality==null) {
+      output.println("pthread_mutex_lock(&atomiclock);");
+      return;
+    }
+
+    if (locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
       return;
+
+
+    if (state.DELAYCOMP) {
+      AtomicRecord ar=atomicmethodmap.get(faen);
+      //copy in
+      for(Iterator<TempDescriptor> tmpit=ar.livein.iterator();tmpit.hasNext();) {
+       TempDescriptor tmp=tmpit.next();
+       output.println("primitives_"+ar.name+"."+tmp.getSafeSymbol()+"="+tmp.getSafeSymbol()+";");
+      }
+
+      //copy outs that depend on path
+      for(Iterator<TempDescriptor> tmpit=ar.liveoutvirtualread.iterator();tmpit.hasNext();) {
+       TempDescriptor tmp=tmpit.next();
+       if (!ar.livein.contains(tmp))
+         output.println("primitives_"+ar.name+"."+tmp.getSafeSymbol()+"="+tmp.getSafeSymbol()+";");
+      }
+    }
+
     /* Backup the temps. */
     for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator(); tmpit.hasNext();) {
       TempDescriptor tmp=tmpit.next();
       output.println(generateTemp(fm, backuptable.get(lb).get(tmp),lb)+"="+generateTemp(fm,tmp,lb)+";");
     }
-    
+
     output.println("goto transstart"+faen.getIdentifier()+";");
 
     /******* Print code to retry aborted transaction *******/
@@ -1962,7 +2827,7 @@ public class BuildCode {
     if (state.DSM) {
       /********* Need to revert local object store ********/
       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
-      
+
       output.println("while ("+revertptr+") {");
       output.println("struct ___Object___ * tmpptr;");
       output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
@@ -1974,7 +2839,7 @@ public class BuildCode {
 
     output.println("transstart"+faen.getIdentifier()+":");
     output.println("transStart();");
-    
+
     if (state.ABORTREADERS) {
       output.println("if (_setjmp(aborttrans)) {");
       output.println("  goto transretry"+faen.getIdentifier()+"; }");
@@ -1983,7 +2848,11 @@ public class BuildCode {
 
   public void generateFlatAtomicExitNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicExitNode faen, PrintWriter output) {
     /* Check to see if we need to generate code for this atomic */
-    if (locality==null||locality.getAtomic(lb).get(faen).intValue()>0)
+    if (locality==null) {
+      output.println("pthread_mutex_unlock(&atomiclock);");
+      return;
+    }
+    if (locality.getAtomic(lb).get(faen).intValue()>0)
       return;
     //store the revert list before we lose the transaction object
     String revertptr=null;
@@ -1991,12 +2860,18 @@ public class BuildCode {
       revertptr=generateTemp(fm, reverttable.get(lb),lb);
       output.println(revertptr+"=revertlist;");
     }
-    output.println("if (transCommit()) {");
+    if (state.DELAYCOMP) {
+      AtomicRecord ar=atomicmethodmap.get(faen.getAtomicEnter());
+
+      //do call
+      output.println("if (transCommit((void (*)(void *, void *, void *))&"+ar.name+", &primitives_"+ar.name+", &"+localsprefix+", "+paramsprefix+")) {");
+    } else
+      output.println("if (transCommit()) {");
     /* Transaction aborts if it returns true */
     output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
     if (state.DSM) {
       output.println("} else {");
-    /* Need to commit local object store */
+      /* Need to commit local object store */
       output.println("while ("+revertptr+") {");
       output.println("struct ___Object___ * tmpptr;");
       output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
@@ -2005,21 +2880,346 @@ public class BuildCode {
       output.println("}");
     }
     output.println("}");
+    if (state.DELAYCOMP) {
+      //copy out
+      AtomicRecord ar=atomicmethodmap.get(faen.getAtomicEnter());
+      output.println("else {");
+      for(Iterator<TempDescriptor> tmpit=ar.liveout.iterator();tmpit.hasNext();) {
+       TempDescriptor tmp=tmpit.next();
+       output.println(tmp.getSafeSymbol()+"=primitives_"+ar.name+"."+tmp.getSafeSymbol()+";");
+      }
+      output.println("}");
+    }
   }
 
+  public void generateFlatSESEEnterNode( FlatMethod fm,  
+                                        LocalityBinding lb, 
+                                        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 ) {
+      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) );");
+
+    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();
+
+      // 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 {
+       output.println("     seseToIssue->"+temp+" = "+
+                      generateTemp( fsen.getfmEnclosing(), temp, null )+";");
+      }
+    }
+
+    // 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() ) {
+       SESEandAgePair srcPair = staticSrcsItr.next();
+       output.println("     {");
+       output.println("       SESEcommon* src = (SESEcommon*)"+srcPair+";");
+       output.println("       pthread_mutex_lock( &(src->lock) );");
+       output.println("       if( !isEmpty( src->forwardList ) &&");
+       output.println("           seseToIssue == peekItem( src->forwardList ) ) {");
+       output.println("         printf( \"This shouldnt already be here\\n\");");
+       output.println("         exit( -1 );");
+       output.println("       }");
+       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("     }");
+
+       // whether or not it is an outstanding dependency, make sure
+       // 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      
+      SESEandAgePair p = new SESEandAgePair( fsen, 0 );
+      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
+    output.println("     if( seseToIssue->common.unresolvedDependencies == 0 ) {");
+    output.println("       workScheduleSubmit( (void*)seseToIssue );");
+    output.println("     }");
+
+    // release this SESE for siblings to update its dependencies or,
+    // eventually, for it to mark itself finished
+    output.println("     pthread_mutex_unlock( &(seseToIssue->common.lock) );");
+    output.println("   }");
 
-  public void generateSESE(FlatMethod fm, LocalityBinding lb, FlatSESEEnterNode faen, PrintWriter output) {
-    
   }
 
+  public void generateFlatSESEExitNode( FlatMethod fm,  
+                                       LocalityBinding lb, 
+                                       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 ) {
+      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 */");
 
-  public void generateFlatSESEEnterNode(FlatMethod fm,  LocalityBinding lb, FlatSESEEnterNode faen, PrintWriter output) {
+    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() ) {
+      TempDescriptor temp = itr.next();      
+      output.println("   "+paramsprefix+
+                    "->"+temp.getSafeSymbol()+
+                    " = "+temp.getSafeSymbol()+";" );
+    }    
+    
+    // mark yourself done, your SESE data is now read-only
+    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
+    output.println("   while( !isEmpty( "+com+".forwardList ) ) {");
+    output.println("     SESEcommon* consumer = (SESEcommon*) getItem( "+com+".forwardList );");
+    output.println("     pthread_mutex_lock( &(consumer->lock) );");
+    output.println("     --(consumer->unresolvedDependencies);");
+    output.println("     if( consumer->unresolvedDependencies == 0 ) {");
+    output.println("       workScheduleSubmit( (void*)consumer );");
+    output.println("     }");
+    output.println("     pthread_mutex_unlock( &(consumer->lock) );");
+    output.println("   }");
+    
+    // if parent is stalling on you, let them know you're done
+    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 generateFlatSESEExitNode(FlatMethod fm,  LocalityBinding lb, FlatSESEExitNode faen, PrintWriter output) {
-    //output.println("mlpNotifyExit( (struct SESE*)0 );");
+  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) {
       String specname=fcn.getSpec();
@@ -2045,19 +3245,24 @@ 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(state.DSM||state.SINGLETM ? locality.getBinding(lb, fc) : md);
+    ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? locality.getBinding(lb, fc) : md);
     ClassDescriptor cn=md.getClassDesc();
     output.println("{");
-    if (GENERATEPRECISEGC) {
-      if (state.DSM||state.SINGLETM) {
+    if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+      if (lb!=null) {
        LocalityBinding fclb=locality.getBinding(lb, fc);
        output.print("       struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
       } else
        output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
 
       output.print(objectparams.numPointers());
-      output.print(", & "+localsprefix);
+      output.print(", "+localsprefixaddr);
       if (md.getThis()!=null) {
        output.print(", ");
        output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis(),lb));
@@ -2092,7 +3297,7 @@ public class BuildCode {
     /* Do we need to do virtual dispatch? */
     if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
       //no
-      if (state.DSM||state.SINGLETM) {
+      if (lb!=null) {
        LocalityBinding fclb=locality.getBinding(lb, fc);
        output.print(cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
       } else {
@@ -2108,8 +3313,8 @@ public class BuildCode {
       output.print("(*)(");
 
       boolean printcomma=false;
-      if (GENERATEPRECISEGC) {
-       if (state.DSM||state.SINGLETM) {
+      if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+       if (lb!=null) {
          LocalityBinding fclb=locality.getBinding(lb, fc);
          output.print("struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
        } else
@@ -2129,7 +3334,7 @@ public class BuildCode {
       }
 
 
-      if (state.DSM||state.SINGLETM) {
+      if (lb!=null) {
        LocalityBinding fclb=locality.getBinding(lb, fc);
        output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getLocalityNumber(fclb)+"])");
       } else
@@ -2138,12 +3343,12 @@ public class BuildCode {
 
     output.print("(");
     boolean needcomma=false;
-    if (GENERATEPRECISEGC) {
+    if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
       output.print("&__parameterlist__");
       needcomma=true;
     }
 
-    if (!GENERATEPRECISEGC) {
+    if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
       if (fc.getThis()!=null) {
        TypeDescriptor ptd=md.getThis().getType();
        if (needcomma)
@@ -2199,9 +3404,13 @@ public class BuildCode {
 
       output.println(dst+"="+ src +"->"+field+ ";");
       if (ffn.getField().getType().isPtr()&&locality.getAtomic(lb).get(ffn).intValue()>0&&
-         ((dc==null)||dc.getNeedTrans(lb, ffn))&&
-         locality.getNodePreTempInfo(lb, ffn).get(ffn.getSrc())!=LocalityAnalysis.SCRATCH) {
-       output.println("TRANSREAD("+dst+", "+dst+");");
+          locality.getNodePreTempInfo(lb, ffn).get(ffn.getSrc())!=LocalityAnalysis.SCRATCH) {
+       if ((dc==null)||(!state.READSET&&dc.getNeedTrans(lb, ffn))||
+           (state.READSET&&dc.getNeedWriteTrans(lb, ffn))) {
+         output.println("TRANSREAD("+dst+", "+dst+", (void *) (" + localsprefixaddr + "));");
+       } else if (state.READSET&&dc.getNeedTrans(lb, ffn)) {
+         output.println("TRANSREADRD("+dst+", "+dst+");");
+       }
       }
     } else if (state.DSM) {
       Integer status=locality.getNodePreTempInfo(lb,ffn).get(ffn.getSrc());
@@ -2266,17 +3475,18 @@ public class BuildCode {
       boolean srcptr=fsfn.getSrc().getType().isPtr();
       String src=generateTemp(fm,fsfn.getSrc(),lb);
       String dst=generateTemp(fm,fsfn.getDst(),lb);
+      output.println("//"+srcptr+" "+fsfn.getSrc().getType().isNull());
       if (srcptr&&!fsfn.getSrc().getType().isNull()) {
        output.println("{");
        if ((dc==null)||dc.getNeedSrcTrans(lb, fsfn)&&
-         locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getSrc())!=LocalityAnalysis.SCRATCH) {
+           locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getSrc())!=LocalityAnalysis.SCRATCH) {
          output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
        } else {
          output.println("INTPTR srcoid=(INTPTR)"+src+";");
        }
       }
       if (wb.needBarrier(fsfn)&&
-         locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getDst())!=LocalityAnalysis.SCRATCH) {
+          locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getDst())!=LocalityAnalysis.SCRATCH) {
        output.println("*((unsigned int *)&("+dst+"->___objstatus___))|=DIRTY;");
       }
       if (srcptr&!fsfn.getSrc().getType().isNull()) {
@@ -2311,8 +3521,8 @@ public class BuildCode {
        /* Link object into list */
        String revertptr=generateTemp(fm, reverttable.get(lb),lb);
        output.println(revertptr+"=revertlist;");
-       if (GENERATEPRECISEGC)
-         output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
+       if (GENERATEPRECISEGC || this.state.MULTICOREGC)
+         output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
        else
          output.println("COPY_OBJ("+dst+");");
        output.println(dst+"->"+nextobjstr+"="+revertptr+";");
@@ -2339,8 +3549,8 @@ public class BuildCode {
        String dst=generateTemp(fm, fsfn.getDst(),lb);
        output.println("if(!"+dst+"->"+localcopystr+") {");
        /* Link object into list */
-       if (GENERATEPRECISEGC)
-         output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
+       if (GENERATEPRECISEGC || this.state.MULTICOREGC)
+         output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
        else
          output.println("COPY_OBJ("+dst+");");
        output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
@@ -2361,7 +3571,7 @@ public class BuildCode {
       type=elementtype.getSafeSymbol()+" ";
 
     if (this.state.ARRAYBOUNDARYCHECK && fen.needsBoundsCheck()) {
-      output.println("if ("+generateTemp(fm, fen.getIndex(),lb)+"< 0 || "+generateTemp(fm, fen.getIndex(),lb)+" >= "+generateTemp(fm,fen.getSrc(),lb) + "->___length___)");
+      output.println("if ("+generateTemp(fm, fen.getIndex(),lb)+"< 0 | "+generateTemp(fm, fen.getIndex(),lb)+" >= "+generateTemp(fm,fen.getSrc(),lb) + "->___length___)");
       output.println("failedboundschk();");
     }
     if (state.SINGLETM) {
@@ -2370,9 +3580,12 @@ public class BuildCode {
       output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
 
       if (elementtype.isPtr()&&locality.getAtomic(lb).get(fen).intValue()>0&&
-         ((dc==null)||dc.getNeedTrans(lb, fen))&&
-         locality.getNodePreTempInfo(lb, fen).get(fen.getSrc())!=LocalityAnalysis.SCRATCH) {
-       output.println("TRANSREAD("+dst+", "+dst+");");
+          locality.getNodePreTempInfo(lb, fen).get(fen.getSrc())!=LocalityAnalysis.SCRATCH) {
+       if ((dc==null)||!state.READSET&&dc.getNeedTrans(lb, fen)||state.READSET&&dc.getNeedWriteTrans(lb, fen)) {
+         output.println("TRANSREAD("+dst+", "+dst+", (void *)(" + localsprefixaddr+"));");
+       } else if (state.READSET&&dc.getNeedTrans(lb, fen)) {
+         output.println("TRANSREADRD("+dst+", "+dst+");");
+       }
       }
     } else if (state.DSM) {
       Integer status=locality.getNodePreTempInfo(lb,fen).get(fen.getSrc());
@@ -2415,14 +3628,14 @@ public class BuildCode {
       type=elementtype.getSafeSymbol()+" ";
 
     if (this.state.ARRAYBOUNDARYCHECK && fsen.needsBoundsCheck()) {
-      output.println("if ("+generateTemp(fm, fsen.getIndex(),lb)+"< 0 || "+generateTemp(fm, fsen.getIndex(),lb)+" >= "+generateTemp(fm,fsen.getDst(),lb) + "->___length___)");
+      output.println("if ("+generateTemp(fm, fsen.getIndex(),lb)+"< 0 | "+generateTemp(fm, fsen.getIndex(),lb)+" >= "+generateTemp(fm,fsen.getDst(),lb) + "->___length___)");
       output.println("failedboundschk();");
     }
 
     if (state.SINGLETM && locality.getAtomic(lb).get(fsen).intValue()>0) {
       //Transaction set element case
       if (wb.needBarrier(fsen)&&
-           locality.getNodePreTempInfo(lb, fsen).get(fsen.getDst())!=LocalityAnalysis.SCRATCH) {
+          locality.getNodePreTempInfo(lb, fsen).get(fsen.getDst())!=LocalityAnalysis.SCRATCH) {
        output.println("*((unsigned int *)&("+generateTemp(fm,fsen.getDst(),lb)+"->___objstatus___))|=DIRTY;");
       }
       if (fsen.getSrc().getType().isPtr()&&!fsen.getSrc().getType().isNull()) {
@@ -2456,8 +3669,8 @@ public class BuildCode {
        /* Link object into list */
        String revertptr=generateTemp(fm, reverttable.get(lb),lb);
        output.println(revertptr+"=revertlist;");
-       if (GENERATEPRECISEGC)
-         output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
+       if ((GENERATEPRECISEGC) || this.state.MULTICOREGC)
+        output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
        else
          output.println("COPY_OBJ("+dst+");");
        output.println(dst+"->"+nextobjstr+"="+revertptr+";");
@@ -2478,8 +3691,8 @@ public class BuildCode {
        String dst=generateTemp(fm, fsen.getDst(),lb);
        output.println("if(!"+dst+"->"+localcopystr+") {");
        /* Link object into list */
-       if (GENERATEPRECISEGC)
-         output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
+       if (GENERATEPRECISEGC || this.state.MULTICOREGC)
+         output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
        else
          output.println("COPY_OBJ("+dst+");");
        output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
@@ -2501,34 +3714,34 @@ public class BuildCode {
        int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
        if (locality.getAtomic(lb).get(fn).intValue()>0) {
          //inside transaction
-         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarraytrans(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
+         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarraytrans("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
        } else {
          //outside transaction
-         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
+         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
        }
       } else {
        if (locality.getAtomic(lb).get(fn).intValue()>0) {
          //inside transaction
-         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newtrans(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
+         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newtrans("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");");
        } else {
          //outside transaction
-         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
+         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");");
        }
       }
     } else if (fn.getType().isArray()) {
       int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
       if (fn.isGlobal()&&(state.DSM||state.SINGLETM)) {
        output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarrayglobal("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
-      } else if (GENERATEPRECISEGC) {
-       output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
+      } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+       output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
       } else {
        output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
       }
     } else {
-      if (fn.isGlobal()) {
+      if (fn.isGlobal()&&(state.DSM||state.SINGLETM)) {
        output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newglobal("+fn.getType().getClassDesc().getId()+");");
-      } else if (GENERATEPRECISEGC) {
-       output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
+      } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+       output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");");
       } else {
        output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
       }
@@ -2549,8 +3762,8 @@ public class BuildCode {
   }
 
   private void generateFlatTagDeclaration(FlatMethod fm, LocalityBinding lb, FlatTagDeclaration fn, PrintWriter output) {
-    if (GENERATEPRECISEGC) {
-      output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");");
+    if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+      output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag("+localsprefixaddr+", "+state.getTagId(fn.getType())+");");
     } else {
       output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag("+state.getTagId(fn.getType())+");");
     }
@@ -2564,6 +3777,17 @@ public class BuildCode {
        else
          output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned int)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";");
 
+      } else if (dc!=null) {
+       output.print(generateTemp(fm, fon.getDest(),lb)+" = ");
+       if (dc.getNeedLeftSrcTrans(lb, fon))
+         output.print("("+generateTemp(fm, fon.getLeft(),lb)+"!=NULL?"+generateTemp(fm, fon.getLeft(),lb)+"->"+oidstr+":NULL)");
+       else
+         output.print(generateTemp(fm, fon.getLeft(),lb));
+       output.print(fon.getOp().toString());
+       if (dc.getNeedRightSrcTrans(lb, fon))
+         output.println("("+generateTemp(fm, fon.getRight(),lb)+"!=NULL?"+generateTemp(fm, fon.getRight(),lb)+"->"+oidstr+":NULL);");
+       else
+         output.println(generateTemp(fm,fon.getRight(),lb)+";");
       } else
        output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+fon.getOp().toString()+generateTemp(fm,fon.getRight(),lb)+";");
     } else if (fon.getOp().getOp()==Operation.ASSIGN)
@@ -2585,7 +3809,7 @@ public class BuildCode {
   private void generateFlatCastNode(FlatMethod fm, LocalityBinding lb, FlatCastNode fcn, PrintWriter output) {
     /* TODO: Do type check here */
     if (fcn.getType().isArray()) {
-      throw new Error();
+      output.println(generateTemp(fm,fcn.getDst(),lb)+"=(struct ArrayObject *)"+generateTemp(fm,fcn.getSrc(),lb)+";");
     } else if (fcn.getType().isClass())
       output.println(generateTemp(fm,fcn.getDst(),lb)+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc(),lb)+";");
     else
@@ -2596,13 +3820,13 @@ public class BuildCode {
     if (fln.getValue()==null)
       output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
     else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
-      if (GENERATEPRECISEGC) {
+      if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
        if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) {
          //Stash pointer in case of GC
          String revertptr=generateTemp(fm, reverttable.get(lb),lb);
          output.println(revertptr+"=revertlist;");
        }
-       output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
+       output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString("+localsprefixaddr+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
        if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) {
          //Stash pointer in case of GC
          String revertptr=generateTemp(fm, reverttable.get(lb),lb);
@@ -2636,14 +3860,21 @@ public class BuildCode {
     }
   }
 
+  protected void generateStoreFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
+    output.println("STOREANDBRANCH(!"+generateTemp(fm, fcb.getTest(),lb)+", "+label+");");
+  }
+
   protected void generateFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
     output.println("if (!"+generateTemp(fm, fcb.getTest(),lb)+") goto "+label+";");
   }
 
   /** This method generates header information for the method or
    * task referenced by the Descriptor des. */
-
   private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
+    generateHeader(fm, lb, des, output, false);
+  }
+
+  private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output, boolean addSESErecord) {
     /* Print header */
     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : des);
     MethodDescriptor md=null;
@@ -2670,9 +3901,9 @@ public class BuildCode {
        output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
     } else
       output.print(task.getSafeSymbol()+"(");
-
+    
     boolean printcomma=false;
-    if (GENERATEPRECISEGC) {
+    if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
       if (md!=null) {
        if (state.DSM||state.SINGLETM) {
          output.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
@@ -2696,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 */
@@ -2793,8 +4024,8 @@ public class BuildCode {
        Iterator tagit=tagtmps.iterator();
        while(tagit.hasNext()) {
          TempDescriptor tagtmp=(TempDescriptor)tagit.next();
-         if (GENERATEPRECISEGC)
-           output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
+         if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
+           output.println("tagclear("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
          else
            output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
        }
@@ -2805,8 +4036,8 @@ public class BuildCode {
        Iterator tagit=tagtmps.iterator();
        while(tagit.hasNext()) {
          TempDescriptor tagtmp=(TempDescriptor)tagit.next();
-         if (GENERATEPRECISEGC)
-           output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
+         if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
+           output.println("tagset("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
          else
            output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp, lb)+", "+generateTemp(fm,tagtmp, lb)+");");
        }