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.readsTemps());
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 Set<TempNodePair> prevset=nodetotnpair.get(fnprev);
65 for(Iterator<TempNodePair> it=prevset.iterator();it.hasNext();) {
66 TempNodePair tnp=it.next();
67 if (reads.contains(tnp.getTemp())&&tnp.getNode()!=null) {
68 //Value actually is read...
69 nodetoconvs.get(tnp.getNode()).add(tnp.getTemp());
71 if (writes.contains(tnp.getTemp())) //value overwritten
73 if (!isatomic&&fn.kind()==FKind.FlatAtomicExitNode) {
74 //Create new node and tag it with this exit
75 if (tnp.getNode()==null) {
76 TempNodePair tnp2=new TempNodePair(tnp.getTemp());
85 //if this is in an atomic block, record temps that are written to
87 /* NOTE: If this compiler is changed to maintain
88 * OID/Ptr's in variables, then we need to use all
89 * global temps that could be read and not just the
90 * ones converted by globalconvnode*/
92 if (fn.kind()!=FKind.FlatGlobalConvNode||
93 ((FlatGlobalConvNode)fn).getLocality()==lb)
94 //If globalconvnode, make sure we have the right locality
95 for(Iterator<TempDescriptor> writeit=writes.iterator();writeit.hasNext();) {
96 TempDescriptor wrtmp=writeit.next();
97 if (nodetemptab.get(wrtmp)==LocalityAnalysis.GLOBAL) {
98 TempNodePair tnp=new TempNodePair(wrtmp);
103 if (!nodetotnpair.containsKey(fn)||!nodetotnpair.get(fn).equals(tempset)) {
104 //changes to set, so enqueue next nodes
105 nodetotnpair.put(fn, tempset); //update set
106 for(int i=0;i<fn.numNext();i++) {
107 toprocess.add(fn.getNext(i));
111 //Place Convert to Oid nodes
112 toprocess=fm.getNodeSet();
113 for(Iterator<FlatNode> it=toprocess.iterator();it.hasNext();) {
114 FlatNode fn=it.next();
115 if (atomictab.get(fn).intValue()==0&&
116 atomictab.get(fn.getPrev(0)).intValue()>0) {
118 assert(fn.kind()==FKind.FlatAtomicExitNode);
120 //insert calls here...
121 Set<TempDescriptor> tempset=nodetoconvs.get(fn);
122 for(Iterator<TempDescriptor> tempit=tempset.iterator();tempit.hasNext();) {
123 FlatGlobalConvNode fgcn=new FlatGlobalConvNode(tempit.next(), lb, false);
124 atomictab.put(fgcn, atomictab.get(fn));
125 temptab.put(fgcn, (Hashtable<TempDescriptor, Integer>) temptab.get(fn).clone());
126 for(int i=0;i<fn.numPrev();i++) {
127 FlatNode fnprev=fn.getPrev(i);
128 for(int j=0;j<fnprev.numNext();j++) {
129 if (fnprev.getNext(j)==fn) {
130 //found index, change node
131 fnprev.setNext(j, fgcn);
142 /* At the beginning of an atomic block, we need to convert any
143 * OID's that will be used in the atomic block to pointers */
145 private void converttoPtr(LocalityBinding lb) {
146 Hashtable<FlatNode, Set<TempDescriptor>> nodetotranstemps=new Hashtable<FlatNode, Set<TempDescriptor>>();
147 Hashtable<FlatNode, Integer> atomictab=locality.getAtomic(lb);
148 Hashtable<FlatNode, Hashtable<TempDescriptor, Integer>> temptab=locality.getNodeTempInfo(lb);
149 MethodDescriptor md=lb.getMethod();
150 FlatMethod fm=state.getMethodFlat(md);
151 Set<FlatNode> toprocess=fm.getNodeSet();
153 while(!toprocess.isEmpty()) {
154 FlatNode fn=toprocess.iterator().next();
155 toprocess.remove(fn);
157 if (atomictab.get(fn).intValue()>0) {
158 //build set of transaction temps use by next nodes
159 HashSet<TempDescriptor> transtemps=new HashSet<TempDescriptor>();
160 for(int i=0;i<fn.numNext();i++) {
161 FlatNode fnnext=fn.getNext(i);
162 if (nodetotranstemps.containsKey(fnnext))
163 transtemps.addAll(nodetotranstemps.get(fnnext));
165 //subtract out the ones we write to
166 transtemps.removeAll(Arrays.asList(fn.writesTemps()));
167 //add in the globals we read from
168 TempDescriptor []readtemps=fn.readsTemps();
169 for(int i=0;i<readtemps.length;i++) {
170 TempDescriptor tmp=readtemps[i];
171 if (temptab.get(fn).get(tmp).intValue()==LocalityAnalysis.GLOBAL) {
175 if (!nodetotranstemps.containsKey(fn)||!nodetotranstemps.get(fn).equals(transtemps)) {
176 nodetotranstemps.put(fn, transtemps);
177 for(int i=0;i<fn.numPrev();i++)
178 toprocess.add(fn.getPrev(i));
182 toprocess=fm.getNodeSet();
183 for(Iterator<FlatNode> it=toprocess.iterator();it.hasNext();) {
184 FlatNode fn=it.next();
185 if (atomictab.get(fn).intValue()>0&&
186 atomictab.get(fn.getPrev(0)).intValue()==0) {
188 assert(fn.kind()==FKind.FlatAtomicEnterNode);
190 //insert calls here...
191 Set<TempDescriptor> tempset=nodetotranstemps.get(fn);
192 for(Iterator<TempDescriptor> tempit=tempset.iterator();tempit.hasNext();) {
193 FlatGlobalConvNode fgcn=new FlatGlobalConvNode(tempit.next(), lb, true);
194 atomictab.put(fgcn, atomictab.get(fn));
195 temptab.put(fgcn, (Hashtable<TempDescriptor, Integer>) temptab.get(fn).clone());
196 fgcn.addNext(fn.getNext(0));