Fixed variable dynamic source bookkeeping bug, regression test runs for single and...
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
index 0a0f7c42af4bb875314ded2dc60d92d837dc3056..9c24aa680a3ee83ca2c5645a87da79b704fdfac0 100644 (file)
@@ -286,6 +286,7 @@ public class BuildCode {
     outmethod.println("  int i;");
 
     if (state.MLP) {
+      //outmethod.println("  pthread_once( &mlpOnceObj, mlpInitOncePerThread );");
       outmethod.println("  workScheduleInit( "+state.MLP_NUMCORES+", invokeSESEmethod );");
     }
 
@@ -1656,6 +1657,32 @@ public class BuildCode {
        output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
     }
 
+
+    if( state.MLP ) {      
+      if( fm.getNext(0) instanceof FlatSESEEnterNode ) {
+       FlatSESEEnterNode callerSESEplaceholder = (FlatSESEEnterNode) fm.getNext( 0 );
+       if( callerSESEplaceholder != mlpa.getMainSESE() ) {
+         // declare variables for naming static SESE's
+         output.println("   /* static SESE names */");
+         Iterator<SESEandAgePair> pItr = callerSESEplaceholder.getNeededStaticNames().iterator();
+         while( pItr.hasNext() ) {
+           SESEandAgePair p = pItr.next();
+           output.println("   void* "+p+";");
+         }
+
+         // declare variables for tracking dynamic sources
+         output.println("   /* dynamic variable sources */");
+         Iterator<TempDescriptor> dynSrcItr = callerSESEplaceholder.getDynamicVarSet().iterator();
+         while( dynSrcItr.hasNext() ) {
+           TempDescriptor dynSrcVar = dynSrcItr.next();
+           output.println("   void* "+dynSrcVar+"_srcSESE;");
+           output.println("   int   "+dynSrcVar+"_srcOffset;");
+         }    
+       }
+      }
+    }
+
+
     /* Check to see if we need to do a GC if this is a
      * multi-threaded program...*/
 
@@ -1679,7 +1706,7 @@ public class BuildCode {
 
 
   protected void initializeSESE( FlatSESEEnterNode fsen ) {
-    
+
     FlatMethod       fm = fsen.getfmEnclosing();
     MethodDescriptor md = fm.getMethod();
     ClassDescriptor  cn = md.getClassDesc();
@@ -1998,9 +2025,11 @@ public class BuildCode {
       }
     }    
 
-    HashSet<FlatNode> exitset=new HashSet<FlatNode>();
-    exitset.add(seseExit);
+    // initialize thread-local var to a non-zero, invalid address
+    output.println("   seseCaller = (SESEcommon*) 0x2;");
 
+    HashSet<FlatNode> exitset=new HashSet<FlatNode>();
+    exitset.add(seseExit);    
 
     generateCode(fsen.getNext(0), fm, null, exitset, output, true);
     
@@ -2118,13 +2147,24 @@ public class BuildCode {
            output.println("primitives->"+tmp.getSafeSymbol()+"="+tmp.getSafeSymbol()+";");
          }
        }
+       if (state.MLP && stopset!=null) {
+         assert first.getPrev( 0 ) instanceof FlatSESEEnterNode;
+         assert current_node       instanceof FlatSESEExitNode;
+         FlatSESEEnterNode fsen = (FlatSESEEnterNode) first.getPrev( 0 );
+         FlatSESEExitNode  fsxn = (FlatSESEExitNode)  current_node;
+         assert fsen.getFlatExit().equals( fsxn );
+         assert fsxn.getFlatEnter().equals( fsen );
+       }
        if (current_node.kind()!=FKind.FlatReturnNode) {
          output.println("   return;");
        }
        current_node=null;
       } else if(current_node.numNext()==1) {
        FlatNode nextnode;
-       if (state.MLP && current_node.kind()==FKind.FlatSESEEnterNode) {
+       if (state.MLP && 
+           current_node.kind()==FKind.FlatSESEEnterNode && 
+           !((FlatSESEEnterNode)current_node).getIsCallerSESEplaceholder()
+          ) {
          FlatSESEEnterNode fsen = (FlatSESEEnterNode)current_node;
          generateFlatNode(fm, lb, current_node, output);
          nextnode=fsen.getFlatExit().getNext(0);
@@ -2342,7 +2382,13 @@ public class BuildCode {
          Iterator<TempDescriptor> tdItr = cp.getCopySet( vst ).iterator();
          while( tdItr.hasNext() ) {
            TempDescriptor td = tdItr.next();
-           output.println("       "+generateTemp( currentSESE.getfmBogus(), td, null )+
+           FlatMethod fmContext;
+           if( currentSESE.getIsCallerSESEplaceholder() ) {
+             fmContext = currentSESE.getfmEnclosing();
+           } else {
+             fmContext = currentSESE.getfmBogus();
+           }
+           output.println("       "+generateTemp( fmContext, td, null )+
                           " = child->"+vst.getAddrVar().getSafeSymbol()+";");
          }
 
@@ -2360,9 +2406,17 @@ public class BuildCode {
          output.println("     if( "+dynVar+"_srcSESE != NULL ) {");
          output.println("       SESEcommon* common = (SESEcommon*) "+dynVar+"_srcSESE;");
          output.println("       psem_take( &(common->stallSem) );");
-         output.println("       "+generateTemp( currentSESE.getfmBogus(), dynVar, null )+
-                                 " = *(("+dynVar.getType()+"*) ("+
-                                 dynVar+"_srcSESE + "+dynVar+"_srcOffset));");
+
+         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("   }");
        }
@@ -2377,6 +2431,14 @@ public class BuildCode {
          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;");
+       }
       }     
     }
 
@@ -2835,18 +2897,46 @@ public class BuildCode {
                                         FlatSESEEnterNode fsen, 
                                         PrintWriter output 
                                       ) {
+
+    // if MLP flag is off, okay that SESE nodes are in IR graph, 
+    // just skip over them and code generates exactly the same
     if( !state.MLP ) {
-      // SESE nodes can be parsed for normal compilation, just skip over them
       return;
     }    
 
+    // there may be an SESE in an unreachable method, skip over
+    if( !mlpa.getAllSESEs().contains( fsen ) ) {
+      return;
+    }
+
+    // also, if we have encountered a placeholder, just skip it
+    if( fsen.getIsCallerSESEplaceholder() ) {
+      return;
+    }
+
     output.println("   {");
 
+    // set up the parent
+    if( fsen == mlpa.getMainSESE() ) {
+      output.println("     SESEcommon* parentCommon = NULL;");
+    } else {
+      if( fsen.getParent() == null ) {
+       System.out.println( "in "+fm+", "+fsen+" has null parent" );
+      }
+      assert fsen.getParent() != null;
+      if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
+       output.println("     SESEcommon* parentCommon = &("+paramsprefix+"->common);");
+      } else {
+       //output.println("     SESEcommon* parentCommon = (SESEcommon*) peekItem( seseCallStack );");
+       output.println("     SESEcommon* parentCommon = seseCaller;");
+      }
+    }
+
     // before doing anything, lock your own record and increment the running children
     if( fsen != mlpa.getMainSESE() ) {      
-      output.println("     pthread_mutex_lock( &("+paramsprefix+"->common.lock) );");
-      output.println("     ++("+paramsprefix+"->common.numRunningChildren);");
-      output.println("     pthread_mutex_unlock( &("+paramsprefix+"->common.lock) );");      
+      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
@@ -2854,6 +2944,9 @@ public class BuildCode {
                           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) );");
@@ -2864,23 +2957,31 @@ public class BuildCode {
     output.println("     seseToIssue->common.doneExecuting = FALSE;");    
     output.println("     pthread_cond_init( &(seseToIssue->common.runningChildrenCond), NULL );");
     output.println("     seseToIssue->common.numRunningChildren = 0;");
-
-    if( fsen != mlpa.getMainSESE() ) {
-      output.println("     seseToIssue->common.parent = (SESEcommon*) "+paramsprefix+";");
-    } else {
-      output.println("     seseToIssue->common.parent = NULL;");
-    }
+    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 )+";");
+                      generateTemp( fsen.getParent().getfmBogus(), temp, null )+";");   
       } else {
        output.println("     seseToIssue->"+temp+" = "+
-                      generateTemp( state.getMethodFlat( typeutil.getMain() ), temp, null )+";");
+                      generateTemp( fsen.getfmEnclosing(), temp, null )+";");
       }
     }
 
