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);
42 Hashtable<FlatNode, Set<TempNodePair>> nodetotnpair=new Hashtable<FlatNode, Set<TempNodePair>>();
43 Hashtable<FlatNode, Set<TempDescriptor>> nodetoconvs=new Hashtable<FlatNode, Set<TempDescriptor>>();
45 Set<FlatNode> toprocess=fm.getNodeSet();
47 while(!toprocess.isEmpty()) {
48 FlatNode fn=toprocess.iterator().next();
50 boolean isatomic=atomictab.get(fn).intValue()>0;
51 Hashtable<TempDescriptor, Integer> nodetemptab=temptab.get(fn);
53 List<TempDescriptor> reads=Arrays.asList(fn.readsTemps());
54 List<TempDescriptor> writes=Arrays.asList(fn.writesTemps());
56 if (!isatomic&&fn.kind()==FKind.FlatAtomicExitNode
57 &&!nodetoconvs.containsKey(fn))
58 nodetoconvs.put(fn, new HashSet<TempDescriptor>());
61 HashSet<TempNodePair> tempset=new HashSet<TempNodePair>();
62 for(int i=0;i<fn.numPrev();i++) {
63 FlatNode fnprev=fn.getPrev(i);
64 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 (reads.contains(tnp.getTemp())&&tnp.getNode()!=null) {
70 //Value actually is read...
71 nodetoconvs.get(tnp.getNode()).add(tnp.getTemp());
73 if (writes.contains(tnp.getTemp())) //value overwritten
75 if (!isatomic&&fn.kind()==FKind.FlatAtomicExitNode) {
76 //Create new node and tag it with this exit
77 if (tnp.getNode()==null) {
78 TempNodePair tnp2=new TempNodePair(tnp.getTemp());
88 //if this is in an atomic block, record temps that are written to
90 /* NOTE: If this compiler is changed to maintain
91 * OID/Ptr's in variables, then we need to use all
92 * global temps that could be read and not just the
93 * ones converted by globalconvnode*/
95 if (fn.kind()!=FKind.FlatGlobalConvNode||
96 ((FlatGlobalConvNode)fn).getLocality()==lb)
97 //If globalconvnode, make sure we have the right locality
98 for(Iterator<TempDescriptor> writeit=writes.iterator();writeit.hasNext();) {
99 TempDescriptor wrtmp=writeit.next();
100 if (nodetemptab.get(wrtmp)==LocalityAnalysis.GLOBAL) {
101 TempNodePair tnp=new TempNodePair(wrtmp);
106 if (!nodetotnpair.containsKey(fn)||!nodetotnpair.get(fn).equals(tempset)) {
107 //changes to set, so enqueue next nodes
108 nodetotnpair.put(fn, tempset); //update set
109 for(int i=0;i<fn.numNext();i++) {
110 toprocess.add(fn.getNext(i));
114 //Place Convert to Oid nodes
115 toprocess=fm.getNodeSet();
116 for(Iterator<FlatNode> it=toprocess.iterator();it.hasNext();) {
117 FlatNode fn=it.next();
118 if (atomictab.get(fn).intValue()==0&&fn.numPrev()>0&&
119 atomictab.get(fn.getPrev(0)).intValue()>0) {
121 assert(fn.kind()==FKind.FlatAtomicExitNode);
122 //insert calls here...
123 Set<TempDescriptor> tempset=nodetoconvs.get(fn);
124 for(Iterator<TempDescriptor> tempit=tempset.iterator();tempit.hasNext();) {
125 FlatGlobalConvNode fgcn=new FlatGlobalConvNode(tempit.next(), lb, false);
126 atomictab.put(fgcn, atomictab.get(fn));
127 temptab.put(fgcn, (Hashtable<TempDescriptor, Integer>) temptab.get(fn).clone());
128 for(int i=0;i<fn.numPrev();i++) {
129 FlatNode fnprev=fn.getPrev(i);
130 for(int j=0;j<fnprev.numNext();j++) {
131 if (fnprev.getNext(j)==fn) {
132 //found index, change node
133 fnprev.setNext(j, fgcn);
144 /* At the beginning of an atomic block, we need to convert any
145 * OID's that will be used in the atomic block to pointers */
147 private void converttoPtr(LocalityBinding lb) {
148 Hashtable<FlatNode, Set<TempDescriptor>> nodetotranstemps=new Hashtable<FlatNode, Set<TempDescriptor>>();
149 Hashtable<FlatNode, Integer> atomictab=locality.getAtomic(lb);
150 Hashtable<FlatNode, Hashtable<TempDescriptor, Integer>> temptab=locality.getNodeTempInfo(lb);
151 MethodDescriptor md=lb.getMethod();
152 FlatMethod fm=state.getMethodFlat(md);
153 Set<FlatNode> toprocess=fm.getNodeSet();
155 while(!toprocess.isEmpty()) {
156 FlatNode fn=toprocess.iterator().next();
157 toprocess.remove(fn);
159 if (atomictab.get(fn).intValue()>0) {
160 //build set of transaction temps use by next nodes
161 HashSet<TempDescriptor> transtemps=new HashSet<TempDescriptor>();
162 for(int i=0;i<fn.numNext();i++) {
163 FlatNode fnnext=fn.getNext(i);
164 if (nodetotranstemps.containsKey(fnnext))
165 transtemps.addAll(nodetotranstemps.get(fnnext));
167 //subtract out the ones we write to
168 transtemps.removeAll(Arrays.asList(fn.writesTemps()));
169 //add in the globals we read from
170 Hashtable<TempDescriptor, Integer> pretemptab=locality.getNodePreTempInfo(lb, fn);
171 TempDescriptor []readtemps=fn.readsTemps();
172 for(int i=0;i<readtemps.length;i++) {
173 TempDescriptor tmp=readtemps[i];
174 if (pretemptab.get(tmp).intValue()==LocalityAnalysis.GLOBAL) {
178 if (!nodetotranstemps.containsKey(fn)||!nodetotranstemps.get(fn).equals(transtemps)) {
179 nodetotranstemps.put(fn, transtemps);
180 for(int i=0;i<fn.numPrev();i++)
181 toprocess.add(fn.getPrev(i));
185 toprocess=fm.getNodeSet();
186 for(Iterator<FlatNode> it=toprocess.iterator();it.hasNext();) {
187 FlatNode fn=it.next();
188 if (atomictab.get(fn).intValue()>0&&
189 atomictab.get(fn.getPrev(0)).intValue()==0) {
191 assert(fn.kind()==FKind.FlatAtomicEnterNode);
193 //insert calls here...
194 Set<TempDescriptor> tempset=nodetotranstemps.get(fn);
195 for(Iterator<TempDescriptor> tempit=tempset.iterator();tempit.hasNext();) {
196 FlatGlobalConvNode fgcn=new FlatGlobalConvNode(tempit.next(), lb, true);
197 atomictab.put(fgcn, atomictab.get(fn));
198 temptab.put(fgcn, (Hashtable<TempDescriptor, Integer>) temptab.get(fn).clone());
199 fgcn.addNext(fn.getNext(0));