changes
[IRC.git] / Robust / src / Analysis / Pointer / Pointer.java
index 0ba6759bf1e7f16bcc8a748e8f3e1505a5b52c63..13dd2844ff3f4bd0be105a997a9cb6d39727c301 100644 (file)
@@ -12,6 +12,7 @@ import Analysis.Disjoint.Canonical;
 import Analysis.Disjoint.HeapAnalysis;
 import Analysis.CallGraph.CallGraph;
 import Analysis.OoOJava.RBlockRelationAnalysis;
+import Analysis.OoOJava.Accessible;
 import Analysis.Disjoint.ExistPred;
 import Analysis.Disjoint.ReachGraph;
 import Analysis.Disjoint.EffectsAnalysis;
@@ -26,6 +27,7 @@ public class Pointer implements HeapAnalysis{
   HashMap<FlatCall, Set<BBlock>> callMap;
   HashMap<BBlock, Set<PPoint>> returnMap;
   HashMap<BBlock, Set<TempDescriptor>> bblivetemps;
+  HashSet<FlatNode> mustProcess;
 
   private boolean OoOJava=false;
   CallGraph callGraph;
@@ -36,15 +38,19 @@ public class Pointer implements HeapAnalysis{
   TempDescriptor returntmp;
   RBlockRelationAnalysis taskAnalysis;
   EffectsAnalysis effectsAnalysis;
+  Accessible accessible;
 
-  public Pointer(State state, TypeUtil typeUtil, CallGraph callGraph, RBlockRelationAnalysis taskAnalysis) {
+  public Pointer(State state, TypeUtil typeUtil, CallGraph callGraph, RBlockRelationAnalysis taskAnalysis, Liveness liveness, BuildStateMachines bsm) {
     this(state, typeUtil);
     this.callGraph=callGraph;
     this.OoOJava=true;
     this.taskAnalysis=taskAnalysis;
     this.effectsAnalysis=new EffectsAnalysis();
     effectsAnalysis.state=state;
-    effectsAnalysis.buildStateMachines=new BuildStateMachines();
+    effectsAnalysis.buildStateMachines=bsm;
+    accessible=new Accessible(state, callGraph, taskAnalysis, liveness);
+    accessible.doAnalysis();
+    State.logEvent("Done Writing Accessible Analysis");
   }
 
   public Pointer(State state, TypeUtil typeUtil) {
@@ -60,6 +66,7 @@ public class Pointer implements HeapAnalysis{
     this.toprocess=new LinkedList<Delta>();
     ClassDescriptor stringcd=typeUtil.getClass(TypeUtil.ObjectClass);
     this.returntmp=new TempDescriptor("RETURNVAL", stringcd);
+    this.mustProcess=new HashSet<FlatNode>();
   }
 
   public EffectsAnalysis getEffectsAnalysis() {
@@ -108,7 +115,6 @@ public class Pointer implements HeapAnalysis{
   }
 
   public void doAnalysis() {
-    double timeStartAnalysis = (double) System.nanoTime();
 
     toprocess.add(buildInitialContext());
     nextdelta:
@@ -141,23 +147,44 @@ public class Pointer implements HeapAnalysis{
       if (!init&&delta.isEmpty())
        continue nextdelta;
       
+      int lasti=-1;
       //Compute delta at exit of each node
       for(int i=startindex; i<nodes.size();i++) {
        FlatNode currNode=nodes.get(i);
        //System.out.println("Start Processing "+currNode);
+
        if (!graphMap.containsKey(currNode)) {
-         if (isNEEDED(currNode))
+         if (isNEEDED(currNode)) {
            graphMap.put(currNode, new Graph(graph));
-         else {
-           if (i==0) {
-             //base graph works for us
-             graphMap.put(currNode, new Graph(graph));
-           } else {
-             //just use previous graph
-             graphMap.put(currNode, graphMap.get(nodes.get(i-1)));
+         } else {
+           boolean fallthru=true;
+           if (isINACC(currNode)&&((lasti==-1)||(lasti==i))) {
+             if (lasti==-1) {
+               for(lasti=nodes.size()-1;lasti>=i;lasti--) {
+                 FlatNode scurrNode=nodes.get(lasti);
+                 if (isNEEDED(scurrNode)||isINACC(scurrNode)) {
+                   break;
+                 }
+               }
+             }
+             if (i==lasti) {
+               mustProcess.add(currNode);
+               graphMap.put(currNode, new Graph(graph));
+               fallthru=false;
+             }
+           }
+           if (fallthru) {
+             if (i==0) {
+               //base graph works for us
+               graphMap.put(currNode, new Graph(graph));
+             } else {
+               //just use previous graph
+               graphMap.put(currNode, graphMap.get(nodes.get(i-1)));
+             }
            }
          }
        }
+
        nodeGraph=graphMap.get(currNode);
        delta=processNode(bblock, i, currNode, delta, nodeGraph);
        //System.out.println("Processing "+currNode+" and generating delta:");
@@ -167,7 +194,7 @@ public class Pointer implements HeapAnalysis{
     }
 
     //DEBUG
-    if (true) {
+    if (false) {
       int debugindex=0;
       for(Map.Entry<BBlock, Graph> e:bbgraphMap.entrySet()) {
        Graph g=e.getValue();
@@ -186,12 +213,12 @@ public class Pointer implements HeapAnalysis{
       } 
     }
 
-    double timeEndAnalysis = (double) System.nanoTime();
-    double dt = (timeEndAnalysis - timeStartAnalysis)/(Math.pow( 10.0, 9.0 ) );
-    System.out.println("Time taken: "+dt);
+    State.logEvent("Done With Pointer Analysis");
+
 
     if (OoOJava) {
       effectsAnalysis.buildStateMachines.writeStateMachines();
+      State.logEvent("Done Writing State Machines");
     }
   }
 
@@ -243,24 +270,14 @@ public class Pointer implements HeapAnalysis{
       
       /* Compute ages */
       if (graph.oldNodes.containsKey(node)) {
-
+       if (graph.oldNodes.get(node).booleanValue())
+         newDelta.addOldNodes.put(node, Boolean.TRUE);
       } else if (graph.parent.oldNodes.containsKey(node)) {
        //parent graphs only contain true...no need to check
        newDelta.addOldNodes.put(node, Boolean.TRUE);
       }
     }
     
-    for(AllocNode node:graph.oldNodes.keySet()) {
-      if (graph.oldNodes.get(node).booleanValue())
-       newDelta.addOldNodes.put(node, Boolean.TRUE);
-    }
-
-    for(AllocNode node:graph.parent.oldNodes.keySet()) {
-      //make sure child doesn't override
-      if (!graph.oldNodes.containsKey(node))
-       newDelta.addOldNodes.put(node, Boolean.TRUE);
-    }
-
     newDelta.addNodeAges.addAll(graph.nodeAges);
     newDelta.addNodeAges.addAll(graph.parent.nodeAges);
   }
@@ -440,25 +457,21 @@ public class Pointer implements HeapAnalysis{
     if (delta.getInit()) {
       removeInitTaints(null, delta, graph);
       for (TempDescriptor tmp:sese.getInVarSet()) {
-       System.out.println("TMP variable:"+tmp);
-       Taint taint=Taint.factory(sese,  null, tmp, AllocFactory.dummyNode, sese, ReachGraph.predsEmpty);
+       Taint taint=Taint.factory(sese,  null, tmp, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
        MySet<Edge> edges=GraphManip.getEdges(graph, delta, tmp);
        for(Edge e:edges) {
          Edge newe=e.addTaint(taint);
          delta.addVarEdge(newe);
-         System.out.println("Adding Edge:"+newe);
        }
       }
     } else {
       removeDiffTaints(null, delta);
       for (TempDescriptor tmp:sese.getInVarSet()) {
-       System.out.println("TMP variable:"+tmp);
-       Taint taint=Taint.factory(sese,  null, tmp, AllocFactory.dummyNode, sese, ReachGraph.predsEmpty);
+       Taint taint=Taint.factory(sese,  null, tmp, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
        MySet<Edge> edges=GraphManip.getDiffEdges(delta, tmp);
        for(Edge e:edges) {
          Edge newe=e.addTaint(taint);
          delta.addVarEdge(newe);
-         System.out.println("DAdding Edge:"+newe);
        }
       }
     }
@@ -639,7 +652,7 @@ public class Pointer implements HeapAnalysis{
        AllocNode node=tovisit.pop();
        MySet<Edge> edges=GraphManip.getEdges(graph, delta, node);
        if (!edges.isEmpty()) {
-         newDelta.heapedgeadd.put(node, edges);
+         newDelta.heapedgeadd.put(node, Edge.makeOld(edges));
          edgeset.addAll(edges);
          for(Edge e:edges) {
            if (!nodeset.contains(e.dst)&&(oldnodeset==null||!oldnodeset.contains(e.dst))) {
@@ -655,7 +668,7 @@ public class Pointer implements HeapAnalysis{
     TempDescriptor tmpthis=fcall.getThis();
     MethodDescriptor md=fcall.getMethod();
     HashSet<MethodDescriptor> targets=new HashSet<MethodDescriptor>();
-    if (md.isStatic()) {
+    if (md.isStatic()||fcall.getSuper()) {
       targets.add(md);
     } else {
       //Compute Edges
@@ -859,6 +872,8 @@ public class Pointer implements HeapAnalysis{
       graph.callTargets=newtargets;
       graph.callNodeAges=new HashSet<AllocNode>();
       graph.callOldNodes=new HashSet<AllocNode>();
+      graph.callNewEdges=new HashMap<AllocNode, MySet<Edge>>();
+      graph.callOldEdges=new HashMap<Edge,MySet<Edge>>();
 
       //Apply diffs to graph
       applyDiffs(graph, delta, true);
@@ -904,7 +919,7 @@ public class Pointer implements HeapAnalysis{
        if (!newDelta.heapedgeadd.containsKey(src)) {
          newDelta.heapedgeadd.put(src, new MySet<Edge>());
        }
-       newDelta.heapedgeadd.get(src).add(e);
+       newDelta.heapedgeadd.get(src).add(e.makeOld());
        if (!nodeset.contains(e.dst)&&!oldnodeset.contains(e.dst)) {
          nodeset.add(e.dst);
          tovisit.add(e.dst);
@@ -916,6 +931,7 @@ public class Pointer implements HeapAnalysis{
       //Compute call targets
       HashSet<MethodDescriptor> newtargets=computeTargets(fcall, newDelta);
       graph.callTargets.addAll(newtargets);
+
       //add in new nodeset and edgeset
       oldnodeset.addAll(nodeset);
       oldedgeset.addAll(edgeset);
@@ -932,7 +948,36 @@ public class Pointer implements HeapAnalysis{
 
       //Move new edges that should be summarized
       processSummarization(graph, delta);
-      
+
+      Set<FlatSESEEnterNode> seseCallers=OoOJava?taskAnalysis.getTransitiveExecutingRBlocks(fcall):null;
+      //Check if the new nodes allow us to insert a new edge
+      for(AllocNode node:nodeset) {
+       if (graph.callNewEdges.containsKey(node)) {
+         for(Iterator<Edge> eit=graph.callNewEdges.get(node).iterator();eit.hasNext();) {
+           Edge e=eit.next();
+           if ((graph.callNodeAges.contains(e.src)||graph.reachNode.contains(e.src))&&
+               (graph.callNodeAges.contains(e.dst)||graph.reachNode.contains(e.dst))) {
+             Edge edgetoadd=e.copy();//we need our own copy to modify below
+             eit.remove();
+             if (seseCallers!=null)
+               edgetoadd.taintModify(seseCallers);
+             mergeCallEdge(graph, delta, edgetoadd);
+           }
+         }
+       }
+      }
+
+      for(Edge e:edgeset) {
+       //See if these edges would allow an old edge to be added
+       if (graph.callOldEdges.containsKey(e)) {
+         for(Edge adde:graph.callOldEdges.get(e)) {
+           Edge ecopy=adde.copy();
+           ecopy.statuspredicate=e.statuspredicate;
+           mergeCallEdge(graph, delta, ecopy);
+         }
+       }
+      }
+
       //Add in new external edges
       graph.externalEdgeSet.addAll(externaledgeset);
       //Apply diffs to graph
@@ -969,15 +1014,16 @@ public class Pointer implements HeapAnalysis{
       }
     }
     for(Edge e:edgestoremove) {
-      delta.removeVarEdge(e);
+      if (!graph.callerEdges.contains(e))
+       delta.removeVarEdge(e);
     }
     for(Edge e:edgestoadd) {
       delta.addVarEdge(e);
     }
   }
+  
   public Alloc getAllocationSiteFromFlatNew(FlatNew node) {
-    return allocFactory.getAllocNode(node, false);
+    return allocFactory.getAllocNode(node, false).getAllocSite();
   }
  
   void processSumHeapEdgeSet(HashMap<AllocNode, MySet<Edge>> map, Delta delta, Graph graph) {
@@ -1006,7 +1052,8 @@ public class Pointer implements HeapAnalysis{
       }
     }
     for(Edge e:edgestoremove) {
-      delta.removeHeapEdge(e);
+      if (!graph.callerEdges.contains(e))
+       delta.removeHeapEdge(e);
     }
     for(Edge e:edgestoadd) {
       delta.addHeapEdge(e);
@@ -1064,22 +1111,58 @@ public class Pointer implements HeapAnalysis{
        /* Need to age node in existing graph*/
        summarizeInGraph(graph, newDelta, node);
       }
+      if (graph.callNewEdges.containsKey(node)) {
+       for(Iterator<Edge> eit=graph.callNewEdges.get(node).iterator();eit.hasNext();) {
+         Edge e=eit.next();
+         if ((graph.callNodeAges.contains(e.src)||graph.reachNode.contains(e.src))&&
+             (graph.callNodeAges.contains(e.dst)||graph.reachNode.contains(e.dst))) {
+           Edge edgetoadd=e.copy();//we need our own copy to modify below
+           eit.remove();
+           if (seseCallers!=null)
+             edgetoadd.taintModify(seseCallers);
+           mergeCallEdge(graph, newDelta, edgetoadd);
+         }
+       }
+      }
     }
+
     //Add heap edges in
     for(Map.Entry<AllocNode, MySet<Edge>> entry:delta.heapedgeadd.entrySet()) {
       for(Edge e:entry.getValue()) {
        boolean addedge=false;
        Edge edgetoadd=null;
        if (e.statuspredicate==Edge.NEW) {
-         edgetoadd=e;
+         if ((graph.callNodeAges.contains(e.src)||graph.reachNode.contains(e.src))&&
+             (graph.callNodeAges.contains(e.dst)||graph.reachNode.contains(e.dst))) {
+           edgetoadd=e.copy();//we need our own copy to modify below
+         } else {
+           graph.addCallEdge(e);
+         }
        } else {
-         Edge origEdgeKey=e.makeStatus(allocFactory);
-         if (oldgraph.nodeMap.containsKey(origEdgeKey.src)&&
-             oldgraph.nodeMap.get(origEdgeKey.src).contains(origEdgeKey)) {
-           Edge origEdge=oldgraph.nodeMap.get(origEdgeKey.src).get(origEdgeKey);
-           //copy the predicate
-           origEdgeKey.statuspredicate=origEdge.statuspredicate;
-           edgetoadd=origEdgeKey;
+         Edge[] edgeArray=e.makeStatus(allocFactory);
+
+         int statuspredicate=0;
+         for(int i=0;i<edgeArray.length;i++) {
+           Edge origEdgeKey=edgeArray[i];
+           if (graph.reachEdge.contains(origEdgeKey)) {
+             Edge origEdge=graph.reachEdge.get(origEdgeKey);
+             //copy the predicate
+             statuspredicate=statuspredicate|origEdge.statuspredicate;
+           }
+           if (!graph.callOldEdges.containsKey(origEdgeKey)) {
+             graph.callOldEdges.put(origEdgeKey, new MySet<Edge>());
+           }
+           if (graph.callOldEdges.get(origEdgeKey).contains(e)) {
+             Edge olde=graph.callOldEdges.get(origEdgeKey).get(e);
+             graph.callOldEdges.get(origEdgeKey).add(olde.merge(e));
+           } else {
+             graph.callOldEdges.get(origEdgeKey).add(e);
+           }
+         }
+         if (statuspredicate!=0) {
+           Edge newe=e.copy();
+           newe.statuspredicate=statuspredicate;
+           edgetoadd=newe;
          }
        }
        if (seseCallers!=null&&edgetoadd!=null)
@@ -1122,13 +1205,14 @@ public class Pointer implements HeapAnalysis{
 
   public void mergeCallEdge(Graph graph, Delta newDelta, Edge edgetoadd) {
     if (edgetoadd!=null) {
-      Edge match=graph.getMatch(edgetoadd);
+      newDelta.addEdgeClear(edgetoadd);
 
+      Edge match=graph.getMatch(edgetoadd);
+      
       if (match==null||!match.subsumes(edgetoadd)) {
        Edge mergededge=edgetoadd.merge(match);
        newDelta.addEdge(mergededge);
        graph.callerEdges.add(mergededge);
-       //System.out.println("ADDING: "+ mergededge);
       }
     }
   }
@@ -1259,7 +1343,6 @@ public class Pointer implements HeapAnalysis{
     for(Map.Entry<TempDescriptor, MySet<Edge>> e: delta.varedgeadd.entrySet()) {
       TempDescriptor tmp=e.getKey();
       MySet<Edge> edgestoadd=e.getValue();
-      System.out.println("ADDING:"+edgestoadd);
       if (graph.varMap.containsKey(tmp)) {
        Edge.mergeEdgesInto(graph.varMap.get(tmp), edgestoadd);
       } else 
@@ -1285,6 +1368,30 @@ public class Pointer implements HeapAnalysis{
     }
   }
 
+  boolean isINACC(FlatNode node) {
+    if (!OoOJava)
+      return false;
+    switch(node.kind()) {
+    case FKind.FlatSetFieldNode: {
+      FlatSetFieldNode n=(FlatSetFieldNode)node;
+      return !accessible.isAccessible(n, n.getDst());
+    }
+    case FKind.FlatSetElementNode: {
+      FlatSetElementNode n=(FlatSetElementNode)node;
+      return !accessible.isAccessible(n, n.getDst());
+    }
+    case FKind.FlatFieldNode: {
+      FlatFieldNode n=(FlatFieldNode)node;
+      return !accessible.isAccessible(n, n.getSrc());
+    }
+    case FKind.FlatElementNode: {
+      FlatElementNode n=(FlatElementNode)node;
+      return !accessible.isAccessible(n, n.getSrc());
+    }
+    }
+    return false;
+  }
+
   Delta processSetFieldElementNode(FlatNode node, Delta delta, Graph graph) {
     TempDescriptor src;
     FieldDescriptor fd;
@@ -1300,13 +1407,34 @@ public class Pointer implements HeapAnalysis{
       fd=ffn.getField();
       dst=ffn.getDst();
     }
-    //Do nothing for non pointers
-    if (!src.getType().isPtr())
-      return delta;
 
     if (delta.getInit()) {
-      MySet<Edge> srcEdges=GraphManip.getEdges(graph, delta, src);
       MySet<Edge> dstEdges=GraphManip.getEdges(graph, delta, dst);
+
+      if (OoOJava&&!accessible.isAccessible(node, dst)) {
+       Taint dstStallTaint=Taint.factory(node,  dst, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
+       dstEdges=Edge.taintAll(dstEdges, dstStallTaint);
+       updateVarDelta(graph, delta, dst, dstEdges, null);
+      }
+      if (OoOJava) {
+       effectsAnalysis.analyzeFlatSetFieldNode(dstEdges, fd, node);
+      }
+
+      //Do nothing for non pointers
+      if (!src.getType().isPtr()) {
+       if (mustProcess.contains(node)) {
+         applyDiffs(graph, delta);
+       }
+       return delta;
+      }
+
+      MySet<Edge> srcEdges=GraphManip.getEdges(graph, delta, src);
+      if (OoOJava&&!accessible.isAccessible(node, src)) {
+       Taint srcStallTaint=Taint.factory(node,  src, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
+       srcEdges=Edge.taintAll(srcEdges, srcStallTaint);
+       updateVarDelta(graph, delta, src, srcEdges, null);
+      }
+
       MySet<Edge> edgesToAdd=GraphManip.genEdges(dstEdges, fd, srcEdges);
       MySet<Edge> edgesToRemove=null;
       if (dstEdges.size()==1&&!dstEdges.iterator().next().dst.isSummary()&&fd!=null) {
@@ -1316,23 +1444,40 @@ public class Pointer implements HeapAnalysis{
       } else
        graph.strongUpdateSet=new MySet<Edge>();
 
-      if (OoOJava) {
-       effectsAnalysis.analyzeFlatSetFieldNode(dstEdges, fd, node);
-      }
-
       /* Update diff */
       updateHeapDelta(graph, delta, edgesToAdd, edgesToRemove);
       applyDiffs(graph, delta);
     } else {
-      /* First look at new sources */
+      MySet<Edge> newDstEdges=GraphManip.getDiffEdges(delta, dst);
+
+      if (OoOJava&&!accessible.isAccessible(node, dst)) {
+       Taint dstStallTaint=Taint.factory(node,  dst, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
+       newDstEdges=Edge.taintAll(newDstEdges, dstStallTaint);
+       updateVarDelta(graph, delta, dst, newDstEdges, null);
+      }
+
+      if (OoOJava) {
+       effectsAnalysis.analyzeFlatSetFieldNode(newDstEdges, fd, node);
+      }
+
+      if (!src.getType().isPtr()) {
+       if (mustProcess.contains(node)) {
+         applyDiffs(graph, delta);
+       }
+       return delta;
+      }
+
+      /* Next look at new sources */
+
       MySet<Edge> edgesToAdd=new MySet<Edge>();
       MySet<Edge> newSrcEdges=GraphManip.getDiffEdges(delta, src);
       MySet<Edge> srcEdges=GraphManip.getEdges(graph, delta, src);
       HashSet<AllocNode> dstNodes=GraphManip.getNodes(graph, delta, dst);
-      MySet<Edge> newDstEdges=GraphManip.getDiffEdges(delta, dst);
 
-      if (OoOJava) {
-       effectsAnalysis.analyzeFlatSetFieldNode(newDstEdges, fd, node);
+      if (OoOJava&&!accessible.isAccessible(node, src)) {
+       Taint srcStallTaint=Taint.factory(node,  src, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
+       newSrcEdges=Edge.taintAll(newSrcEdges, srcStallTaint);
+       updateVarDelta(graph, delta, src, newSrcEdges, null);
       }
 
       MySet<Edge> edgesToRemove=null;
@@ -1431,29 +1576,52 @@ public class Pointer implements HeapAnalysis{
       fd=ffn.getField();
       dst=ffn.getDst();
     }
-    if (OoOJava&&taskAnalysis.isPotentialStallSite(node)) {
-      taint=TaintSet.factory(Taint.factory(node,  src, AllocFactory.dummyNode, null, ReachGraph.predsEmpty));
+    if (OoOJava&&!accessible.isAccessible(node, src)) {
+      taint=TaintSet.factory(Taint.factory(node,  src, AllocFactory.dummySite, null, ReachGraph.predsEmpty));
     }
 
     //Do nothing for non pointers
-    if (!dst.getType().isPtr())
-      return delta;
     if (delta.getInit()) {
       MySet<Edge> srcedges=GraphManip.getEdges(graph, delta, src);
-      MySet<Edge> edgesToAdd=GraphManip.dereference(graph, delta, dst, srcedges, fd, node, taint);
-      MySet<Edge> edgesToRemove=GraphManip.getEdges(graph, delta, dst);
-      if (OoOJava)
+      if (OoOJava) {
+       if (taint!=null) {
+         srcedges=Edge.taintAll(srcedges, taint);
+         updateVarDelta(graph, delta, src, srcedges, null);
+       }
        effectsAnalysis.analyzeFlatFieldNode(srcedges, fd, node);
+      }
+      if (!dst.getType().isPtr()) {
+       if (mustProcess.contains(node)) {
+         applyDiffs(graph, delta);
+       }
+       return delta;
+      }
+
+      MySet<Edge> edgesToAdd=GraphManip.dereference(graph, delta, dst, srcedges, fd, node);
+      MySet<Edge> edgesToRemove=GraphManip.getEdges(graph, delta, dst);
 
       updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
       applyDiffs(graph, delta);
     } else {
+      MySet<Edge> newsrcedges=GraphManip.getDiffEdges(delta, src);
+      if (OoOJava) {
+       if (taint!=null) {
+         newsrcedges=Edge.taintAll(newsrcedges, taint);
+         updateVarDelta(graph, delta, src, newsrcedges, null);
+       }
+       effectsAnalysis.analyzeFlatFieldNode(newsrcedges, fd, node);
+      }
+      if (!dst.getType().isPtr()) {
+       if (mustProcess.contains(node)) {
+         applyDiffs(graph, delta);
+       }
+       return delta;
+      }
       /* First compute new objects we read fields of */
       MySet<Edge> allsrcedges=GraphManip.getEdges(graph, delta, src);
-      MySet<Edge> edgesToAdd=GraphManip.diffDereference(delta, dst, allsrcedges, fd, node, taint);
+      MySet<Edge> edgesToAdd=GraphManip.diffDereference(delta, dst, allsrcedges, fd, node);
       /* Next compute new targets of fields */
-      MySet<Edge> newsrcedges=GraphManip.getDiffEdges(delta, src);
-      MySet<Edge> newfdedges=GraphManip.dereference(graph, delta, dst, newsrcedges, fd, node, taint);
+      MySet<Edge> newfdedges=GraphManip.dereference(graph, delta, dst, newsrcedges, fd, node);
 
       /* Compute the union, and then the set of edges */
       Edge.mergeEdgesInto(edgesToAdd, newfdedges);
@@ -1461,8 +1629,6 @@ public class Pointer implements HeapAnalysis{
       /* Compute set of edges to remove */
       MySet<Edge> edgesToRemove=GraphManip.getDiffEdges(delta, dst);      
 
-      if (OoOJava)
-       effectsAnalysis.analyzeFlatFieldNode(newsrcedges, fd, node);
       
       /* Update diff */
       updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
@@ -1476,21 +1642,31 @@ public class Pointer implements HeapAnalysis{
     MySet<Edge> edgeAdd=delta.varedgeadd.get(tmp);
     MySet<Edge> edgeRemove=delta.varedgeremove.get(tmp);
     MySet<Edge> existingEdges=graph.getEdges(tmp);
-    for(Edge e: edgestoRemove) {
-      //remove edge from delta
-      if (edgeAdd!=null)
-       edgeAdd.remove(e);
-      //if the edge is already in the graph, add an explicit remove to the delta
-      if (existingEdges.contains(e))
-       delta.removeVarEdge(e);
-    }
+    if (edgestoRemove!=null)
+      for(Edge e: edgestoRemove) {
+       //remove edge from delta
+       if (edgeAdd!=null)
+         edgeAdd.remove(e);
+       //if the edge is already in the graph, add an explicit remove to the delta
+       if (existingEdges.contains(e))
+         delta.removeVarEdge(e);
+      }
     for(Edge e: edgestoAdd) {
       //Remove the edge from the remove set
       if (edgeRemove!=null)
        edgeRemove.remove(e);
       //Explicitly add it to the add set unless it is already in the graph
-      if (!existingEdges.contains(e)&&typeUtil.isSuperorType(tmp.getType(),e.dst.getType()))
-       delta.addVarEdge(e);
+      if (typeUtil.isSuperorType(tmp.getType(), e.dst.getType())) {
+       if (!existingEdges.contains(e)) {
+         delta.addVarEdge(e);
+       } else {
+         //See if the old edge subsumes the new one
+         Edge olde=existingEdges.get(e);
+         if (!olde.subsumes(e)) {
+           delta.addVarEdge(olde.merge(e));
+         }
+       }
+      }
     }
   }
 
@@ -1517,8 +1693,14 @@ public class Pointer implements HeapAnalysis{
        if (edgeRemove!=null)
          edgeRemove.remove(e);
        //Explicitly add it to the add set unless it is already in the graph
-       if (!existingEdges.contains(e)||!existingEdges.get(e).isNew()) {
+       if (!existingEdges.contains(e)) {
          delta.addHeapEdge(e);
+       } else {
+         //See if the old edge subsumes the new one
+         Edge olde=existingEdges.get(e);
+         if (!olde.subsumes(e)) {
+           delta.addHeapEdge(olde.merge(e));
+         }
        }
       }
   }
@@ -1644,9 +1826,10 @@ public class Pointer implements HeapAnalysis{
        delta.addOldNodes.put(single, Boolean.FALSE);
       }
       
-      //Apply incoming diffs to graph
-      applyDiffs(graph, delta);      
     }
+    //Apply incoming diffs to graph
+    applyDiffs(graph, delta);      
+
     return delta;
   }