more 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   State state;
13   TypeUtil typeUtil;
14   AllocFactory allocFactory;
15   LinkedList<Delta> toprocess;
16
17   public Pointer(State state, TypeUtil typeUtil) {
18     this.state=state;
19     this.blockMap=new HashMap<FlatMethod, BasicBlock>();
20     this.bbgraphMap=new HashMap<BBlock, Graph>();
21     this.graphMap=new HashMap<FlatNode, Graph>();
22     this.typeUtil=typeUtil;
23     this.allocFactory=new AllocFactory(state, typeUtil);
24     this.toprocess=new LinkedList<Delta>();
25   }
26
27   public BasicBlock getBBlock(FlatMethod fm) {
28     if (!blockMap.containsKey(fm))
29       blockMap.put(fm, BasicBlock.getBBlock(fm));
30     return blockMap.get(fm);
31   }
32   
33   Delta buildInitialContext() {
34     MethodDescriptor md=typeUtil.getMain();
35     FlatMethod fm=state.getMethodFlat(md);
36     BasicBlock bb=getBBlock(fm);
37     BBlock start=bb.getStart();
38     Delta delta=new Delta(start, true);
39     HashSet<Edge> arrayset=new HashSet<Edge>();
40     HashSet<Edge> varset=new HashSet<Edge>();
41     arrayset.add(new Edge(allocFactory.StringArray, null, allocFactory.Strings));
42     varset.add(new Edge(fm.getParameter(0), allocFactory.StringArray));
43     delta.heapedgeadd.put(allocFactory.StringArray, arrayset);
44     delta.varedgeadd.put(fm.getParameter(0), varset);
45     return delta;
46   }
47
48   void doAnalysis() {
49     toprocess.add(buildInitialContext());
50
51     while(!toprocess.isEmpty()) {
52       Delta delta=toprocess.remove();
53       BBlock bblock=delta.getBlock();
54       Vector<FlatNode> nodes=bblock.nodes();
55
56       //Build base graph for entrance to this basic block
57       delta=applyInitDelta(delta, bblock);
58       Graph graph=bbgraphMap.get(bblock);
59
60       Graph nodeGraph=null;
61       //Compute delta at exit of each node
62       for(int i=0; i<nodes.size();i++) {
63         FlatNode currNode=nodes.get(i);
64         if (!graphMap.containsKey(currNode)) {
65           graphMap.put(currNode, new Graph(graph));
66         }
67         nodeGraph=graphMap.get(currNode);
68         delta=processNode(currNode, delta, nodeGraph);
69       }
70       generateFinalDelta(delta, nodeGraph);
71     }    
72   }
73
74   void generateFinalDelta(Delta delta, Graph graph) {
75     Delta newDelta=new Delta(null, false);
76     if (delta.getInit()) {
77       //First compute the set of temps
78       HashSet<TempDescriptor> tmpSet=new HashSet<TempDescriptor>();
79       tmpSet.addAll(graph.varMap.keySet());
80       tmpSet.addAll(graph.parent.varMap.keySet());
81
82       //Next build the temp map part of the delta
83       for(TempDescriptor tmp:tmpSet) {
84         HashSet<Edge> edgeSet=new HashSet<Edge>();
85         /* Get target set */
86         if (graph.varMap.containsKey(tmp))
87           edgeSet.addAll(graph.varMap.get(tmp));
88         else
89           edgeSet.addAll(graph.parent.varMap.get(tmp));
90         newDelta.varedgeadd.put(tmp, edgeSet);
91       }
92
93       //Next compute the set of src allocnodes
94       HashSet<AllocNode> nodeSet=new HashSet<AllocNode>();
95       nodeSet.addAll(graph.nodeMap.keySet());
96       nodeSet.addAll(graph.parent.nodeMap.keySet());
97
98       for(AllocNode node:nodeSet) {
99         HashSet<Edge> edgeSet=new HashSet<Edge>();
100         /* Get edge set */
101         if (graph.nodeMap.containsKey(node))
102           edgeSet.addAll(graph.nodeMap.get(node));
103         else
104           edgeSet.addAll(graph.parent.nodeMap.get(node));
105         newDelta.heapedgeadd.put(node, edgeSet);
106       }
107     } else {
108       /* We can break the old delta...it is done being used */
109       /* First we will build variable edges */
110       HashSet<TempDescriptor> tmpSet=new HashSet<TempDescriptor>();
111       tmpSet.addAll(delta.basevaredge.keySet());
112       tmpSet.addAll(delta.varedgeadd.keySet());
113       for(TempDescriptor tmp:tmpSet) {
114         /* Start with the new incoming edges */
115         HashSet<Edge> newbaseedge=delta.basevaredge.get(tmp);
116         /* Remove the remove set */
117         newbaseedge.removeAll(delta.varedgeremove.get(tmp));
118         /* Add in the new set*/
119         newbaseedge.addAll(delta.varedgeadd.get(tmp));
120         /* Store the results */
121         newDelta.varedgeadd.put(tmp, newbaseedge);
122       }
123
124       /* Next we build heap edges */
125       HashSet<AllocNode> nodeSet=new HashSet<AllocNode>();
126       nodeSet.addAll(delta.baseheapedge.keySet());
127       nodeSet.addAll(delta.heapedgeadd.keySet());
128       nodeSet.addAll(delta.heapedgeremove.keySet());
129       for(AllocNode node:nodeSet) {
130         /* Start with the new incoming edges */
131         HashSet<Edge> newheapedge=(HashSet<Edge>) delta.baseheapedge.get(node).clone();
132         /* Remove the remove set */
133         newheapedge.removeAll(delta.heapedgeremove.get(node));
134         /* Add in the add set */
135         newheapedge.addAll(delta.heapedgeadd.get(node));
136         newDelta.heapedgeadd.put(node, newheapedge);
137
138         /* Also need to subtract off some edges */
139         HashSet<Edge> removeset=delta.heapedgeremove.get(node);
140         /* Remove the newly created edges..no need to propagate a diff for those */
141         removeset.removeAll(delta.baseheapedge.get(node));
142         newDelta.heapedgeremove.put(node, removeset);
143       }
144     }
145     /* Now we need to propagate newdelta */
146     if (!newDelta.heapedgeadd.isEmpty()||!newDelta.heapedgeremove.isEmpty()||!newDelta.varedgeadd.isEmpty()) {
147       /* We have a delta to propagate */
148       BBlock curr=delta.getBlock();
149       Vector<BBlock> blockvector=curr.next();
150       for(int i=0;i<blockvector.size();i++) {
151         if (i==0) {
152           newDelta.setBlock(blockvector.get(i));
153           toprocess.add(newDelta);
154         } else {
155           toprocess.add(newDelta.diffBlock(blockvector.get(i)));
156         }
157       }
158
159     }
160   }
161
162   Delta processNode(FlatNode node, Delta delta, Graph newgraph) {
163     switch(node.kind()) {
164     case FKind.FlatNew:
165       return processNewNode((FlatNew)node, delta, newgraph);
166     case FKind.FlatFieldNode:
167     case FKind.FlatElementNode:
168       return processFieldElementNode(node, delta, newgraph);
169     case FKind.FlatCastNode:
170     case FKind.FlatOpNode:
171       return processCopyNode(node, delta, newgraph);
172     case FKind.FlatSetFieldNode:
173     case FKind.FlatSetElementNode:
174       return processSetFieldElementNode(node, delta, newgraph);
175     case FKind.FlatMethod:
176     case FKind.FlatCall:
177     case FKind.FlatReturnNode:
178     case FKind.FlatExit:
179
180     case FKind.FlatSESEEnterNode:
181     case FKind.FlatSESEExitNode:
182       throw new Error("Unimplemented node:"+node);
183     default:
184       throw new Error("Unrecognized node:"+node);
185     }
186   }
187
188   void applyDiffs(Graph graph, Delta delta) {
189     //Add hidden base edges
190     for(Map.Entry<AllocNode, HashSet<Edge>> e: delta.baseheapedge.entrySet()) {
191       AllocNode node=e.getKey();
192       HashSet<Edge> edges=e.getValue();
193       if (graph.nodeMap.containsKey(node)) {
194         HashSet<Edge> nodeEdges=graph.nodeMap.get(node);
195         nodeEdges.addAll(edges);
196       }
197     }
198
199     //Remove heap edges
200     for(Map.Entry<AllocNode, HashSet<Edge>> e: delta.heapedgeremove.entrySet()) {
201       AllocNode node=e.getKey();
202       HashSet<Edge> edgestoremove=e.getValue();
203       if (graph.nodeMap.containsKey(node)) {
204         //Just apply diff to current map
205         graph.nodeMap.get(node).removeAll(edgestoremove);
206       } else {
207         //Generate diff from parent graph
208         HashSet<Edge> parentedges=graph.parent.nodeMap.get(node);
209         HashSet<Edge> newedgeset=Util.setSubtract(parentedges, edgestoremove);
210         graph.nodeMap.put(node, newedgeset);
211       }
212     }
213
214     //Add heap edges
215     for(Map.Entry<AllocNode, HashSet<Edge>> e: delta.heapedgeadd.entrySet()) {
216       AllocNode node=e.getKey();
217       HashSet<Edge> edgestoadd=e.getValue();
218       //If we have not done a subtract, then 
219       if (!graph.nodeMap.containsKey(node)) {
220         //Copy the parent entry
221         graph.nodeMap.put(node, (HashSet<Edge>)graph.parent.nodeMap.get(node).clone());
222       }
223       graph.nodeMap.get(node).addAll(edgestoadd);
224     }
225
226     //Remove var edges
227     for(Map.Entry<TempDescriptor, HashSet<Edge>> e: delta.varedgeremove.entrySet()) {
228       TempDescriptor tmp=e.getKey();
229       HashSet<Edge> edgestoremove=e.getValue();
230
231       if (graph.varMap.containsKey(tmp)) {
232         //Just apply diff to current map
233         graph.varMap.get(tmp).removeAll(edgestoremove);
234       } else {
235         //Generate diff from parent graph
236         HashSet<Edge> parentedges=graph.parent.varMap.get(tmp);
237         HashSet<Edge> newedgeset=Util.setSubtract(parentedges, edgestoremove);
238         graph.varMap.put(tmp, newedgeset);
239       }
240     }
241
242     //Add var edges
243     for(Map.Entry<TempDescriptor, HashSet<Edge>> e: delta.varedgeadd.entrySet()) {
244       TempDescriptor tmp=e.getKey();
245       HashSet<Edge> edgestoadd=e.getValue();
246       graph.varMap.put(tmp, (HashSet<Edge>) edgestoadd.clone());
247     }
248   }
249
250   Delta processSetFieldElementNode(FlatNode node, Delta delta, Graph graph) {
251     TempDescriptor src;
252     FieldDescriptor fd;
253     TempDescriptor dst;
254     if (node.kind()==FKind.FlatSetElementNode) {
255       FlatSetElementNode fen=(FlatSetElementNode) node;
256       src=fen.getSrc();
257       fd=null;
258       dst=fen.getDst();
259     } else {
260       FlatSetFieldNode ffn=(FlatSetFieldNode) node;
261       src=ffn.getSrc();
262       fd=ffn.getField();
263       dst=ffn.getDst();
264     }
265     if (delta.getInit()) {
266       HashSet<AllocNode> srcNodes=GraphManip.getNodes(graph, delta, src);
267       HashSet<AllocNode> dstNodes=GraphManip.getNodes(graph, delta, dst);
268       HashSet<Edge> edgesToAdd=GraphManip.genEdges(srcNodes, fd, dstNodes);
269       HashSet<Edge> edgesToRemove=null;
270       if (dstNodes.size()==1&&!dstNodes.iterator().next().isSummary()) {
271         /* Can do a strong update */
272         edgesToRemove=GraphManip.getEdges(graph, delta, dstNodes, fd);
273       }
274       /* Update diff */
275       updateHeapDelta(graph, delta, edgesToAdd, edgesToRemove);
276       applyDiffs(graph, delta);
277     } else {
278       /* First look at new sources */
279       HashSet<Edge> edgesToAdd=new HashSet<Edge>();
280       HashSet<AllocNode> newSrcNodes=GraphManip.getDiffNodes(delta, src);
281       HashSet<AllocNode> dstNodes=GraphManip.getDiffNodes(delta, dst);
282       edgesToAdd.addAll(GraphManip.genEdges(newSrcNodes, fd, dstNodes));
283       HashSet<AllocNode> newDstNodes=GraphManip.getDiffNodes(delta, dst);
284       HashSet<Edge> edgesToRemove=null;
285       if (newDstNodes.size()!=0) {
286         if (dstNodes.size()==1&&!dstNodes.iterator().next().isSummary()) {
287           /* Need to undo strong update */
288           if (graph.strongUpdateSet!=null) {
289             edgesToAdd.addAll(graph.strongUpdateSet);
290             graph.strongUpdateSet.clear();
291           }
292         } else if (dstNodes.size()==0&&newDstNodes.size()==1&&!newDstNodes.iterator().next().isSummary()&&graph.strongUpdateSet==null) {
293           edgesToRemove=GraphManip.getEdges(graph, delta, dstNodes, fd);
294         }
295         HashSet<AllocNode> srcNodes=GraphManip.getDiffNodes(delta, src);
296         edgesToAdd.addAll(GraphManip.genEdges(srcNodes, fd, newDstNodes));
297       }
298       /* Update diff */
299       updateHeapDelta(graph, delta, edgesToAdd, edgesToRemove);
300       applyDiffs(graph, delta);
301     }
302     return delta;
303   }
304
305   Delta processCopyNode(FlatNode node, Delta delta, Graph graph) {
306     TempDescriptor src;
307     TempDescriptor dst;
308     if (node.kind()==FKind.FlatOpNode) {
309       FlatOpNode fon=(FlatOpNode) node;
310       src=fon.getLeft();
311       dst=fon.getDest();
312     } else {
313       FlatCastNode fcn=(FlatCastNode) node;
314       src=fcn.getSrc();
315       dst=fcn.getDst();
316     }
317     if (delta.getInit()) {
318       HashSet<AllocNode> srcnodes=GraphManip.getNodes(graph, delta, src);
319       HashSet<Edge> edgesToAdd=GraphManip.genEdges(src, srcnodes);
320       HashSet<Edge> edgesToRemove=GraphManip.getEdges(graph, delta, dst);
321       updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
322       applyDiffs(graph, delta);
323     } else {
324       /* First compute new src nodes */
325       HashSet<AllocNode> newSrcNodes=GraphManip.getDiffNodes(delta, src);
326
327       /* Compute the union, and then the set of edges */
328       HashSet<Edge> edgesToAdd=GraphManip.genEdges(src, newSrcNodes);
329       
330       /* Compute set of edges to remove */
331       HashSet<Edge> edgesToRemove=GraphManip.getDiffEdges(delta, dst);      
332
333       /* Update diff */
334       updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
335       applyDiffs(graph, delta);
336     }
337     return delta;
338   }
339
340   Delta processFieldElementNode(FlatNode node, Delta delta, Graph graph) {
341     TempDescriptor src;
342     FieldDescriptor fd;
343     TempDescriptor dst;
344     if (node.kind()==FKind.FlatElementNode) {
345       FlatElementNode fen=(FlatElementNode) node;
346       src=fen.getSrc();
347       fd=null;
348       dst=fen.getDst();
349     } else {
350       FlatFieldNode ffn=(FlatFieldNode) node;
351       src=ffn.getSrc();
352       fd=ffn.getField();
353       dst=ffn.getDst();
354     }
355     if (delta.getInit()) {
356       HashSet<AllocNode> srcnodes=GraphManip.getNodes(graph, delta, src);
357       HashSet<AllocNode> fdnodes=GraphManip.getNodes(graph, delta, srcnodes, fd);
358       HashSet<Edge> edgesToAdd=GraphManip.genEdges(src, fdnodes);
359       HashSet<Edge> edgesToRemove=GraphManip.getEdges(graph, delta, dst);
360       updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
361       applyDiffs(graph, delta);
362     } else {
363       /* First compute new objects we read fields of */
364       HashSet<AllocNode> allsrcnodes=GraphManip.getNodes(graph, delta, src);
365       HashSet<AllocNode> difffdnodes=GraphManip.getDiffNodes(delta, allsrcnodes, fd);     
366       /* Next compute new targets of fields */
367       HashSet<AllocNode> newsrcnodes=GraphManip.getDiffNodes(delta, src);
368       HashSet<AllocNode> newfdnodes=GraphManip.getNodes(graph, delta, newsrcnodes, fd);
369       /* Compute the union, and then the set of edges */
370       HashSet<AllocNode> newTargets=new HashSet<AllocNode>();
371       newTargets.addAll(newfdnodes);
372       newTargets.addAll(difffdnodes);
373       HashSet<Edge> edgesToAdd=GraphManip.genEdges(src, newTargets);      
374       
375       /* Compute set of edges to remove */
376       HashSet<Edge> edgesToRemove=GraphManip.getDiffEdges(delta, dst);      
377
378       /* Update diff */
379       updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
380       applyDiffs(graph, delta);
381     }
382     return delta;
383   }
384
385   static void updateVarDelta(Graph graph, Delta delta, TempDescriptor tmp, HashSet<Edge> edgestoAdd, HashSet<Edge> edgestoRemove) {
386     HashSet<Edge> edgeAdd=delta.varedgeadd.get(tmp);
387     HashSet<Edge> edgeRemove=delta.varedgeremove.get(tmp);
388     HashSet<Edge> existingEdges=graph.getEdges(tmp);
389     for(Edge e: edgestoRemove) {
390       //remove edge from delta
391       edgeAdd.remove(e);
392       //if the edge is already in the graph, add an explicit remove to the delta
393       if (existingEdges.contains(e))
394         edgeRemove.add(e);
395     }
396     for(Edge e: edgestoAdd) {
397       //Remove the edge from the remove set
398       edgeRemove.remove(e);
399       //Explicitly add it to the add set unless it is already in the graph
400       if (!existingEdges.contains(e))
401         edgeAdd.add(e);
402     }
403   }
404
405   static void updateHeapDelta(Graph graph, Delta delta, HashSet<Edge> edgestoAdd, HashSet<Edge> edgestoRemove) {
406     for(Edge e: edgestoRemove) {
407       AllocNode src=e.src;
408       HashSet<Edge> edgeAdd=delta.heapedgeadd.get(src);
409       HashSet<Edge> existingEdges=graph.getEdges(src);
410       //remove edge from delta
411       edgeAdd.remove(e);
412       //if the edge is already in the graph, add an explicit remove to the delta
413       if (existingEdges.contains(e)) {
414         HashSet<Edge> edgeRemove=delta.heapedgeremove.get(src);
415         edgeRemove.add(e);
416       }
417     }
418     for(Edge e: edgestoAdd) {
419       AllocNode src=e.src;
420       HashSet<Edge> edgeRemove=delta.heapedgeremove.get(src);
421       HashSet<Edge> existingEdges=graph.getEdges(src);
422       //Remove the edge from the remove set
423       edgeRemove.remove(e);
424       //Explicitly add it to the add set unless it is already in the graph
425       if (!existingEdges.contains(e)) {
426         HashSet<Edge> edgeAdd=delta.heapedgeadd.get(src);
427         edgeAdd.add(e);
428       }
429     }
430   }
431
432   Delta processNewNode(FlatNew node, Delta delta, Graph graph) {
433     AllocNode summary=allocFactory.getAllocNode(node, true);
434     AllocNode single=allocFactory.getAllocNode(node, false);
435     TempDescriptor tmp=node.getDst();
436       
437     if (delta.getInit()) {
438       //Build new Edge
439       Edge e=new Edge(tmp, single);
440       //Build new Edge set
441       HashSet<Edge> newedges=new HashSet<Edge>();
442       newedges.add(e);
443       //Add it into the diffs
444       delta.varedgeadd.put(tmp, newedges);
445       //Remove the old edges
446       delta.varedgeremove.put(tmp, graph.getEdges(tmp));
447       //Apply incoming diffs to graph
448       applyDiffs(graph, delta);
449     } else {
450       /* 1. Fix up the variable edge additions */
451
452       for(Iterator<Map.Entry<TempDescriptor, HashSet<Edge>>> entryIt=delta.varedgeadd.entrySet().iterator();entryIt.hasNext();) {
453         Map.Entry<TempDescriptor, HashSet<Edge>> entry=entryIt.next();
454
455         if (entry.getKey()==tmp) {
456           /* Check if this is the tmp we overwrite */
457           entryIt.remove();
458         } else {
459           /* Otherwise, check if the target of the edge is changed... */
460           rewriteSet(entry.getValue(), graph.varMap.get(entry.getKey()), single, summary);
461         }
462       }
463       
464       /* 2. Fix up the base variable edges */
465
466       for(Iterator<Map.Entry<TempDescriptor, HashSet<Edge>>> entryIt=delta.basevaredge.entrySet().iterator();entryIt.hasNext();) {
467         Map.Entry<TempDescriptor, HashSet<Edge>> entry=entryIt.next();
468         TempDescriptor entrytmp=entry.getKey();
469         if (entrytmp==tmp) {
470           /* Check is this is the tmp we overwrite, if so add to remove set */
471           Util.relationUpdate(delta.varedgeremove, tmp, null, entry.getValue());
472         } else {
473           /* Check if the target of the edge is changed */ 
474           HashSet<Edge> newset=(HashSet<Edge>)entry.getValue().clone();
475           HashSet<Edge> removeset=shrinkSet(newset, graph.varMap.get(entrytmp), single, summary);
476           Util.relationUpdate(delta.varedgeremove, entrytmp, newset, removeset);
477           Util.relationUpdate(delta.varedgeadd, entrytmp, null, newset);
478         }
479       }
480
481
482       /* 3. Fix up heap edge additions */
483
484       HashMap<AllocNode, HashSet<Edge>> addheapedge=new HashMap<AllocNode, HashSet<Edge>>();
485       for(Iterator<Map.Entry<AllocNode, HashSet<Edge>>> entryIt=delta.heapedgeadd.entrySet().iterator();entryIt.hasNext();) {
486         Map.Entry<AllocNode, HashSet<Edge>> entry=entryIt.next();
487         HashSet<Edge> edgeset=entry.getValue();
488         AllocNode allocnode=entry.getKey();
489         if (allocnode==single) {
490           entryIt.remove();
491           rewriteSet(edgeset, graph.nodeMap.get(summary), single, summary);
492           addheapedge.put(summary, edgeset);
493         } else {
494           rewriteSet(edgeset, graph.nodeMap.get(allocnode), single, summary);
495         }
496       }
497       
498       /* Merge in diffs */
499
500       for(Map.Entry<AllocNode, HashSet<Edge>> entry:addheapedge.entrySet()) {
501         AllocNode allocnode=entry.getKey();
502         Util.relationUpdate(delta.heapedgeadd, allocnode, null, entry.getValue());
503       }
504
505       /* 4. Fix up the base heap edges */
506
507       for(Iterator<Map.Entry<AllocNode, HashSet<Edge>>> entryIt=delta.baseheapedge.entrySet().iterator();entryIt.hasNext();) {
508         Map.Entry<AllocNode, HashSet<Edge>> entry=entryIt.next();
509         HashSet<Edge> edgeset=entry.getValue();
510         AllocNode allocnode=entry.getKey();
511         if (allocnode==single) {
512           entryIt.remove();
513         }
514         AllocNode addnode=(allocnode==single)?summary:allocnode;
515
516         HashSet<Edge> newset=(HashSet<Edge>) edgeset.clone();
517         HashSet<Edge> removeset=shrinkSet(newset, graph.nodeMap.get(addnode), single, summary);
518         Util.relationUpdate(delta.heapedgeadd, addnode, null, newset);
519         Util.relationUpdate(delta.heapedgeremove, allocnode, null, removeset);
520       }
521       
522       //Apply incoming diffs to graph
523       applyDiffs(graph, delta);      
524     }
525     return delta;
526   }
527
528   void rewriteSet(HashSet<Edge> edgeset, HashSet<Edge> oldedgeset, AllocNode oldnode, AllocNode newnode) {
529     HashSet<Edge> newSet=null;
530     for(Iterator<Edge> edgeit=edgeset.iterator();edgeit.hasNext();) {
531       Edge e=edgeit.next();
532       if (e.dst==oldnode||e.src==oldnode) {
533         if (newSet==null) {
534           newSet=new HashSet<Edge>();
535         }
536         edgeit.remove();
537         if (e.dst==oldnode)
538           e.dst=newnode;
539         if (e.src==oldnode)
540           e.src=newnode;
541         if (oldedgeset==null||!oldedgeset.contains(e))
542           newSet.add(e);
543       }
544     }
545     if (newSet!=null)
546       edgeset.addAll(newSet);
547   }
548
549   /* Shrinks the incoming set to just include rewritten values.
550    * Returns a set of the original rewritten values */
551
552   HashSet<Edge> shrinkSet(HashSet<Edge> edgeset, HashSet<Edge> oldedgeset, AllocNode oldnode, AllocNode newnode) {
553     HashSet<Edge> newSet=null;
554     HashSet<Edge> removeSet=null;
555     for(Iterator<Edge> edgeit=edgeset.iterator();edgeit.hasNext();) {
556       Edge e=edgeit.next();
557       edgeit.remove();
558       if (e.dst==oldnode||e.src==oldnode) {
559         if (newSet==null) {
560           newSet=new HashSet<Edge>();
561           removeSet=new HashSet<Edge>();
562         }
563
564         removeSet.add(e.copy());
565         if (e.dst==oldnode)
566           e.dst=newnode;
567         if (e.src==oldnode)
568           e.src=newnode;
569         if (oldedgeset==null||!oldedgeset.contains(e))
570           newSet.add(e);
571       }
572     }
573     if (newSet!=null)
574       edgeset.addAll(newSet);
575     return removeSet;
576   } 
577
578   Delta applyInitDelta(Delta delta, BBlock block) {
579     //Apply delta to graph
580     boolean newGraph=false;
581     if (!bbgraphMap.containsKey(block)) {
582       bbgraphMap.put(block, new Graph(null));
583       newGraph=true;
584     }
585     Delta newdelta;
586     Graph graph=bbgraphMap.get(block);
587
588     if (newGraph) {
589       newdelta=new Delta(null, true);
590       //Add in heap edges and throw away original diff
591       graph.nodeMap.putAll(delta.heapedgeadd);
592       //Add in var edges and throw away original diff
593       graph.varMap.putAll(delta.varedgeadd);
594       //Record that this is initial set...
595     } else {
596       newdelta=new Delta(null, false);
597       //merge in heap edges and variables
598       mergeHeapEdges(graph, delta, newdelta);
599       mergeVarEdges(graph, delta, newdelta);
600       //Record that this is a diff
601       newdelta.setInit(false);
602     }
603     return newdelta;
604   }
605
606   /* This function merges in the heap edges.  It updates delta to be
607    * the difference */
608
609   void mergeHeapEdges(Graph graph, Delta delta, Delta newdelta) {
610     //Merge in edges
611     for(Map.Entry<AllocNode, HashSet<Edge>> heapedge:delta.heapedgeadd.entrySet()) {
612       AllocNode nsrc=heapedge.getKey();
613       HashSet<Edge> edges=heapedge.getValue();
614       if (!graph.nodeMap.containsKey(nsrc)) {
615         graph.nodeMap.put(nsrc, new HashSet<Edge>());
616       }
617       HashSet<Edge> dstedges=graph.nodeMap.get(nsrc);
618       HashSet<Edge> diffedges=new HashSet<Edge>();
619       for(Edge e:edges) {
620         if (!dstedges.contains(e)) {
621           //We have a new edge
622           diffedges.add(e);
623           dstedges.add(e);
624         }
625       }
626       //Done with edge set...
627       if (diffedges.size()>0) {
628         //completely new
629         newdelta.baseheapedge.put(nsrc, diffedges);
630       }
631     }
632   }
633
634   /* This function merges in the var edges.  It updates delta to be
635    * the difference */
636
637   void mergeVarEdges(Graph graph, Delta delta, Delta newdelta) {
638     //Merge in edges
639     for(Map.Entry<TempDescriptor, HashSet<Edge>> varedge:delta.varedgeadd.entrySet()) {
640       TempDescriptor tmpsrc=varedge.getKey();
641       HashSet<Edge> edges=varedge.getValue();
642       if (!graph.varMap.containsKey(tmpsrc)) {
643         graph.varMap.put(tmpsrc, new HashSet<Edge>());
644       }
645       HashSet<Edge> dstedges=graph.varMap.get(tmpsrc);
646       HashSet<Edge> diffedges=new HashSet<Edge>();
647       for(Edge e:edges) {
648         if (!dstedges.contains(e)) {
649           //We have a new edge
650           diffedges.add(e);
651           dstedges.add(e);
652         }
653       }
654       //Done with edge set...
655       if (diffedges.size()>=0) {
656         //completely new
657         newdelta.basevaredge.put(tmpsrc,diffedges);
658       }
659     }
660   }
661 }