cpaturing some makefile updates and have OoOJava print number of sites disjoint reach...
[IRC.git] / Robust / src / Analysis / Disjoint / DisjointAnalysis.java
index 49aebc74717d66b2156e2f2a8a22d927e4caf72f..129bffd2ddafff07ed8f643d16c9c1ecb83dde25 100644 (file)
@@ -3,6 +3,8 @@ package Analysis.Disjoint;
 import Analysis.CallGraph.*;
 import Analysis.Liveness;
 import Analysis.ArrayReferencees;
+import Analysis.OoOJava.RBlockRelationAnalysis;
+import Analysis.OoOJava.RBlockStatusAnalysis;
 import IR.*;
 import IR.Flat.*;
 import IR.Tree.Modifiers;
@@ -12,86 +14,124 @@ import java.io.*;
 
 public class DisjointAnalysis {
        
-         ///////////////////////////////////////////
-         //
-         //  Public interface to discover possible
-         //  aliases in the program under analysis
-         //
-         ///////////////////////////////////////////
-       
-         public HashSet<AllocSite>
-         getFlaggedAllocationSitesReachableFromTask(TaskDescriptor td) {
-           checkAnalysisComplete();
-           return getFlaggedAllocationSitesReachableFromTaskPRIVATE(td);
-         }
+  ///////////////////////////////////////////
+  //
+  //  Public interface to discover possible
+  //  sharing in the program under analysis
+  //
+  ///////////////////////////////////////////
+
+  // if an object allocated at the target site may be
+  // reachable from both an object from root1 and an
+  // object allocated at root2, return TRUE
+  public boolean mayBothReachTarget( FlatMethod fm,
+                                     FlatNew fnRoot1,
+                                     FlatNew fnRoot2,
+                                     FlatNew fnTarget ) {
+    
+    AllocSite asr1 = getAllocationSiteFromFlatNew( fnRoot1 );
+    AllocSite asr2 = getAllocationSiteFromFlatNew( fnRoot2 );
+    assert asr1.isFlagged();
+    assert asr2.isFlagged();
+
+    AllocSite ast = getAllocationSiteFromFlatNew( fnTarget );
+    ReachGraph rg = getPartial( fm.getMethod() );
+
+    return rg.mayBothReachTarget( asr1, asr2, ast );
+  }
+
+  // similar to the method above, return TRUE if ever
+  // more than one object from the root allocation site
+  // may reach an object from the target site
+  public boolean mayManyReachTarget( FlatMethod fm,
+                                     FlatNew fnRoot,
+                                     FlatNew fnTarget ) {
+    
+    AllocSite asr = getAllocationSiteFromFlatNew( fnRoot );
+    assert asr.isFlagged();
+    
+    AllocSite ast = getAllocationSiteFromFlatNew( fnTarget );    
+    ReachGraph rg = getPartial( fm.getMethod() );
+    
+    return rg.mayManyReachTarget( asr, ast );
+  }
+
+
+
+  
+  public HashSet<AllocSite>
+    getFlaggedAllocationSitesReachableFromTask(TaskDescriptor td) {
+    checkAnalysisComplete();
+    return getFlaggedAllocationSitesReachableFromTaskPRIVATE(td);
+  }
          
-         public AllocSite getAllocationSiteFromFlatNew(FlatNew fn) {
-                   checkAnalysisComplete();
-                   return getAllocSiteFromFlatNewPRIVATE(fn);
-          }      
+  public AllocSite getAllocationSiteFromFlatNew(FlatNew fn) {
+    checkAnalysisComplete();
+    return getAllocSiteFromFlatNewPRIVATE(fn);
+  }      
          
-         public AllocSite getAllocationSiteFromHeapRegionNodeID(Integer id) {
-                   checkAnalysisComplete();
-                   return mapHrnIdToAllocSite.get(id);
-         }
+  public AllocSite getAllocationSiteFromHeapRegionNodeID(Integer id) {
+    checkAnalysisComplete();
+    return mapHrnIdToAllocSite.get(id);
+  }
          
-         public Set<HeapRegionNode> hasPotentialSharing(Descriptor taskOrMethod,
-              int paramIndex1,
-              int paramIndex2) {
-                 checkAnalysisComplete();
-                 ReachGraph rg=mapDescriptorToCompleteReachGraph.get(taskOrMethod);
-                 FlatMethod fm=state.getMethodFlat(taskOrMethod);
-                 assert(rg != null);
-                 return rg.mayReachSharedObjects(fm, paramIndex1, paramIndex2);
-         }
+  public Set<HeapRegionNode> hasPotentialSharing(Descriptor taskOrMethod,
+                                                 int paramIndex1,
+                                                 int paramIndex2) {
+    checkAnalysisComplete();
+    ReachGraph rg=mapDescriptorToCompleteReachGraph.get(taskOrMethod);
+    FlatMethod fm=state.getMethodFlat(taskOrMethod);
+    assert(rg != null);
+    return rg.mayReachSharedObjects(fm, paramIndex1, paramIndex2);
+  }
          
-       public Set<HeapRegionNode> hasPotentialSharing(Descriptor taskOrMethod,
-                       int paramIndex, AllocSite alloc) {
-               checkAnalysisComplete();
-               ReachGraph rg = mapDescriptorToCompleteReachGraph.get(taskOrMethod);
-           FlatMethod fm=state.getMethodFlat(taskOrMethod);
-               assert (rg != null);
-               return rg.mayReachSharedObjects(fm, paramIndex, alloc);
-       }
+  public Set<HeapRegionNode> hasPotentialSharing(Descriptor taskOrMethod,
+                                                 int paramIndex, AllocSite alloc) {
+    checkAnalysisComplete();
+    ReachGraph rg = mapDescriptorToCompleteReachGraph.get(taskOrMethod);
+    FlatMethod fm=state.getMethodFlat(taskOrMethod);
+    assert (rg != null);
+    return rg.mayReachSharedObjects(fm, paramIndex, alloc);
+  }
 
-       public Set<HeapRegionNode> hasPotentialSharing(Descriptor taskOrMethod,
-                       AllocSite alloc, int paramIndex) {
-               checkAnalysisComplete();
-               ReachGraph rg  = mapDescriptorToCompleteReachGraph.get(taskOrMethod);
-               FlatMethod fm=state.getMethodFlat(taskOrMethod);
-               assert (rg != null);
-               return rg.mayReachSharedObjects(fm, paramIndex, alloc);
-       }
+  public Set<HeapRegionNode> hasPotentialSharing(Descriptor taskOrMethod,
+                                                 AllocSite alloc, int paramIndex) {
+    checkAnalysisComplete();
+    ReachGraph rg  = mapDescriptorToCompleteReachGraph.get(taskOrMethod);
+    FlatMethod fm=state.getMethodFlat(taskOrMethod);
+    assert (rg != null);
+    return rg.mayReachSharedObjects(fm, paramIndex, alloc);
+  }
 
-       public Set<HeapRegionNode> hasPotentialSharing(Descriptor taskOrMethod,
-                       AllocSite alloc1, AllocSite alloc2) {
-               checkAnalysisComplete();
-               ReachGraph rg  = mapDescriptorToCompleteReachGraph.get(taskOrMethod);
-               assert (rg != null);
-               return rg.mayReachSharedObjects(alloc1, alloc2);
-       }
+  public Set<HeapRegionNode> hasPotentialSharing(Descriptor taskOrMethod,
+                                                 AllocSite alloc1, AllocSite alloc2) {
+    checkAnalysisComplete();
+    ReachGraph rg  = mapDescriptorToCompleteReachGraph.get(taskOrMethod);
+    assert (rg != null);
+    return rg.mayReachSharedObjects(alloc1, alloc2);
+  }
        
-       public String prettyPrintNodeSet(Set<HeapRegionNode> s) {
-               checkAnalysisComplete();
+  public String prettyPrintNodeSet(Set<HeapRegionNode> s) {
+    checkAnalysisComplete();
 
-               String out = "{\n";
+    String out = "{\n";
 
-               Iterator<HeapRegionNode> i = s.iterator();
-               while (i.hasNext()) {
-                       HeapRegionNode n = i.next();
+    Iterator<HeapRegionNode> i = s.iterator();
+    while (i.hasNext()) {
+      HeapRegionNode n = i.next();
 
-                       AllocSite as = n.getAllocSite();
-                       if (as == null) {
-                               out += "  " + n.toString() + ",\n";
-                       } else {
-                               out += "  " + n.toString() + ": " + as.toStringVerbose()
-                                               + ",\n";
-                       }
-               }
+      AllocSite as = n.getAllocSite();
+      if (as == null) {
+        out += "  " + n.toString() + ",\n";
+      } else {
+        out += "  " + n.toString() + ": " + as.toStringVerbose()
+          + ",\n";
+      }
+    }
 
-               out += "}\n";
-               return out;
-       }
+    out += "}\n";
+    return out;
+  }
        
   // use the methods given above to check every possible sharing class
   // between task parameters and flagged allocation sites reachable
@@ -233,8 +273,15 @@ public class DisjointAnalysis {
 
     bw.close();
   }
+
+
        
   // this version of writeAllSharing is for Java programs that have no tasks
+  // ***********************************
+  // WARNING: THIS DOES NOT DO THE RIGHT THING, REPORTS 0 ALWAYS!
+  // It should use mayBothReachTarget and mayManyReachTarget like
+  // OoOJava does to query analysis results
+  // ***********************************
   public void writeAllSharingJava(String outputFile, 
                                   String timeReport,
                                   String justTime,
@@ -306,6 +353,8 @@ public class DisjointAnalysis {
   //
   ///////////////////////////////////////////
 
+
+
   protected void checkAnalysisComplete() {
     if( !analysisComplete ) {
       throw new Error("Warning: public interface method called while analysis is running.");
@@ -313,6 +362,10 @@ public class DisjointAnalysis {
   } 
 
 
+
+
+
+
   // run in faster mode, only when bugs wrung out!
   public static boolean releaseMode;
 
@@ -320,16 +373,29 @@ public class DisjointAnalysis {
   // should attempt to be deterministic
   public static boolean determinismDesired;
 
+  // when we want to enforce determinism in the 
+  // analysis we need to sort descriptors rather
+  // than toss them in efficient sets, use this
+  public static DescriptorComparator dComp =
+    new DescriptorComparator();
+
+
   // data from the compiler
   public State            state;
   public CallGraph        callGraph;
   public Liveness         liveness;
   public ArrayReferencees arrayReferencees;
+  public RBlockRelationAnalysis rblockRel;
+  public RBlockStatusAnalysis rblockStatus;
   public TypeUtil         typeUtil;
   public int              allocationDepth;
+
+  protected boolean doEffectsAnalysis = false;
+  protected EffectsAnalysis effectsAnalysis;
   
   // data structure for public interface
-  private Hashtable<Descriptor,    HashSet<AllocSite> > mapDescriptorToAllocSiteSet;
+  private Hashtable< Descriptor, HashSet<AllocSite> > 
+    mapDescriptorToAllocSiteSet;
 
   
   // for public interface methods to warn that they
@@ -405,6 +471,11 @@ public class DisjointAnalysis {
   protected Hashtable< Descriptor, Set<Descriptor> >
     mapDescriptorToSetDependents;
 
+  // if the analysis client wants to flag allocation sites
+  // programmatically, it should provide a set of FlatNew
+  // statements--this may be null if unneeded
+  protected Set<FlatNew> sitesToFlag;
+
   // maps each flat new to one analysis abstraction
   // allocate site object, these exist outside reach graphs
   protected Hashtable<FlatNew, AllocSite>
@@ -461,6 +532,8 @@ public class DisjointAnalysis {
   static protected Hashtable<FlatNode, ReachGraph> fn2rg =
     new Hashtable<FlatNode, ReachGraph>();
 
+  private Hashtable<FlatCall, Descriptor> fc2enclosing;  
+
 
   // allocate various structures that are not local
   // to a single class method--should be done once
@@ -468,9 +541,7 @@ public class DisjointAnalysis {
     
     if( determinismDesired ) {
       // use an ordered set
-      descriptorsToAnalyze 
-        = new TreeSet<Descriptor>( new DescriptorComparator() );
-      
+      descriptorsToAnalyze = new TreeSet<Descriptor>( dComp );      
     } else {
       // otherwise use a speedy hashset
       descriptorsToAnalyze = new HashSet<Descriptor>();
@@ -496,7 +567,7 @@ public class DisjointAnalysis {
 
     mapBackEdgeToMonotone =
       new Hashtable<FlatNode, ReachGraph>();
-
+    
     mapHrnIdToAllocSite =
       new Hashtable<Integer, AllocSite>();
 
@@ -531,6 +602,8 @@ public class DisjointAnalysis {
        new Hashtable<Descriptor, ReachGraph>();
 
     pm = new PointerMethod();
+
+    fc2enclosing = new Hashtable<FlatCall, Descriptor>();
   }
 
 
@@ -541,31 +614,60 @@ public class DisjointAnalysis {
                           TypeUtil         tu,
                           CallGraph        cg,
                           Liveness         l,
-                          ArrayReferencees ar
-                           ) throws java.io.IOException {
-    init( s, tu, cg, l, ar );
+                          ArrayReferencees ar,
+                           Set<FlatNew> sitesToFlag,
+                           RBlockRelationAnalysis rra,
+                           RBlockStatusAnalysis rsa
+                           ) {
+    init( s, tu, cg, l, ar, sitesToFlag, rra, rsa, false );
+  }
+
+  public DisjointAnalysis( State            s,
+                          TypeUtil         tu,
+                          CallGraph        cg,
+                          Liveness         l,
+                          ArrayReferencees ar,
+                           Set<FlatNew> sitesToFlag,
+                           RBlockRelationAnalysis rra,
+                           RBlockStatusAnalysis rsa,
+                           boolean suppressOutput
+                           ) {
+    init( s, tu, cg, l, ar, sitesToFlag, rra, rsa, suppressOutput );
   }
   
   protected void init( State            state,
                        TypeUtil         typeUtil,
                        CallGraph        callGraph,
                        Liveness         liveness,
-                       ArrayReferencees arrayReferencees
-                       ) throws java.io.IOException {
+                       ArrayReferencees arrayReferencees,
+                       Set<FlatNew> sitesToFlag,
+                       RBlockRelationAnalysis rra,
+                       RBlockStatusAnalysis rsa,
+                       boolean suppressOutput
+                       ) {
          
     analysisComplete = false;
     
-    this.state                   = state;
-    this.typeUtil                = typeUtil;
-    this.callGraph               = callGraph;
-    this.liveness                = liveness;
-    this.arrayReferencees        = arrayReferencees;
+    this.state            = state;
+    this.typeUtil         = typeUtil;
+    this.callGraph        = callGraph;
+    this.liveness         = liveness;
+    this.arrayReferencees = arrayReferencees;
+    this.sitesToFlag      = sitesToFlag;
+    this.rblockRel        = rra;
+    this.rblockStatus     = rsa;
+
+    if( rblockRel != null ) {
+      doEffectsAnalysis = true;
+      effectsAnalysis   = new EffectsAnalysis();
+    }
+
     this.allocationDepth         = state.DISJOINTALLOCDEPTH;
     this.releaseMode             = state.DISJOINTRELEASEMODE;
     this.determinismDesired      = state.DISJOINTDETERMINISM;
 
-    this.writeFinalDOTs          = state.DISJOINTWRITEDOTS && !state.DISJOINTWRITEALL;
-    this.writeAllIncrementalDOTs = state.DISJOINTWRITEDOTS &&  state.DISJOINTWRITEALL;
+    this.writeFinalDOTs          = state.DISJOINTWRITEDOTS && !state.DISJOINTWRITEALL && !suppressOutput;
+    this.writeAllIncrementalDOTs = state.DISJOINTWRITEDOTS &&  state.DISJOINTWRITEALL && !suppressOutput;
 
     this.takeDebugSnapshots      = state.DISJOINTSNAPSYMBOL != null;
     this.descSymbolDebug         = state.DISJOINTSNAPSYMBOL;
@@ -606,35 +708,57 @@ public class DisjointAnalysis {
     double timeStartAnalysis = (double) System.nanoTime();
 
     // start interprocedural fixed-point computation
-    analyzeMethods();
+    try {
+      analyzeMethods();
+    } catch( IOException e ) {
+      throw new Error( "IO Exception while writing disjointness analysis output." );
+    }
+
     analysisComplete=true;
 
+
     double timeEndAnalysis = (double) System.nanoTime();
     double dt = (timeEndAnalysis - timeStartAnalysis)/(Math.pow( 10.0, 9.0 ) );
-    String treport = String.format( "The reachability analysis took %.3f sec.", dt );
+
+    String treport;
+    if( sitesToFlag != null ) {
+      treport = String.format( "Disjoint reachability analysis flagged %d sites and took %.3f sec.", sitesToFlag.size(), dt );
+    } else {
+      treport = String.format( "Disjoint reachability analysis took %.3f sec.", dt );
+    }
     String justtime = String.format( "%.2f", dt );
     System.out.println( treport );
 
-    if( writeFinalDOTs && !writeAllIncrementalDOTs ) {
-      writeFinalGraphs();      
-    }
 
-    if( state.DISJOINTWRITEIHMS ) {
-      writeFinalIHMs();
-    }
+    try {
+      if( writeFinalDOTs && !writeAllIncrementalDOTs ) {
+        writeFinalGraphs();      
+      }
 
-    if( state.DISJOINTALIASFILE != null ) {
-      if( state.TASK ) {
-        writeAllSharing(state.DISJOINTALIASFILE, treport, justtime, state.DISJOINTALIASTAB, state.lines);
-      } else {
-        writeAllSharingJava(state.DISJOINTALIASFILE, 
-                            treport, 
-                            justtime, 
-                            state.DISJOINTALIASTAB, 
-                            state.lines
-                            );
+      if( state.DISJOINTWRITEIHMS && !suppressOutput ) {
+        writeFinalIHMs();
+      }
+
+      if( state.DISJOINTWRITEINITCONTEXTS && !suppressOutput ) {
+        writeInitialContexts();
       }
+
+      if( state.DISJOINTALIASFILE != null && !suppressOutput ) {
+        if( state.TASK ) {
+          writeAllSharing(state.DISJOINTALIASFILE, treport, justtime, state.DISJOINTALIASTAB, state.lines);
+        } else {
+          writeAllSharingJava(state.DISJOINTALIASFILE, 
+                              treport, 
+                              justtime, 
+                              state.DISJOINTALIASTAB, 
+                              state.lines
+                              );
+        }
+      }
+    } catch( IOException e ) {
+      throw new Error( "IO Exception while writing disjointness analysis output." );
     }
+
   }
 
 
@@ -791,35 +915,23 @@ public class DisjointAnalysis {
             System.out.println( "    "+dNext );
           }
        }
+      }
 
-        if( state.DISJOINTDVISITSTACKEESONTOP ) {
-
-          if( state.DISJOINTDEBUGSCHEDULING ) {
-            System.out.println( "  contexts changed, scheduling callees for analysis:" );
-          }
-
-          depsItr = calleesToEnqueue.iterator();
-          while( depsItr.hasNext() ) {
-            Descriptor dNext = depsItr.next();
-            enqueue( dNext );
-
-            if( state.DISJOINTDEBUGSCHEDULING ) {
-              System.out.println( "    "+dNext );
-            }
-          }
-          calleesToEnqueue.clear();
+      // whether or not the method under analysis changed,
+      // we may have some callees that are scheduled for 
+      // more analysis, and they should go on the top of
+      // the stack now (in other method-visiting modes they
+      // are already enqueued at this point
+      if( state.DISJOINTDVISITSTACKEESONTOP ) {
+        Iterator<Descriptor> depsItr = calleesToEnqueue.iterator();
+        while( depsItr.hasNext() ) {
+          Descriptor dNext = depsItr.next();
+          enqueue( dNext );
         }
+        calleesToEnqueue.clear();
+      }     
 
-      } else {
-        // we got the result result as the last visit
-        // to this method, but we might need to clean
-        // something up
-        if( state.DISJOINTDVISITSTACKEESONTOP ) {
-          calleesToEnqueue.clear();
-        }
-      }
-     
-    }
+    }   
   }
 
   protected ReachGraph analyzeMethod( Descriptor d ) 
@@ -891,7 +1003,7 @@ public class DisjointAnalysis {
          rg.merge( rgParent );
        }
       }
-
+      
 
       if( takeDebugSnapshots && 
          d.getSymbol().equals( descSymbolDebug ) 
@@ -983,10 +1095,13 @@ public class DisjointAnalysis {
     // nullified in the graph to reduce edges
     //rg.nullifyDeadVars( liveness.getLiveInTemps( fmContaining, fn ) );
 
-         
-    TempDescriptor  lhs;
-    TempDescriptor  rhs;
-    FieldDescriptor fld;
+    TempDescriptor    lhs;
+    TempDescriptor    rhs;
+    FieldDescriptor   fld;
+    TypeDescriptor    tdElement;
+    FieldDescriptor   fdElement;
+    FlatSESEEnterNode sese;
+    FlatSESEExitNode  fsexn;
 
     // use node type to decide what transfer function
     // to apply to the reachability graph
@@ -1027,7 +1142,19 @@ public class DisjointAnalysis {
       if( fon.getOp().getOp() == Operation.ASSIGN ) {
        lhs = fon.getDest();
        rhs = fon.getLeft();
-       rg.assignTempXEqualToTempY( lhs, rhs );
+
+        // before transfer, do effects analysis support
+        if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+          if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+            // x gets status of y
+            if(!rg.isAccessible(rhs)){
+              rg.makeInaccessible(lhs);
+            }
+          }    
+        }
+
+        // transfer func
+       rg.assignTempXEqualToTempY( lhs, rhs ); 
       }
       break;
 
@@ -1038,65 +1165,183 @@ public class DisjointAnalysis {
 
       TypeDescriptor td = fcn.getType();
       assert td != null;
+
+      // before transfer, do effects analysis support
+      if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+        if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+          // x gets status of y
+          if(!rg.isAccessible(rhs)){
+            rg.makeInaccessible(lhs);
+          }
+        }    
+      }
       
+      // transfer func
       rg.assignTempXEqualToCastedTempY( lhs, rhs, td );
       break;
 
     case FKind.FlatFieldNode:
       FlatFieldNode ffn = (FlatFieldNode) fn;
+
       lhs = ffn.getDst();
       rhs = ffn.getSrc();
       fld = ffn.getField();
-      if( shouldAnalysisTrack( fld.getType() ) ) {
+
+      // before graph transform, possible inject
+      // a stall-site taint
+      if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+
+        if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+          // x=y.f, stall y if not accessible
+          // contributes read effects on stall site of y
+          if(!rg.isAccessible(rhs)) {
+            rg.taintStallSite(fn, rhs);
+          }
+
+          // after this, x and y are accessbile. 
+          rg.makeAccessible(lhs);
+          rg.makeAccessible(rhs);            
+        }
+      }
+
+      if( shouldAnalysisTrack( fld.getType() ) ) {       
+        // transfer func
        rg.assignTempXEqualToTempYFieldF( lhs, rhs, fld );
       }          
+
+      // after transfer, use updated graph to
+      // do effects analysis
+      if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+        effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fld );          
+      }
       break;
 
     case FKind.FlatSetFieldNode:
       FlatSetFieldNode fsfn = (FlatSetFieldNode) fn;
+
       lhs = fsfn.getDst();
       fld = fsfn.getField();
       rhs = fsfn.getSrc();
+
+      boolean strongUpdate = false;
+
+      // before transfer func, possibly inject
+      // stall-site taints
+      if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+
+        if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+          // x.y=f , stall x and y if they are not accessible
+          // also contribute write effects on stall site of x
+          if(!rg.isAccessible(lhs)) {
+            rg.taintStallSite(fn, lhs);
+          }
+
+          if(!rg.isAccessible(rhs)) {
+            rg.taintStallSite(fn, rhs);
+          }
+
+          // accessible status update
+          rg.makeAccessible(lhs);
+          rg.makeAccessible(rhs);            
+        }
+      }
+
       if( shouldAnalysisTrack( fld.getType() ) ) {
-       rg.assignTempXFieldFEqualToTempY( lhs, fld, rhs );
+        // transfer func
+        strongUpdate = rg.assignTempXFieldFEqualToTempY( lhs, fld, rhs );
       }           
+
+      // use transformed graph to do effects analysis
+      if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+        effectsAnalysis.analyzeFlatSetFieldNode( rg, lhs, fld, strongUpdate );          
+      }
       break;
 
     case FKind.FlatElementNode:
       FlatElementNode fen = (FlatElementNode) fn;
+
       lhs = fen.getDst();
       rhs = fen.getSrc();
-      if( shouldAnalysisTrack( lhs.getType() ) ) {
 
-       assert rhs.getType() != null;
-       assert rhs.getType().isArray();
-       
-       TypeDescriptor  tdElement = rhs.getType().dereference();
-       FieldDescriptor fdElement = getArrayField( tdElement );
-  
+      assert rhs.getType() != null;
+      assert rhs.getType().isArray();
+
+      tdElement = rhs.getType().dereference();
+      fdElement = getArrayField( tdElement );
+
+      // before transfer func, possibly inject
+      // stall-site taint
+      if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+          
+        if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+          // x=y.f, stall y if not accessible
+          // contributes read effects on stall site of y
+          // after this, x and y are accessbile. 
+          if(!rg.isAccessible(rhs)) {
+            rg.taintStallSite(fn, rhs);
+          }
+
+          rg.makeAccessible(lhs);
+          rg.makeAccessible(rhs);            
+        }
+      }
+
+      if( shouldAnalysisTrack( lhs.getType() ) ) {
+        // transfer func
        rg.assignTempXEqualToTempYFieldF( lhs, rhs, fdElement );
       }
+
+      // use transformed graph to do effects analysis
+      if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+        effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fdElement );                    
+      }        
       break;
 
     case FKind.FlatSetElementNode:
       FlatSetElementNode fsen = (FlatSetElementNode) fn;
 
