a whole bunch of optimizations...should be useful for transactions
[IRC.git] / Robust / src / Analysis / Loops / CopyPropagation.java
1 package Analysis.Loops;
2 import IR.Flat.*;
3 import IR.Operation;
4 import java.util.Iterator;
5 import java.util.Hashtable;
6 import java.util.HashSet;
7 import java.util.Map;
8
9 public class CopyPropagation {
10   public CopyPropagation() {
11   }
12
13   public void optimize(FlatMethod fm) {
14     Hashtable<FlatNode, Hashtable<TempDescriptor, TempDescriptor>> table
15       =new Hashtable<FlatNode, Hashtable<TempDescriptor, TempDescriptor>>();
16     boolean changed=false;
17     do {
18       changed=false;
19       HashSet tovisit=new HashSet();
20       HashSet discovered=new HashSet();
21       tovisit.add(fm);
22       discovered.add(fm);
23       while(!tovisit.isEmpty()) {
24         FlatNode fn=(FlatNode) tovisit.iterator().next();
25         tovisit.remove(fn);
26         for(int i=0;i<fn.numNext();i++) {
27           FlatNode nnext=fn.getNext(i);
28           if (!discovered.contains(nnext)) {
29             discovered.add(nnext);
30             tovisit.add(nnext);
31           }
32         }
33         Hashtable<TempDescriptor, TempDescriptor> tab;
34         if (fn.numPrev()>=1&&table.containsKey(fn.getPrev(0)))
35           tab=new Hashtable<TempDescriptor, TempDescriptor>(table.get(fn.getPrev(0)));
36         else
37           tab=new Hashtable<TempDescriptor, TempDescriptor>();
38         //Compute intersection
39         for(int i=1;i<fn.numPrev();i++) {
40           Hashtable<TempDescriptor, TempDescriptor> tp=table.get(fn.getPrev(i));
41           for(Iterator tmpit=tab.entrySet().iterator();tmpit.hasNext();) {
42             Map.Entry t=(Map.Entry)tmpit.next();
43             TempDescriptor tmp=(TempDescriptor)t.getKey();
44             if (tp!=null&&(!tp.containsKey(tmp)||tp.get(tmp)!=tab.get(tmp))) {
45               tmpit.remove();
46             }
47           }
48         }
49         TempDescriptor[]writes=fn.writesTemps();
50         for(int i=0;i<writes.length;i++) {
51           TempDescriptor tmp=writes[i];
52           for(Iterator<TempDescriptor> tmpit=tab.keySet().iterator();tmpit.hasNext();) {        
53             TempDescriptor tmp2=tmpit.next();
54             if (tmp==tab.get(tmp2))
55               tmpit.remove();
56           }
57         }
58         if (fn.kind()==FKind.FlatOpNode) {
59           FlatOpNode fon=(FlatOpNode)fn;
60           if (fon.getOp().getOp()==Operation.ASSIGN) {
61             tab.put(fon.getDest(), fon.getLeft());
62           }
63         }
64         if (!table.containsKey(fn)||!table.get(fn).equals(tab)) {
65           table.put(fn,tab);
66           changed=true;
67           for(int i=0;i<fn.numNext();i++) {
68             FlatNode nnext=fn.getNext(i);
69             tovisit.add(nnext);
70           }
71         }
72       }
73       for(Iterator<FlatNode> it=fm.getNodeSet().iterator();it.hasNext();) {
74         FlatNode fn=it.next();
75         Hashtable<TempDescriptor, TempDescriptor> tab=table.get(fn);
76         TempMap tmap=null;
77         TempDescriptor[]reads=fn.readsTemps();
78         for(int i=0;i<reads.length;i++) {
79           TempDescriptor tmp=reads[i];
80           if (tab.containsKey(tmp)) {
81             if (tmap==null)
82               tmap=new TempMap();
83             tmap.addPair(tmp, tab.get(tmp));
84           }
85         }
86         if (tmap!=null)
87           fn.rewriteUse(tmap);
88       }
89     } while(changed);
90   }
91 }