successfully keep def reach info just for the store transform
[IRC.git] / Robust / src / Analysis / Disjoint / DisjointAnalysis.java
index 5c230a4a6d19b48b1108b3cc9c6e56b8dbba24a0..4b9b4f0dc79e2e1160701da4ca25a89e69c8fda2 100644 (file)
@@ -726,8 +726,6 @@ public class DisjointAnalysis implements HeapAnalysis {
     mapDescriptorToReachGraph =
       new Hashtable<Descriptor, ReachGraph>();
 
-    pm = new PointerMethod();
-
     fc2enclosing = new Hashtable<FlatCall, Descriptor>();
   }
 
@@ -849,9 +847,11 @@ public class DisjointAnalysis implements HeapAnalysis {
     ReachGraph.debugCallSiteVisitCounter
       = 0; // count visits from 1, is incremented before first visit    
 
+    pm = new PointerMethod();
+
     if( state.DO_DEFINITE_REACH_ANALYSIS ) {
       doDefiniteReachAnalysis = true;
-      definiteReachAnalysis = new DefiniteReachAnalysis();
+      definiteReachAnalysis = new DefiniteReachAnalysis( pm );
     }
 
 
@@ -1302,12 +1302,20 @@ public class DisjointAnalysis implements HeapAnalysis {
     FlatSESEEnterNode sese;
     FlatSESEExitNode fsexn;
 
+    Set<EdgeKey> edgeKeysForLoad;
+    Set<EdgeKey> edgeKeysRemoved;
+    Set<EdgeKey> edgeKeysAdded;
+
     //Stores the flatnode's reach graph at enter
     ReachGraph rgOnEnter = new ReachGraph();
     rgOnEnter.merge(rg);
     fn2rgAtEnter.put(fn, rgOnEnter);
 
 
+    
+    boolean didDefReachTransfer = false;    
+
+
 
     // use node type to decide what transfer function
     // to apply to the reachability graph
@@ -1375,6 +1383,7 @@ public class DisjointAnalysis implements HeapAnalysis {
           params.add( fm.getParameter( i ) );
         }
         definiteReachAnalysis.methodEntry( fn, params );
+        didDefReachTransfer = true;
       }
     } break;
 
@@ -1399,6 +1408,7 @@ public class DisjointAnalysis implements HeapAnalysis {
 
         if( doDefiniteReachAnalysis ) {
           definiteReachAnalysis.copy( fn, lhs, rhs );
+          didDefReachTransfer = true;
         }
       }
       break;
@@ -1426,6 +1436,7 @@ public class DisjointAnalysis implements HeapAnalysis {
 
       if( doDefiniteReachAnalysis ) {
         definiteReachAnalysis.copy( fn, lhs, rhs );
+        didDefReachTransfer = true;
       }
       break;
 
@@ -1453,12 +1464,18 @@ public class DisjointAnalysis implements HeapAnalysis {
         }
       }
 
+      edgeKeysForLoad = null;
+      if( doDefiniteReachAnalysis ) {
+        edgeKeysForLoad = new HashSet<EdgeKey>();
+      }
+
       if( shouldAnalysisTrack(fld.getType() ) ) {
         // transfer func
-        rg.assignTempXEqualToTempYFieldF(lhs, rhs, fld, fn);
+        rg.assignTempXEqualToTempYFieldF( lhs, rhs, fld, fn, edgeKeysForLoad );
 
         if( doDefiniteReachAnalysis ) {
-          definiteReachAnalysis.load( fn, lhs, rhs, fld );
+          definiteReachAnalysis.load( fn, lhs, rhs, fld, edgeKeysForLoad );
+          didDefReachTransfer = true;
         }
       }
 