-      if( arrayReferencees.doesNotCreateNewReaching( fsen ) ) {
-       // skip this node if it cannot create new reachability paths
-        break;
-      }
-
       lhs = fsen.getDst();
       rhs = fsen.getSrc();
-      if( shouldAnalysisTrack( rhs.getType() ) ) {
 
-       assert lhs.getType() != null;
-       assert lhs.getType().isArray();
-       
-       TypeDescriptor  tdElement = lhs.getType().dereference();
-       FieldDescriptor fdElement = getArrayField( tdElement );
+      assert lhs.getType() != null;
+      assert lhs.getType().isArray();  
+
+      tdElement = lhs.getType().dereference();
+      fdElement = getArrayField( tdElement );
+
+      // before transfer func, possibly inject
+      // stall-site taints
+      if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+          
+        if(rblockStatus.isInCriticalRegion(fmContaining, fn)){
+          // x.y=f , stall x and y if they are not accessible
+          // also contribute write effects on stall site of x
+          if(!rg.isAccessible(lhs)) {
+            rg.taintStallSite(fn, lhs);
+          }
+
+          if(!rg.isAccessible(rhs)) {
+            rg.taintStallSite(fn, rhs);
+          }
+            
+          // accessible status update
+          rg.makeAccessible(lhs);
+          rg.makeAccessible(rhs);            
+        }
+      }
 
