bug fixes
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
index a4679e761bfcb0145af2f26358052056c83deb5f..5518e0a06fd6355c5d4e6c9007350ed3600bdd04 100644 (file)
@@ -15,6 +15,7 @@ import Analysis.TaskStateAnalysis.SafetyAnalysis;
 import Analysis.TaskStateAnalysis.TaskIndex;
 import Analysis.Locality.LocalityAnalysis;
 import Analysis.Locality.LocalityBinding;
+import Analysis.Prefetch.*;
 
 public class BuildCode {
     State state;
@@ -32,6 +33,8 @@ public class BuildCode {
     public static boolean GENERATEPRECISEGC=false;
     public static String PREFIX="";
     public static String arraytype="ArrayObject";
+    public static int count = 0;
+    public static int flagcount = 0;
     Virtual virtualcalls;
     TypeUtil typeutil;
     private int maxtaskparams=0;
@@ -189,6 +192,9 @@ public class BuildCode {
     private void outputMainMethod(PrintWriter outmethod) {
        outmethod.println("int main(int argc, const char *argv[]) {");
        outmethod.println("  int i;");
+       if (state.THREAD||state.DSM) {
+           outmethod.println("initializethreads();");
+       }
        if (state.DSM) {
            outmethod.println("if (dstmStartup(argv[1])) {");
            if (GENERATEPRECISEGC) {
@@ -203,9 +209,6 @@ public class BuildCode {
                outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
            }
        }
-       if (state.THREAD) {
-           outmethod.println("initializethreads();");
-       }
        if (state.DSM) {
            outmethod.println("  for(i=2;i<argc;i++) {");
        } else 
@@ -249,12 +252,13 @@ public class BuildCode {
            outmethod.println("}");
        }
 
-       if (state.THREAD) {
+       if (state.THREAD||state.DSM) {
            outmethod.println("pthread_mutex_lock(&gclistlock);");
            outmethod.println("threadcount--;");
            outmethod.println("pthread_cond_signal(&gccond);");
            outmethod.println("pthread_mutex_unlock(&gclistlock);");
-           outmethod.println("pthread_exit(NULL);");
+           if (state.THREAD)
+               outmethod.println("pthread_exit(NULL);");
        }
 
 
@@ -304,7 +308,7 @@ public class BuildCode {
        if (state.DSM) {
            outmethod.println("#include \"localobjects.h\"");
        }
-       if (state.THREAD)
+       if (state.THREAD||state.DSM)
            outmethod.println("#include <thread.h>");
        if (state.main!=null) {
            outmethod.println("#include <string.h>");       
@@ -324,12 +328,12 @@ public class BuildCode {
        /* Generate code for methods */
        if (state.DSM) {
            for(Iterator<LocalityBinding> lbit=locality.getLocalityBindings().iterator();lbit.hasNext();) {
-               LocalityBinding lb=lbit.next();
-               MethodDescriptor md=lb.getMethod();
-               FlatMethod fm=state.getMethodFlat(md);
-               if (!md.getModifiers().isNative()) {
-                   generateFlatMethod(fm, lb, outmethod);
-               }
+               LocalityBinding lb=lbit.next();
+                MethodDescriptor md=lb.getMethod();
+               FlatMethod fm=state.getMethodFlat(md);
+               if (!md.getModifiers().isNative()) {
+                       generateFlatMethod(fm, lb, outmethod);
+               }
            }
        } else {
            Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
@@ -391,7 +395,7 @@ public class BuildCode {
     }
 
     private void outputClassDeclarations(PrintWriter outclassdefs) {
-       if (state.THREAD)
+       if (state.THREAD||state.DSM)
            outclassdefs.println("#include <pthread.h>");
        if(state.OPTIONAL)
            outclassdefs.println("#include \"optionalstruct.h\"");
@@ -1242,7 +1246,7 @@ public class BuildCode {
        /* Check to see if we need to do a GC if this is a
         * multi-threaded program...*/
 
-       if (state.THREAD&&GENERATEPRECISEGC) {
+       if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) {
            output.println("checkcollect(&"+localsprefix+");");
        }
        
@@ -1260,7 +1264,7 @@ public class BuildCode {
            if (nodetolabel.containsKey(current_node))
                output.println("L"+nodetolabel.get(current_node)+":");
            if (state.INSTRUCTIONFAILURE) {
-               if (state.THREAD) {
+               if (state.THREAD||state.DSM) {
                    output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
                }
                else
@@ -1295,7 +1299,6 @@ public class BuildCode {
                    current_node=current_node.getNext(0);
            } else throw new Error();
        }
-
        output.println("}\n\n");
     }
 
@@ -1412,46 +1415,358 @@ public class BuildCode {
        case FKind.FlatFlagActionNode:
            generateFlatFlagActionNode(fm, lb, (FlatFlagActionNode) fn, output);
            return;
+       case FKind.FlatPrefetchNode:
+           generateFlatPrefetchNode(fm,lb, (FlatPrefetchNode) fn, output);
+           return;
        }
        throw new Error();
+    }
+    public void generateFlatPrefetchNode(FlatMethod fm, LocalityBinding lb, FlatPrefetchNode fpn, PrintWriter output) {
+           short[] arrayfields = null;
+           Vector fieldoffset = new Vector();
+           Vector endoffset = new Vector();
+           Vector oids = new Vector();
+           short offsetcount = 0;
+           int tuplecount = 0;  //Keeps track of number of prefetch tuples that need to be generated
+           int i,j;
+          
+           if (state.PREFETCH) {
+                   output.println("/* prefetch */");
+                   output.println("; /* empty statement to avoid compiler error */");
+                   Iterator it = fpn.hspp.iterator();
+                   String oidlist = new String();
+                   while(it.hasNext()) {
+                           PrefetchPair pp = (PrefetchPair) it.next();
+                           Integer statusbase = locality.getNodePreTempInfo(lb,fpn).get(pp.base);
+                           /* Find prefetches that can generate oid */
+                           if(statusbase == LocalityAnalysis.GLOBAL) {
+                                   if(locality.getAtomic(lb).get(fpn).intValue()>0) { /* Inside transaction */
+                                           generateInsideTransCode(fm,lb,output, pp,oids,fieldoffset,endoffset,tuplecount);
+                                   } else {/* Outside Transaction */
+                                           generateOutsideTransCode(fm,lb,pp,oids,fieldoffset,endoffset,tuplecount);
+                                   }
+                                   tuplecount++;
+                           } else if(statusbase == LocalityAnalysis.LOCAL) {
+                                   generateLocalTransCode(fm,lb,pp,oids,fieldoffset,endoffset,tuplecount);
+                           } else {
+                                   continue;
+                           }
+                   }
+
+                   /*Create C code for numtuples */
+                   output.println("   int numtuples_" + count + " = " + tuplecount + ";");
+                   /*Create C code for oid array */
+                   output.print("   unsigned int oidarray_" + count + "[] = {");
+                   boolean needcomma=false;
+                   it = oids.iterator();
+                   while(it.hasNext()) {
+                           if (needcomma)
+                                   output.print(", ");
+                           output.print(it.next());
+                           needcomma=true;
+                   }
+                   output.println("};");
+                   /*Create C code for endoffset values */
+                   output.print("   unsigned short endoffsetarry_" + count +"[] = {");
+                   needcomma=false;
+                   it = endoffset.iterator();
+                   while(it.hasNext()) {
+                           if (needcomma)
+                                   output.print(", ");
+                           output.print(it.next());
+                           needcomma=true;
+                   }
+                   output.println("};");
+                   /*Create C code for Field Offset Values */
+                   output.print("   short fieldarry_" + count +"[] = {");
+                   needcomma=false;
+                   it = fieldoffset.iterator();
+                   while(it.hasNext()) {
+                           if (needcomma)
+                                   output.print(", ");
+                           output.print(it.next());
+                           needcomma=true;
+                   }
+                   output.println("};");
+                   /* make the prefetch call to Runtime */
+                   output.println("   prefetch((int) numtuples_"+count+ ", oidarray_"+count+ ", endoffsetarry_"+
+                                   count+", fieldarry_"+count+");");
+                   count++;
+           }   
+
+           /* Free heap memory */
+           fieldoffset = null;
+           endoffset = null;
+           oids = null;
+    }   
+
+    public void generateInsideTransCode(FlatMethod fm, LocalityBinding lb,PrintWriter output,PrefetchPair pp,Vector oids, Vector fieldoffset,Vector endoffset, int tuplecount){
+           int i,j;
+           short offsetcount = 0;
+
+           Object newdesc = pp.desc.get(0);
+           if(newdesc instanceof FieldDescriptor) {
+                   FieldDescriptor fd = (FieldDescriptor)newdesc;
+                   String oid = new String("(unsigned int) (" + 
+                                   generateTemp(fm, pp.base, lb) + " != NULL ? " + 
+                                   generateTemp(fm, pp.base, lb) + "->" + ((FieldDescriptor)fd).getSafeSymbol() +
+                                   " : NULL)");
+                   oids.add(oid);
+           } else {
+                   IndexDescriptor id = (IndexDescriptor)newdesc;
+                   String tstlbl = new String();
+                   for(i=0; i<id.tddesc.size(); i++) {
+                           tstlbl += generateTemp(fm, id.getTempDescAt(i), lb) + "+";
+                   }
+                   tstlbl += id.offset.toString();
+                   output.println("   int flag_" + flagcount + "=  0;");
+                   output.println("if ("+tstlbl+"< 0 || "+tstlbl+" >= "+
+                                   generateTemp(fm, pp.base, lb) + "->___length___) {");
+                   output.println("    flag_" + flagcount+"  = 1;");
+                   output.println("}");
 
+                   output.println("if (flag_"+flagcount+") {");
+                   output.println("}");
+
+                   TypeDescriptor elementtype = pp.base.getType().dereference();
+                   String type="";
+                   if (elementtype.isArray()||elementtype.isClass())
+                           type="void *";
+                   else 
+                           type=elementtype.getSafeSymbol()+" ";
+
+                   String oid = new String("(unsigned int) (" + generateTemp(fm, pp.base, lb) + " != NULL ? " + "((" + type + "*)(((char *) &("+ generateTemp(fm, pp.base, lb)+ "->___length___))+sizeof(int)))["+tstlbl+"] : 0)");
+                   oids.add(oid);
+           }
+
+           for(i = 1; i < pp.desc.size(); i++) {
+                   TypeDescriptor newtd;
+                   ClassDescriptor cd;
+                   String newfieldoffset;
+                   Object desc = pp.getDescAt(i);
+                   offsetcount++;
+                   if(desc instanceof FieldDescriptor) {
+                           Object prevdesc = pp.getDescAt(i-1);
+                           if(prevdesc instanceof IndexDescriptor){
+                                   if((i-1) == 0) {
+                                           newtd = pp.base.getType(); 
+                                           cd = newtd.getClassDesc();
+                                   } else {
+                                           //FIXME currently handles one dimensional arrays
+                                           newtd = ((FieldDescriptor)pp.getDescAt(i-2)).getType();
+                                           cd = newtd.getClassDesc();
+                                   }
+                                   newfieldoffset = new String("(unsigned int)(&(((struct "+ cd.getSafeSymbol() +" *)0)->"+ 
+                                                   ((FieldDescriptor)desc).getSafeSymbol()+ "))");
+                           } else {
+                                   newtd = ((FieldDescriptor)pp.getDescAt(i-1)).getType();
+                                   newfieldoffset = new String("(unsigned int)(&(((struct "+ newtd.getSafeSymbol()+" *)0)->"+ 
+                                           ((FieldDescriptor)desc).getSafeSymbol()+ "))");
+                           }
+                           fieldoffset.add(newfieldoffset);
+                   } else {
+                           String tstlbl = new String();
+                           for(j = 0; j < ((IndexDescriptor)desc).tddesc.size(); j++) {
+                                   tstlbl += generateTemp(fm, ((IndexDescriptor)desc).getTempDescAt(j), lb) + "+";
+                           }
+                           tstlbl += ((IndexDescriptor)desc).offset.toString();
+                           newfieldoffset = new String(tstlbl);
+                           fieldoffset.add(newfieldoffset);
+                   }
+           }
+           if(tuplecount > 0) {
+                   int tmp = (int) ((Short)(endoffset.get(tuplecount-1))).shortValue() + (int) offsetcount;
+                   short endoffsetval = (short) tmp;
+                   endoffset.add(endoffsetval);
+           }else {
+                   endoffset.add(offsetcount);
+           }
+           flagcount++;
     }
-    
+
+    public void generateOutsideTransCode(FlatMethod fm, LocalityBinding lb,PrefetchPair pp, Vector oids, Vector fieldoffset, Vector endoffset, int tuplecount) {
+           int i,j;
+           short offsetcount = 0;
+
+           String oid = new String(" (unsigned int) (" + generateTemp(fm, pp.base, lb)+ ")");
+           oids.add(oid);
+           for(i = 0; i < pp.desc.size(); i++) {
+                   TypeDescriptor newtd;
+                   ClassDescriptor cd;
+                   String newfieldoffset;
+                   Object desc = pp.getDescAt(i);
+                   offsetcount++;
+                   if(desc instanceof FieldDescriptor) {
+                           if(i == 0){
+                                   newtd = pp.base.getType(); 
+                                   newfieldoffset = new String("(unsigned int)(&(((struct "+ newtd.getSafeSymbol()+" *)0)->"+ 
+                                                   ((FieldDescriptor)desc).getSafeSymbol()+ "))");
+                           } else {
+                                   Object prevdesc = pp.getDescAt(i-1);
+                                   if(prevdesc instanceof IndexDescriptor){
+                                           if((i-1) == 0) {
+                                                   newtd = pp.base.getType(); 
+                                                   cd = newtd.getClassDesc();
+                                           } else {
+                                                   //FIXME currently handles one dimensional arrays
+                                                   newtd = ((FieldDescriptor)pp.getDescAt(i-2)).getType();
+                                                   cd = newtd.getClassDesc();
+                                           }
+                                           newfieldoffset = new String("(unsigned int)(&(((struct "+ cd.getSafeSymbol() +" *)0)->"+ 
+                                                           ((FieldDescriptor)desc).getSafeSymbol()+ "))");
+                                   } else {
+                                           newtd = ((FieldDescriptor)pp.getDescAt(i-1)).getType();
+                                           newfieldoffset = new String("(unsigned int)(&(((struct "+ newtd.getSafeSymbol()+" *)0)->"+ 
+                                                           ((FieldDescriptor)desc).getSafeSymbol()+ "))");
+                                   }
+                           }
+                   } else {
+                           String tstlbl = new String();
+                           for(j = 0; j < ((IndexDescriptor)desc).tddesc.size(); j++) {
+                                   tstlbl += generateTemp(fm, ((IndexDescriptor)desc).getTempDescAt(j), lb) + "+";
+                           }
+                           tstlbl += ((IndexDescriptor)desc).offset.toString();
+                           newfieldoffset = new String(tstlbl);
+                   }
+                   fieldoffset.add(newfieldoffset);
+           }
+           if(tuplecount > 0) {
+                   int tmp = (int) ((Short)(endoffset.get(tuplecount-1))).shortValue() + (int) offsetcount;
+                   short endoffsetval = (short) tmp;
+                   endoffset.add(endoffsetval);
+           }else {
+                   endoffset.add(offsetcount);
+           }
+    }
+
+    public void generateLocalTransCode(FlatMethod fm, LocalityBinding lb,PrefetchPair pp,Vector oids, Vector fieldoffset,Vector endoffset, int tuplecount) {
+           int i, j, k;
+           short offsetcount = 0;
+
+           Vector prefix = new Vector();
+           prefix.add(generateTemp(fm,pp.base,lb));
+           String tstlbl = new String("(" + prefix.get(0) + " != NULL ");
+           for (i = 0; i < pp.desc.size(); i++) {
+                   Object newdesc = pp.desc.get(i);
+                   if(newdesc instanceof FieldDescriptor) {
+                           FieldDescriptor fd = (FieldDescriptor) newdesc;
+                           if(fd.isGlobal()){
+                                   /* Field descriptor is global */
+                                   String oid = new String(" (unsigned int) (");
+                                   tstlbl += ") ? ";
+                                   for(j = 0; j < prefix.size(); j++) {
+                                           tstlbl += prefix.get(j) + "->";
+                                   }
+                                   tstlbl += fd.getSafeSymbol() + ": NULL";
+                                   oid += tstlbl+ " )";
+                                   oids.add(oid);
+                                   for(j = i+1; j < pp.desc.size(); j++) {
+                                           TypeDescriptor newtd;
+                                           String newfieldoffset;
+                                           Object desc = pp.getDescAt(j);
+                                           offsetcount++;
+                                           if(desc instanceof FieldDescriptor) {
+                                                   Object prevdesc = pp.getDescAt(j-1);
+                                                   if(prevdesc instanceof IndexDescriptor){
+                                                           //FIXME currently handles one dimensional arrays
+                                                           newtd = ((FieldDescriptor)pp.getDescAt(j-2)).getType();
+                                                   } else {
+                                                           newtd = ((FieldDescriptor) pp.getDescAt(j-1)).getType();
+                                                   }
+                                                   newfieldoffset = new String("(unsigned int)(&(((struct "+ newtd.getSafeSymbol()+" *)0)->"+ 
+                                                                   ((FieldDescriptor)desc).getSafeSymbol()+ "))");
+                                           } else {
+                                                   String indexlbl = new String();
+                                                   for(k = 0; k < ((IndexDescriptor)desc).tddesc.size(); k++) {
+                                                           indexlbl += generateTemp(fm, ((IndexDescriptor)desc).getTempDescAt(k), lb) + "+";
+                                                   }
+                                                   indexlbl += ((IndexDescriptor)desc).offset.toString();
+                                                   newfieldoffset = new String(indexlbl);
+                                           }
+                                           fieldoffset.add(newfieldoffset);
+                                   }
+                                   if(tuplecount > 0) {
+                                           int tmp = (int) ((Short)(endoffset.get(tuplecount-1))).shortValue() + (int) offsetcount;
+                                           short endoffsetval = (short) tmp;
+                                           endoffset.add(endoffsetval);
+                                   }else {
+                                           endoffset.add(offsetcount);
+                                   }
+                                   tuplecount++;
+                                   break; //break from outer for loop
+                           } else {
+                                   tstlbl += "&& ";
+                                   for(j = 0; j < prefix.size(); j++) {
+                                           tstlbl += prefix.get(j) + "->";
+                                   }
+                                   prefix.add(fd.getSafeSymbol());
+                                   tstlbl += fd.getSafeSymbol() + " != NULL";
+                           }
+                   } else { /* if Index descriptor */
+                           String indexstring = new String();
+                           IndexDescriptor id = (IndexDescriptor) newdesc;
+                           if(i == 0) {
+                                   indexstring = generateTemp(fm, pp.base, lb);
+                           } else {
+                                   indexstring = ((FieldDescriptor)pp.getDescAt(i-1)).getSafeSymbol();
+                           }
+                           tstlbl += "&& ";
+                           for(j = 0; j < prefix.size(); j++) {
+                                   tstlbl += prefix.get(j) + "[";
+                           }
+                           indexstring += "[";
+                           for(j = 0; j < id.tddesc.size(); j++) {
+                                   tstlbl += generateTemp(fm, id.getTempDescAt(j), lb) + "+"; 
+                                   indexstring += generateTemp(fm,id.getTempDescAt(j), lb) + "+";
+                           }
+                           tstlbl += id.offset.toString()+ "]";
+                           indexstring += id.offset.toString()+ "]";
+                           prefix. removeElementAt(prefix.size() -1);
+                           prefix.add(indexstring);
+                           tstlbl += " != NULL";
+                   }
+           }
+    }
+
     public void generateFlatGlobalConvNode(FlatMethod fm, LocalityBinding lb, FlatGlobalConvNode fgcn, PrintWriter output) {
-       if (lb!=fgcn.getLocality())
-           return;
-       /* Have to generate flat globalconv */
-       if (fgcn.getMakePtr()) {
-           output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)transRead(trans, (unsigned int) "+generateTemp(fm, fgcn.getSrc(),lb)+");");
-       } else {
-           /* Need to convert to OID */
-           output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
-       }
+           if (lb!=fgcn.getLocality())
+                   return;
+           /* Have to generate flat globalconv */
+           if (fgcn.getMakePtr()) {
+                   output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)transRead(trans, (unsigned int) "+generateTemp(fm, fgcn.getSrc(),lb)+");");
+           } else {
+                   /* Need to convert to OID */
+                   output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
+           }
     }
 
     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.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
-           return;
-       /* 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(tmp),lb)+"="+generateTemp(fm,tmp,lb)+";");
-       }
-       output.println("goto transstart"+faen.getIdentifier()+";");
+           /* Check to see if we need to generate code for this atomic */
+           if (locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
+                   return;
+           /* 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(tmp),lb)+"="+generateTemp(fm,tmp,lb)+";");
+           }
+           output.println("goto transstart"+faen.getIdentifier()+";");
 
-       /******* Print code to retry aborted transaction *******/
-       output.println("transretry"+faen.getIdentifier()+":");
+           /******* Print code to retry aborted transaction *******/
+           output.println("transretry"+faen.getIdentifier()+":");
 
-       /* Restore temps */
-       for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) {
-           TempDescriptor tmp=tmpit.next();
-           output.println(generateTemp(fm, tmp,lb)+"="+generateTemp(fm,backuptable.get(tmp),lb)+";");
-       }
+           /* Restore temps */
+           for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) {
+                   TempDescriptor tmp=tmpit.next();
+                   output.println(generateTemp(fm, tmp,lb)+"="+generateTemp(fm,backuptable.get(tmp),lb)+";");
+           }
+
+           /********* Need to revert local object store ********/
+           String revertptr=generateTemp(fm, reverttable.get(lb),lb);
 
-       /********* 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+";");
@@ -1691,7 +2006,7 @@ public class BuildCode {
            } else if (status==LocalityAnalysis.EITHER) {
                //Code is reading from a null pointer
                output.println("if ("+generateTemp(fm, ffn.getSrc(),lb)+") {");
-               output.println("printf(\"BIG ERROR\n\");exit(-1);}");
+               output.println("printf(\"BIG ERROR\\n\");exit(-1);}");
                //This should throw a suitable null pointer error
                output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
            } else
@@ -1700,6 +2015,7 @@ public class BuildCode {
            output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
     }
 
+
     private void generateFlatSetFieldNode(FlatMethod fm, LocalityBinding lb, FlatSetFieldNode fsfn, PrintWriter output) {
        if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
            throw new Error("Can't set array length");
@@ -1712,7 +2028,7 @@ public class BuildCode {
            String dst=generateTemp(fm,fsfn.getDst(),lb);
            if (srcglobal) {
                output.println("{");
-               output.println("int srcoid="+src+"->"+oidstr+";");
+               output.println("int srcoid=(int)"+src+"->"+oidstr+";");
            }
            if (statusdst.equals(LocalityAnalysis.GLOBAL)) {
                String glbdst=dst;
@@ -1720,15 +2036,14 @@ public class BuildCode {
                output.println("*((unsigned int *)&("+dst+"->___localcopy___))|=DIRTY;");
                if (srcglobal) {
                    output.println("*((unsigned int *)&("+glbdst+"->"+ fsfn.getField().getSafeSymbol()+"))=srcoid;");
-                   output.println("}");
                } else
                    output.println(glbdst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");          
            } else if (statusdst.equals(LocalityAnalysis.LOCAL)) {
                /** Check if we need to copy */
                output.println("if(!"+dst+"->"+localcopystr+") {");
                /* Link object into list */
-               output.println(dst+"->"+nextobjstr+"=trans->localtrans;");
-               output.println("trans->localtrans="+dst+";");
+               output.println(dst+"->"+nextobjstr+"=trans->revertlist;");
+               output.println("trans->revertlist=(struct ___Object___ *)"+dst+";");
                if (GENERATEPRECISEGC)
                    output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
                else
@@ -1741,7 +2056,7 @@ public class BuildCode {
            } else if (statusdst.equals(LocalityAnalysis.EITHER)) {
                //writing to a null...bad
                output.println("if ("+dst+") {");
-               output.println("printf(\"BIG ERROR 2\n\");exit(-1);}");
+               output.println("printf(\"BIG ERROR 2\\n\");exit(-1);}");
                if (srcglobal)
                    output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=srcoid;");
                else
@@ -1768,8 +2083,30 @@ public class BuildCode {
            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.DSM) {
+           Integer status=locality.getNodePreTempInfo(lb,fen).get(fen.getSrc());
+           if (status==LocalityAnalysis.GLOBAL) {
+               String dst=generateTemp(fm, fen.getDst(),lb);
 
-       output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
+               if (elementtype.isPtr()) {
+                   output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
+                   output.println(dst+"=(void *) transRead(trans, (unsigned int) "+dst+");");
+               } else {
+                   output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
+               }
+           } else if (status==LocalityAnalysis.LOCAL) {
+               output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
+           } else if (status==LocalityAnalysis.EITHER) {
+               //Code is reading from a null pointer
+               output.println("if ("+generateTemp(fm, fen.getSrc(),lb)+") {");
+               output.println("printf(\"BIG ERROR\\n\");exit(-1);}");
+               //This should throw a suitable null pointer error
+               output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
+           } else
+               throw new Error("Read from non-global/non-local in:"+lb.getExplanation());
+       } else {
+           output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
+       }
     }
 
     private void generateFlatSetElementNode(FlatMethod fm, LocalityBinding lb, FlatSetElementNode fsen, PrintWriter output) {
@@ -1784,12 +2121,31 @@ public class BuildCode {
        else 
            type=elementtype.getSafeSymbol()+" ";
 
+
        if (fsen.needsBoundsCheck()) {
            output.println("if ("+generateTemp(fm, fsen.getIndex(),lb)+"< 0 || "+generateTemp(fm, fsen.getIndex(),lb)+" >= "+generateTemp(fm,fsen.getDst(),lb) + "->___length___)");
            output.println("failedboundschk();");
        }
 
-       output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
+       if (state.DSM && locality.getAtomic(lb).get(fsen).intValue()>0) {
+           Integer statussrc=locality.getNodePreTempInfo(lb,fsen).get(fsen.getSrc());
+           Integer statusdst=locality.getNodePreTempInfo(lb,fsen).get(fsen.getDst());
+           boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL;
+           boolean dstglobal=statusdst==LocalityAnalysis.GLOBAL;
+           if (dstglobal) {
+               output.println("*((unsigned int *)&("+generateTemp(fm,fsen.getDst(),lb)+"->___localcopy___))|=DIRTY;");
+           }
+           if (srcglobal) {
+               output.println("{");
+               String src=generateTemp(fm, fsen.getSrc(), lb);
+               output.println("int srcoid=(int)"+src+"->"+oidstr+";");
+               output.println("((int*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]=srcoid;");
+               output.println("}");
+           } else {
+               output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
+           }
+       } else
+           output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
     }
 
     private void generateFlatNew(FlatMethod fm, LocalityBinding lb, FlatNew fn, PrintWriter output) {
@@ -1822,9 +2178,16 @@ public class BuildCode {
     }
 
     private void generateFlatOpNode(FlatMethod fm, LocalityBinding lb, FlatOpNode fon, PrintWriter output) {
-       if (fon.getRight()!=null)
-           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)
+       if (fon.getRight()!=null) {
+           if (fon.getOp().getOp()==Operation.URIGHTSHIFT) {
+               if (fon.getLeft().getType().isLong())
+                   output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned long long)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";");
+               else
+                   output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned int)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+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)
            output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
        else if (fon.getOp().getOp()==Operation.UNARYPLUS)
            output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
@@ -1832,6 +2195,8 @@ public class BuildCode {
            output.println(generateTemp(fm, fon.getDest(),lb)+" = -"+generateTemp(fm, fon.getLeft(),lb)+";");
        else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
            output.println(generateTemp(fm, fon.getDest(),lb)+" = !"+generateTemp(fm, fon.getLeft(),lb)+";");
+       else if (fon.getOp().getOp()==Operation.COMP)
+           output.println(generateTemp(fm, fon.getDest(),lb)+" = ~"+generateTemp(fm, fon.getLeft(),lb)+";");
        else if (fon.getOp().getOp()==Operation.ISAVAILABLE) {
            output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+"->fses==NULL;");
        } else
@@ -1865,6 +2230,8 @@ public class BuildCode {
        } else if (fln.getType().isChar()) {
            String st=FlatLiteralNode.escapeString(fln.getValue().toString());
            output.println(generateTemp(fm, fln.getDst(),lb)+"='"+st+"';");
+       } else if (fln.getType().isLong()) {
+           output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+"LL;");
        } else
            output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+";");
     }
@@ -2295,7 +2662,7 @@ public class BuildCode {
                 }      
             } else
                 continue;
-                    // if there is no optionals, there is no need to build the rest of the struct 
+            // if there are no optionals, there is no need to build the rest of the struct 
             
             output.println("struct optionaltaskdescriptor * otdarray"+cdtemp.getSafeSymbol()+"[]={");
             c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
@@ -2366,9 +2733,12 @@ public class BuildCode {
                 Set<TaskIndex> tiset=sa.getTaskIndex(fs);
                 for(Iterator<TaskIndex> itti=tiset.iterator();itti.hasNext();) {
                     TaskIndex ti=itti.next();
-                    Set<OptionalTaskDescriptor> otdset=sa.getOptions(fs, ti.getTask(), ti.getIndex());
+                    if (ti.isRuntime())
+                        continue;
 
-                    output.print("struct optionaltaskdescriptor * optionaltaskfailure_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array[] = {");
+                    Set<OptionalTaskDescriptor> otdset=sa.getOptions(fs, ti);
+
+                    output.print("struct optionaltaskdescriptor * optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array[] = {");
                     boolean needcomma=false;
                     for(Iterator<OptionalTaskDescriptor> otdit=ordertd(otdset).iterator();otdit.hasNext();) {
                         OptionalTaskDescriptor otd=otdit.next();
@@ -2379,23 +2749,28 @@ public class BuildCode {
                     }
                     output.println("};");
 
-                    output.print("struct taskfailure taskfailure_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+" = {");
+                    output.print("struct taskfailure taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+" = {");
                     output.print("&task_"+ti.getTask().getSafeSymbol()+", ");
                     output.print(ti.getIndex()+", ");
                     output.print(otdset.size()+", ");
-                    output.print("optionaltaskfailure_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array");
+                    output.print("optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array");
                     output.println("};");
                 }
 
                 tiset=sa.getTaskIndex(fs);
                 boolean needcomma=false;
+                int runtimeti=0;
                 output.println("struct taskfailure * taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
                 for(Iterator<TaskIndex> itti=tiset.iterator();itti.hasNext();) {
                     TaskIndex ti=itti.next();
+                    if (ti.isRuntime()) {
+                        runtimeti++;
+                        continue;
+                    }
                     if (needcomma)
                         output.print(", ");
                     needcomma=true;
-                    output.print("&taskfailure_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex());
+                    output.print("&taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex());
                 }
                 output.println("};\n");
 
@@ -2405,7 +2780,7 @@ public class BuildCode {
                 output.println("/*flag*/"+flagid+",");
                 output.println("/* number of tags*/"+tagcounter+",");
                 output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
-                output.println("/* numtask failures */"+tiset.size()+",");
+                output.println("/* numtask failures */"+(tiset.size()-runtimeti)+",");
                 output.println("taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
                 output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
                 output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());