1 package Analysis.Locality;
5 import IR.MethodDescriptor;
8 public class GenerateConversions {
9 LocalityAnalysis locality;
12 /** Warning: This class modifies the code in place. */
14 public GenerateConversions(LocalityAnalysis la, State state) {
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
33 /* At the end of an atomic block, we need to convert any global
34 * references that will be used again into OID's. */
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>>();
44 Set<FlatNode> toprocess=fm.getNodeSet();
46 while(!toprocess.isEmpty()) {
47 FlatNode fn=toprocess.iterator().next();
49 boolean isatomic=atomictab.get(fn).intValue()>0;
50 Hashtable<TempDescriptor, Integer> nodetemptab=temptab.get(fn);
52 List<TempDescriptor> reads=Arrays.asList(fn.readsTemps());
53 List<TempDescriptor> writes=Arrays.asList(fn.writesTemps());
55 if (!isatomic&&fn.kind()==FKind.FlatAtomicExitNode
56 &&!nodetoconvs.containsKey(fn))
57 nodetoconvs.put(fn, new HashSet<TempDescriptor>());
59 HashSet<TempNodePair> tempset=new HashSet<TempNodePair>();
61 for(int i=0; i<fn.numPrev(); i++) {
62 FlatNode fnprev=fn.getPrev(i);
63 if (!nodetotnpair.containsKey(fnprev))
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) {
75 if (reads.contains(tnp.getTemp())&&tnp.getNode()!=null) {
76 //Value actually is read...
77 nodetoconvs.get(tnp.getNode()).add(tnp.getTemp());
79 if (writes.contains(tnp.getTemp())) //value overwritten
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());
94 /* If this is in an atomic block, record temps that
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*/
102 if (fn.kind()!=FKind.FlatGlobalConvNode||
103 ((FlatGlobalConvNode)fn).getLocality()==lb) {
104 /*If globalconvnode, make sure we have the right
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);
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));
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) {
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());
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);
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 */
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();
165 while(!toprocess.isEmpty()) {
166 FlatNode fn=toprocess.iterator().next();
167 toprocess.remove(fn);
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));
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) {
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));
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) {
201 assert(fn.kind()==FKind.FlatAtomicEnterNode);
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));