-       rg.assignTempXFieldFEqualToTempY( lhs, fdElement, rhs );
+      if( shouldAnalysisTrack( rhs.getType() ) ) {
+        // transfer func, BUT
+        // skip this node if it cannot create new reachability paths
+        if( !arrayReferencees.doesNotCreateNewReaching( fsen ) ) {
+          rg.assignTempXFieldFEqualToTempY( lhs, fdElement, rhs );
+        }
+      }
+
+      // use transformed graph to do effects analysis
+      if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+        effectsAnalysis.analyzeFlatSetFieldNode( rg, lhs, fdElement,
+                                                 false );          
       }
       break;
       
@@ -1105,10 +1350,58 @@ public class DisjointAnalysis {
       lhs = fnn.getDst();
       if( shouldAnalysisTrack( lhs.getType() ) ) {
        AllocSite as = getAllocSiteFromFlatNewPRIVATE( fnn );   
-       rg.assignTempEqualToNewAlloc( lhs, as );
+
+        // before transform, support effects analysis
+        if (doEffectsAnalysis && fmContaining != fmAnalysisEntry) {
+          if (rblockStatus.isInCriticalRegion(fmContaining, fn)) {
+            // after creating new object, lhs is accessible
+            rg.makeAccessible(lhs);
+          }
+        } 
+
+        // transfer func
+       rg.assignTempEqualToNewAlloc( lhs, as );        
+      }
+      break;
+
+    case FKind.FlatSESEEnterNode:
+      sese = (FlatSESEEnterNode) fn;
+
+      if( sese.getIsCallerSESEplaceholder() ) {
+        // ignore these dummy rblocks!
+        break;
+      }
+
+      if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+        
+        // always remove ALL stall site taints at enter
+        rg.removeAllStallSiteTaints();
+
+        // inject taints for in-set vars      
+        rg.taintInSetVars( sese );
+
+      }
+      break;
+
+    case FKind.FlatSESEExitNode:
+      fsexn = (FlatSESEExitNode) fn;
+      sese  = fsexn.getFlatEnter();
+
+      if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+
+        // @ sese exit make all live variables
+        // inaccessible to later parent statements
+        rg.makeInaccessible( liveness.getLiveInTemps( fmContaining, fn ) );
+        
+        // always remove ALL stall site taints at exit
+        rg.removeAllStallSiteTaints();
+        
+        // remove in-set var taints for the exiting rblock
+        rg.removeInContextTaints( sese );
       }
       break;
 
