changes
[IRC.git] / Robust / src / Analysis / Pointer / Pointer.java
1 package Analysis.Pointer;
2 import java.util.*;
3 import IR.Flat.*;
4 import IR.*;
5 import Analysis.Pointer.BasicBlock.BBlock;
6 import Analysis.Pointer.AllocFactory.AllocNode;
7
8 public class Pointer {
9   HashMap<FlatMethod, BasicBlock> blockMap;
10   HashMap<BBlock, Graph> bbgraphMap;
11   HashMap<FlatNode, Graph> graphMap;
12   HashMap<FlatCall, Set<BBlock>> callMap;
13   HashMap<BBlock, Set<PPoint>> returnMap;
14
15   State state;
16   TypeUtil typeUtil;
17   AllocFactory allocFactory;
18   LinkedList<Delta> toprocess;
19   TempDescriptor returntmp;
20
21   public Pointer(State state, TypeUtil typeUtil) {
22     this.state=state;
23     this.blockMap=new HashMap<FlatMethod, BasicBlock>();
24     this.bbgraphMap=new HashMap<BBlock, Graph>();
25     this.graphMap=new HashMap<FlatNode, Graph>();
26     this.callMap=new HashMap<FlatCall, Set<BBlock>>();
27     this.returnMap=new HashMap<BBlock, Set<PPoint>>();
28     this.typeUtil=typeUtil;
29     this.allocFactory=new AllocFactory(state, typeUtil);
30     this.toprocess=new LinkedList<Delta>();
31     ClassDescriptor stringcd=typeUtil.getClass(TypeUtil.ObjectClass);
32     this.returntmp=new TempDescriptor("RETURNVAL", stringcd);
33   }
34
35   public BasicBlock getBBlock(FlatMethod fm) {
36     if (!blockMap.containsKey(fm))
37       blockMap.put(fm, BasicBlock.getBBlock(fm));
38     return blockMap.get(fm);
39   }
40   
41   Delta buildInitialContext() {
42     MethodDescriptor md=typeUtil.getMain();
43     FlatMethod fm=state.getMethodFlat(md);
44     BasicBlock bb=getBBlock(fm);
45     BBlock start=bb.getStart();
46     Delta delta=new Delta(new PPoint(start), true);
47     MySet<Edge> arrayset=new MySet<Edge>();
48     MySet<Edge> varset=new MySet<Edge>();
49     Edge arrayedge=new Edge(allocFactory.StringArray, null, allocFactory.Strings);
50     Edge stringedge=new Edge(fm.getParameter(0), allocFactory.StringArray);
51     delta.addHeapEdge(arrayedge);
52     delta.addVarEdge(stringedge);
53
54     return delta;
55   }
56
57   public void doAnalysis() {
58     toprocess.add(buildInitialContext());
59
60     while(!toprocess.isEmpty()) {
61       Delta delta=toprocess.remove();
62       PPoint ppoint=delta.getBlock();
63       BBlock bblock=ppoint.getBBlock();
64       Vector<FlatNode> nodes=bblock.nodes();
65       int startindex=0;
66       if (ppoint.getIndex()==-1) {
67         //Build base graph for entrance to this basic block
68         delta=applyInitDelta(delta, bblock);
69       } else {
70         startindex=ppoint.getIndex()+1;
71         delta=applyCallDelta(delta, bblock);
72       }
73
74       Graph graph=bbgraphMap.get(bblock);
75       Graph nodeGraph=null;
76       //Compute delta at exit of each node
77       for(int i=startindex; i<nodes.size();i++) {
78         FlatNode currNode=nodes.get(i);
79         if (!graphMap.containsKey(currNode)) {
80           graphMap.put(currNode, new Graph(graph));
81         }
82         nodeGraph=graphMap.get(currNode);
83         delta=processNode(bblock, i, currNode, delta, nodeGraph);
84       }
85       generateFinalDelta(bblock, delta, nodeGraph);
86     }
87   }
88
89   void buildInitDelta(Graph graph, Delta newDelta) {
90     //First compute the set of temps
91     HashSet<TempDescriptor> tmpSet=new HashSet<TempDescriptor>();
92     tmpSet.addAll(graph.varMap.keySet());
93     tmpSet.addAll(graph.parent.varMap.keySet());
94     
95     //Next build the temp map part of the delta
96     for(TempDescriptor tmp:tmpSet) {
97       MySet<Edge> edgeSet=new MySet<Edge>();
98       /* Get target set */
99       if (graph.varMap.containsKey(tmp))
100         edgeSet.addAll(graph.varMap.get(tmp));
101       else
102         edgeSet.addAll(graph.parent.varMap.get(tmp));
103       newDelta.varedgeadd.put(tmp, edgeSet);
104     }
105     
106     //Next compute the set of src allocnodes
107     HashSet<AllocNode> nodeSet=new HashSet<AllocNode>();
108     nodeSet.addAll(graph.nodeMap.keySet());
109     nodeSet.addAll(graph.parent.nodeMap.keySet());
110     
111     for(AllocNode node:nodeSet) {
112       MySet<Edge> edgeSet=new MySet<Edge>();
113       /* Get edge set */
114       if (graph.nodeMap.containsKey(node))
115         edgeSet.addAll(graph.nodeMap.get(node));
116       else
117         edgeSet.addAll(graph.parent.nodeMap.get(node));
118       newDelta.heapedgeadd.put(node, edgeSet);
119       
120       /* Compute ages */
121       if (graph.nodeAges.contains(node))
122         newDelta.addNodeAges.add(node);
123       else if (graph.parent.nodeAges.contains(node))
124         newDelta.addNodeAges.add(node);
125
126       /* Compute ages */
127       if (graph.oldNodes.containsKey(node)) {
128         if (graph.oldNodes.get(node).booleanValue())
129           newDelta.addOldNodes.put(node, Boolean.TRUE);
130       } else if (graph.parent.oldNodes.containsKey(node)) {
131         //parent graphs only contain true...no need to check
132         newDelta.addOldNodes.put(node, Boolean.TRUE);
133       }
134     }
135   }
136
137   void generateFinalDelta(BBlock bblock, Delta delta, Graph graph) {
138     Delta newDelta=new Delta(null, false);
139     if (delta.getInit()) {
140       buildInitDelta(graph, newDelta);
141     } else {
142       /* We can break the old delta...it is done being used */
143       /* First we will build variable edges */
144       HashSet<TempDescriptor> tmpSet=new HashSet<TempDescriptor>();
145       tmpSet.addAll(delta.basevaredge.keySet());
146       tmpSet.addAll(delta.varedgeadd.keySet());
147       for(TempDescriptor tmp:tmpSet) {
148         /* Start with the new incoming edges */
149         MySet<Edge> newbaseedge=delta.basevaredge.get(tmp);
150         /* Remove the remove set */
151         newbaseedge.removeAll(delta.varedgeremove.get(tmp));
152         /* Add in the new set*/
153         newbaseedge.addAll(delta.varedgeadd.get(tmp));
154         /* Store the results */
155         newDelta.varedgeadd.put(tmp, newbaseedge);
156       }
157
158       /* Next we build heap edges */
159       HashSet<AllocNode> nodeSet=new HashSet<AllocNode>();
160       nodeSet.addAll(delta.baseheapedge.keySet());
161       nodeSet.addAll(delta.heapedgeadd.keySet());
162       nodeSet.addAll(delta.heapedgeremove.keySet());
163       for(AllocNode node:nodeSet) {
164         /* Start with the new incoming edges */
165         MySet<Edge> newheapedge=(MySet<Edge>) delta.baseheapedge.get(node).clone();
166         /* Remove the remove set */
167         newheapedge.removeAll(delta.heapedgeremove.get(node));
168         /* Add in the add set */
169         newheapedge.addAll(delta.heapedgeadd.get(node));
170         newDelta.heapedgeadd.put(node, newheapedge);
171
172         /* Also need to subtract off some edges */
173         MySet<Edge> removeset=delta.heapedgeremove.get(node);
174
175         /* Remove the newly created edges..no need to propagate a diff for those */
176         removeset.removeAll(delta.baseheapedge.get(node));
177         newDelta.heapedgeremove.put(node, removeset);
178       }
179
180       /* Compute new ages */
181       newDelta.addNodeAges.addAll(delta.baseNodeAges);
182       newDelta.addNodeAges.addAll(delta.addNodeAges);
183       HashSet<AllocNode> oldNodes=new HashSet<AllocNode>();
184
185       /* Compute whether old nodes survive */
186       oldNodes.addAll(delta.baseOldNodes.keySet());
187       oldNodes.addAll(delta.addOldNodes.keySet());
188       for(AllocNode node:oldNodes) {
189         if (delta.addOldNodes.containsKey(node)) {
190           if (delta.addOldNodes.get(node).booleanValue()) {
191             newDelta.addOldNodes.put(node, Boolean.TRUE);
192           }
193         } else {
194           if (delta.baseOldNodes.get(node).booleanValue()) {
195             newDelta.addOldNodes.put(node, Boolean.TRUE);
196           }
197         }
198       }
199     }
200
201     /* Now we need to propagate newdelta */
202     if (!newDelta.heapedgeadd.isEmpty()||!newDelta.heapedgeremove.isEmpty()||!newDelta.varedgeadd.isEmpty()||!newDelta.addNodeAges.isEmpty()||!newDelta.addOldNodes.isEmpty()) {
203       /* We have a delta to propagate */
204       Vector<BBlock> blockvector=bblock.next();
205       for(int i=0;i<blockvector.size();i++) {
206         if (i==0) {
207           newDelta.setBlock(new PPoint(blockvector.get(i)));
208           toprocess.add(newDelta);
209         } else {
210           toprocess.add(newDelta.diffBlock(new PPoint(blockvector.get(i))));
211         }
212       }
213     }
214   }
215
216   Delta processNode(BBlock bblock, int index, FlatNode node, Delta delta, Graph newgraph) {
217     switch(node.kind()) {
218     case FKind.FlatNew:
219       return processNewNode((FlatNew)node, delta, newgraph);
220     case FKind.FlatFieldNode:
221     case FKind.FlatElementNode:
222       return processFieldElementNode(node, delta, newgraph);
223     case FKind.FlatCastNode:
224     case FKind.FlatOpNode:
225     case FKind.FlatReturnNode:
226       return processCopyNode(node, delta, newgraph);
227     case FKind.FlatSetFieldNode:
228     case FKind.FlatSetElementNode:
229       return processSetFieldElementNode(node, delta, newgraph);
230     case FKind.FlatMethod:
231     case FKind.FlatExit:
232       return processFlatNop(node, delta, newgraph);
233     case FKind.FlatCall:
234       return processFlatCall(bblock, index, (FlatCall) node, delta, newgraph);
235     case FKind.FlatSESEEnterNode:
236     case FKind.FlatSESEExitNode:
237       throw new Error("Unimplemented node:"+node);
238     default:
239       throw new Error("Unrecognized node:"+node);
240     }
241   }
242
243   void processThisTargets(HashSet<ClassDescriptor> targetSet, Graph graph, Delta delta, Delta newDelta, HashSet<AllocNode> nodeset, Stack<AllocNode> tovisit, MySet<Edge> edgeset, TempDescriptor tmpthis, HashSet<AllocNode> oldnodeset) {
244     //Handle the this temp
245     if (tmpthis!=null) {
246       MySet<Edge> edges=(oldnodeset!=null)?GraphManip.getDiffEdges(delta, tmpthis):GraphManip.getEdges(graph, delta, tmpthis);
247       newDelta.varedgeadd.put(tmpthis, (MySet<Edge>) edges.clone());
248       edgeset.addAll(edges);
249       for(Edge e:edges) {
250         AllocNode dstnode=e.dst;
251         if (!nodeset.contains(dstnode)&&(oldnodeset==null||!oldnodeset.contains(dstnode))) {
252           TypeDescriptor type=dstnode.getType();
253           if (!type.isArray()) {
254             targetSet.add(type.getClassDesc());
255           } else {
256             //arrays don't have code
257             targetSet.add(typeUtil.getClass(TypeUtil.ObjectClass));
258           }
259           nodeset.add(dstnode);
260           tovisit.add(dstnode);
261         }
262       }
263     }
264   }
265
266   void processParams(Graph graph, Delta delta, Delta newDelta, HashSet<AllocNode> nodeset, Stack<AllocNode> tovisit, MySet<Edge> edgeset, FlatCall fcall, boolean diff) {
267     //Go through each temp
268     for(int i=0;i<fcall.numArgs();i++) {
269       TempDescriptor tmp=fcall.getArg(i);
270       MySet<Edge> edges=diff?GraphManip.getDiffEdges(delta, tmp):GraphManip.getEdges(graph, delta, tmp);
271       newDelta.varedgeadd.put(tmp, (MySet<Edge>) edges.clone());
272       edgeset.addAll(edges);
273       for(Edge e:edges) {
274         if (!nodeset.contains(e.dst)) {
275           nodeset.add(e.dst);
276           tovisit.add(e.dst);
277         }
278       }
279     }
280   }
281
282   void computeReachableNodes(Graph graph, Delta delta, Delta newDelta, HashSet<AllocNode> nodeset, Stack<AllocNode> tovisit, MySet<Edge> edgeset, HashSet<AllocNode> oldnodeset) {
283       while(!tovisit.isEmpty()) {
284         AllocNode node=tovisit.pop();
285         MySet<Edge> edges=GraphManip.getEdges(graph, delta, node);
286         newDelta.heapedgeadd.put(node, edges);
287         edgeset.addAll(edges);
288         for(Edge e:edges) {
289           if (!nodeset.contains(e.dst)&&(oldnodeset==null||!oldnodeset.contains(e.dst))) {
290             nodeset.add(e.dst);
291             tovisit.add(e.dst);
292           }
293         }
294       }
295   }
296
297   HashSet<MethodDescriptor> computeTargets(FlatCall fcall, Delta newDelta) {
298     TempDescriptor tmpthis=fcall.getThis();
299     MethodDescriptor md=fcall.getMethod();
300     HashSet<MethodDescriptor> targets=new HashSet<MethodDescriptor>();
301     if (md.isStatic()) {
302       targets.add(md);
303     } else {
304       //Compute Edges
305       for(Edge e:newDelta.varedgeadd.get(tmpthis)) {
306         AllocNode node=e.dst;
307         ClassDescriptor cd=node.getType().getClassDesc();
308         //Figure out exact method called and add to set
309         targets.add(cd.getCalledMethod(md));
310       }
311     }
312     return targets;
313   }
314
315   void fixMapping(FlatCall fcall, HashSet<MethodDescriptor> targets, MySet<Edge> oldedgeset, Delta newDelta, BBlock callblock, int callindex) {
316     Delta basedelta=null;
317     TempDescriptor tmpthis=fcall.getThis();
318
319     for(MethodDescriptor calledmd:targets) {
320       FlatMethod fm=state.getMethodFlat(calledmd);
321       boolean newmethod=false;
322       
323       //Build tmpMap
324       HashMap<TempDescriptor, TempDescriptor> tmpMap=new HashMap<TempDescriptor, TempDescriptor>();
325       int offset=0;
326       if(tmpthis!=null) {
327         tmpMap.put(tmpthis, fm.getParameter(offset++));
328       }
329       for(int i=0;i<fcall.numArgs();i++) {
330         TempDescriptor tmp=fcall.getArg(i);
331         tmpMap.put(tmp,fm.getParameter(i+offset));
332       }
333
334       //Get basicblock for the method
335       BasicBlock block=getBBlock(fm);
336       
337       //Hook up exits
338       if (!callMap.containsKey(fcall)) {
339         callMap.put(fcall, new HashSet<BBlock>());
340       }
341       
342       Delta returnDelta=null;
343       if (!callMap.get(fcall).contains(block.getStart())) {
344         callMap.get(fcall).add(block.getStart());
345         newmethod=true;
346         
347         //Hook up return
348         if (!returnMap.containsKey(block.getExit())) {
349           returnMap.put(block.getExit(), new HashSet<PPoint>());
350         }
351         returnMap.get(block.getExit()).add(new PPoint(callblock, callindex));
352         
353         if (bbgraphMap.containsKey(block.getExit())) {
354           //Need to push existing results to current node
355           if (returnDelta==null) {
356             returnDelta=new Delta(null, false);
357             buildInitDelta(bbgraphMap.get(block.getExit()), returnDelta);
358             if (!returnDelta.heapedgeadd.isEmpty()||!returnDelta.heapedgeremove.isEmpty()||!returnDelta.varedgeadd.isEmpty()) {
359               returnDelta.setBlock(new PPoint(callblock, callindex));
360               toprocess.add(returnDelta);
361             }
362           } else {
363             if (!returnDelta.heapedgeadd.isEmpty()||!returnDelta.heapedgeremove.isEmpty()||!returnDelta.varedgeadd.isEmpty()) {
364               toprocess.add(returnDelta.diffBlock(new PPoint(callblock, callindex)));
365             }
366           }
367         }
368       }
369       
370       if (oldedgeset==null) {
371         //First build of this graph
372         //Build and enqueue delta...safe to just use existing delta
373         Delta d=newDelta.changeParams(tmpMap, new PPoint(block.getStart()));
374         toprocess.add(d);
375       } else if (newmethod) {
376         if (basedelta==null) {
377           basedelta=newDelta.buildBase(oldedgeset);
378         }
379         //Build and enqueue delta
380         Delta d=basedelta.changeParams(tmpMap, new PPoint(block.getStart()));
381         toprocess.add(d);
382       } else  {
383         //Build and enqueue delta
384         Delta d=newDelta.changeParams(tmpMap, new PPoint(block.getStart()));
385         toprocess.add(d);
386       }
387     }
388   }
389
390
391   /* This function computes all edges that start outside of the callee context and go into the callee context */
392
393   void computeExternalEdges(Graph graph, Delta delta, HashSet<AllocNode> nodeset, HashSet<AllocNode> deltaset, MySet<Edge> externaledgeset) {
394     //Do heap edges first
395     HashSet<AllocNode> externalnodes=new HashSet<AllocNode>();
396     externalnodes.addAll(delta.baseheapedge.keySet());
397     externalnodes.addAll(delta.heapedgeadd.keySet());
398     externalnodes.addAll(delta.heapedgeremove.keySet());
399     //remove allinternal nodes
400     externalnodes.removeAll(nodeset);
401     for(AllocNode extNode:externalnodes) {
402       //Compute set of edges from given node
403       MySet<Edge> edges=new MySet<Edge>(delta.baseheapedge.get(extNode));
404       edges.removeAll(delta.heapedgeremove.get(extNode));
405       edges.addAll(delta.heapedgeadd.get(extNode));
406       
407       for(Edge e:edges) {
408         if (nodeset.contains(e.dst))
409           externaledgeset.add(e);
410       }
411     }
412
413     //Do heap edges first
414     HashSet<TempDescriptor> temps=new HashSet<TempDescriptor>();
415     temps.addAll(delta.basevaredge.keySet());
416     temps.addAll(delta.varedgeadd.keySet());
417     temps.addAll(delta.varedgeremove.keySet());
418     //remove allinternal nodes
419     temps.removeAll(nodeset);
420     
421     for(TempDescriptor tmp:temps) {
422       //Compute set of edges from given node
423       MySet<Edge> edges=new MySet<Edge>(delta.basevaredge.get(tmp));
424       edges.removeAll(delta.varedgeremove.get(tmp));
425       edges.addAll(delta.varedgeadd.get(tmp));
426       
427       for(Edge e:edges) {
428         if (nodeset.contains(e.dst))
429           externaledgeset.add(e);
430       }
431     }
432   }
433   
434   void removeEdges(Delta delta, HashSet<AllocNode> nodeset, MySet<Edge> edgeset, MySet<Edge> externaledgeset) {
435     //Want to remove the set of internal edges
436     for(Edge e:edgeset) {
437       if (e.src!=null) {
438         delta.removeHeapEdge(e);
439       }
440     }
441
442     //Want to remove the set of external edges
443     for(Edge e:externaledgeset) {
444       //want to remove the set of internal edges
445       delta.removeEdge(e);
446     }
447   }
448   
449
450   Delta processFlatCall(BBlock callblock, int callindex, FlatCall fcall, Delta delta, Graph graph) {
451     Delta newDelta=new Delta(null, false);
452
453     if (delta.getInit()) {
454       MySet<Edge> edgeset=new MySet<Edge>();
455       MySet<Edge> externaledgeset=new MySet<Edge>();
456       HashSet<AllocNode> nodeset=new HashSet<AllocNode>();
457       HashSet<ClassDescriptor> targetSet=new HashSet<ClassDescriptor>();
458       Stack<AllocNode> tovisit=new Stack<AllocNode>();
459       TempDescriptor tmpthis=fcall.getThis();
460
461       //Handle the this temp
462       processThisTargets(targetSet, graph, delta, newDelta, nodeset, tovisit, edgeset, tmpthis, null);
463
464       //Go through each temp
465       processParams(graph, delta, newDelta, nodeset, tovisit, edgeset, fcall, false);
466       
467       //Traverse all reachable nodes
468       computeReachableNodes(graph, delta, newDelta, nodeset, tovisit, edgeset, null);
469
470       //Compute call targets
471       HashSet<MethodDescriptor> targets=computeTargets(fcall, newDelta);
472
473       //Fix mapping
474       fixMapping(fcall, targets, null, newDelta, callblock, callindex);
475
476       //Compute edges into region to splice out
477       computeExternalEdges(graph, delta, nodeset, null, externaledgeset);
478
479       //Splice out internal edges
480       removeEdges(delta, nodeset, edgeset, externaledgeset);
481
482       //store data structures
483       graph.externalEdgeSet=externaledgeset;
484       graph.reachNode=nodeset;
485       graph.reachEdge=edgeset;
486       
487       graph.callNodeAges=new HashSet<AllocNode>();
488       graph.callOldNodes=new HashSet<AllocNode>();
489
490       //Apply diffs to graph
491       applyDiffs(graph, delta, true);
492     } else {
493       MySet<Edge> edgeset=new MySet<Edge>();
494       MySet<Edge> externaledgeset=new MySet<Edge>();
495       HashSet<AllocNode> nodeset=new HashSet<AllocNode>();
496       MySet<Edge> oldedgeset=graph.reachEdge;
497       HashSet<AllocNode> oldnodeset=graph.reachNode;
498
499       HashSet<ClassDescriptor> targetSet=new HashSet<ClassDescriptor>();
500       Stack<AllocNode> tovisit=new Stack<AllocNode>();
501       TempDescriptor tmpthis=fcall.getThis();
502
503       //Handle the this temp
504       processThisTargets(targetSet, graph, delta, newDelta, nodeset, tovisit, edgeset, tmpthis, oldnodeset);
505
506       //Go through each temp
507       processParams(graph, delta, newDelta, nodeset, tovisit, edgeset, fcall, true);
508
509       //Go through each new heap edge that starts from old node
510       MySet<Edge> newedges=GraphManip.getDiffEdges(delta, oldnodeset);
511       edgeset.addAll(newedges);
512       for(Edge e:newedges) {
513         if (!nodeset.contains(e.dst)&&!oldnodeset.contains(e.dst)) {
514           nodeset.add(e.dst);
515           tovisit.add(e.dst);
516         }
517       }
518       
519       //Traverse all reachable nodes
520       computeReachableNodes(graph, delta, newDelta, nodeset, tovisit, edgeset, oldnodeset);
521
522       //Compute call targets
523       HashSet<MethodDescriptor> targets=computeTargets(fcall, newDelta);
524
525       //add in new nodeset and edgeset
526       oldnodeset.addAll(nodeset);
527       oldedgeset.addAll(edgeset);
528
529       //Fix mapping
530       fixMapping(fcall, targets, oldedgeset, newDelta, callblock, callindex);
531
532       //Compute edges into region to splice out
533       computeExternalEdges(graph, delta, oldnodeset, nodeset, externaledgeset);
534
535       //Splice out internal edges
536       removeEdges(delta, nodeset, edgeset, externaledgeset);
537
538       //Add in new external edges
539       graph.externalEdgeSet.addAll(externaledgeset);
540
541       //Apply diffs to graph
542       applyDiffs(graph, delta);
543     }
544     return delta;
545   }
546
547   
548
549   Delta applyCallDelta(Delta delta, BBlock bblock) {
550     Delta newDelta=new Delta(null, false);
551     Vector<FlatNode> nodes=bblock.nodes();
552     PPoint ppoint=delta.getBlock();
553     FlatCall fcall=(FlatCall)nodes.get(ppoint.getIndex());
554     Graph graph=graphMap.get(fcall);
555     Graph oldgraph=(ppoint.getIndex()==0)?
556       bbgraphMap.get(bblock):
557       graphMap.get(nodes.get(ppoint.getIndex()-1));
558     
559     //Age outside edges if necessary
560     for(Iterator<AllocNode> nodeit=delta.addNodeAges.iterator();nodeit.hasNext();) {
561       AllocNode node=nodeit.next();
562       if (!graph.callNodeAges.contains(node)) {
563         graph.callNodeAges.add(node);
564       } else {
565         nodeit.remove();
566       }
567       if (!graph.reachNode.contains(node)&&!node.isSummary()) {
568         /* Need to age node in existing graph*/
569         summarizeInGraph(graph, newDelta, node);
570       }
571     }
572     
573     //Add heap edges in
574     for(Map.Entry<AllocNode, MySet<Edge>> entry:delta.heapedgeadd.entrySet()) {
575       for(Edge e:entry.getValue()) {
576         boolean addedge=false;
577         Edge edgetoadd=null;
578         if (e.statuspredicate==Edge.NEW) {
579           edgetoadd=e;
580         } else {
581           Edge origEdgeKey=e.makeStatus(allocFactory);
582           if (oldgraph.nodeMap.containsKey(origEdgeKey.src)&&
583               oldgraph.nodeMap.get(origEdgeKey.src).contains(origEdgeKey)) {
584             Edge origEdge=oldgraph.nodeMap.get(origEdgeKey.src).get(origEdgeKey);
585             //copy the predicate
586             origEdgeKey.statuspredicate=origEdge.statuspredicate;
587             edgetoadd=origEdgeKey;
588           }
589         }
590         if (edgetoadd!=null) {
591           newDelta.addHeapEdge(edgetoadd);
592         }
593       }
594     }
595
596     //Add external edges in
597     for(Edge e:graph.externalEdgeSet) {
598       //First did we age the source
599       Edge newedge=e.copy();
600       if (newedge.src!=null&&!e.src.isSummary()&&graph.callNodeAges.contains(e.src)) {
601         AllocNode summaryNode=allocFactory.getAllocNode(newedge.src, true);
602         newedge.src=summaryNode;
603       }
604       //Compute target
605       if (graph.callNodeAges.contains(e.dst)&&!e.dst.isSummary()) {
606         if (graph.callOldNodes.contains(e.dst)) {
607           //Need two edges
608           Edge copy=newedge.copy();
609           newDelta.addEdge(copy);
610         }
611         //Now add summarized node
612         newedge.dst=allocFactory.getAllocNode(newedge.dst, true);
613         newDelta.addEdge(newedge);
614       } else {
615         //Add edge to single node
616         newDelta.addEdge(newedge);
617       }
618     }
619     
620     return newDelta;
621   }
622
623   /* Summarizes out of context nodes in graph */
624   void summarizeInGraph(Graph graph, Delta newDelta, AllocNode singleNode) {
625     AllocNode summaryNode=allocFactory.getAllocNode(singleNode, true);
626
627     //Handle outgoing heap edges
628     MySet<Edge> edgeset=graph.getEdges(singleNode);
629
630     for(Edge e:edgeset) {
631       Edge rewrite=e.rewrite(singleNode, summaryNode);
632       //Remove old edge
633       newDelta.removeHeapEdge(e);
634       newDelta.addHeapEdge(rewrite);
635     }
636     
637     //Handle incoming edges
638     MySet<Edge> backedges=graph.getBackEdges(singleNode);
639     for(Edge e:backedges) {
640       if (e.dst==singleNode) {
641         Edge rewrite=e.rewrite(singleNode, summaryNode);
642         newDelta.removeEdge(e);
643         newDelta.addEdge(rewrite);
644       }
645     }
646   }
647
648   void applyDiffs(Graph graph, Delta delta) {
649     applyDiffs(graph, delta, false);
650   }
651
652   void applyDiffs(Graph graph, Delta delta, boolean genbackwards) {
653     //build backwards map if requested
654     if (genbackwards&&graph.backMap==null) {
655       graph.backMap=new HashMap<AllocNode, MySet<Edge>>();
656       if (graph.parent.backMap==null) {
657         graph.parent.backMap=new HashMap<AllocNode, MySet<Edge>>();
658         for(Map.Entry<AllocNode, MySet<Edge>> entry:graph.nodeMap.entrySet()) {
659           for(Edge e:entry.getValue()) {
660             if (!graph.parent.backMap.containsKey(e.dst))
661               graph.parent.backMap.put(e.dst, new MySet<Edge>());
662             graph.parent.backMap.get(e.dst).add(e);
663           }
664         }
665         for(Map.Entry<TempDescriptor, MySet<Edge>> entry:graph.varMap.entrySet()) {
666           for(Edge e:entry.getValue()) {
667             if (!graph.parent.backMap.containsKey(e.dst))
668               graph.parent.backMap.put(e.dst, new MySet<Edge>());
669             graph.parent.backMap.get(e.dst).add(e);
670           }
671         }
672       }
673     }
674
675     //Add hidden base edges
676     for(Map.Entry<AllocNode, MySet<Edge>> e: delta.baseheapedge.entrySet()) {
677       AllocNode node=e.getKey();
678       MySet<Edge> edges=e.getValue();
679       if (graph.nodeMap.containsKey(node)) {
680         MySet<Edge> nodeEdges=graph.nodeMap.get(node);
681         nodeEdges.addAll(edges);
682       }
683     }
684
685     //Remove heap edges
686     for(Map.Entry<AllocNode, MySet<Edge>> e: delta.heapedgeremove.entrySet()) {
687       AllocNode node=e.getKey();
688       MySet<Edge> edgestoremove=e.getValue();
689       if (graph.nodeMap.containsKey(node)) {
690         //Just apply diff to current map
691         graph.nodeMap.get(node).removeAll(edgestoremove);
692       } else {
693         //Generate diff from parent graph
694         MySet<Edge> parentedges=graph.parent.nodeMap.get(node);
695         MySet<Edge> newedgeset=Util.setSubtract(parentedges, edgestoremove);
696         graph.nodeMap.put(node, newedgeset);
697       }
698     }
699
700     //Add heap edges
701     for(Map.Entry<AllocNode, MySet<Edge>> e: delta.heapedgeadd.entrySet()) {
702       AllocNode node=e.getKey();
703       MySet<Edge> edgestoadd=e.getValue();
704       //If we have not done a subtract, then 
705       if (!graph.nodeMap.containsKey(node)) {
706         //Copy the parent entry
707         graph.nodeMap.put(node, (MySet<Edge>)graph.parent.nodeMap.get(node).clone());
708       }
709       graph.nodeMap.get(node).addAll(edgestoadd);
710       if (genbackwards) {
711         for(Edge eadd:edgestoadd) {
712           if (!graph.backMap.containsKey(eadd.dst))
713             graph.backMap.put(eadd.dst, new MySet<Edge>());
714           graph.backMap.get(eadd.dst).add(eadd);
715         }
716       }
717     }
718
719     //Remove var edges
720     for(Map.Entry<TempDescriptor, MySet<Edge>> e: delta.varedgeremove.entrySet()) {
721       TempDescriptor tmp=e.getKey();
722       MySet<Edge> edgestoremove=e.getValue();
723
724       if (graph.varMap.containsKey(tmp)) {
725         //Just apply diff to current map
726         graph.varMap.get(tmp).removeAll(edgestoremove);
727       } else {
728         //Generate diff from parent graph
729         MySet<Edge> parentedges=graph.parent.varMap.get(tmp);
730         MySet<Edge> newedgeset=Util.setSubtract(parentedges, edgestoremove);
731         graph.varMap.put(tmp, newedgeset);
732       }
733     }
734
735     //Add var edges
736     for(Map.Entry<TempDescriptor, MySet<Edge>> e: delta.varedgeadd.entrySet()) {
737       TempDescriptor tmp=e.getKey();
738       MySet<Edge> edgestoadd=e.getValue();
739       graph.varMap.put(tmp, (MySet<Edge>) edgestoadd.clone());
740       if (genbackwards) {
741         for(Edge eadd:edgestoadd) {
742           if (!graph.backMap.containsKey(eadd.dst))
743             graph.backMap.put(eadd.dst, new MySet<Edge>());
744           graph.backMap.get(eadd.dst).add(eadd);
745         }
746       }
747     }
748
749     //Add node additions
750     for(AllocNode node:delta.addNodeAges) {
751       graph.nodeAges.add(node);
752     }
753     
754     for(Map.Entry<AllocNode, Boolean> nodeentry:delta.addOldNodes.entrySet()) {
755       AllocNode node=nodeentry.getKey();
756       Boolean ispresent=nodeentry.getValue();
757       graph.oldNodes.put(node, ispresent);
758     }
759   }
760
761   Delta processSetFieldElementNode(FlatNode node, Delta delta, Graph graph) {
762     TempDescriptor src;
763     FieldDescriptor fd;
764     TempDescriptor dst;
765     if (node.kind()==FKind.FlatSetElementNode) {
766       FlatSetElementNode fen=(FlatSetElementNode) node;
767       src=fen.getSrc();
768       fd=null;
769       dst=fen.getDst();
770     } else {
771       FlatSetFieldNode ffn=(FlatSetFieldNode) node;
772       src=ffn.getSrc();
773       fd=ffn.getField();
774       dst=ffn.getDst();
775     }
776     if (delta.getInit()) {
777       HashSet<AllocNode> srcNodes=GraphManip.getNodes(graph, delta, src);
778       HashSet<AllocNode> dstNodes=GraphManip.getNodes(graph, delta, dst);
779       MySet<Edge> edgesToAdd=GraphManip.genEdges(srcNodes, fd, dstNodes);
780       MySet<Edge> edgesToRemove=null;
781       if (dstNodes.size()==1&&!dstNodes.iterator().next().isSummary()) {
782         /* Can do a strong update */
783         edgesToRemove=GraphManip.getEdges(graph, delta, dstNodes, fd);
784       }
785       /* Update diff */
786       updateHeapDelta(graph, delta, edgesToAdd, edgesToRemove);
787       applyDiffs(graph, delta);
788     } else {
789       /* First look at new sources */
790       MySet<Edge> edgesToAdd=new MySet<Edge>();
791       HashSet<AllocNode> newSrcNodes=GraphManip.getDiffNodes(delta, src);
792       HashSet<AllocNode> dstNodes=GraphManip.getDiffNodes(delta, dst);
793       edgesToAdd.addAll(GraphManip.genEdges(newSrcNodes, fd, dstNodes));
794       HashSet<AllocNode> newDstNodes=GraphManip.getDiffNodes(delta, dst);
795       MySet<Edge> edgesToRemove=null;
796       if (newDstNodes.size()!=0) {
797         if (dstNodes.size()==1&&!dstNodes.iterator().next().isSummary()) {
798           /* Need to undo strong update */
799           if (graph.strongUpdateSet!=null) {
800             edgesToAdd.addAll(graph.strongUpdateSet);
801             graph.strongUpdateSet.clear();
802           }
803         } else if (dstNodes.size()==0&&newDstNodes.size()==1&&!newDstNodes.iterator().next().isSummary()&&graph.strongUpdateSet==null) {
804           edgesToRemove=GraphManip.getEdges(graph, delta, dstNodes, fd);
805         }
806         HashSet<AllocNode> srcNodes=GraphManip.getDiffNodes(delta, src);
807         edgesToAdd.addAll(GraphManip.genEdges(srcNodes, fd, newDstNodes));
808       }
809       /* Update diff */
810       updateHeapDelta(graph, delta, edgesToAdd, edgesToRemove);
811       applyDiffs(graph, delta);
812     }
813     return delta;
814   }
815
816   Delta processCopyNode(FlatNode node, Delta delta, Graph graph) {
817     TempDescriptor src;
818     TempDescriptor dst;
819     if (node.kind()==FKind.FlatOpNode) {
820       FlatOpNode fon=(FlatOpNode) node;
821       src=fon.getLeft();
822       dst=fon.getDest();
823     } else if (node.kind()==FKind.FlatReturnNode) {
824       FlatReturnNode frn=(FlatReturnNode)node;
825       src=frn.getReturnTemp();
826       dst=returntmp;
827     } else {
828       FlatCastNode fcn=(FlatCastNode) node;
829       src=fcn.getSrc();
830       dst=fcn.getDst();
831     }
832     if (delta.getInit()) {
833       HashSet<AllocNode> srcnodes=GraphManip.getNodes(graph, delta, src);
834       MySet<Edge> edgesToAdd=GraphManip.genEdges(src, srcnodes);
835       MySet<Edge> edgesToRemove=GraphManip.getEdges(graph, delta, dst);
836       updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
837       applyDiffs(graph, delta);
838     } else {
839       /* First compute new src nodes */
840       HashSet<AllocNode> newSrcNodes=GraphManip.getDiffNodes(delta, src);
841
842       /* Compute the union, and then the set of edges */
843       MySet<Edge> edgesToAdd=GraphManip.genEdges(src, newSrcNodes);
844       
845       /* Compute set of edges to remove */
846       MySet<Edge> edgesToRemove=GraphManip.getDiffEdges(delta, dst);      
847
848       /* Update diff */
849       updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
850       applyDiffs(graph, delta);
851     }
852     return delta;
853   }
854
855   Delta processFieldElementNode(FlatNode node, Delta delta, Graph graph) {
856     TempDescriptor src;
857     FieldDescriptor fd;
858     TempDescriptor dst;
859     if (node.kind()==FKind.FlatElementNode) {
860       FlatElementNode fen=(FlatElementNode) node;
861       src=fen.getSrc();
862       fd=null;
863       dst=fen.getDst();
864     } else {
865       FlatFieldNode ffn=(FlatFieldNode) node;
866       src=ffn.getSrc();
867       fd=ffn.getField();
868       dst=ffn.getDst();
869     }
870     if (delta.getInit()) {
871       HashSet<AllocNode> srcnodes=GraphManip.getNodes(graph, delta, src);
872       HashSet<AllocNode> fdnodes=GraphManip.getNodes(graph, delta, srcnodes, fd);
873       MySet<Edge> edgesToAdd=GraphManip.genEdges(src, fdnodes);
874       MySet<Edge> edgesToRemove=GraphManip.getEdges(graph, delta, dst);
875       updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
876       applyDiffs(graph, delta);
877     } else {
878       /* First compute new objects we read fields of */
879       HashSet<AllocNode> allsrcnodes=GraphManip.getNodes(graph, delta, src);
880       HashSet<AllocNode> difffdnodes=GraphManip.getDiffNodes(delta, allsrcnodes, fd);     
881       /* Next compute new targets of fields */
882       HashSet<AllocNode> newsrcnodes=GraphManip.getDiffNodes(delta, src);
883       HashSet<AllocNode> newfdnodes=GraphManip.getNodes(graph, delta, newsrcnodes, fd);
884       /* Compute the union, and then the set of edges */
885       HashSet<AllocNode> newTargets=new HashSet<AllocNode>();
886       newTargets.addAll(newfdnodes);
887       newTargets.addAll(difffdnodes);
888       MySet<Edge> edgesToAdd=GraphManip.genEdges(src, newTargets);      
889       
890       /* Compute set of edges to remove */
891       MySet<Edge> edgesToRemove=GraphManip.getDiffEdges(delta, dst);      
892
893       /* Update diff */
894       updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
895       applyDiffs(graph, delta);
896     }
897     return delta;
898   }
899
900   static void updateVarDelta(Graph graph, Delta delta, TempDescriptor tmp, MySet<Edge> edgestoAdd, MySet<Edge> edgestoRemove) {
901     MySet<Edge> edgeAdd=delta.varedgeadd.get(tmp);
902     MySet<Edge> edgeRemove=delta.varedgeremove.get(tmp);
903     MySet<Edge> existingEdges=graph.getEdges(tmp);
904     for(Edge e: edgestoRemove) {
905       //remove edge from delta
906       edgeAdd.remove(e);
907       //if the edge is already in the graph, add an explicit remove to the delta
908       if (existingEdges.contains(e))
909         edgeRemove.add(e);
910     }
911     for(Edge e: edgestoAdd) {
912       //Remove the edge from the remove set
913       edgeRemove.remove(e);
914       //Explicitly add it to the add set unless it is already in the graph
915       if (!existingEdges.contains(e))
916         edgeAdd.add(e);
917     }
918   }
919
920   static void updateHeapDelta(Graph graph, Delta delta, MySet<Edge> edgestoAdd, MySet<Edge> edgestoRemove) {
921     for(Edge e: edgestoRemove) {
922       AllocNode src=e.src;
923       MySet<Edge> edgeAdd=delta.heapedgeadd.get(src);
924       MySet<Edge> existingEdges=graph.getEdges(src);
925       //remove edge from delta
926       edgeAdd.remove(e);
927       //if the edge is already in the graph, add an explicit remove to the delta
928       if (existingEdges.contains(e)) {
929         MySet<Edge> edgeRemove=delta.heapedgeremove.get(src);
930         edgeRemove.add(e);
931       }
932     }
933     for(Edge e: edgestoAdd) {
934       AllocNode src=e.src;
935       MySet<Edge> edgeRemove=delta.heapedgeremove.get(src);
936       MySet<Edge> existingEdges=graph.getEdges(src);
937       //Remove the edge from the remove set
938       edgeRemove.remove(e);
939       //Explicitly add it to the add set unless it is already in the graph
940       if (!existingEdges.contains(e)) {
941         MySet<Edge> edgeAdd=delta.heapedgeadd.get(src);
942         edgeAdd.add(e);
943       }
944     }
945   }
946
947   Delta processFlatNop(FlatNode node, Delta delta, Graph graph) {
948     applyDiffs(graph, delta);
949     return delta;
950   }
951   
952   Delta processNewNode(FlatNew node, Delta delta, Graph graph) {
953     AllocNode summary=allocFactory.getAllocNode(node, true);
954     AllocNode single=allocFactory.getAllocNode(node, false);
955     TempDescriptor tmp=node.getDst();
956
957     if (delta.getInit()) {
958       /* We don't have to deal with summarization here...  The
959        * intuition is that this is the only place where we generate
960        * nodes for this allocation site and this is the first time
961        * we've analyzed this site */
962
963       //Build new Edge
964       Edge e=new Edge(tmp, single);
965       //Build new Edge set
966       MySet<Edge> newedges=new MySet<Edge>();
967       newedges.add(e);
968       //Add it into the diffs
969       delta.varedgeadd.put(tmp, newedges);
970       //Remove the old edges
971       delta.varedgeremove.put(tmp, graph.getEdges(tmp));
972       //Apply incoming diffs to graph
973       applyDiffs(graph, delta);
974       //Note that we create a single node
975       delta.addNodeAges.add(single);
976       //Kill the old node
977       if (delta.addOldNodes.containsKey(single)||delta.baseOldNodes.containsKey(single)) {
978         delta.addOldNodes.put(single, Boolean.FALSE);
979       }
980     } else {
981       /* 1. Fix up the variable edge additions */
982
983       for(Iterator<Map.Entry<TempDescriptor, MySet<Edge>>> entryIt=delta.varedgeadd.entrySet().iterator();entryIt.hasNext();) {
984         Map.Entry<TempDescriptor, MySet<Edge>> entry=entryIt.next();
985
986         if (entry.getKey()==tmp) {
987           /* Check if this is the tmp we overwrite */
988           entryIt.remove();
989         } else {
990           /* Otherwise, check if the target of the edge is changed... */
991           summarizeSet(entry.getValue(), graph.varMap.get(entry.getKey()), single, summary);
992         }
993       }
994       
995       /* 2. Fix up the base variable edges */
996
997       for(Iterator<Map.Entry<TempDescriptor, MySet<Edge>>> entryIt=delta.basevaredge.entrySet().iterator();entryIt.hasNext();) {
998         Map.Entry<TempDescriptor, MySet<Edge>> entry=entryIt.next();
999         TempDescriptor entrytmp=entry.getKey();
1000         if (entrytmp==tmp) {
1001           /* Check is this is the tmp we overwrite, if so add to remove set */
1002           Util.relationUpdate(delta.varedgeremove, tmp, null, entry.getValue());
1003         } else {
1004           /* Check if the target of the edge is changed */ 
1005           MySet<Edge> newset=(MySet<Edge>)entry.getValue().clone();
1006           MySet<Edge> removeset=shrinkSet(newset, graph.varMap.get(entrytmp), single, summary);
1007           Util.relationUpdate(delta.varedgeremove, entrytmp, newset, removeset);
1008           Util.relationUpdate(delta.varedgeadd, entrytmp, null, newset);
1009         }
1010       }
1011
1012
1013       /* 3. Fix up heap edge additions */
1014
1015       HashMap<AllocNode, MySet<Edge>> addheapedge=new HashMap<AllocNode, MySet<Edge>>();
1016       for(Iterator<Map.Entry<AllocNode, MySet<Edge>>> entryIt=delta.heapedgeadd.entrySet().iterator();entryIt.hasNext();) {
1017         Map.Entry<AllocNode, MySet<Edge>> entry=entryIt.next();
1018         MySet<Edge> edgeset=entry.getValue();
1019         AllocNode allocnode=entry.getKey();
1020         if (allocnode==single) {
1021           entryIt.remove();
1022           summarizeSet(edgeset, graph.nodeMap.get(summary), single, summary);
1023           addheapedge.put(summary, edgeset);
1024         } else {
1025           summarizeSet(edgeset, graph.nodeMap.get(allocnode), single, summary);
1026         }
1027       }
1028       
1029       /* Merge in diffs */
1030
1031       for(Map.Entry<AllocNode, MySet<Edge>> entry:addheapedge.entrySet()) {
1032         AllocNode allocnode=entry.getKey();
1033         Util.relationUpdate(delta.heapedgeadd, allocnode, null, entry.getValue());
1034       }
1035
1036       /* 4. Fix up the base heap edges */
1037
1038       for(Iterator<Map.Entry<AllocNode, MySet<Edge>>> entryIt=delta.baseheapedge.entrySet().iterator();entryIt.hasNext();) {
1039         Map.Entry<AllocNode, MySet<Edge>> entry=entryIt.next();
1040         MySet<Edge> edgeset=entry.getValue();
1041         AllocNode allocnode=entry.getKey();
1042         if (allocnode==single) {
1043           entryIt.remove();
1044         }
1045         AllocNode addnode=(allocnode==single)?summary:allocnode;
1046
1047         MySet<Edge> newset=(MySet<Edge>) edgeset.clone();
1048         MySet<Edge> removeset=shrinkSet(newset, graph.nodeMap.get(addnode), single, summary);
1049         Util.relationUpdate(delta.heapedgeadd, addnode, null, newset);
1050         Util.relationUpdate(delta.heapedgeremove, allocnode, null, removeset);
1051       }
1052
1053       /* Update Node Ages...If the base or addNodeAges set contains a
1054        * single node, it now should also contain a summary node...  No
1055        * need to generate a single node as that has already been
1056        * done. */
1057       if (delta.baseNodeAges.contains(single)||delta.addNodeAges.contains(single)) {
1058         delta.addNodeAges.add(summary);
1059       }
1060
1061       //Kill the old node if someone tries to add it
1062       if (delta.addOldNodes.containsKey(single)||delta.baseOldNodes.containsKey(single)) {
1063         delta.addOldNodes.put(single, Boolean.FALSE);
1064       }
1065       
1066       //Apply incoming diffs to graph
1067       applyDiffs(graph, delta);      
1068     }
1069     return delta;
1070   }
1071
1072   /* This function builds a new edge set where oldnode is summarized into new node */
1073
1074   void summarizeSet(MySet<Edge> edgeset, MySet<Edge> oldedgeset, AllocNode oldnode, AllocNode sumnode) {
1075     MySet<Edge> newSet=null;
1076     for(Iterator<Edge> edgeit=edgeset.iterator();edgeit.hasNext();) {
1077       Edge e=edgeit.next();
1078       if (e.dst==oldnode||e.src==oldnode) {
1079         if (newSet==null) {
1080           newSet=new MySet<Edge>();
1081         }
1082         edgeit.remove();
1083         e=e.copy();
1084
1085         if (e.dst==oldnode) {
1086           e.dst=sumnode;
1087         }
1088         if (e.src==oldnode) {
1089           e.src=sumnode;
1090         }
1091         if (oldedgeset==null||!oldedgeset.contains(e))
1092           newSet.add(e);
1093       }
1094     }
1095     if (newSet!=null)
1096       edgeset.addAll(newSet);
1097   }
1098
1099   /* Shrinks the incoming set to just include rewritten values.
1100    * Returns a set of the original rewritten values */
1101
1102   MySet<Edge> shrinkSet(MySet<Edge> edgeset, MySet<Edge> oldedgeset, AllocNode oldnode, AllocNode newnode) {
1103     MySet<Edge> newSet=null;
1104     MySet<Edge> removeSet=null;
1105     for(Iterator<Edge> edgeit=edgeset.iterator();edgeit.hasNext();) {
1106       Edge e=edgeit.next();
1107       edgeit.remove();
1108       if (e.dst==oldnode||e.src==oldnode) {
1109         if (newSet==null) {
1110           newSet=new MySet<Edge>();
1111           removeSet=new MySet<Edge>();
1112         }
1113
1114         removeSet.add(e.copy());
1115         if (e.dst==oldnode)
1116           e.dst=newnode;
1117         if (e.src==oldnode)
1118           e.src=newnode;
1119         if (oldedgeset==null||!oldedgeset.contains(e))
1120           newSet.add(e);
1121       }
1122     }
1123     if (newSet!=null)
1124       edgeset.addAll(newSet);
1125     return removeSet;
1126   } 
1127
1128   /* This function returns a completely new Delta...  It is safe to
1129    * modify this */
1130
1131   Delta applyInitDelta(Delta delta, BBlock block) {
1132     //Apply delta to graph
1133     boolean newGraph=false;
1134     if (!bbgraphMap.containsKey(block)) {
1135       bbgraphMap.put(block, new Graph(null));
1136       newGraph=true;
1137     }
1138     Delta newdelta;
1139     Graph graph=bbgraphMap.get(block);
1140
1141     if (newGraph) {
1142       newdelta=new Delta(null, true);
1143       //Add in heap edges and throw away original diff
1144       graph.nodeMap.putAll(delta.heapedgeadd);
1145       //Add in var edges and throw away original diff
1146       graph.varMap.putAll(delta.varedgeadd);
1147       //Record that this is initial set...
1148       graph.nodeAges.addAll(delta.addNodeAges);
1149       //Add old nodes
1150       for(Map.Entry<AllocNode, Boolean> oldentry:delta.addOldNodes.entrySet()) {
1151         if (oldentry.getValue().booleanValue()) {
1152           graph.oldNodes.put(oldentry.getKey(), Boolean.TRUE);
1153         }
1154       }
1155     } else {
1156       newdelta=new Delta(null, false);
1157       //merge in heap edges and variables
1158       mergeHeapEdges(graph, delta, newdelta);
1159       mergeVarEdges(graph, delta, newdelta);
1160       mergeAges(graph, delta, newdelta);
1161     }
1162     return newdelta;
1163   }
1164
1165   /* This function merges in the heap edges.  It updates delta to be
1166    * the difference */
1167
1168   void mergeHeapEdges(Graph graph, Delta delta, Delta newdelta) {
1169     //Merge in edges
1170     for(Map.Entry<AllocNode, MySet<Edge>> heapedge:delta.heapedgeadd.entrySet()) {
1171       AllocNode nsrc=heapedge.getKey();
1172       MySet<Edge> edges=heapedge.getValue();
1173
1174       if (graph.backMap!=null) {
1175         for(Edge e:edges) {
1176           if (!graph.backMap.containsKey(e.dst))
1177             graph.backMap.put(e.dst, new MySet<Edge>());
1178           graph.backMap.get(e.dst).add(e);
1179         }
1180       }
1181
1182       if (!graph.nodeMap.containsKey(nsrc)) {
1183         graph.nodeMap.put(nsrc, new MySet<Edge>());
1184       }
1185       MySet<Edge> dstedges=graph.nodeMap.get(nsrc);
1186       MySet<Edge> diffedges=new MySet<Edge>();
1187       for(Edge e:edges) {
1188         if (!dstedges.contains(e)) {
1189           //We have a new edge
1190           diffedges.add(e);
1191           dstedges.add(e);
1192         }
1193       }
1194       //Done with edge set...
1195       if (diffedges.size()>0) {
1196         //completely new
1197         newdelta.baseheapedge.put(nsrc, diffedges);
1198       }
1199     }
1200   }
1201
1202   /* This function merges in the var edges.  It updates delta to be
1203    * the difference */
1204
1205   void mergeVarEdges(Graph graph, Delta delta, Delta newdelta) {
1206     //Merge in edges
1207     for(Map.Entry<TempDescriptor, MySet<Edge>> varedge:delta.varedgeadd.entrySet()) {
1208       TempDescriptor tmpsrc=varedge.getKey();
1209       MySet<Edge> edges=varedge.getValue();
1210       if (graph.backMap!=null) {
1211         for(Edge e:edges) {
1212           if (!graph.backMap.containsKey(e.dst))
1213             graph.backMap.put(e.dst, new MySet<Edge>());
1214           graph.backMap.get(e.dst).add(e);
1215         }
1216       }
1217
1218       if (!graph.varMap.containsKey(tmpsrc)) {
1219         graph.varMap.put(tmpsrc, new MySet<Edge>());
1220       }
1221       MySet<Edge> dstedges=graph.varMap.get(tmpsrc);
1222       MySet<Edge> diffedges=new MySet<Edge>();
1223       for(Edge e:edges) {
1224         if (!dstedges.contains(e)) {
1225           //We have a new edge
1226           diffedges.add(e);
1227           dstedges.add(e);
1228         }
1229       }
1230       //Done with edge set...
1231       if (diffedges.size()>=0) {
1232         //completely new
1233         newdelta.basevaredge.put(tmpsrc,diffedges);
1234       }
1235     }
1236   }
1237
1238   void mergeAges(Graph graph, Delta delta, Delta newDelta) {
1239     //Merge in edges
1240     for(AllocNode node:delta.addNodeAges) {
1241       if (!graph.nodeAges.contains(node)) {
1242         graph.nodeAges.add(node);
1243         newDelta.baseNodeAges.add(node);
1244       }
1245     }
1246     for(Map.Entry<AllocNode, Boolean> oldentry:delta.addOldNodes.entrySet()) {
1247       AllocNode node=oldentry.getKey();
1248       boolean ispresent=oldentry.getValue().booleanValue();
1249       if (ispresent&&!graph.oldNodes.containsKey(node)) {
1250         graph.oldNodes.put(node, Boolean.TRUE);
1251         newDelta.baseOldNodes.put(node, Boolean.TRUE);
1252       }
1253     }
1254   }
1255 }