1 cananian 1.1.2.1 // SSIToSSAMap.java, created Thu Jun 17 16:11:41 1999 by root 2 cananian 1.1.2.1 // Copyright (C) 1999 Brian Demsky <bdemsky@mit.edu> 3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1.2.1 package harpoon.Analysis.Quads; 5 cananian 1.1.2.1 import harpoon.Temp.TempMap; 6 cananian 1.1.2.1 import harpoon.Temp.Temp; 7 cananian 1.3 import net.cscott.jutil.WorkSet; 8 cananian 1.1.2.1 import harpoon.IR.LowQuad.LowQuadVisitor; 9 cananian 1.1.2.1 import harpoon.IR.Quads.AGET; 10 cananian 1.1.2.1 import harpoon.IR.Quads.ASET; 11 cananian 1.1.2.1 import harpoon.IR.Quads.GET; 12 cananian 1.1.2.1 import harpoon.IR.Quads.HANDLER; 13 cananian 1.1.2.1 import harpoon.IR.Quads.OPER; 14 cananian 1.1.2.1 import harpoon.IR.Quads.PHI; 15 cananian 1.1.2.1 import harpoon.IR.Quads.Quad; 16 cananian 1.1.2.1 import harpoon.IR.Quads.SET; 17 cananian 1.1.2.1 import harpoon.IR.Quads.SIGMA; 18 cananian 1.1.2.1 import harpoon.ClassFile.HCode; 19 cananian 1.1.2.1 20 cananian 1.1.2.1 import java.util.HashMap; 21 cananian 1.1.2.1 import java.util.Iterator; 22 cananian 1.1.2.1 import java.util.Set; 23 cananian 1.1.2.1 /** 24 cananian 1.1.2.1 * An <code>SSIToSSAMap</code> allows you to look at an SSI 25 cananian 1.1.2.1 * representation "with glasses on" so that it appears as SSA. This 26 cananian 1.1.2.1 * is often useful when the additional value-information 27 cananian 1.1.2.1 * discrimination of SSI form is unnecessary, but converting the input 28 cananian 1.1.2.1 * to SSA is undesirable. 29 cananian 1.1.2.1 * 30 cananian 1.1.2.1 * @author Brian Demsky <bdemsky@mit.edu> 31 cananian 1.4 * @version $Id: SSIToSSAMap.java,v 1.4 2004/02/08 03:20:10 cananian Exp $ 32 cananian 1.1.2.1 */ 33 cananian 1.1.2.1 public class SSIToSSAMap implements TempMap { 34 cananian 1.1.2.1 35 cananian 1.1.2.1 /** Creates a <code>SSIToSSAMap</code> for the <code>HCode</code> 36 cananian 1.1.2.1 * <code>hc</code>. */ 37 cananian 1.1.2.1 public SSIToSSAMap(HCode hc) { 38 cananian 1.1.2.1 //We need to build to map in the constructor 39 cananian 1.1.2.1 //Set HCode pointer 40 cananian 1.1.2.1 this.hc=hc; 41 cananian 1.1.2.1 42 cananian 1.1.2.1 //Set forward SSI->SSA Map 43 cananian 1.1.2.1 this.forward=new HashMap(); 44 cananian 1.1.2.1 45 cananian 1.1.2.1 //Set backward SSA->set of SSI Temps Map 46 cananian 1.1.2.1 this.backward=new HashMap(); 47 cananian 1.1.2.1 48 cananian 1.1.2.1 //List of sigmas 49 cananian 1.1.2.1 this.sigmas=new WorkSet(); 50 cananian 1.1.2.1 51 cananian 1.1.2.1 //List of phis 52 cananian 1.1.2.1 this.phis=new WorkSet(); 53 cananian 1.1.2.1 54 cananian 1.1.2.1 //List of phi destinations 55 cananian 1.1.2.1 this.phiresults=new WorkSet(); 56 cananian 1.1.2.1 57 cananian 1.1.2.1 //Build the map 58 cananian 1.1.2.1 buildmap(); 59 cananian 1.1.2.1 //debug(); 60 cananian 1.1.2.1 } 61 cananian 1.1.2.1 62 cananian 1.1.2.1 void debug() { 63 cananian 1.1.2.1 //Print out the map 64 cananian 1.1.2.1 Set W=forward.keySet(); 65 cananian 1.4 for (Object tO : W) { 66 cananian 1.4 Temp t = (Temp) tO; 67 cananian 1.1.2.1 Temp tt=(Temp)forward.get(t); 68 cananian 1.1.2.1 System.out.println(t.toString()+"--->"+tt.toString()); 69 cananian 1.1.2.1 } 70 cananian 1.1.2.1 } 71 cananian 1.1.2.1 72 cananian 1.1.2.1 void buildmap() { 73 cananian 1.1.2.1 //Find all of the Sigmas and Phis 74 cananian 1.1.2.1 findSigmaPhis(); 75 cananian 1.1.2.1 76 cananian 1.1.2.1 //Add the Sigmas into the map 77 cananian 1.1.2.1 addSigmas(); 78 cananian 1.1.2.1 79 cananian 1.1.2.1 //Add the Phis into the map 80 cananian 1.1.2.1 addPhis(); 81 cananian 1.1.2.1 } 82 cananian 1.1.2.1 83 cananian 1.1.2.1 void addSigmas() { 84 cananian 1.1.2.1 //Iterate over the set of sigmas 85 cananian 1.1.2.1 86 cananian 1.1.2.1 Iterator iterate=sigmas.iterator(); 87 cananian 1.1.2.1 while (iterate.hasNext()) { 88 cananian 1.1.2.1 89 cananian 1.1.2.1 //Put the current SIGMA object in sigma 90 cananian 1.1.2.1 SIGMA sigma=(SIGMA) iterate.next(); 91 cananian 1.1.2.1 int numbersigmas=sigma.numSigmas(); 92 cananian 1.1.2.1 int splitting=sigma.arity(); 93 cananian 1.1.2.1 94 cananian 1.1.2.1 //Loop over each individual sigma in it 95 cananian 1.1.2.1 for (int i=0;i<numbersigmas;i++) { 96 cananian 1.1.2.1 97 cananian 1.1.2.1 98 cananian 1.1.2.1 Temp tmpsrc; 99 cananian 1.1.2.1 WorkSet backset; 100 cananian 1.1.2.1 101 cananian 1.1.2.1 //Need to see if the source of the sigma is already in our map 102 cananian 1.1.2.1 if (forward.get(sigma.src(i))!=null) { 103 cananian 1.1.2.1 104 cananian 1.1.2.1 //If so, we need to look at its source to get 105 cananian 1.1.2.1 //the original SSA assignment 106 cananian 1.1.2.1 tmpsrc=(Temp)forward.get(sigma.src(i)); 107 cananian 1.1.2.1 108 cananian 1.1.2.1 //We also need to get its backset to add the 109 cananian 1.1.2.1 //destinations of our sigmas to 110 cananian 1.1.2.1 backset=(WorkSet)backward.get(tmpsrc); 111 cananian 1.1.2.1 } 112 cananian 1.1.2.1 else { 113 cananian 1.1.2.1 //The source isn't in the map 114 cananian 1.1.2.1 //Create a new backwards entry for it 115 cananian 1.1.2.1 if (backward.containsKey(sigma.src(i))) { 116 cananian 1.1.2.1 backset=(WorkSet)backward.get(sigma.src(i)); 117 cananian 1.1.2.1 } 118 cananian 1.1.2.1 else { 119 cananian 1.1.2.1 backset=new WorkSet(); 120 cananian 1.1.2.1 121 cananian 1.1.2.1 //Push this entry in the backwards map 122 cananian 1.1.2.1 backward.put(sigma.src(i), backset); 123 cananian 1.1.2.1 } 124 cananian 1.1.2.1 125 cananian 1.1.2.1 //Set the source up for the destinations of the sigmas 126 cananian 1.1.2.1 tmpsrc=sigma.src(i); 127 cananian 1.1.2.1 } 128 cananian 1.1.2.1 for (int j=0;j<splitting;j++) { 129 cananian 1.1.2.1 //src(i)--><dst(i,0),dst(i,1)...dst(i,splitting)> 130 cananian 1.1.2.1 131 cananian 1.1.2.1 //Put us in the forward map 132 cananian 1.1.2.1 forward.put((Temp)sigma.dst(i,j),tmpsrc); 133 cananian 1.1.2.1 134 cananian 1.1.2.1 //Add us to the set of things referencing tmpsrc 135 cananian 1.1.2.1 backset.push((Temp)sigma.dst(i,j)); 136 cananian 1.1.2.1 137 cananian 1.1.2.1 //look for nodes referencing us 138 cananian 1.1.2.1 WorkSet back=(WorkSet)backward.get(sigma.dst(i,j)); 139 cananian 1.1.2.1 140 cananian 1.1.2.1 if (back!=null) { 141 cananian 1.1.2.1 //get rid of our backward reference set 142 cananian 1.1.2.1 backward.remove(sigma.dst(i,j)); 143 cananian 1.1.2.1 144 cananian 1.1.2.1 //Iterate through temps referencing us 145 cananian 1.4 for (Object tO : back) { 146 cananian 1.4 Temp t = (Temp) tO; 147 cananian 1.1.2.1 148 cananian 1.1.2.1 //Fix their forward map 149 cananian 1.1.2.1 forward.put(t,tmpsrc); 150 cananian 1.1.2.1 //Add them to the set referencing tmpsrc 151 cananian 1.1.2.1 backset.push(t); 152 cananian 1.1.2.1 } 153 cananian 1.1.2.1 } 154 cananian 1.1.2.1 } 155 cananian 1.1.2.1 } 156 cananian 1.1.2.1 } 157 cananian 1.1.2.1 } 158 cananian 1.1.2.1 159 cananian 1.1.2.1 void addPhis() { 160 cananian 1.1.2.1 boolean dirty=true; 161 cananian 1.1.2.1 //Iterate through the phi's until we stop 162 cananian 1.1.2.1 //adding phi's into our maps 163 cananian 1.1.2.1 while (dirty) { 164 cananian 1.1.2.1 dirty=false; 165 cananian 1.1.2.1 166 cananian 1.1.2.1 167 cananian 1.1.2.1 Iterator iterate = phis.iterator(); 168 cananian 1.1.2.1 while (iterate.hasNext()) { 169 cananian 1.1.2.1 //Put the next phi in a variable 170 cananian 1.1.2.1 InternalPhi nxtPhi=(InternalPhi)iterate.next(); 171 cananian 1.1.2.1 172 cananian 1.1.2.1 //Phi's with only one unique definition 173 cananian 1.1.2.1 //Can be eliminated 174 cananian 1.1.2.1 Temp uniquedef=null; 175 cananian 1.1.2.1 176 cananian 1.1.2.1 //Set flag that keeps track of whether we can 177 cananian 1.1.2.1 //put this phi in our mapping 178 cananian 1.1.2.1 boolean good=true; 179 cananian 1.1.2.1 180 cananian 1.1.2.1 //Set this boolean to flag if 181 cananian 1.1.2.1 //we have a definition from outside 182 cananian 1.1.2.1 //the set {phi destinations, sigma destinations} 183 cananian 1.1.2.1 184 cananian 1.1.2.1 boolean outsidedef=false; 185 cananian 1.1.2.1 186 cananian 1.1.2.1 //Loop through each phi src arguement 187 cananian 1.1.2.1 188 cananian 1.1.2.1 for (int i=0;i<nxtPhi.src.length;i++) { 189 cananian 1.1.2.1 190 cananian 1.1.2.1 //Possible Conditions: 191 cananian 1.1.2.1 //1) All sources are either the destination of the Phi 192 cananian 1.1.2.1 //or one unique Temp 193 cananian 1.1.2.1 //Then add this phi to our mapping 194 cananian 1.1.2.1 // 195 cananian 1.1.2.1 //2) One source is not in the set {phi destinations, 196 cananian 1.1.2.1 //sigma sources, sigma destinations} 197 cananian 1.1.2.1 // 198 cananian 1.1.2.1 // 199 cananian 1.1.2.1 //3) Two sources are not in the set 200 cananian 1.1.2.1 //{phi destination, sigma destinations} 201 cananian 1.1.2.1 //Useless phi, toss it! 202 cananian 1.1.2.1 203 cananian 1.1.2.1 if (forward.containsKey(nxtPhi.src[i])) { 204 cananian 1.1.2.1 //This phi is in our forward mapping already 205 cananian 1.1.2.1 Temp tmp=(Temp)forward.get(nxtPhi.src[i]); 206 cananian 1.1.2.1 207 cananian 1.1.2.1 //Check to see if this references our destination 208 cananian 1.1.2.1 //if so just ignore it 209 cananian 1.1.2.1 if (tmp!=nxtPhi.dst) { 210 cananian 1.1.2.1 //If not, we need to see if we already have found an unique reference 211 cananian 1.1.2.1 if (uniquedef==null) 212 cananian 1.1.2.1 //if not, set Temp to this reference 213 cananian 1.1.2.1 uniquedef=tmp; 214 cananian 1.1.2.1 else { 215 cananian 1.1.2.1 //If we have found one already, see if they are the same one 216 cananian 1.1.2.1 if (uniquedef!=tmp) { 217 cananian 1.1.2.1 //Nope... Set flag, and break out of here 218 cananian 1.1.2.1 good=false; 219 cananian 1.1.2.1 break; 220 cananian 1.1.2.1 } 221 cananian 1.1.2.1 } 222 cananian 1.1.2.1 } 223 cananian 1.1.2.1 } else { 224 cananian 1.1.2.1 if (!phiresults.contains(nxtPhi.src[i])) { 225 cananian 1.1.2.1 //Approach here is to get useless nodes out of our list to speed up iterations 226 cananian 1.1.2.1 227 cananian 1.1.2.1 if (outsidedef) { 228 cananian 1.1.2.1 //If we already have a unique outside definition, trash this one 229 cananian 1.1.2.1 if(uniquedef!=nxtPhi.src[i]) { 230 cananian 1.1.2.1 phiresults.remove(nxtPhi.dst); 231 cananian 1.1.2.1 good=false; 232 cananian 1.1.2.1 iterate.remove(); 233 cananian 1.1.2.1 break; 234 cananian 1.1.2.1 } 235 cananian 1.1.2.1 } else { 236 cananian 1.1.2.1 //Make this out unique definition 237 cananian 1.1.2.1 outsidedef=true; 238 cananian 1.1.2.1 239 cananian 1.1.2.1 if (uniquedef==null) 240 cananian 1.1.2.1 //Good we don't have a def yet 241 cananian 1.1.2.1 uniquedef=nxtPhi.src[i]; 242 cananian 1.1.2.1 else { 243 cananian 1.1.2.1 //we already have one, is it the same? 244 cananian 1.1.2.1 if (uniquedef!=nxtPhi.src[i]) { 245 cananian 1.1.2.1 //nope...toss it back to the pool 246 cananian 1.1.2.1 good=false; 247 cananian 1.1.2.1 break; 248 cananian 1.1.2.1 } 249 cananian 1.1.2.1 } 250 cananian 1.1.2.1 } 251 cananian 1.1.2.1 } else { 252 cananian 1.1.2.1 //This one has a src that is in the Phi pool 253 cananian 1.1.2.1 if (nxtPhi.src[i]!=nxtPhi.dst) { 254 cananian 1.1.2.1 //Make sure it isn't ourself 255 cananian 1.1.2.1 if (uniquedef==null) 256 cananian 1.1.2.1 //Store a uniquedef 257 cananian 1.1.2.1 uniquedef=nxtPhi.src[i]; 258 cananian 1.1.2.1 else { 259 cananian 1.1.2.1 //We have a uniquedef, see if they are the same 260 cananian 1.1.2.1 if (uniquedef!=nxtPhi.src[i]) { 261 cananian 1.1.2.1 //Toss it back into the pool for the next iteration 262 cananian 1.1.2.1 good=false; 263 cananian 1.1.2.1 break; 264 cananian 1.1.2.1 } 265 cananian 1.1.2.1 } 266 cananian 1.1.2.1 } 267 cananian 1.1.2.1 } 268 cananian 1.1.2.1 } 269 cananian 1.1.2.1 } 270 cananian 1.1.2.1 if (good) { 271 cananian 1.1.2.1 //Set the dirty flag to true for another pass 272 cananian 1.1.2.1 dirty=true; 273 cananian 1.1.2.1 274 cananian 1.1.2.1 phiresults.remove(nxtPhi.dst); 275 cananian 1.1.2.1 276 cananian 1.1.2.1 //Get rid of this phi in the phi WorkSet 277 cananian 1.1.2.1 iterate.remove(); 278 cananian 1.1.2.1 279 cananian 1.1.2.1 //Need to look for references looking at our destination 280 cananian 1.1.2.1 if (backward.containsKey(nxtPhi.dst)) { 281 cananian 1.1.2.1 //Fix each of them 282 cananian 1.1.2.1 WorkSet tmp=(WorkSet)backward.get(nxtPhi.dst); 283 cananian 1.1.2.1 Iterator iterat=tmp.iterator(); 284 cananian 1.1.2.1 Temp dest; 285 cananian 1.1.2.1 //Correct the forward references 286 cananian 1.1.2.1 while(iterat.hasNext()) { 287 cananian 1.1.2.1 forward.put(iterat.next(),uniquedef); 288 cananian 1.1.2.1 } 289 cananian 1.1.2.1 290 cananian 1.1.2.1 //Make a new super set of people looking at uniquedef 291 cananian 1.1.2.1 WorkSet tmp2; 292 cananian 1.1.2.1 if (backward.containsKey(uniquedef)) 293 cananian 1.1.2.1 tmp2=(WorkSet)backward.get(uniquedef); 294 cananian 1.1.2.1 else 295 cananian 1.1.2.1 tmp2=new WorkSet(); 296 cananian 1.1.2.1 297 cananian 1.1.2.1 //Add the set of people looking at us to this new set 298 cananian 1.1.2.1 iterat=tmp.iterator(); 299 cananian 1.1.2.1 while(iterat.hasNext()) { 300 cananian 1.1.2.1 tmp2.push((Temp)iterat.next()); 301 cananian 1.1.2.1 } 302 cananian 1.1.2.1 303 cananian 1.1.2.1 //Add us into the set 304 cananian 1.1.2.1 tmp2.push(nxtPhi.dst); 305 cananian 1.1.2.1 //Hand off the new set 306 cananian 1.1.2.1 backward.put(uniquedef,tmp2); 307 cananian 1.1.2.1 //No one is referencing us anymore....tell the backward list 308 cananian 1.1.2.1 backward.remove(nxtPhi.dst); 309 cananian 1.1.2.1 //Add out forward link 310 cananian 1.1.2.1 forward.put(nxtPhi.dst, uniquedef); 311 cananian 1.1.2.1 } else { 312 cananian 1.1.2.1 //Just add us... 313 cananian 1.1.2.1 forward.put(nxtPhi.dst,uniquedef); 314 cananian 1.1.2.1 if (backward.containsKey(uniquedef)) { 315 cananian 1.1.2.1 //Set of references to uniquedef exist, add us 316 cananian 1.1.2.1 ((WorkSet)backward.get(uniquedef)).push(nxtPhi.dst); 317 cananian 1.1.2.1 } else { 318 cananian 1.1.2.1 //No set exist, create on with us in it... 319 cananian 1.1.2.1 WorkSet us=new WorkSet(); 320 cananian 1.1.2.1 us.push(nxtPhi.dst); 321 cananian 1.1.2.1 backward.put(uniquedef,us); 322 cananian 1.1.2.1 } 323 cananian 1.1.2.1 } 324 cananian 1.1.2.1 } 325 cananian 1.1.2.1 } 326 cananian 1.1.2.1 } 327 cananian 1.1.2.1 } 328 cananian 1.1.2.1 329 cananian 1.1.2.1 void findSigmaPhis() { 330 cananian 1.1.2.1 LowQuadVisitor visitor = new LowQuadVisitor(false/*non-strict*/) { 331 cananian 1.1.2.1 public void visit(Quad q) { 332 cananian 1.1.2.1 } 333 cananian 1.1.2.1 334 cananian 1.1.2.1 public void visit(SIGMA q) { 335 cananian 1.1.2.1 sigmas.push(q); 336 cananian 1.1.2.1 } 337 cananian 1.1.2.1 338 cananian 1.1.2.1 public void visit(PHI q) { 339 cananian 1.1.2.1 //create list of phi temps 340 cananian 1.1.2.1 int numberofphis=q.numPhis(); 341 cananian 1.1.2.1 for (int i=0;i<numberofphis;i++) { 342 cananian 1.1.2.1 phiresults.push(q.dst(i)); 343 cananian 1.1.2.1 phis.push(new InternalPhi(q.src(i),q.dst(i))); 344 cananian 1.1.2.1 } 345 cananian 1.1.2.1 } 346 cananian 1.1.2.1 }; 347 cananian 1.1.2.1 348 cananian 1.1.2.1 Iterator iterate=hc.getElementsI(); 349 cananian 1.1.2.1 while (iterate.hasNext()) { 350 cananian 1.1.2.1 Quad thisone=(Quad) iterate.next(); 351 cananian 1.1.2.1 thisone.accept(visitor); 352 cananian 1.1.2.1 } 353 cananian 1.1.2.1 } 354 cananian 1.1.2.1 355 cananian 1.1.2.1 public Temp tempMap(Temp t) { 356 cananian 1.1.2.1 if (forward.containsKey(t)) 357 cananian 1.1.2.1 return ((Temp)forward.get(t)); 358 cananian 1.1.2.1 else 359 cananian 1.1.2.1 return t; 360 cananian 1.1.2.1 } 361 cananian 1.1.2.1 362 cananian 1.1.2.1 private class InternalPhi { 363 cananian 1.1.2.1 public Temp [] src; 364 cananian 1.1.2.1 public Temp dst; 365 cananian 1.1.2.1 InternalPhi (Temp [] src, Temp dst) { 366 cananian 1.1.2.1 this.src=src; 367 cananian 1.1.2.1 this.dst=dst; 368 cananian 1.1.2.1 } 369 cananian 1.1.2.1 } 370 cananian 1.1.2.1 371 cananian 1.1.2.1 HCode hc; 372 cananian 1.1.2.1 HashMap forward; 373 cananian 1.1.2.1 HashMap backward; 374 cananian 1.1.2.1 WorkSet sigmas; 375 cananian 1.1.2.1 WorkSet phis; 376 cananian 1.1.2.1 WorkSet phiresults; 377 cananian 1.1.2.1 } 378 cananian 1.1.2.1 379 cananian 1.1.2.1 380 cananian 1.2