got 2nd case of def reach up and running, one to go
authorjjenista <jjenista>
Fri, 11 Nov 2011 00:38:51 +0000 (00:38 +0000)
committerjjenista <jjenista>
Fri, 11 Nov 2011 00:38:51 +0000 (00:38 +0000)
Robust/src/Analysis/Disjoint/DefiniteReachAnalysis.java
Robust/src/Analysis/Disjoint/DefiniteReachState.java
Robust/src/Analysis/Disjoint/DisjointAnalysis.java
Robust/src/Analysis/Disjoint/ReachGraph.java

index e327fcec65704425c40611967f51c1e0bb9ba6a2..90b09b81819f91c584f8de05eef3e6bba3e61af2 100644 (file)
@@ -41,6 +41,14 @@ public class DefiniteReachAnalysis {
   }
 
 
+  public Set<DefiniteReachState.FdEntry> edgesToElidePropagation( TempDescriptor x, 
+                                                                  TempDescriptor y,
+                                                                  FlatNode fn ) {
+    return makeIn( fn ).edgesToElidePropagation( x, y );
+  }
+
+
+
   private void addPartialResult( FlatNode fn, DefiniteReachState state ) {
     fn2state.put( fn, state );
     fnHasPartial.add( fn );
index 72238d9b1098b2a76005875aa47cb118b7185de7..09f2ff4dec2d220a7d320215d085a53a47ad7523 100644 (file)
@@ -51,6 +51,18 @@ public class DefiniteReachState {
   //
   // Entries <x, f, y> mean x.f points directly at what
   // y points at.
+  public class FdEntry {
+    TempDescriptor  y;
+    FieldDescriptor f0;
+    TempDescriptor  z;
+    public FdEntry( TempDescriptor  y,
+                    FieldDescriptor f0,
+                    TempDescriptor  z ) {
+      this.y  = y;
+      this.f0 = f0;
+      this.z  = z;
+    }
+  }
   private static MultiViewMapBuilder<Object> FdBuilder;
   private static BitSet viewFd0;
   private static BitSet viewFd2;
@@ -122,6 +134,39 @@ public class DefiniteReachState {
   }
 
 
+  public Set<FdEntry> edgesToElidePropagation( TempDescriptor x, 
+                                               TempDescriptor y ) {
+    // return the set of edges that definite reach analysis tells
+    // us we can elide propagating reach info across during the
+    // store: x.f = y 
+
+    Set<FdEntry> out = new HashSet<FdEntry>();
+
+    // we have to know something about y
+    DefReachKnown known = Rs.get( y );
+    if( known == null || known == DefReachKnown.UNKNOWN ) {
+      return out;
+    }
+
+    // find all 'y points at' entries in Fd
+    MultiKey keyY = MultiKey.factory( y );
+    Map<MultiKey, Object> mapY0 = Fd.get( viewFd0, keyY );
+
+    for( MultiKey fullKeyY : mapY0.keySet() ) {
+      // if y.f0 points at z, and z is already reachable from x,
+      // include the edge y.f0->z
+      FieldDescriptor f0 = (FieldDescriptor) fullKeyY.get( 1 );
+      TempDescriptor  z  = (TempDescriptor)  fullKeyY.get( 2 );
+
+      if( isAlreadyReachable( z, x ) ) {
+        out.add( new FdEntry( y, f0, z ) );
+      }
+    }
+    
+    return out;
+  }
+
+
 
 
   public void methodEntry( Set<TempDescriptor> parameters ) {
index 3128519ed2bce28e4c2a4487aa050877bd612ef4..99eb4f62f27b48a40022f4f024a18d7d897e304e 100644 (file)
@@ -1306,6 +1306,7 @@ public class DisjointAnalysis implements HeapAnalysis {
     Set<EdgeKey> edgeKeysForLoad;
     Set<EdgeKey> edgeKeysRemoved;
     Set<EdgeKey> edgeKeysAdded;
+    Set<DefiniteReachState.FdEntry> edgesToElideFromProp;
 
     //Stores the flatnode's reach graph at enter
     ReachGraph rgOnEnter = new ReachGraph();
@@ -1496,13 +1497,15 @@ public class DisjointAnalysis implements HeapAnalysis {
 
       boolean strongUpdate = false;
 
-      alreadyReachable = false;
-      edgeKeysRemoved  = null;
-      edgeKeysAdded    = null;
+      alreadyReachable     = false;
+      edgeKeysRemoved      = null;
+      edgeKeysAdded        = null;
+      edgesToElideFromProp = null;
       if( doDefiniteReachAnalysis ) {
-        alreadyReachable = definiteReachAnalysis.isAlreadyReachable( rhs, lhs, fn );
-        edgeKeysRemoved  = new HashSet<EdgeKey>();
-        edgeKeysAdded    = new HashSet<EdgeKey>();
+        alreadyReachable     = definiteReachAnalysis.isAlreadyReachable( rhs, lhs, fn );
+        edgeKeysRemoved      = new HashSet<EdgeKey>();
+        edgeKeysAdded        = new HashSet<EdgeKey>();
+        edgesToElideFromProp = definiteReachAnalysis.edgesToElidePropagation( lhs, rhs, fn );
       }
 
       // before transfer func, possibly inject
@@ -1534,7 +1537,8 @@ public class DisjointAnalysis implements HeapAnalysis {
                                                          fn, 
                                                          alreadyReachable,
                                                          edgeKeysRemoved,
-                                                         edgeKeysAdded );
+                                                         edgeKeysAdded,
+                                                         edgesToElideFromProp );
         if( doDefiniteReachAnalysis ) {
           definiteReachAnalysis.store( fn, 
                                        lhs,
@@ -1613,13 +1617,15 @@ public class DisjointAnalysis implements HeapAnalysis {
       tdElement = lhs.getType().dereference();
       fdElement = getArrayField(tdElement);
 
-      alreadyReachable = false;
-      edgeKeysRemoved  = null;
-      edgeKeysAdded    = null;
+      alreadyReachable     = false;
+      edgeKeysRemoved      = null;
+      edgeKeysAdded        = null;
+      edgesToElideFromProp = null;
       if( doDefiniteReachAnalysis ) {
-        alreadyReachable = definiteReachAnalysis.isAlreadyReachable( rhs, lhs, fn );
-        edgeKeysRemoved = new HashSet<EdgeKey>();
-        edgeKeysAdded   = new HashSet<EdgeKey>();
+        alreadyReachable     = definiteReachAnalysis.isAlreadyReachable( rhs, lhs, fn );
+        edgeKeysRemoved      = new HashSet<EdgeKey>();
+        edgeKeysAdded        = new HashSet<EdgeKey>();
+        edgesToElideFromProp = definiteReachAnalysis.edgesToElidePropagation( lhs, rhs, fn );
       }
 
       // before transfer func, possibly inject
@@ -1653,7 +1659,8 @@ public class DisjointAnalysis implements HeapAnalysis {
                                             fn, 
                                             alreadyReachable,
                                             edgeKeysRemoved,
-                                            edgeKeysAdded );
+                                            edgeKeysAdded,
+                                            edgesToElideFromProp );
         }
 
         if( doDefiniteReachAnalysis ) {
index 8de46b97f60638ad8bb162256920d92a0e50cf27..7a4522d701ace718b0894472e3fabfd2cbd4aac2 100644 (file)
@@ -428,6 +428,7 @@ public class ReachGraph {
                                    null,
                                    false,
                                    null,
+                                   null,
                                    null );
   }
 
@@ -597,7 +598,8 @@ public class ReachGraph {
                                                FlatNode currentProgramPoint,
                                                boolean alreadyReachable,
                                                Set<EdgeKey> edgeKeysRemoved,
-                                               Set<EdgeKey> edgeKeysAdded
+                                               Set<EdgeKey> edgeKeysAdded,
+                                               Set<DefiniteReachState.FdEntry> edgesToElideFromPropFd
                                                ) {
 
     VariableNode lnX = getVariableNodeFromTemp(x);
@@ -644,6 +646,51 @@ public class ReachGraph {
     }
 
 
+    // definite reachability analysis can elide some edges from
+    // propagating reach information
+    Set<RefEdge> edgesToElideFromProp = null;
+    if( edgesToElideFromPropFd != null ) {
+      edgesToElideFromProp = new HashSet<RefEdge>();
+      Iterator<RefEdge> itrY = lnY.iteratorToReferencees();
+      while( itrY.hasNext() ) {
+        HeapRegionNode hrnSrc = itrY.next().getDst();
+
+        Iterator<RefEdge> itrhrn = hrnSrc.iteratorToReferencees();
+        while( itrhrn.hasNext() ) {
+          RefEdge        edgeToElide = itrhrn.next();
+          String         f0          = edgeToElide.getField();
+          HeapRegionNode hrnDst      = edgeToElide.getDst();
+
+          // does this graph edge match a statically-named edge
+          // that def reach says we don't have to prop over?
+          for( DefiniteReachState.FdEntry entry : edgesToElideFromPropFd ) {
+            if( !entry.f0.getSymbol().equals( f0 ) ) {
+              continue;
+            }
+            boolean refByZ = false;
+            Iterator<RefEdge> itrRef = hrnDst.iteratorToReferencers();
+            while( itrRef.hasNext() ) {
+              RefEdge edgeZ = itrRef.next();
+              if( edgeZ.getSrc() instanceof VariableNode ) {
+                VariableNode vnZ = (VariableNode) edgeZ.getSrc();
+                if( vnZ.getTempDescriptor().equals( entry.z ) ) {
+                  refByZ = true;
+                  break;
+                }
+              }
+            }
+            if( refByZ ) {
+              // this graph edge matches the def reach edge, mark it for
+              // no propagation
+              edgesToElideFromProp.add( edgeToElide );
+            }
+          }
+        }
+      }
+    }
+
+
+
     // definite reachability analysis can elide reachability propagation
     if( !alreadyReachable ) {
 
@@ -672,7 +719,11 @@ public class ReachGraph {
           // propagate tokens over nodes starting from hrnSrc, and it will
           // take care of propagating back up edges from any touched nodes
           ChangeSet Cy = Canonical.unionUpArityToChangeSet(O, R);
-          propagateTokensOverNodes(hrnY, Cy, nodesWithNewAlpha, edgesWithNewBeta);
+          propagateTokensOverNodes( hrnY, 
+                                    Cy, 
+                                    nodesWithNewAlpha, 
+                                    edgesWithNewBeta,
+                                    edgesToElideFromProp );
 
           // then propagate back just up the edges from hrn
           ChangeSet Cx = Canonical.unionUpArityToChangeSet(R, O);
@@ -688,9 +739,10 @@ public class ReachGraph {
             edgePlannedChanges.put(edgeUpstream, Cx);
           }
 
-          propagateTokensOverEdges(todoEdges,
-                                   edgePlannedChanges,
-                                   edgesWithNewBeta);
+          propagateTokensOverEdges( todoEdges,
+                                    edgePlannedChanges,
+                                    edgesWithNewBeta,
+                                    edgesToElideFromProp );
         }
       }
     }
@@ -1187,7 +1239,8 @@ public class ReachGraph {
   protected void propagateTokensOverNodes(HeapRegionNode nPrime,
                                           ChangeSet c0,
                                           HashSet<HeapRegionNode> nodesWithNewAlpha,
-                                          HashSet<RefEdge>        edgesWithNewBeta) {
+                                          HashSet<RefEdge>        edgesWithNewBeta,
+                                          Set<RefEdge>            edgesToElideProp ) {
 
     HashSet<HeapRegionNode> todoNodes
       = new HashSet<HeapRegionNode>();
@@ -1211,6 +1264,10 @@ public class ReachGraph {
       Iterator<RefEdge> referItr = n.iteratorToReferencers();
       while( referItr.hasNext() ) {
         RefEdge edge = referItr.next();
+
+        if( edgesToElideProp != null && edgesToElideProp.contains( edge ) ) {
+          continue;
+        }
         todoEdges.add(edge);
 
         if( !edgePlannedChanges.containsKey(edge) ) {
@@ -1229,6 +1286,11 @@ public class ReachGraph {
       Iterator<RefEdge> refeeItr = n.iteratorToReferencees();
       while( refeeItr.hasNext() ) {
         RefEdge edgeF = refeeItr.next();
+
+        if( edgesToElideProp != null && edgesToElideProp.contains( edgeF ) ) {
+          continue;
+        }
+
         HeapRegionNode m     = edgeF.getDst();
 
         ChangeSet changesToPass = ChangeSet.factory();
@@ -1291,14 +1353,15 @@ public class ReachGraph {
 
     propagateTokensOverEdges(todoEdges,
                              edgePlannedChanges,
-                             edgesWithNewBeta
-                             );
+                             edgesWithNewBeta,
+                             edgesToElideProp);
   }
 
 
   protected void propagateTokensOverEdges(HashSet  <RefEdge>            todoEdges,
                                           Hashtable<RefEdge, ChangeSet> edgePlannedChanges,
-                                          HashSet  <RefEdge>            edgesWithNewBeta) {
+                                          HashSet  <RefEdge>            edgesWithNewBeta,
+                                          Set<RefEdge>                  edgesToElideProp ) {
 
     // first propagate all change tuples everywhere they can go
     while( !todoEdges.isEmpty() ) {
@@ -1334,6 +1397,10 @@ public class ReachGraph {
         while( referItr.hasNext() ) {
           RefEdge edgeF = referItr.next();
 
+          if( edgesToElideProp != null && edgesToElideProp.contains( edgeF ) ) {
+            continue;
+          }
+
           if( !edgePlannedChanges.containsKey(edgeF) ) {
             edgePlannedChanges.put(edgeF,
                                    ChangeSet.factory()
@@ -2920,9 +2987,10 @@ public class ReachGraph {
     // of the caller graph edges
     HashSet<RefEdge> edgesUpdated = new HashSet<RefEdge>();
 
-    propagateTokensOverEdges(edgesForPropagation,  // source edges
-                             edgePlannedChanges,   // map src edge to change set
-                             edgesUpdated);        // list of updated edges
+    propagateTokensOverEdges( edgesForPropagation,  // source edges
+                              edgePlannedChanges,   // map src edge to change set
+                              edgesUpdated,         // list of updated edges
+                              null );        
 
     // commit beta' (beta<-betaNew)
     Iterator<RefEdge> edgeItr = edgesUpdated.iterator();
@@ -3555,7 +3623,8 @@ public class ReachGraph {
 
     propagateTokensOverEdges(edgesForPropagation,
                              edgePlannedChanges,
-                             edgesUpdated);
+                             edgesUpdated,
+                             null);
 
     // at the end of the 1st phase reference edges have
     // beta, betaNew that correspond to beta and betaR