successfully keep def reach info just for the store transform
[IRC.git] / Robust / src / Analysis / Disjoint / DisjointAnalysis.java
index 5dd67e5b86ee1ca946f663b3c7bc0326302f38a8..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
@@ -1330,6 +1338,14 @@ public class DisjointAnalysis implements HeapAnalysis {
     } break;
 
 
+    case FKind.FlatGenDefReachNode: {
+      FlatGenDefReachNode fgdrn = (FlatGenDefReachNode) fn;
+      if( doDefiniteReachAnalysis ) {
+        definiteReachAnalysis.writeState( fn, fgdrn.getOutputName() );
+      }
+    } break;
+
+
     case FKind.FlatMethod: {
       // construct this method's initial heap model (IHM)
       // since we're working on the FlatMethod, we know
@@ -1360,6 +1376,15 @@ public class DisjointAnalysis implements HeapAnalysis {
       rg.merge(rgPrevContext);
       mapDescriptorToInitialContext.put(d, rg);
 
+      if( doDefiniteReachAnalysis ) {
+        FlatMethod fm = (FlatMethod) fn;
+        Set<TempDescriptor> params = new HashSet<TempDescriptor>();
+        for( int i = 0; i < fm.numParameters(); ++i ) {
+          params.add( fm.getParameter( i ) );
+        }
+        definiteReachAnalysis.methodEntry( fn, params );
+        didDefReachTransfer = true;
+      }
     } break;
 
     case FKind.FlatOpNode:
@@ -1380,6 +1405,11 @@ public class DisjointAnalysis implements HeapAnalysis {
 
         // transfer func
         rg.assignTempXEqualToTempY(lhs, rhs);
+
+        if( doDefiniteReachAnalysis ) {
+          definiteReachAnalysis.copy( fn, lhs, rhs );
+          didDefReachTransfer = true;
+        }
       }
       break;
 
@@ -1403,6 +1433,11 @@ public class DisjointAnalysis implements HeapAnalysis {
 
       // transfer func
       rg.assignTempXEqualToCastedTempY(lhs, rhs, td);
+
+      if( doDefiniteReachAnalysis ) {
+        definiteReachAnalysis.copy( fn, lhs, rhs );
+        didDefReachTransfer = true;
+      }
       break;
 
     case FKind.FlatFieldNode:
@@ -1429,9 +1464,19 @@ 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, edgeKeysForLoad );
+          didDefReachTransfer = true;
+        }
       }
 
       // after transfer, use updated graph to
@@ -1450,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 ) {
@@ -1473,7 +1525,21 @@ 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,
+                                       edgeKeysRemoved,
+                                       edgeKeysAdded );
+          didDefReachTransfer = true;
+        }
       }
 
       // use transformed graph to do effects analysis
@@ -1510,9 +1576,19 @@ 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, edgeKeysForLoad );
+          didDefReachTransfer = true;
+        }
       }
 
       // use transformed graph to do effects analysis
@@ -1526,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 ) {
@@ -1558,7 +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, 
+                                       edgeKeysRemoved,
+                                       edgeKeysAdded );
+          didDefReachTransfer = true;
         }
       }
 
@@ -1585,6 +1683,11 @@ public class DisjointAnalysis implements HeapAnalysis {
 
         // transfer func
         rg.assignTempEqualToNewAlloc(lhs, as);
+
+        if( doDefiniteReachAnalysis ) {
+          definiteReachAnalysis.newObject( fn, lhs );
+          didDefReachTransfer = true;
+        }
       }
       break;
 
@@ -1650,11 +1753,10 @@ public class DisjointAnalysis implements HeapAnalysis {
       FlatMethod fmCallee = state.getMethodFlat(mdCallee);
 
 
-
-
-
-
-
+      if( doDefiniteReachAnalysis ) {
+        definiteReachAnalysis.methodCall( fn, fc.getReturnTemp() );
+        didDefReachTransfer = true;
+      }
 
       
       // the transformation for a call site should update the
@@ -1736,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 ) {
@@ -1842,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
@@ -2377,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 );
+    
   }