@@ -2937,8 +3038,22 @@ public class BuildCode {
        output.println("         pthread_mutex_unlock( &(src->lock) );");       
        output.println("         seseToIssue->"+dynInVar+"_srcOffset = "+dynInVar+"_srcOffset;");
        output.println("       } else {");
-       output.println("         seseToIssue->"+dynInVar+" = "+
-                      generateTemp( fsen.getParent().getfmBogus(), dynInVar, null )+";");
+
+       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("     }");
        
@@ -2948,9 +3063,13 @@ public class BuildCode {
       }
       
       // maintain pointers for for finding dynamic SESE 
-      // instances from static names
+      // instances from static names      
       SESEandAgePair p = new SESEandAgePair( fsen, 0 );
-      if( fsen.getParent().getNeededStaticNames().contains( p ) ) {
+      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 );
@@ -2977,11 +3096,25 @@ public class BuildCode {
                                        FlatSESEExitNode fsexn, 
                                        PrintWriter output
                                      ) {
+
+    // if MLP flag is off, okay that SESE nodes are in IR graph, 
+    // just skip over them and code generates exactly the same 
     if( !state.MLP ) {
-      // SESE nodes can be parsed for normal compilation, just skip over them
       return;
     }
 
+    // there may be an SESE in an unreachable method, skip over
+    if( !mlpa.getAllSESEs().contains( fsexn.getFlatEnter() ) ) {
+      return;
+    }
+
+    // also, if we have encountered a placeholder, just jump it
+    if( fsexn.getFlatEnter().getIsCallerSESEplaceholder() ) {
+      return;
+    }
+
+    output.println("   /* SESE exiting */");
+
     String com = paramsprefix+"->common";
 
     // this SESE cannot be done until all of its children are done
@@ -2991,7 +3124,6 @@ public class BuildCode {
     output.println("   while( "+com+".numRunningChildren > 0 ) {");
     output.println("     pthread_cond_wait( &("+com+".runningChildrenCond), &("+com+".lock) );");
     output.println("   }");
-    //output.println("   pthread_mutex_unlock( &("+com+".lock) );");    
 
     // copy out-set from local temps into the sese record
     Iterator<TempDescriptor> itr = fsexn.getFlatEnter().getOutVarSet().iterator();
@@ -3003,7 +3135,6 @@ public class BuildCode {
     }    
     
     // mark yourself done, your SESE data is now read-only
-    //output.println("   pthread_mutex_lock( &("+com+".lock) );");
     output.println("   "+com+".doneExecuting = TRUE;");
     output.println("   pthread_cond_signal( &("+com+".doneCond) );");
     output.println("   pthread_mutex_unlock( &("+com+".lock) );");
@@ -3031,6 +3162,11 @@ public class BuildCode {
     output.println("     pthread_cond_signal( &("+paramsprefix+"->common.parent->runningChildrenCond) );");
     output.println("     pthread_mutex_unlock( &("+paramsprefix+"->common.parent->lock) );");
     output.println("   }");    
+
+    // this is a thread-only variable that can be handled when critical sese-to-sese
+    // data has been taken care of--set sese pointer to remember self over method
+    // calls to a non-zero, invalid address
+    output.println("   seseCaller = (SESEcommon*) 0x1;");    
   }
 
   public void generateFlatWriteDynamicVarNode( FlatMethod fm,  
@@ -3109,6 +3245,11 @@ public class BuildCode {
   }
 
   private void generateFlatCall(FlatMethod fm, LocalityBinding lb, FlatCall fc, PrintWriter output) {
+
+    if( state.MLP && !nonSESEpass ) {
+      output.println("     seseCaller = (SESEcommon*)"+paramsprefix+";");
+    }
+
     MethodDescriptor md=fc.getMethod();
     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? locality.getBinding(lb, fc) : md);
     ClassDescriptor cn=md.getClassDesc();
@@ -3761,12 +3902,6 @@ public class BuildCode {
     } else
       output.print(task.getSafeSymbol()+"(");
     
-    /*
-    if (addSESErecord) {
-      output.print("SESErecord* currentSESE, ");
-    }
-    */
-
     boolean printcomma=false;
     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
       if (md!=null) {