+
     case FKind.FlatCall: {
       Descriptor mdCaller;
       if( fmContaining.getMethod() != null ){
@@ -1119,8 +1412,7 @@ public class DisjointAnalysis {
       FlatCall         fc       = (FlatCall) fn;
       MethodDescriptor mdCallee = fc.getMethod();
       FlatMethod       fmCallee = state.getMethodFlat( mdCallee );
-
-
+  
       boolean debugCallSite =
         mdCaller.getSymbol().equals( state.DISJOINTDEBUGCALLER ) &&
         mdCallee.getSymbol().equals( state.DISJOINTDEBUGCALLEE );
@@ -1179,26 +1471,34 @@ public class DisjointAnalysis {
         // and reschedule the callee for analysis
         addIHMcontribution( mdCallee, fc, heapForThisCall_cur );        
 
+        // map a FlatCall to its enclosing method/task descriptor 
+        // so we can write that info out later
+        fc2enclosing.put( fc, mdCaller );
+
+        if( state.DISJOINTDEBUGSCHEDULING ) {
+          System.out.println( "  context changed, scheduling callee: "+mdCallee );
+        }
+
         if( state.DISJOINTDVISITSTACKEESONTOP ) {
           calleesToEnqueue.add( mdCallee );
         } else {
           enqueue( mdCallee );
-
-          if( state.DISJOINTDEBUGSCHEDULING ) {
-            System.out.println( "  context changed, scheduling callee: "+mdCallee );
-          }
-
         }
 
       }
 
-
       // the transformation for a call site should update the
       // current heap abstraction with any effects from the callee,
       // or if the method is virtual, the effects from any possible
       // callees, so find the set of callees...
-      Set<MethodDescriptor> setPossibleCallees =
-        new HashSet<MethodDescriptor>();
+      Set<MethodDescriptor> setPossibleCallees;
+      if( determinismDesired ) {
+        // use an ordered set
+        setPossibleCallees = new TreeSet<MethodDescriptor>( dComp );        
+      } else {
+        // otherwise use a speedy hashset
+        setPossibleCallees = new HashSet<MethodDescriptor>();
+      }
 
       if( mdCallee.isStatic() ) {        
         setPossibleCallees.add( mdCallee );
@@ -1209,7 +1509,7 @@ public class DisjointAnalysis {
                                    );
       }
 
-      ReachGraph rgMergeOfEffects = new ReachGraph();
+      ReachGraph rgMergeOfPossibleCallers = new ReachGraph();
 
       Iterator<MethodDescriptor> mdItr = setPossibleCallees.iterator();
       while( mdItr.hasNext() ) {
@@ -1222,34 +1522,43 @@ public class DisjointAnalysis {
         // don't alter the working graph (rg) until we compute a 
         // result for every possible callee, merge them all together,
         // then set rg to that
-        ReachGraph rgCopy = new ReachGraph();
-        rgCopy.merge( rg );            
+        ReachGraph rgPossibleCaller = new ReachGraph();
+        rgPossibleCaller.merge( rg );          
                 
-        ReachGraph rgEffect = getPartial( mdPossible );
+        ReachGraph rgPossibleCallee = getPartial( mdPossible );
 
-        if( rgEffect == null ) {
+        if( rgPossibleCallee == null ) {
           // if this method has never been analyzed just schedule it 
           // for analysis and skip over this call site for now
           if( state.DISJOINTDVISITSTACKEESONTOP ) {
             calleesToEnqueue.add( mdPossible );
           } else {
             enqueue( mdPossible );
+          }
+          
+          if( state.DISJOINTDEBUGSCHEDULING ) {
+            System.out.println( "  callee hasn't been analyzed, scheduling: "+mdPossible );
+          }
 
-            if( state.DISJOINTDEBUGSCHEDULING ) {
-              System.out.println( "  callee hasn't been analyzed, scheduling: "+mdPossible );
+
+        } else {
+          // calculate the method call transform         
+          rgPossibleCaller.resolveMethodCall( fc, 
+                                              fmPossible, 
+                                              rgPossibleCallee,
+                                              callerNodeIDsCopiedToCallee,
+                                              writeDebugDOTs
+                                              );
+
+          if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+            if( !rgPossibleCallee.isAccessible( ReachGraph.tdReturn ) ) {
+              rgPossibleCaller.makeInaccessible( fc.getReturnTemp() );
             }
           }
 
-        } else {
-          rgCopy.resolveMethodCall( fc, 
-                                    fmPossible, 
-                                    rgEffect,
-                                    callerNodeIDsCopiedToCallee,
-                                    writeDebugDOTs
-                                    );
         }
         
-        rgMergeOfEffects.merge( rgCopy );
+        rgMergeOfPossibleCallers.merge( rgPossibleCaller );        
       }
 
 
@@ -1261,16 +1570,25 @@ public class DisjointAnalysis {
 
       // now that we've taken care of building heap models for
       // callee analysis, finish this transformation
-      rg = rgMergeOfEffects;
+      rg = rgMergeOfPossibleCallers;
     } break;
       
 
     case FKind.FlatReturnNode:
       FlatReturnNode frn = (FlatReturnNode) fn;
       rhs = frn.getReturnTemp();
+
+      // before transfer, do effects analysis support
+      if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+        if(!rg.isAccessible(rhs)){
+          rg.makeInaccessible(ReachGraph.tdReturn);
+        }
+      }
+
       if( rhs != null && shouldAnalysisTrack( rhs.getType() ) ) {
        rg.assignReturnEqualToTemp( rhs );
       }
+
       setRetNodes.add( frn );
       break;
 
@@ -1334,11 +1652,13 @@ public class DisjointAnalysis {
       ReachGraph rg = (ReachGraph) me.getValue();
 
       rg.writeGraph( "COMPLETE"+d,
-                     true,   // write labels (variables)                
-                     true,   // selectively hide intermediate temp vars 
-                     true,   // prune unreachable heap regions          
-                     false,  // hide subset reachability states         
-                     true ); // hide edge taints                        
+                     true,    // write labels (variables)                
+                     true,    // selectively hide intermediate temp vars 
+                     true,    // prune unreachable heap regions          
+                     false,   // hide reachability altogether
+                     true,    // hide subset reachability states         
+                     true,    // hide predicates
+                     false ); // hide edge taints                        
     }
   }
 
@@ -1355,15 +1675,36 @@ public class DisjointAnalysis {
         FlatCall   fc  = (FlatCall)   me2.getKey();
         ReachGraph rg  = (ReachGraph) me2.getValue();
                 
-        rg.writeGraph( "IHMPARTFOR"+d+"FROM"+fc,
+        rg.writeGraph( "IHMPARTFOR"+d+"FROM"+fc2enclosing.get( fc )+fc,
                        true,   // write labels (variables)
                        true,   // selectively hide intermediate temp vars
+                       true,   // hide reachability altogether
                        true,   // prune unreachable heap regions
-                       false,  // hide subset reachability states
+                       true,   // hide subset reachability states
+                       false,  // hide predicates
                        true ); // hide edge taints
       }
     }
   }
+
+  private void writeInitialContexts() {
+    Set entrySet = mapDescriptorToInitialContext.entrySet();
+    Iterator itr = entrySet.iterator();
+    while( itr.hasNext() ) {
+      Map.Entry  me = (Map.Entry)  itr.next();
+      Descriptor  d = (Descriptor) me.getKey();
+      ReachGraph rg = (ReachGraph) me.getValue();
+
+      rg.writeGraph( "INITIAL"+d,
+                     true,   // write labels (variables)                
+                     true,   // selectively hide intermediate temp vars 
+                     true,   // prune unreachable heap regions          
+                     false,  // hide all reachability
+                     true,   // hide subset reachability states         
+                     true,   // hide predicates
+                     false );// hide edge taints                        
+    }
+  }
    
 
   protected ReachGraph getPartial( Descriptor d ) {
@@ -1388,8 +1729,10 @@ public class DisjointAnalysis {
                      true,   // write labels (variables)
                      true,   // selectively hide intermediate temp vars
                      true,   // prune unreachable heap regions
-                     false,  // hide subset reachability states
-                     true ); // hide edge taints
+                     false,  // hide all reachability
+                     true,   // hide subset reachability states
+                     false,  // hide predicates
+                     false); // hide edge taints
       
       mapDescriptorToNumUpdates.put( d, n + 1 );
     }
