code correction
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
index 7a5ddc6f8414ed70d4f438f72439ef716a9cda02..7d484a856952492d8cc0cf222a3f8a9e71c72b2d 100644 (file)
@@ -8,10 +8,14 @@ import java.util.*;
 import java.io.*;
 import Util.Relation;
 import Analysis.TaskStateAnalysis.FlagState;
+import Analysis.TaskStateAnalysis.FlagComparator;
 import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
 import Analysis.TaskStateAnalysis.Predicate;
+import Analysis.TaskStateAnalysis.SafetyAnalysis;
+import Analysis.TaskStateAnalysis.TaskIndex;
 import Analysis.Locality.LocalityAnalysis;
 import Analysis.Locality.LocalityBinding;
+import Analysis.Prefetch.*;
 
 public class BuildCode {
     State state;
@@ -38,12 +42,18 @@ public class BuildCode {
     LocalityAnalysis locality;
     Hashtable<TempDescriptor, TempDescriptor> backuptable;
     Hashtable<LocalityBinding, TempDescriptor> reverttable;
+    SafetyAnalysis sa;
 
-    public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
-       this(st, temptovar, typeutil, null);
+    public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa) {
+       this(st, temptovar, typeutil, null, sa);
     }
 
     public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality) {
+       this(st, temptovar, typeutil, locality, null);
+    }
+
+    public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, SafetyAnalysis sa) {
+       this.sa=sa;
        state=st;
        this.temptovar=temptovar;
        paramstable=new Hashtable();
@@ -315,12 +325,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();
@@ -331,8 +341,9 @@ public class BuildCode {
                    /* Classify parameters */
                    MethodDescriptor md=(MethodDescriptor)methodit.next();
                    FlatMethod fm=state.getMethodFlat(md);
-                   if (!md.getModifiers().isNative())
+                   if (!md.getModifiers().isNative()) {
                        generateFlatMethod(fm, null, outmethod);
+                   }
                }
            }
        } 
