remove some codes for scheduling
[IRC.git] / Robust / src / Analysis / Locality / GenerateConversions.java
1 package Analysis.Locality;
2 import IR.State;
3 import IR.Flat.*;
4 import java.util.*;
5 import IR.MethodDescriptor;
6
7
8 public class GenerateConversions {
9     LocalityAnalysis locality;
10     State state;
11
12     /** Warning: This class modifies the code in place.  */
13
14     public GenerateConversions(LocalityAnalysis la, State state) {
15         locality=la;
16         this.state=state;
17         doConversion();
18     }
19     
20     private void doConversion() {
21         Set<LocalityBinding> bindings=locality.getLocalityBindings();
22         Iterator<LocalityBinding> bindit=bindings.iterator();
23         while(bindit.hasNext()) {
24             LocalityBinding lb=bindit.next();
25             //Don't need to do conversion if it is already atomic
26             if (lb.isAtomic())
27                 continue;
28             converttoPtr(lb);
29             converttoOid(lb);
30         }
31     }
32
33     /* At the end of an atomic block, we need to convert any global
34      * references that will be used again into OID's. */
35
36     private void converttoOid(LocalityBinding lb) {
37         Hashtable<FlatNode, Integer> atomictab=locality.getAtomic(lb);
38         Hashtable<FlatNode, Hashtable<TempDescriptor, Integer>> temptab=locality.getNodeTempInfo(lb);
39         MethodDescriptor md=lb.getMethod();
40         FlatMethod fm=state.getMethodFlat(md);
41         Hashtable<FlatNode, Set<TempNodePair>> nodetotnpair=new Hashtable<FlatNode, Set<TempNodePair>>();
42         Hashtable<FlatNode, Set<TempDescriptor>> nodetoconvs=new Hashtable<FlatNode, Set<TempDescriptor>>();
43
44         Set<FlatNode> toprocess=fm.getNodeSet();
45
46         while(!toprocess.isEmpty()) {
47             FlatNode fn=toprocess.iterator().next();
48             toprocess.remove(fn);
49             boolean isatomic=atomictab.get(fn).intValue()>0;
50             Hashtable<TempDescriptor, Integer> nodetemptab=temptab.get(fn);
51             
52             List<TempDescriptor> reads=Arrays.asList(fn.readsTemps());
53             List<TempDescriptor> writes=Arrays.asList(fn.writesTemps());
54             
55             if (!isatomic&&fn.kind()==FKind.FlatAtomicExitNode
56                 &&!nodetoconvs.containsKey(fn))
57                 nodetoconvs.put(fn, new HashSet<TempDescriptor>());
58             
59             HashSet<TempNodePair> tempset=new HashSet<TempNodePair>();
60
61             for(int i=0;i<fn.numPrev();i++) {
62                 FlatNode fnprev=fn.getPrev(i);
63                 if (!nodetotnpair.containsKey(fnprev))
64                     continue;
65
66                 Set<TempNodePair> prevset=nodetotnpair.get(fnprev);
67                 for(Iterator<TempNodePair> it=prevset.iterator();it.hasNext();) {
68                     TempNodePair tnp=it.next();
69                     if (fn.kind()==FKind.FlatGlobalConvNode&&
70                          ((FlatGlobalConvNode)fn).getLocality()!=lb) {
71                         //ignore this node
72                         tempset.add(tnp);
73                         continue;
74                     }
75                     if (reads.contains(tnp.getTemp())&&tnp.getNode()!=null) {
76                         //Value actually is read...
77                         nodetoconvs.get(tnp.getNode()).add(tnp.getTemp());
78                     }
79                     if (writes.contains(tnp.getTemp())) //value overwritten
80                         continue;
81                     if (!isatomic&&fn.kind()==FKind.FlatAtomicExitNode) {
82                         //Create new node and tag it with this exit
83                         if (tnp.getNode()==null) {
84                             TempNodePair tnp2=new TempNodePair(tnp.getTemp());
85                             tnp2.setNode(fn);
86                             tempset.add(tnp2);
87                         } else
88                             tempset.add(tnp);
89                     } else
90                         tempset.add(tnp);
91                 }
92             }
93             if (isatomic) {
94                 /* If this is in an atomic block, record temps that
95                  * are written to.*/
96
97                 /* NOTE: If this compiler is changed to maintain
98                  * OID/Ptr's in variables, then we need to use all
99                  * global temps that could be read and not just the
100                  * ones converted by globalconvnode*/
101
102                 if (fn.kind()!=FKind.FlatGlobalConvNode||
103                     ((FlatGlobalConvNode)fn).getLocality()==lb) {
104                     /*If globalconvnode, make sure we have the right
105                      * locality. */
106                     for(Iterator<TempDescriptor> writeit=writes.iterator();writeit.hasNext();) {
107                         TempDescriptor wrtmp=writeit.next();
108                         if (nodetemptab.get(wrtmp)==LocalityAnalysis.GLOBAL) {
109                             TempNodePair tnp=new TempNodePair(wrtmp);
110                             tempset.add(tnp);
111                         }
112                     }
113                 }
114             }
115             if (!nodetotnpair.containsKey(fn)||!nodetotnpair.get(fn).equals(tempset)) {
116                 //changes to set, so enqueue next nodes
117                 nodetotnpair.put(fn, tempset); //update set
118                 for(int i=0;i<fn.numNext();i++) {
119                     toprocess.add(fn.getNext(i));
120                 }
121             }
122         }
123         //Place Convert to Oid nodes
124         toprocess=fm.getNodeSet();
125         for(Iterator<FlatNode> it=toprocess.iterator();it.hasNext();) {
126             FlatNode fn=it.next();
127             if (atomictab.get(fn).intValue()==0&&fn.numPrev()>0&&
128                 atomictab.get(fn.getPrev(0)).intValue()>0) {
129                 //sanity check
130                 assert(fn.kind()==FKind.FlatAtomicExitNode);
131                 //insert calls here...
132                 Set<TempDescriptor> tempset=nodetoconvs.get(fn);
133                 for(Iterator<TempDescriptor> tempit=tempset.iterator();tempit.hasNext();) {
134                     FlatGlobalConvNode fgcn=new FlatGlobalConvNode(tempit.next(), lb, false);
135                     atomictab.put(fgcn, atomictab.get(fn));
136                     temptab.put(fgcn, (Hashtable<TempDescriptor, Integer>) temptab.get(fn).clone());
137
138                     for(int i=0;i<fn.numPrev();i++) {
139                         FlatNode fnprev=fn.getPrev(i);
140                         for(int j=0;j<fnprev.numNext();j++) {
141                             if (fnprev.getNext(j)==fn) {
142                                 //found index, change node
143                                 fnprev.setNext(j, fgcn);
144                                 break;
145                             }
146                         }
147                     }
148                     fgcn.addNext(fn);
149                 }
150             }
151         }
152     }
153     
154     /* At the beginning of an atomic block, we need to convert any
155      * OID's that will be used in the atomic block to pointers */
156
157     private void converttoPtr(LocalityBinding lb) {
158         Hashtable<FlatNode, Set<TempDescriptor>> nodetotranstemps=new Hashtable<FlatNode, Set<TempDescriptor>>();
159         Hashtable<FlatNode, Integer> atomictab=locality.getAtomic(lb);
160         Hashtable<FlatNode, Hashtable<TempDescriptor, Integer>> temptab=locality.getNodeTempInfo(lb);
161         MethodDescriptor md=lb.getMethod();
162         FlatMethod fm=state.getMethodFlat(md);
163         Set<FlatNode> toprocess=fm.getNodeSet();
164
165         while(!toprocess.isEmpty()) {
166             FlatNode fn=toprocess.iterator().next();
167             toprocess.remove(fn);
168
169             if (atomictab.get(fn).intValue()>0) {
170                 //build set of transaction temps use by next nodes
171                 HashSet<TempDescriptor> transtemps=new HashSet<TempDescriptor>();
172                 for(int i=0;i<fn.numNext();i++) {
173                     FlatNode fnnext=fn.getNext(i);
174                     if (nodetotranstemps.containsKey(fnnext))
175                         transtemps.addAll(nodetotranstemps.get(fnnext));
176                 }
177                 //subtract out the ones we write to
178                 transtemps.removeAll(Arrays.asList(fn.writesTemps()));
179                 //add in the globals we read from
180                 Hashtable<TempDescriptor, Integer> pretemptab=locality.getNodePreTempInfo(lb, fn);
181                 TempDescriptor []readtemps=fn.readsTemps();
182                 for(int i=0;i<readtemps.length;i++) {
183                     TempDescriptor tmp=readtemps[i];
184                     if (pretemptab.get(tmp).intValue()==LocalityAnalysis.GLOBAL) {
185                         transtemps.add(tmp);
186                     }
187                 }
188                 if (!nodetotranstemps.containsKey(fn)||!nodetotranstemps.get(fn).equals(transtemps)) {
189                     nodetotranstemps.put(fn, transtemps);
190                     for(int i=0;i<fn.numPrev();i++)
191                         toprocess.add(fn.getPrev(i));
192                 }
193             }
194         }
195         toprocess=fm.getNodeSet();
196         for(Iterator<FlatNode> it=toprocess.iterator();it.hasNext();) {
197             FlatNode fn=it.next();
198             if (atomictab.get(fn).intValue()>0&&
199                 atomictab.get(fn.getPrev(0)).intValue()==0) {
200                 //sanity check
201                 assert(fn.kind()==FKind.FlatAtomicEnterNode);
202                 
203                 //insert calls here...
204                 Set<TempDescriptor> tempset=nodetotranstemps.get(fn);
205                 for(Iterator<TempDescriptor> tempit=tempset.iterator();tempit.hasNext();) {
206                     FlatGlobalConvNode fgcn=new FlatGlobalConvNode(tempit.next(), lb, true);
207                     atomictab.put(fgcn, atomictab.get(fn));
208                     temptab.put(fgcn, (Hashtable<TempDescriptor, Integer>) temptab.get(fn).clone());
209                     fgcn.addNext(fn.getNext(0));
210                     fn.setNext(0, fgcn);
211                 }       
212             }
213         }
214     }
215 }