cpaturing some makefile updates and have OoOJava print number of sites disjoint reach...
[IRC.git] / Robust / src / Analysis / Disjoint / DisjointAnalysis.java
index 9cde75ff458b2803782c5ea90c0b9b40fcc7e1d9..129bffd2ddafff07ed8f643d16c9c1ecb83dde25 100644 (file)
@@ -3,7 +3,8 @@ package Analysis.Disjoint;
 import Analysis.CallGraph.*;
 import Analysis.Liveness;
 import Analysis.ArrayReferencees;
-import Analysis.RBlockRelationAnalysis;
+import Analysis.OoOJava.RBlockRelationAnalysis;
+import Analysis.OoOJava.RBlockStatusAnalysis;
 import IR.*;
 import IR.Flat.*;
 import IR.Tree.Modifiers;
@@ -13,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
@@ -234,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,
@@ -307,6 +353,8 @@ public class DisjointAnalysis {
   //
   ///////////////////////////////////////////
 
+
+
   protected void checkAnalysisComplete() {
     if( !analysisComplete ) {
       throw new Error("Warning: public interface method called while analysis is running.");
@@ -314,6 +362,10 @@ public class DisjointAnalysis {
   } 
 
 
+
+
+
+
   // run in faster mode, only when bugs wrung out!
   public static boolean releaseMode;
 
@@ -334,6 +386,7 @@ public class DisjointAnalysis {
   public Liveness         liveness;
   public ArrayReferencees arrayReferencees;
   public RBlockRelationAnalysis rblockRel;
+  public RBlockStatusAnalysis rblockStatus;
   public TypeUtil         typeUtil;
   public int              allocationDepth;
 
@@ -418,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>
@@ -557,9 +615,24 @@ public class DisjointAnalysis {
                           CallGraph        cg,
                           Liveness         l,
                           ArrayReferencees ar,
-                           RBlockRelationAnalysis rra
+                           Set<FlatNew> sitesToFlag,
+                           RBlockRelationAnalysis rra,
+                           RBlockStatusAnalysis rsa
                            ) {
-    init( s, tu, cg, l, ar, rra );
+    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,
@@ -567,17 +640,22 @@ public class DisjointAnalysis {
                        CallGraph        callGraph,
                        Liveness         liveness,
                        ArrayReferencees arrayReferencees,
-                       RBlockRelationAnalysis rra
+                       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.rblockRel               = rra;
+    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;
@@ -588,8 +666,8 @@ public class DisjointAnalysis {
     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;
@@ -638,26 +716,34 @@ public class DisjointAnalysis {
 
     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 );
 
+
     try {
       if( writeFinalDOTs && !writeAllIncrementalDOTs ) {
         writeFinalGraphs();      
       }
 
-      if( state.DISJOINTWRITEIHMS ) {
+      if( state.DISJOINTWRITEIHMS && !suppressOutput ) {
         writeFinalIHMs();
       }
 
-      if( state.DISJOINTWRITEINITCONTEXTS ) {
+      if( state.DISJOINTWRITEINITCONTEXTS && !suppressOutput ) {
         writeInitialContexts();
       }
 
-      if( state.DISJOINTALIASFILE != null ) {
+      if( state.DISJOINTALIASFILE != null && !suppressOutput ) {
         if( state.TASK ) {
           writeAllSharing(state.DISJOINTALIASFILE, treport, justtime, state.DISJOINTALIASTAB, state.lines);
         } else {
@@ -673,9 +759,6 @@ public class DisjointAnalysis {
       throw new Error( "IO Exception while writing disjointness analysis output." );
     }
 
-    if( doEffectsAnalysis ) {
-      effectsAnalysis.writeEffects( "effects.txt" );
-    }
   }
 
 
@@ -1012,17 +1095,13 @@ public class DisjointAnalysis {
     // nullified in the graph to reduce edges
     //rg.nullifyDeadVars( liveness.getLiveInTemps( fmContaining, fn ) );
 
-    /*
-      if( doEffectsAnalysis &&  && fmContaining != fmAnalysisEntry
-        rra.isEndOfRegion(fn)){
-      rg.clearAccessibleVarSet();
-      also need to clear stall mapping
-    }
-    */
-         
-    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
@@ -1063,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;
 
@@ -1074,84 +1165,184 @@ 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() ) ) {
-       rg.assignTempXEqualToTempYFieldF( lhs, rhs, fld );
 
-        if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
-          effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fld );          
+      // 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();
 
-      if( shouldAnalysisTrack( fld.getType() ) ) {
-        boolean strongUpdate = rg.assignTempXFieldFEqualToTempY( lhs, fld, rhs );
+      boolean strongUpdate = false;
 
-        if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
-          effectsAnalysis.analyzeFlatSetFieldNode( rg, lhs, fld, strongUpdate );
+      // 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() ) ) {
+        // 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 );
-  
-       rg.assignTempXEqualToTempYFieldF( lhs, rhs, fdElement );
-        
-        if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
-          effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fdElement );          
+      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();  
 
-       rg.assignTempXFieldFEqualToTempY( lhs, fdElement, rhs );
+      tdElement = lhs.getType().dereference();
+      fdElement = getArrayField( tdElement );
 
-        if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
-          effectsAnalysis.analyzeFlatSetFieldNode( rg, lhs, fdElement,
-                                                   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( 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;
       
     case FKind.FlatNew:
@@ -1159,21 +1350,54 @@ 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 ) {
-        FlatSESEEnterNode sese = (FlatSESEEnterNode) fn;
-        rg.taintInSetVars( sese );                         
+        
+        // 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 ) {
-        FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
-        rg.removeInContextTaints( fsexn.getFlatEnter() );
+
+        // @ 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;
 
@@ -1188,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 );
@@ -1286,7 +1509,7 @@ public class DisjointAnalysis {
                                    );
       }
 
-      ReachGraph rgMergeOfEffects = new ReachGraph();
+      ReachGraph rgMergeOfPossibleCallers = new ReachGraph();
 
       Iterator<MethodDescriptor> mdItr = setPossibleCallees.iterator();
       while( mdItr.hasNext() ) {
@@ -1299,12 +1522,12 @@ 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 ) {
@@ -1320,15 +1543,22 @@ public class DisjointAnalysis {
 
         } else {
           // calculate the method call transform         
-          rgCopy.resolveMethodCall( fc, 
-                                    fmPossible, 
-                                    rgEffect,
-                                    callerNodeIDsCopiedToCallee,
-                                    writeDebugDOTs
-                                    );
+          rgPossibleCaller.resolveMethodCall( fc, 
+                                              fmPossible, 
+                                              rgPossibleCallee,
+                                              callerNodeIDsCopiedToCallee,
+                                              writeDebugDOTs
+                                              );
+
+          if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+            if( !rgPossibleCallee.isAccessible( ReachGraph.tdReturn ) ) {
+              rgPossibleCaller.makeInaccessible( fc.getReturnTemp() );
+            }
+          }
+
         }
         
-        rgMergeOfEffects.merge( rgCopy );        
+        rgMergeOfPossibleCallers.merge( rgPossibleCaller );        
       }
 
 
@@ -1340,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;
 
@@ -1504,11 +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(),
-                                        false
+                                        flagProgrammatically
                                         );
 
       // the newest nodes are single objects
@@ -2246,6 +2490,10 @@ getFlaggedAllocationSitesReachableFromTaskPRIVATE(TaskDescriptor td) {
     return effectsAnalysis;
   }
   
+  public ReachGraph getReachGraph(Descriptor d){
+    return mapDescriptorToCompleteReachGraph.get(d);
+  }
+  
   
   // get successive captures of the analysis state, use compiler
   // flags to control