@@ -345,6 +356,12 @@ public class BuildCode {
 
        /* Output #defines that the runtime uses to determine type
         * numbers for various objects it needs */
+       outstructs.println("#define MAXCOUNT "+maxcount);
+       if (state.DSM) {
+           LocalityBinding lb=new LocalityBinding(typeutil.getRun(), false);
+           lb.setGlobalThis(LocalityAnalysis.GLOBAL);
+           outstructs.println("#define RUNMETHOD "+virtualcalls.getLocalityNumber(lb));
+       }
 
        outstructs.println("#define STRINGARRAYTYPE "+
                           (state.getArrayNumber(
@@ -399,12 +416,8 @@ public class BuildCode {
            outclassdefs.println("  int flag;");
            outclassdefs.println("  void * flagptr;");
            if(state.OPTIONAL){
-               outclassdefs.println("  int failedstatus;");
-               outclassdefs.println("  int hashcode;");
-               outclassdefs.println("  int numexitfses;");
-               outclassdefs.println("  int * exitfses;");
-               outclassdefs.println("  int numotds;");
-               outclassdefs.println("  struct optionaltaskdescriptor ** otds;");
+               outclassdefs.println("  int numfses;");
+               outclassdefs.println("  int * fses;");
            }
        }
        printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
@@ -743,7 +756,7 @@ public class BuildCode {
        for(int i=0;i<fm.numParameters();i++) {
            TempDescriptor temp=fm.getParameter(i);
            TypeDescriptor type=temp.getType();
-           if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
+           if (type.isPtr()&&GENERATEPRECISEGC)
                objectparams.addPtr(temp);
            else
                objectparams.addPrim(temp);
@@ -774,7 +787,7 @@ public class BuildCode {
            for(int i=0;i<writes.length;i++) {
                TempDescriptor temp=writes[i];
                TypeDescriptor type=temp.getType();
-               if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
+               if (type.isPtr()&&GENERATEPRECISEGC)
                    objecttemps.addPtr(temp);
                else
                    objecttemps.addPrim(temp);
@@ -789,7 +802,7 @@ public class BuildCode {
            for(Iterator<TempDescriptor> tmpit=backuptable.values().iterator();tmpit.hasNext();) {
                TempDescriptor tmp=tmpit.next();
                TypeDescriptor type=tmp.getType();
-               if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
+               if (type.isPtr()&&GENERATEPRECISEGC)
                    objecttemps.addPtr(tmp);
                else
                    objecttemps.addPrim(tmp);
@@ -825,7 +838,7 @@ public class BuildCode {
                TypeDescriptor type=fd.getType();
                if (state.DSM&&fd.isGlobal()) //Don't GC the global objects for now
                    continue;
-               if (type.isPtr()||type.isArray())
+               if (type.isPtr())
                    count++;
            }
            output.print(count);
@@ -835,7 +848,7 @@ public class BuildCode {
                TypeDescriptor type=fd.getType();
                if (state.DSM&&fd.isGlobal()) //Don't GC the global objects for now
                    continue;
-               if (type.isPtr()||type.isArray()) {
+               if (type.isPtr()) {
                    output.println(",");
                    output.print("((unsigned int)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))");
                }
@@ -978,12 +991,8 @@ public class BuildCode {
            classdefout.println("  int flag;");
            classdefout.println("  void * flagptr;");
            if (state.OPTIONAL){
-               classdefout.println("  int failedstatus;");
-               classdefout.println("  int hashcode;");
-               classdefout.println("  int numexitfses;");
-               classdefout.println("  int * exitfses;");
-               classdefout.println("  int numotds;");
-               classdefout.println("  struct optionaltaskdescriptor ** otds;");
+               classdefout.println("  int numfses;");
+               classdefout.println("  int * fses;");
            }
        }
        printClassStruct(cn, classdefout);
@@ -1189,6 +1198,7 @@ public class BuildCode {
 
     private void generateFlatMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
        MethodDescriptor md=fm.getMethod();
+       
        TaskDescriptor task=fm.getTask();
 
                ClassDescriptor cn=md!=null?md.getClassDesc():null;
@@ -1392,7 +1402,7 @@ public class BuildCode {
            output.println("/* nop */");
            return;
        case FKind.FlatBackEdge:
-           if (state.THREAD&&GENERATEPRECISEGC) {
+           if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) {
                output.println("checkcollect(&"+localsprefix+");");
            } else
                output.println("/* nop */");
@@ -1403,11 +1413,47 @@ 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) {
+       System.out.println("Inside generateFlatPrefetchNode()");
+       if (state.PREFETCH) {
+           System.out.println("The Prefetch pairs to be fetched are "+ fpn.hspp);
+           Iterator it = fpn.hspp.iterator();
+           for(;it.hasNext();) {
+                PrefetchPair pp = (PrefetchPair) it.next();
+                //TODO handle arrays in prefetch tuples, currently only handle fields
+                Integer statusbase = locality.getNodePreTempInfo(lb,fpn).get(pp.base);
+                System.out.println("DEBUG-> generateFlatPrefetchNode()" + statusbase);
+                if(statusbase == LocalityAnalysis.GLOBAL) {
+                    // Generate oid for base
+                } else {
+                    for(int i = 0; i<pp.desc.size(); i++) {
+                       Object o = pp.desc.get(i);
+                       if(!(o instanceof IndexDescriptor)) {
+                               FieldDescriptor fd = (FieldDescriptor) o;
+                               Integer statusfd = locality.getNodePreTempInfo(lb,fpn).get(fd);
+                               System.out.println("DEBUG-> generateFlatPrefetchNode() fd" + statusfd);
+                               //find out the locality of the fieldDescriptor
+                               if(statusfd == LocalityAnalysis.GLOBAL) {
+                                       //generate oid for it
+                               }
+                       }
+                    }
+                }
+             }
+             //Each temp descriptor can be an oid
+            //Find locality of each prefetch tuple in the FLatPrefetchNode
+            //Separate them as Local or Global
+            //generate oids and offset value for prefetch tuple
+       }
+    }   
+
     public void generateFlatGlobalConvNode(FlatMethod fm, LocalityBinding lb, FlatGlobalConvNode fgcn, PrintWriter output) {
        if (lb!=fgcn.getLocality())
            return;
@@ -1416,7 +1462,7 @@ public class BuildCode {
            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)+"=OID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
+           output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
        }
     }
 
@@ -1649,14 +1695,13 @@ public class BuildCode {
 
     private void generateFlatFieldNode(FlatMethod fm, LocalityBinding lb, FlatFieldNode ffn, PrintWriter output) {
        if (state.DSM) {
-           Integer status=locality.getNodeTempInfo(lb).get(ffn).get(ffn.getSrc());
+           Integer status=locality.getNodePreTempInfo(lb,ffn).get(ffn.getSrc());
            if (status==LocalityAnalysis.GLOBAL) {
                String field=ffn.getField().getSafeSymbol();
-               String src="((struct "+ffn.getSrc().getType().getSafeSymbol()+" *)((unsigned int)"+generateTemp(fm, ffn.getSrc(),lb)+"+sizeof(objheader_t)))";
+               String src=generateTemp(fm, ffn.getSrc(),lb);
                String dst=generateTemp(fm, ffn.getDst(),lb);
                    
-               if (ffn.getField().getType().isPtr()||
-                   ffn.getField().getType().isArray()) {
+               if (ffn.getField().getType().isPtr()) {
 
                    //TODO: Uncomment this when we have runtime support
                    //if (ffn.getSrc()==ffn.getDst()) {
@@ -1692,11 +1737,12 @@ 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");
        if (state.DSM && locality.getAtomic(lb).get(fsfn).intValue()>0) {
-           Integer statussrc=locality.getNodeTempInfo(lb).get(fsfn).get(fsfn.getSrc());
+           Integer statussrc=locality.getNodePreTempInfo(lb,fsfn).get(fsfn.getSrc());
            Integer statusdst=locality.getNodeTempInfo(lb).get(fsfn).get(fsfn.getDst());
            boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL;
 
@@ -1704,23 +1750,22 @@ 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="((struct "+fsfn.getDst().getType().getSafeSymbol()+" *)((unsigned int)"+dst+" +sizeof(objheader_t)))";
+               String glbdst=dst;
                //mark it dirty
                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
@@ -1824,7 +1869,9 @@ 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
+       else if (fon.getOp().getOp()==Operation.ISAVAILABLE) {
+           output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+"->fses==NULL;");
+       } else
            output.println(generateTemp(fm, fon.getDest(),lb)+fon.getOp().toString()+generateTemp(fm, fon.getLeft(),lb)+";");
     }
 
@@ -1860,9 +1907,12 @@ public class BuildCode {
     }
 
     private void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
-       if (frn.getReturnTemp()!=null)
-           output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
-       else
+       if (frn.getReturnTemp()!=null) {
+           if (frn.getReturnTemp().getType().isPtr())
+               output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
+           else
+               output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
+       } else
            output.println("return;");
     }
 
@@ -2064,16 +2114,13 @@ public class BuildCode {
        }
     }
 
-     void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution, Hashtable optionaltaskdescriptors) {
-        
+    void generateOptionalHeader(PrintWriter headers) {
+
         //GENERATE HEADERS
         headers.println("#include \"task.h\"\n\n");
         headers.println("#ifndef _OPTIONAL_STRUCT_");
         headers.println("#define _OPTIONAL_STRUCT_");
         
-        
-        
-        
         //STRUCT PREDICATEMEMBER
         headers.println("struct predicatemember{");
         headers.println("int type;");
@@ -2082,28 +2129,30 @@ public class BuildCode {
         headers.println("int numtags;");
         headers.println("int * tags;\n};\n\n");
 
-        /*//STRUCT EXITSTATES
-        headers.println("struct exitstates{");
-        headers.println("int numflagstates;");
-        headers.println("int * flagstatearray;\n};\n\n");*///appeared to be useless
-
         //STRUCT OPTIONALTASKDESCRIPTOR
         headers.println("struct optionaltaskdescriptor{");
         headers.println("struct taskdescriptor * task;");
+        headers.println("int index;");
         headers.println("int numenterflags;");
         headers.println("int * enterflags;");
         headers.println("int numpredicatemembers;");
         headers.println("struct predicatemember ** predicatememberarray;");
-        //headers.println("int numexitstates;");
-        //headers.println("int numTotal;");
-        //headers.println("struct exitstates ** exitstatesarray;\n};\n\n");
-        headers.println("\n};\n\n");
-                
+        headers.println("};\n\n");
+        
+        //STRUCT TASKFAILURE
+        headers.println("struct taskfailure {");
+        headers.println("struct taskdescriptor * task;");
+        headers.println("int index;");
+        headers.println("int numoptionaltaskdescriptors;");
+        headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
+
         //STRUCT FSANALYSISWRAPPER
         headers.println("struct fsanalysiswrapper{");
         headers.println("int  flags;");
         headers.println("int numtags;");
         headers.println("int * tags;");
+        headers.println("int numtaskfailures;");
+        headers.println("struct taskfailure ** taskfailurearray;");
         headers.println("int numoptionaltaskdescriptors;");
         headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
 
@@ -2113,11 +2162,9 @@ public class BuildCode {
         headers.println("int numotd;");
         headers.println("struct optionaltaskdescriptor ** otdarray;");
         headers.println("int numfsanalysiswrappers;");
-        headers.println("struct fsanalysiswrapper ** fsanalysiswrapperarray;\n};\n\n");
+        headers.println("struct fsanalysiswrapper ** fsanalysiswrapperarray;\n};");
         
-        headers.println("struct classanalysiswrapper * classanalysiswrapperarray[];\n");
-
-       
+        headers.println("extern struct classanalysiswrapper * classanalysiswrapperarray[];");
 
         Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
         while(taskit.hasNext()) {
@@ -2125,12 +2172,105 @@ public class BuildCode {
             headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
         }
         
-        
-        
+    }
+
+    //CHECK OVER THIS -- THERE COULD BE SOME ERRORS HERE
+    int generateOptionalPredicate(Predicate predicate, OptionalTaskDescriptor otd, ClassDescriptor cdtemp, PrintWriter output) {
+       int predicateindex = 0;
+       //iterate through the classes concerned by the predicate
+       Set c_vard = predicate.vardescriptors;
+       Hashtable<TempDescriptor, Integer> slotnumber=new Hashtable<TempDescriptor, Integer>();
+       int current_slot=0;
+       
+       for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();){
+           VarDescriptor vard = (VarDescriptor)vard_it.next();
+           TypeDescriptor typed = vard.getType();
+           
+           //generate for flags
+           HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
+           output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+           int numberterms=0;
+           if (fen_hashset!=null){
+               for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();){
+                   FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
+                   if (fen!=null) {
+                       DNFFlag dflag=fen.getDNF();
+                       numberterms+=dflag.size();
+                       
+                       Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
+                       
+                       for(int j=0;j<dflag.size();j++) {
+                           if (j!=0)
+                               output.println(",");
+                           Vector term=dflag.get(j);
+                           int andmask=0;
+                           int checkmask=0;
+                           for(int k=0;k<term.size();k++) {
+                               DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
+                               FlagDescriptor fd=dfa.getFlag();
+                               boolean negated=dfa.getNegated();
+                               int flagid=1<<((Integer)flags.get(fd)).intValue();
+                               andmask|=flagid;
+                               if (!negated)
+                                   checkmask|=flagid;
+                           }
+                           output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
+                       }
+                   }
+               }
+           }
+           output.println("};\n");
+           
+           //generate for tags
+           TagExpressionList tagel = predicate.tags.get(vard.getSymbol()); 
+           output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+           int numtags = 0;
+           if (tagel!=null){
+               for(int j=0;j<tagel.numTags();j++) {
+                   if (j!=0)
+                       output.println(",");
+                   TempDescriptor tmp=tagel.getTemp(j);
+                   if (!slotnumber.containsKey(tmp)) {
+                       Integer slotint=new Integer(current_slot++);
+                       slotnumber.put(tmp,slotint);
+                   }
+                   int slot=slotnumber.get(tmp).intValue();
+                   output.println("/* slot */"+ slot+", /*tagid*/"+state.getTagId(tmp.getTag()));
+               }
+               numtags = tagel.numTags();
+           }
+           output.println("};");
+           
+           //store the result into a predicatemember struct
+           output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
+           output.println("/*type*/"+typed.getClassDesc().getId()+",");
+           output.println("/* number of dnf terms */"+numberterms+",");
+           output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+           output.println("/* number of tag */"+numtags+",");
+           output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+           output.println("};\n");
+           predicateindex++;
+       }
+       
+       
+       //generate an array that stores the entire predicate
+       output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+       for( int j = 0; j<predicateindex; j++){
+           if( j != predicateindex-1)output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+           else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
+       }
+       output.println("};\n");
+       return predicateindex;
+    }
+
+
+     void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, Set<OptionalTaskDescriptor>>> safeexecution, Hashtable optionaltaskdescriptors) {
+        generateOptionalHeader(headers);
         //GENERATE STRUCTS
         output.println("#include \"optionalstruct.h\"\n\n");    
+        output.println("#include \"stdlib.h\"\n");
+
         HashSet processedcd = new HashSet();
-       
         int maxotd=0;
         Enumeration e = safeexecution.keys();
         while (e.hasMoreElements()) {
@@ -2139,17 +2279,7 @@ public class BuildCode {
             ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
             Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);//will be used several times
             
-            //////////////////////////DEBUG
-            System.out.println(cdtemp.getSymbol()+" "+cdtemp.getId());
-            for(Iterator flags = cdtemp.getFlags(); flags.hasNext();){
-                FlagDescriptor flagd = (FlagDescriptor)flags.next();
-                int flagid=1<<((Integer)flaginfo.get(flagd)).intValue();
-                System.out.println(" Flag "+flagd.getSymbol()+" 0x"+Integer.toHexString(flagid)+" int "+flagid);
-            }
-            ///////////////////////////
-            
             //Generate the struct of optionals
-            if((Hashtable)optionaltaskdescriptors.get(cdtemp)==null) System.out.println("Was in cd :"+cdtemp.getSymbol());
             Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
             numotd = c_otd.size();
             if(maxotd<numotd) maxotd = numotd; 
@@ -2159,200 +2289,87 @@ public class BuildCode {
                     
                     //generate the int arrays for the predicate
                     Predicate predicate = otd.predicate;
-                    int predicateindex = 0;
-                    //iterate through the classes concerned by the predicate
-                    Collection c_vard = predicate.vardescriptors.values();
-                    for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();){
-                        VarDescriptor vard = (VarDescriptor)vard_it.next();
-                        TypeDescriptor typed = vard.getType();
-                        
-                        //generate for flags
-                        HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
-                        output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
-                        int numberterms=0;
-                        if (fen_hashset!=null){
-                            for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();){
-                                FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
-                                if (fen==null) {
-                                }    
-                                else {
-                                    
-                                    DNFFlag dflag=fen.getDNF();
-                                    numberterms+=dflag.size();
-                                    
-                                    Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
-                                    
-                                    for(int j=0;j<dflag.size();j++) {
-                                        if (j!=0)
-                                            output.println(",");
-                                        Vector term=dflag.get(j);
-                                        int andmask=0;
-                                        int checkmask=0;
-                                        for(int k=0;k<term.size();k++) {
-                                            DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
-                                            FlagDescriptor fd=dfa.getFlag();
-                                            boolean negated=dfa.getNegated();
-                                            int flagid=1<<((Integer)flags.get(fd)).intValue();
-                                            andmask|=flagid;
-                                            if (!negated)
-                                                checkmask|=flagid;
-                                        }
-                                        output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
-                                    }
-                                }
-                            }
-                        }
-                        output.println("};\n");
-                        
-                        //generate for tags
-                        TagExpressionList tagel = predicate.tags.get(vard.getSymbol()); 
-                        output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
-                        //BUG...added next line to fix, test with any task program
-                        int numtags = 0;
-                        if (tagel!=null){
-                            for(int j=0;j<tagel.numTags();j++) {
-                                if (j!=0)
-                                    output.println(",");
-                                TempDescriptor tmp=tagel.getTemp(j);
-                                //got rid of slot, maybe some improvments to do ???
-                                output.println("/*tagid*/"+state.getTagId(tmp.getTag()));
-                            }
-                            numtags = tagel.numTags();
-                        }
-                        output.println("};");
-                        
-                        //store the result into a predicatemember struct
-                        output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
-                        output.println("/*type*/"+typed.getClassDesc().getId()+",");
-                        output.println("/* number of dnf terms */"+numberterms+",");
-                        output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
-                        output.println("/* number of tag */"+numtags+",");
-                        output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
-                        output.println("};\n");
-                        predicateindex++;
-                    }
-                    
-
-                    //generate an array that stores the entire predicate
-                    output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
-                    for( int j = 0; j<predicateindex; j++){
-                        if( j != predicateindex-1)output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
-                        else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
-                    }
-                    output.println("};\n");
-
-                    //generate the struct for possible exitfses, appeared to be useless
-                    /*HashSet<HashSet> exitfses = otd.exitfses;
-                    int exitindex = 0;
-                    int nbexit = exitfses.size();
-                    int fsnumber;
+                    int predicateindex = generateOptionalPredicate(predicate, otd, cdtemp, output);
+                    TreeSet<Integer> fsset=new TreeSet<Integer>();
+                    //iterate through possible FSes corresponding to
+                    //the state when entering
                     
-                    //iterate through possible exits
-                    int nbtotal=0;
-                    for(Iterator exitfseshash = exitfses.iterator(); exitfseshash.hasNext();){
-                        HashSet temp_hashset = (HashSet)exitfseshash.next();
-                        fsnumber = 0 ;
-                        output.println("int flag_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
-                        //iterate through possible FSes corresponding to the exit
-                        for(Iterator exfses = temp_hashset.iterator(); exfses.hasNext();){
-                            FlagState fs = (FlagState)exfses.next();
-                            fsnumber++;
-                            nbtotal++;
-                            int flagid=0;
-                            for(Iterator flags = fs.getFlags(); flags.hasNext();){
-                                FlagDescriptor flagd = (FlagDescriptor)flags.next();
-                                int id=1<<((Integer)flaginfo.get(flagd)).intValue();
-                                flagid+=id;
-                            }
-                            if(fsnumber!=1) output.print(",");
-                            output.print(flagid);
-                            //do the same for tags.
-                            //maybe not needed because no tag changes tolerated.
-                        }
-                        output.println("};\n");
-                        
-                        
-                        //store that information in a struct
-                        output.println("struct exitstates exitstates"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
-                        output.println(fsnumber+",");
-                        output.println("flag_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
-                        output.println("};\n");
-
-                        exitindex++;
-                    }
-                    
-                    //store the information concerning all exits into an array
-                    output.println("struct exitstates * exitstatesarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
-                    for( int j = 0; j<nbexit; j++){
-                        if( j != nbexit-1)output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
-                        else output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
-                    }*/
-
-                    int fsnumber = 0 ;
-                    output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
-                        //iterate through possible FSes corresponding to the state when entering
-                    for(Iterator fses = otd.flagstates.iterator(); fses.hasNext();){
+                    for(Iterator fses = otd.enterflagstates.iterator(); fses.hasNext();){
                         FlagState fs = (FlagState)fses.next();
-                        fsnumber++;
                         int flagid=0;
                         for(Iterator flags = fs.getFlags(); flags.hasNext();){
                             FlagDescriptor flagd = (FlagDescriptor)flags.next();
                             int id=1<<((Integer)flaginfo.get(flagd)).intValue();
-                            flagid+=id;
+                            flagid|=id;
                         }
-                        if(fsnumber!=1) output.print(",");
-                        output.print(flagid);
-                        //tag information not needed because tag changes are not tolerated.
+                        fsset.add(new Integer(flagid));
+                        //tag information not needed because tag
+                        //changes are not tolerated.
                     }
+
+                    output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+                    boolean needcomma=false;
+                    for(Iterator<Integer> it=fsset.iterator();it.hasNext();) {
+                        if(needcomma)
+                            output.print(", ");
+                        output.println(it.next());
+                    }
+                    
                     output.println("};\n");
                     
                     
-                    //generate optionaltaskdescriptor that actually includes exit fses, predicate and the task concerned
+                    //generate optionaltaskdescriptor that actually
+                    //includes exit fses, predicate and the task
+                    //concerned
                     output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
                     output.println("&task_"+otd.td.getSafeSymbol()+",");
-                    output.println("/*number of enter flags*/"+fsnumber+",");
+                    output.println("/*index*/"+otd.getIndex()+",");
+                    output.println("/*number of enter flags*/"+fsset.size()+",");
                     output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
                     output.println("/*number of members */"+predicateindex+",");
                     output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
-                    //output.println("/*number of exitstates */"+nbexit+",");
-                    //output.println("/*total number of fses*/"+nbtotal+",");
-                    //output.println("exitstatesarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
                     output.println("};\n");
                 }      
-            }
-            else continue; // if there is no optionals, there is no need to build the rest of the struct 
+            } else
+                continue;
+            // 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();
-            int x=0;
             if( !c_otd.isEmpty() ){
+                boolean needcomma=false;
                 for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
                     OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
-                    if(x!=0) output.println(",");
-                    x++;
+                    if(needcomma) 
+                        output.println(",");
+                    needcomma=true;
                     output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
                 }
             }
             output.println("};\n");
             
-            //get all the possible falgstates reachable by an object
+            //get all the possible flagstates reachable by an object
             Hashtable hashtbtemp = safeexecution.get(cdtemp);
-            Enumeration fses = hashtbtemp.keys();
             int fscounter = 0;
-            while(fses.hasMoreElements()){
-                FlagState fs = (FlagState)fses.nextElement();
+            TreeSet fsts=new TreeSet(new FlagComparator(flaginfo));
+            fsts.addAll(hashtbtemp.keySet());
+            for(Iterator fsit=fsts.iterator();fsit.hasNext();) {
+                FlagState fs = (FlagState)fsit.next();
                 fscounter++;
                 
                 //get the set of OptionalTaskDescriptors corresponding
-                HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
-                //iterate through the OptionalTaskDescriptors and store the pointers to the optionals struct (see on top) into an array
+                HashSet<OptionalTaskDescriptor> availabletasks = (HashSet<OptionalTaskDescriptor>)hashtbtemp.get(fs);
+                //iterate through the OptionalTaskDescriptors and
+                //store the pointers to the optionals struct (see on
+                //top) into an array
                 
                 output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
-                for(Iterator mos = availabletasks.iterator(); mos.hasNext();){
-                    OptionalTaskDescriptor mm = (OptionalTaskDescriptor)mos.next();
-                    if(!mos.hasNext()) output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol());
-                    
-                    else output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+                for(Iterator<OptionalTaskDescriptor> mos = ordertd(availabletasks).iterator(); mos.hasNext();){
+                    OptionalTaskDescriptor mm = mos.next();
+                    if(!mos.hasNext()) 
+                        output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol());
+                    else 
+                        output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
                 }
 
                 output.println("};\n");
@@ -2363,10 +2380,9 @@ public class BuildCode {
                 for(Iterator flags = fs.getFlags(); flags.hasNext();){
                     FlagDescriptor flagd = (FlagDescriptor)flags.next();
                     int id=1<<((Integer)flaginfo.get(flagd)).intValue();
-                    flagid+=id;
+                    flagid|=id;
                 }
                 
-                
                 //process tag information
                 
                 int tagcounter = 0;
@@ -2384,13 +2400,58 @@ public class BuildCode {
                 }
                 output.println("};");
                 
-                
+                Set<TaskIndex> tiset=sa.getTaskIndex(fs);
+                for(Iterator<TaskIndex> itti=tiset.iterator();itti.hasNext();) {
+                    TaskIndex ti=itti.next();
+                    if (ti.isRuntime())
+                        continue;
+
+                    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();
+                        if(needcomma)
+                            output.print(", ");
+                        needcomma=true;
+                        output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
+                    }
+                    output.println("};");
+
+                    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_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_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex());
+                }
+                output.println("};\n");
+
                 //Store the result in fsanalysiswrapper
                 
                 output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
                 output.println("/*flag*/"+flagid+",");
                 output.println("/* number of tags*/"+tagcounter+",");
                 output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
+                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());
                 output.println("};\n");
@@ -2399,12 +2460,14 @@ public class BuildCode {
 
             //Build the array of fsanalysiswrappers
             output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
+            boolean needcomma=false;
             for(int i = 0; i<fscounter; i++){
-                if(i==fscounter-1) output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+"};\n");
-                        
-                    else output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+",");
+                if (needcomma) output.print(",");
+                output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol());
+                needcomma=true;
             }
-
+            output.println("};");
+            
             //Build the classanalysiswrapper referring to the previous array
             output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
             output.println("/*type*/"+cdtemp.getId()+",");
@@ -2412,27 +2475,45 @@ public class BuildCode {
             output.println("otdarray"+cdtemp.getSafeSymbol()+",");
             output.println("/* number of fsanalysiswrappers */"+fscounter+",");
             output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
-            fscounter = 0;
             processedcd.add(cdtemp);
         }
         
         //build an array containing every classes for which code has been build
         output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
-        for(Iterator classit = processedcd.iterator(); classit.hasNext();){
-            ClassDescriptor cdtemp=(ClassDescriptor)classit.next();
-            if(!classit.hasNext()) output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol()+"};\n");
-            else output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol()+",");
+        for(int i=0;i<state.numClasses();i++) {
+            ClassDescriptor cn=cdarray[i];
+            if (i>0)
+                output.print(", ");
+            if (processedcd.contains(cn))
+                output.print("&classanalysiswrapper_"+cn.getSafeSymbol());
+            else
+                output.print("NULL");
         }
+        output.println("};");
         
-        output.println("int numclasses="+processedcd.size()+";");
-        headers.println("extern numclasses;");
-        output.println("int maxotd="+maxotd+";");
-        headers.println("extern maxotd;");
+        output.println("#define MAXOTD "+maxotd);
         headers.println("#endif");
-       
-        
      }
-    
+
+    public List<OptionalTaskDescriptor> ordertd(Set<OptionalTaskDescriptor> otdset) {
+       Relation r=new Relation();
+       for(Iterator<OptionalTaskDescriptor>otdit=otdset.iterator();otdit.hasNext();) {
+           OptionalTaskDescriptor otd=otdit.next();
+           TaskIndex ti=new TaskIndex(otd.td, otd.getIndex());
+           r.put(ti, otd);
+       }
+
+       LinkedList<OptionalTaskDescriptor> l=new LinkedList<OptionalTaskDescriptor>();
+       for(Iterator it=r.keySet().iterator();it.hasNext();) {
+           Set s=r.get(it.next());
+           for(Iterator it2=s.iterator();it2.hasNext();) {
+               OptionalTaskDescriptor otd=(OptionalTaskDescriptor)it2.next();
+               l.add(otd);
+           }
+       }
+       
+       return l;
+    }
 }