This commit was manufactured by cvs2svn to create tag 'buildscript'.
[IRC.git] /
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 }