@@ -1478,6 +1495,13 @@ public class DisjointAnalysis implements HeapAnalysis {
 
       boolean strongUpdate = false;
 
+      edgeKeysRemoved = null;
+      edgeKeysAdded   = null;
+      if( doDefiniteReachAnalysis ) {
+        edgeKeysRemoved = new HashSet<EdgeKey>();
+        edgeKeysAdded   = new HashSet<EdgeKey>();
+      }
+
       // before transfer func, possibly inject
       // stall-site taints
       if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
@@ -1501,10 +1525,20 @@ public class DisjointAnalysis implements HeapAnalysis {
 
       if( shouldAnalysisTrack(fld.getType() ) ) {
         // transfer func
-        strongUpdate = rg.assignTempXFieldFEqualToTempY(lhs, fld, rhs, fn);
-
+        strongUpdate = rg.assignTempXFieldFEqualToTempY( lhs, 
+                                                         fld, 
+                                                         rhs, 
+                                                         fn, 
+                                                         edgeKeysRemoved,
+                                                         edgeKeysAdded );
         if( doDefiniteReachAnalysis ) {
-          definiteReachAnalysis.store( fn, lhs, fld, rhs );
+          definiteReachAnalysis.store( fn, 
+                                       lhs,
+                                       fld,
+                                       rhs,
+                                       edgeKeysRemoved,
+                                       edgeKeysAdded );
+          didDefReachTransfer = true;
         }
       }
 
@@ -1542,12 +1576,18 @@ public class DisjointAnalysis implements HeapAnalysis {
         }
       }
 
+      edgeKeysForLoad = null;
+      if( doDefiniteReachAnalysis ) {
+        edgeKeysForLoad = new HashSet<EdgeKey>();
+      }
+
       if( shouldAnalysisTrack(lhs.getType() ) ) {
         // transfer func
-        rg.assignTempXEqualToTempYFieldF(lhs, rhs, fdElement, fn);
+        rg.assignTempXEqualToTempYFieldF( lhs, rhs, fdElement, fn, edgeKeysForLoad );
 
         if( doDefiniteReachAnalysis ) {
-          definiteReachAnalysis.load( fn, lhs, rhs, fdElement );
+          definiteReachAnalysis.load( fn, lhs, rhs, fdElement, edgeKeysForLoad );
+          didDefReachTransfer = true;
         }
       }
 
@@ -1562,13 +1602,20 @@ public class DisjointAnalysis implements HeapAnalysis {
 
       lhs = fsen.getDst();
       rhs = fsen.getSrc();
-
+      
       assert lhs.getType() != null;
       assert lhs.getType().isArray();
 
       tdElement = lhs.getType().dereference();
       fdElement = getArrayField(tdElement);
 
+      edgeKeysRemoved = null;
+      edgeKeysAdded   = null;
+      if( doDefiniteReachAnalysis ) {
+        edgeKeysRemoved = new HashSet<EdgeKey>();
+        edgeKeysAdded   = new HashSet<EdgeKey>();
+      }
+
       // before transfer func, possibly inject
       // stall-site taints
       if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
@@ -1594,11 +1641,22 @@ public class DisjointAnalysis implements HeapAnalysis {
         // transfer func, BUT
         // skip this node if it cannot create new reachability paths
         if( !arrayReferencees.doesNotCreateNewReaching(fsen) ) {
-          rg.assignTempXFieldFEqualToTempY(lhs, fdElement, rhs, fn);
+          rg.assignTempXFieldFEqualToTempY( lhs, 
+                                            fdElement, 
+                                            rhs, 
+                                            fn, 
+                                            edgeKeysRemoved,
+                                            edgeKeysAdded );
         }
 
         if( doDefiniteReachAnalysis ) {
-          definiteReachAnalysis.store( fn, lhs, fdElement, rhs );
+          definiteReachAnalysis.store( fn,
+                                       lhs,
+                                       fdElement, 
+                                       rhs, 
+                                       edgeKeysRemoved,
+                                       edgeKeysAdded );
+          didDefReachTransfer = true;
         }
       }
 
@@ -1628,6 +1686,7 @@ public class DisjointAnalysis implements HeapAnalysis {
 
         if( doDefiniteReachAnalysis ) {
           definiteReachAnalysis.newObject( fn, lhs );
+          didDefReachTransfer = true;
         }
       }
       break;
@@ -1696,6 +1755,7 @@ public class DisjointAnalysis implements HeapAnalysis {
 
       if( doDefiniteReachAnalysis ) {
         definiteReachAnalysis.methodCall( fn, fc.getReturnTemp() );
+        didDefReachTransfer = true;
       }
 
       
@@ -1778,7 +1838,7 @@ public class DisjointAnalysis implements HeapAnalysis {
           fc2enclosing.put(fc, mdCaller);
 
           if( state.DISJOINTDEBUGSCHEDULING ) {
-            System.out.println("  context changed, scheduling callee: "+mdPossible);
+            System.out.println("  context changed at callsite: "+fc+", scheduling callee: "+mdPossible);
           }
 
           if( state.DISJOINTDVISITSTACKEESONTOP ) {
@@ -1884,6 +1944,13 @@ public class DisjointAnalysis implements HeapAnalysis {
     } // end switch
 
 
+
+    if( doDefiniteReachAnalysis && !didDefReachTransfer ) {
+      definiteReachAnalysis.otherStatement( fn );
+    }
+
+
+
     // dead variables were removed before the above transfer function
     // was applied, so eliminate heap regions and edges that are no
     // longer part of the abstractly-live heap graph, and sweep up
@@ -2419,7 +2486,13 @@ public class DisjointAnalysis implements HeapAnalysis {
     Hashtable<FlatCall, ReachGraph> heapsFromCallers =
       getIHMcontributions(d);
 
-    heapsFromCallers.put(fc, rg);
+    // ensure inputs to initial contexts increase monotonically
+    ReachGraph merged = new ReachGraph();
+    merged.merge( rg );
+    merged.merge( heapsFromCallers.get( fc ) );
+
+    heapsFromCallers.put( fc, merged );
+    
   }