@@ -1400,10 +1743,16 @@ public class DisjointAnalysis {
   // return just the allocation site associated with one FlatNew node
   protected AllocSite getAllocSiteFromFlatNewPRIVATE( FlatNew fnew ) {
 
+    boolean flagProgrammatically = false;
+    if( sitesToFlag != null && sitesToFlag.contains( fnew ) ) {
+      flagProgrammatically = true;
+    }
+
     if( !mapFlatNewToAllocSite.containsKey( fnew ) ) {
       AllocSite as = AllocSite.factory( allocationDepth, 
                                         fnew, 
-                                        fnew.getDisjointId() 
+                                        fnew.getDisjointId(),
+                                        flagProgrammatically
                                         );
 
       // the newest nodes are single objects
@@ -1505,9 +1854,7 @@ public class DisjointAnalysis {
 
     if( determinismDesired ) {
       // use an ordered set
-      discovered
-        = new TreeSet<Descriptor>( new DescriptorComparator() );
-      
+      discovered = new TreeSet<Descriptor>( dComp );      
     } else {
       // otherwise use a speedy hashset
       discovered = new HashSet<Descriptor>();
@@ -1644,12 +1991,13 @@ public class DisjointAnalysis {
       getIHMcontributions( d );
 
     if( !heapsFromCallers.containsKey( fc ) ) {
-      heapsFromCallers.put( fc, new ReachGraph() );
+      return null;
     }
 
     return heapsFromCallers.get( fc );
   }
 
+
   public void addIHMcontribution( Descriptor d,
                                   FlatCall   fc,
                                   ReachGraph rg
@@ -1660,6 +2008,7 @@ public class DisjointAnalysis {
     heapsFromCallers.put( fc, rg );
   }
 
+
   private AllocSite createParameterAllocSite( ReachGraph     rg, 
                                               TempDescriptor tempDesc,
                                               boolean        flagRegions
@@ -1683,7 +2032,8 @@ public class DisjointAnalysis {
     // create allocation site
     AllocSite as = AllocSite.factory( allocationDepth, 
                                       flatNew, 
-                                      flatNew.getDisjointId()
+                                      flatNew.getDisjointId(),
+                                      false
                                       );
     for (int i = 0; i < allocationDepth; ++i) {
        Integer id = generateUniqueHeapRegionNodeID();
@@ -1755,12 +2105,13 @@ private Set<FieldDescriptor> getFieldSetTobeAnalyzed(TypeDescriptor typeDesc){
            
            if(prevNode==null){
                    // make a new reference between new summary node and source
-                   RefEdge edgeToSummary = new RefEdge(srcHRN, // source
+              RefEdge edgeToSummary = new RefEdge(srcHRN, // source
                                                        hrnSummary, // dest
                                                        typeDesc, // type
                                                        fd.getSymbol(), // field name
                                                        alpha, // beta
-                                                       ExistPredSet.factory(rg.predTrue) // predicates
+                                                  ExistPredSet.factory(rg.predTrue), // predicates
+                                                  null
                                                        );
                    
                    rg.addRefEdge(srcHRN, hrnSummary, edgeToSummary);
@@ -1773,7 +2124,8 @@ private Set<FieldDescriptor> getFieldSetTobeAnalyzed(TypeDescriptor typeDesc){
                                                        typeDesc, // type
                                                        arrayElementFieldName, // field name
                                                        alpha, // beta
-                                                       ExistPredSet.factory(rg.predTrue) // predicates
+                                                       ExistPredSet.factory(rg.predTrue), // predicates
+                                                        null
                                                        );
                    
                    rg.addRefEdge(prevNode, hrnSummary, edgeToSummary);
@@ -1810,19 +2162,21 @@ private Set<FieldDescriptor> getFieldSetTobeAnalyzed(TypeDescriptor typeDesc){
                                        typeDesc, // type
                                        arrayElementFieldName, // field name
                                         alpha, // beta
-                                       ExistPredSet.factory(rg.predTrue) // predicates
+                                                        ExistPredSet.factory(rg.predTrue), // predicates
+                                                        null
                                        );
                    rg.addRefEdge(prevNode, hrnSummary, edgeToSummary);
                    prevNode=hrnSummary;
        }else{
-               HeapRegionNode hrnSummary=mapToExistingNode.get(typeDesc);
+          HeapRegionNode hrnSummary=mapToExistingNode.get(typeDesc);
                if(prevNode.getReferenceTo(hrnSummary, typeDesc, arrayElementFieldName)==null){
                        RefEdge edgeToSummary = new RefEdge(prevNode, // source
                                        hrnSummary, // dest
                                        typeDesc, // type
                                        arrayElementFieldName, // field name
                                        alpha, // beta
-                                       ExistPredSet.factory(rg.predTrue) // predicates
+                                                            ExistPredSet.factory(rg.predTrue), // predicates
+                                                            null
                                        );
                    rg.addRefEdge(prevNode, hrnSummary, edgeToSummary);
                }
@@ -1864,7 +2218,8 @@ private ReachGraph createInitialTaskReachGraph(FlatMethod fm) {
                                      taskDesc.getParamType(idx), // type
                                      null, // field name
                                      hrnNewest.getAlpha(), // beta
-                                     ExistPredSet.factory(rg.predTrue) // predicates
+                                     ExistPredSet.factory(rg.predTrue), // predicates
+                                      null
                                      );
        rg.addRefEdge(lnX, hrnNewest, edgeNew);
 
@@ -1934,7 +2289,8 @@ private ReachGraph createInitialTaskReachGraph(FlatMethod fm) {
                                                        type, // type
                                                        fd.getSymbol(), // field name
                                                        hrnNewest.getAlpha(), // beta
-                                                       ExistPredSet.factory(rg.predTrue) // predicates
+                                                       ExistPredSet.factory(rg.predTrue), // predicates
+                                                        null
                                                        );
                    
                    rg.addRefEdge(srcHRN, hrnSummary, edgeToSummary);
@@ -1975,7 +2331,8 @@ private ReachGraph createInitialTaskReachGraph(FlatMethod fm) {
                                                        fd.getType(), // type
                                                        fd.getSymbol(), // field name
                                                        srcHRN.getAlpha(), // beta
-                                                       ExistPredSet.factory(rg.predTrue) // predicates
+                                                       ExistPredSet.factory(rg.predTrue), // predicates  
+                                                        null
                                                        );
                    rg.addRefEdge(srcHRN, hrnDst, edgeToSummary);
                    
@@ -2125,7 +2482,17 @@ getFlaggedAllocationSitesReachableFromTaskPRIVATE(TaskDescriptor td) {
   return asSetTotal;
 }
 
+  public Set<Descriptor> getDescriptorsToAnalyze() {
+    return descriptorsToAnalyze;
+  }
 
+  public EffectsAnalysis getEffectsAnalysis(){
+    return effectsAnalysis;
+  }
+  
+  public ReachGraph getReachGraph(Descriptor d){
+    return mapDescriptorToCompleteReachGraph.get(d);
+  }
   
   
   // get successive captures of the analysis state, use compiler
@@ -2154,11 +2521,11 @@ getFlaggedAllocationSitesReachableFromTaskPRIVATE(TaskDescriptor td) {
                           " @@@" );
       String graphName;
       if( in ) {
-        graphName = String.format( "snap%02d_%04din",
+        graphName = String.format( "snap%03d_%04din",
                                    snapVisitCounter,
                                    snapNodeCounter );
       } else {
-        graphName = String.format( "snap%02d_%04dout",
+        graphName = String.format( "snap%03d_%04dout",
                                    snapVisitCounter,
                                    snapNodeCounter );
       }
@@ -2166,11 +2533,13 @@ getFlaggedAllocationSitesReachableFromTaskPRIVATE(TaskDescriptor td) {
        graphName = graphName + fn;
       }
       rg.writeGraph( graphName,
-                     true,  // write labels (variables)
-                     true,  // selectively hide intermediate temp vars
-                     true,  // prune unreachable heap regions
-                     false, // hide subset reachability states
-                     true );// hide edge taints
+                     true,   // write labels (variables)
+                     true,   // selectively hide intermediate temp vars
+                     true,   // prune unreachable heap regions
+                     false,  // hide reachability
+                     true,   // hide subset reachability states
+                     true,   // hide predicates
+                     false );// hide edge taints
     }
   }