1 bdemsky 1.1.2.1 // AllInductions.java, created Mon Jun 28 13:40:31 1999 by bdemsky 2 bdemsky 1.1.2.1 // Copyright (C) 1999 Brian Demsky <bdemsky@mit.edu> 3 bdemsky 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 bdemsky 1.1.2.1 package harpoon.Analysis.LowQuad.Loop; 5 bdemsky 1.1.2.1 6 cananian 1.1.2.11 import harpoon.Analysis.Loops.Loops; 7 cananian 1.5 import net.cscott.jutil.WorkSet; 8 bdemsky 1.1.2.1 import harpoon.Analysis.UseDef; 9 cananian 1.1.2.11 import harpoon.ClassFile.HCode; 10 cananian 1.1.2.11 import harpoon.IR.LowQuad.LQop; 11 cananian 1.1.2.11 import harpoon.IR.LowQuad.LowQuadVisitor; 12 cananian 1.1.2.11 import harpoon.IR.LowQuad.PAOFFSET; 13 cananian 1.1.2.11 import harpoon.IR.LowQuad.POPER; 14 cananian 1.1.2.10 import harpoon.IR.Properties.CFGraphable; 15 cananian 1.1.2.11 import harpoon.IR.Quads.AGET; 16 cananian 1.1.2.11 import harpoon.IR.Quads.ASET; 17 cananian 1.1.2.11 import harpoon.IR.Quads.CONST; 18 cananian 1.1.2.11 import harpoon.IR.Quads.GET; 19 cananian 1.1.2.11 import harpoon.IR.Quads.HANDLER; 20 cananian 1.1.2.11 import harpoon.IR.Quads.OPER; 21 cananian 1.1.2.11 import harpoon.IR.Quads.Qop; 22 cananian 1.1.2.11 import harpoon.IR.Quads.Quad; 23 cananian 1.1.2.11 import harpoon.IR.Quads.SET; 24 bdemsky 1.1.2.1 import harpoon.Temp.Temp; 25 bdemsky 1.1.2.1 import harpoon.Temp.TempMap; 26 bdemsky 1.1.2.1 import harpoon.Util.Util; 27 bdemsky 1.1.2.1 28 bdemsky 1.1.2.1 import java.util.HashMap; 29 bdemsky 1.1.2.1 import java.util.Iterator; 30 bdemsky 1.1.2.1 31 bdemsky 1.1.2.1 /** 32 bdemsky 1.1.2.1 * <code>AllInductions</code> 33 bdemsky 1.1.2.1 * 34 bdemsky 1.1.2.1 * @author Brian Demsky <bdemsky@mit.edu> 35 cananian 1.5 * @version $Id: AllInductions.java,v 1.5 2004/02/08 01:52:53 cananian Exp $ 36 bdemsky 1.1.2.1 */ 37 bdemsky 1.1.2.1 public class AllInductions { 38 bdemsky 1.1.2.1 TempMap tm; 39 bdemsky 1.1.2.1 HCode hc; 40 bdemsky 1.1.2.1 41 bdemsky 1.1.2.3 /** Creates a <code>AllInductions</code> object. */ 42 bdemsky 1.1.2.1 public AllInductions(TempMap tm, HCode hc) { 43 bdemsky 1.1.2.1 this.tm=tm; 44 bdemsky 1.1.2.1 this.hc=hc; 45 bdemsky 1.1.2.1 } 46 bdemsky 1.1.2.1 47 bdemsky 1.1.2.2 /** Returns a Hashmap mapping induction <code>Temp</code>s 48 bdemsky 1.1.2.2 * to <code>Induction</code> objects containing information 49 bdemsky 1.1.2.2 * on their derivation.*/ 50 bdemsky 1.1.2.2 51 bdemsky 1.1.2.3 public HashMap doAllInductions(Loops lp, WorkSet invariants, HashMap basicinductions) { 52 bdemsky 1.1.2.1 HashMap allInductions=new HashMap(basicinductions); 53 bdemsky 1.1.2.1 CompleteVisitor visitor=new CompleteVisitor(allInductions,invariants); 54 cananian 1.1.2.14 WorkSet elements=new WorkSet(lp.loopIncElements()); 55 bdemsky 1.1.2.1 // Want to look for patterns like: 56 bdemsky 1.1.2.1 /* k=j*b, k=j+-b, k=b+-j */ 57 bdemsky 1.1.2.1 // Use the representation: 58 bdemsky 1.1.2.1 // (i*a+b)*pa+pb-->i*(a+pa)+(b*pa+pb) 59 bdemsky 1.1.2.1 boolean change=true; 60 bdemsky 1.1.2.1 while (change) { 61 bdemsky 1.1.2.1 change=false; 62 bdemsky 1.1.2.1 Iterator iterate=elements.iterator(); 63 bdemsky 1.1.2.1 while (iterate.hasNext()) { 64 bdemsky 1.1.2.1 Quad element=(Quad)iterate.next(); 65 cananian 1.1.2.6 element.accept(visitor); 66 bdemsky 1.1.2.1 if (visitor.change()) { 67 bdemsky 1.1.2.1 change=true; 68 bdemsky 1.1.2.1 iterate.remove(); 69 bdemsky 1.1.2.1 } 70 bdemsky 1.1.2.1 } 71 bdemsky 1.1.2.1 } 72 bdemsky 1.1.2.1 return allInductions; 73 bdemsky 1.1.2.1 } 74 bdemsky 1.1.2.1 75 bdemsky 1.1.2.1 76 bdemsky 1.1.2.2 /** CompleteVisitor extends <code>LowQuadVisitor</code> 77 bdemsky 1.1.2.2 * and is used to find derived induction variables. */ 78 bdemsky 1.1.2.2 79 bdemsky 1.1.2.1 class CompleteVisitor extends LowQuadVisitor { 80 bdemsky 1.1.2.1 HashMap inductions; 81 bdemsky 1.1.2.1 WorkSet invariants; 82 bdemsky 1.1.2.1 boolean changed; 83 bdemsky 1.1.2.1 UseDef ud; 84 bdemsky 1.1.2.1 85 bdemsky 1.1.2.1 CompleteVisitor(HashMap inductions,WorkSet invariants) { 86 cananian 1.1.2.12 super(false/*non-strict*/); 87 bdemsky 1.1.2.1 changed=false; 88 bdemsky 1.1.2.1 this.inductions=inductions; 89 bdemsky 1.1.2.1 this.invariants=invariants; 90 bdemsky 1.1.2.1 ud=new UseDef(); 91 bdemsky 1.1.2.1 } 92 bdemsky 1.1.2.1 93 bdemsky 1.1.2.1 public boolean change() { 94 bdemsky 1.1.2.1 return changed; 95 bdemsky 1.1.2.1 } 96 bdemsky 1.1.2.1 97 bdemsky 1.1.2.1 public void visit(Quad q) { 98 bdemsky 1.1.2.1 //Do nothing 99 bdemsky 1.1.2.1 } 100 bdemsky 1.1.2.7 101 bdemsky 1.1.2.1 public void visit(OPER q) { 102 bdemsky 1.1.2.7 switch (q.opcode()) { 103 bdemsky 1.1.2.7 case Qop.IADD: 104 bdemsky 1.1.2.7 //Binary operators 105 bdemsky 1.1.2.7 InstanceofCONSTVisitor visitor=new InstanceofCONSTVisitor(); 106 bdemsky 1.1.2.9 boolean good=true; 107 bdemsky 1.1.2.9 int invar=0; 108 bdemsky 1.1.2.9 int index=0; 109 bdemsky 1.1.2.7 for (int i=0;i<q.operandsLength();i++) { 110 bdemsky 1.1.2.7 Temp t=tm.tempMap(q.operands(i)); 111 bdemsky 1.1.2.7 if (inductions.containsKey(t)) { 112 bdemsky 1.1.2.7 index=i; 113 bdemsky 1.1.2.7 invar++; 114 bdemsky 1.1.2.7 } 115 bdemsky 1.1.2.7 else 116 bdemsky 1.1.2.7 if (!invariants.contains(ud.defMap(hc,t)[0])) { 117 bdemsky 1.1.2.7 good=false; 118 bdemsky 1.1.2.7 break; 119 bdemsky 1.1.2.7 } 120 bdemsky 1.1.2.7 } 121 bdemsky 1.1.2.7 //Need one induction variable and constants 122 bdemsky 1.1.2.7 if ((invar==1)&&(good)) { 123 bdemsky 1.1.2.7 changed=true; 124 bdemsky 1.1.2.7 //***************** 125 bdemsky 1.1.2.7 Induction tmp=new Induction((Induction)inductions.get(tm.tempMap(q.operands(index)))); 126 bdemsky 1.1.2.7 for (int i=0;i<q.operandsLength();i++) 127 bdemsky 1.1.2.7 if (i!=index) { 128 bdemsky 1.1.2.7 Temp t=tm.tempMap(q.operands(i)); 129 bdemsky 1.1.2.7 visitor.reset(); 130 bdemsky 1.1.2.7 ((Quad)ud.defMap(hc,t)[0]).accept(visitor); 131 bdemsky 1.1.2.7 if (visitor.resetstatus()) 132 bdemsky 1.1.2.7 tmp=tmp.add 133 bdemsky 1.1.2.7 (((Integer)(((CONST)ud.defMap(hc,t)[0]).value())).intValue()); 134 bdemsky 1.1.2.7 else 135 bdemsky 1.1.2.7 tmp=tmp.add(tm.tempMap(q.operands(i))); 136 bdemsky 1.1.2.7 } 137 bdemsky 1.1.2.7 inductions.put(q.dst(),tmp); 138 bdemsky 1.1.2.7 } else 139 bdemsky 1.1.2.7 changed=false; 140 bdemsky 1.1.2.7 break; 141 bdemsky 1.1.2.7 142 bdemsky 1.1.2.7 143 bdemsky 1.1.2.7 144 bdemsky 1.1.2.7 case Qop.IMUL: 145 bdemsky 1.1.2.7 //Binary operators 146 bdemsky 1.1.2.7 visitor=new InstanceofCONSTVisitor(); 147 bdemsky 1.1.2.7 good=true; 148 bdemsky 1.1.2.7 invar=0; 149 bdemsky 1.1.2.7 index=0; 150 bdemsky 1.1.2.7 for (int i=0;i<q.operandsLength();i++) { 151 bdemsky 1.1.2.7 Temp t=tm.tempMap(q.operands(i)); 152 bdemsky 1.1.2.7 if (inductions.containsKey(t)) { 153 bdemsky 1.1.2.7 index=i; 154 bdemsky 1.1.2.7 invar++; 155 bdemsky 1.1.2.7 } 156 bdemsky 1.1.2.7 else 157 bdemsky 1.1.2.7 if (!invariants.contains(ud.defMap(hc,t)[0])) { 158 bdemsky 1.1.2.7 good=false; 159 bdemsky 1.1.2.7 break; 160 bdemsky 1.1.2.7 } 161 bdemsky 1.1.2.7 } 162 bdemsky 1.1.2.7 //Need one induction variable and constants 163 bdemsky 1.1.2.7 if ((invar==1)&&(good)) { 164 bdemsky 1.1.2.7 changed=true; 165 bdemsky 1.1.2.7 //***************** 166 bdemsky 1.1.2.7 Induction tmp=new Induction((Induction)inductions.get(tm.tempMap(q.operands(index)))); 167 bdemsky 1.1.2.7 for (int i=0;i<q.operandsLength();i++) 168 bdemsky 1.1.2.7 if (i!=index) { 169 bdemsky 1.1.2.7 Temp t=tm.tempMap(q.operands(i)); 170 bdemsky 1.1.2.7 visitor.reset(); 171 bdemsky 1.1.2.7 ((Quad)ud.defMap(hc,t)[0]).accept(visitor); 172 bdemsky 1.1.2.7 if (visitor.resetstatus()) 173 bdemsky 1.1.2.7 tmp=tmp.multiply( 174 bdemsky 1.1.2.7 ((Integer)((CONST)ud.defMap(hc,t)[0]).value()).intValue()); 175 bdemsky 1.1.2.7 else 176 bdemsky 1.1.2.7 tmp=tmp.multiply(tm.tempMap(q.operands(i))); 177 bdemsky 1.1.2.7 } 178 bdemsky 1.1.2.7 inductions.put(q.dst(),tmp); 179 bdemsky 1.1.2.7 } else 180 bdemsky 1.1.2.7 changed=false; 181 bdemsky 1.1.2.7 break; 182 bdemsky 1.1.2.7 183 bdemsky 1.1.2.7 case Qop.INEG: 184 bdemsky 1.1.2.7 //Unary operators 185 bdemsky 1.1.2.7 186 bdemsky 1.1.2.7 if (inductions.containsKey(tm.tempMap(q.operands(0)))) { 187 bdemsky 1.1.2.7 changed=true; 188 bdemsky 1.1.2.7 //**************** 189 bdemsky 1.1.2.7 Induction tmp=((Induction)inductions.get(tm.tempMap(q.operands(0)))).negate(); 190 bdemsky 1.1.2.7 inductions.put(q.dst(),tmp); 191 bdemsky 1.1.2.7 } else 192 bdemsky 1.1.2.7 changed=false; 193 bdemsky 1.1.2.7 break; 194 bdemsky 1.1.2.7 default: 195 bdemsky 1.1.2.7 } 196 bdemsky 1.1.2.1 } 197 bdemsky 1.1.2.7 198 bdemsky 1.1.2.1 199 bdemsky 1.1.2.1 public void visit(PAOFFSET q) { 200 bdemsky 1.1.2.1 //Find if induction variable 201 bdemsky 1.1.2.1 if (inductions.containsKey(tm.tempMap(q.index()))) { 202 bdemsky 1.1.2.1 changed=true; 203 bdemsky 1.1.2.1 204 bdemsky 1.1.2.1 Induction tmp=(Induction)inductions.get(tm.tempMap(q.index())); 205 cananian 1.3.2.1 assert tmp.pointerindex==false; 206 bdemsky 1.1.2.1 207 bdemsky 1.1.2.1 //********* 208 bdemsky 1.1.2.4 inductions.put(q.dst(), new Induction(tmp,q.arrayType())); 209 bdemsky 1.1.2.1 210 bdemsky 1.1.2.1 } else 211 bdemsky 1.1.2.1 changed=false; 212 bdemsky 1.1.2.1 } 213 bdemsky 1.1.2.1 214 bdemsky 1.1.2.1 public void visit(POPER q) { 215 bdemsky 1.1.2.1 switch (q.opcode()) { 216 bdemsky 1.1.2.1 case LQop.PADD: 217 bdemsky 1.1.2.1 //Binary operators 218 bdemsky 1.1.2.1 int invar=0; 219 bdemsky 1.1.2.1 int index=0; 220 bdemsky 1.1.2.1 boolean good=true; 221 bdemsky 1.1.2.1 for (int i=0;i<q.operandsLength();i++) { 222 bdemsky 1.1.2.1 Temp t=tm.tempMap(q.operands(i)); 223 bdemsky 1.1.2.1 if (inductions.containsKey(t)) { 224 bdemsky 1.1.2.1 index=i; 225 bdemsky 1.1.2.1 invar++; 226 bdemsky 1.1.2.1 } 227 bdemsky 1.1.2.1 else 228 bdemsky 1.1.2.1 if (!invariants.contains(ud.defMap(hc,t)[0])) { 229 bdemsky 1.1.2.1 good=false; 230 bdemsky 1.1.2.1 break; 231 bdemsky 1.1.2.1 } 232 bdemsky 1.1.2.1 } 233 bdemsky 1.1.2.1 //Need one induction variable and invariants 234 bdemsky 1.1.2.1 if ((invar==1)&&(good)) { 235 bdemsky 1.1.2.1 changed=true; 236 bdemsky 1.1.2.1 //***************** 237 bdemsky 1.1.2.1 Induction tmp=new Induction((Induction)inductions.get(tm.tempMap(q.operands(index)))); 238 bdemsky 1.1.2.1 for (int i=0;i<q.operandsLength();i++) { 239 bdemsky 1.1.2.1 if (i!=index) 240 bdemsky 1.1.2.4 tmp.padd(tm.tempMap(q.operands(i))); 241 bdemsky 1.1.2.1 } 242 bdemsky 1.1.2.1 inductions.put(q.dst(),tmp); 243 bdemsky 1.1.2.1 } else 244 bdemsky 1.1.2.1 changed=false; 245 bdemsky 1.1.2.1 break; 246 bdemsky 1.1.2.1 247 bdemsky 1.1.2.1 248 bdemsky 1.1.2.1 case Qop.IADD: 249 bdemsky 1.1.2.1 //Binary operators 250 bdemsky 1.1.2.1 InstanceofCONSTVisitor visitor=new InstanceofCONSTVisitor(); 251 bdemsky 1.1.2.5 good=true; 252 bdemsky 1.1.2.1 invar=0; 253 bdemsky 1.1.2.1 index=0; 254 bdemsky 1.1.2.1 for (int i=0;i<q.operandsLength();i++) { 255 bdemsky 1.1.2.1 Temp t=tm.tempMap(q.operands(i)); 256 bdemsky 1.1.2.1 if (inductions.containsKey(t)) { 257 bdemsky 1.1.2.1 index=i; 258 bdemsky 1.1.2.1 invar++; 259 bdemsky 1.1.2.1 } 260 bdemsky 1.1.2.5 else 261 bdemsky 1.1.2.5 if (!invariants.contains(ud.defMap(hc,t)[0])) { 262 bdemsky 1.1.2.5 good=false; 263 bdemsky 1.1.2.5 break; 264 bdemsky 1.1.2.5 } 265 bdemsky 1.1.2.1 } 266 bdemsky 1.1.2.1 //Need one induction variable and constants 267 bdemsky 1.1.2.5 if ((invar==1)&&(good)) { 268 bdemsky 1.1.2.1 changed=true; 269 bdemsky 1.1.2.1 //***************** 270 bdemsky 1.1.2.1 Induction tmp=new Induction((Induction)inductions.get(tm.tempMap(q.operands(index)))); 271 bdemsky 1.1.2.1 for (int i=0;i<q.operandsLength();i++) 272 bdemsky 1.1.2.4 if (i!=index) { 273 bdemsky 1.1.2.4 Temp t=tm.tempMap(q.operands(i)); 274 bdemsky 1.1.2.4 visitor.reset(); 275 cananian 1.1.2.6 ((Quad)ud.defMap(hc,t)[0]).accept(visitor); 276 bdemsky 1.1.2.4 if (visitor.resetstatus()) 277 bdemsky 1.1.2.4 tmp=tmp.add 278 bdemsky 1.1.2.4 (((Integer)(((CONST)ud.defMap(hc,t)[0]).value())).intValue()); 279 bdemsky 1.1.2.4 else 280 bdemsky 1.1.2.4 tmp=tmp.add(tm.tempMap(q.operands(i))); 281 bdemsky 1.1.2.4 } 282 bdemsky 1.1.2.1 inductions.put(q.dst(),tmp); 283 bdemsky 1.1.2.1 } else 284 bdemsky 1.1.2.1 changed=false; 285 bdemsky 1.1.2.1 break; 286 bdemsky 1.1.2.1 287 bdemsky 1.1.2.1 288 bdemsky 1.1.2.1 289 bdemsky 1.1.2.1 case Qop.IMUL: 290 bdemsky 1.1.2.1 //Binary operators 291 bdemsky 1.1.2.1 visitor=new InstanceofCONSTVisitor(); 292 bdemsky 1.1.2.5 good=true; 293 bdemsky 1.1.2.1 invar=0; 294 bdemsky 1.1.2.1 index=0; 295 bdemsky 1.1.2.1 for (int i=0;i<q.operandsLength();i++) { 296 bdemsky 1.1.2.1 Temp t=tm.tempMap(q.operands(i)); 297 bdemsky 1.1.2.1 if (inductions.containsKey(t)) { 298 bdemsky 1.1.2.1 index=i; 299 bdemsky 1.1.2.1 invar++; 300 bdemsky 1.1.2.1 } 301 bdemsky 1.1.2.5 else 302 bdemsky 1.1.2.5 if (!invariants.contains(ud.defMap(hc,t)[0])) { 303 bdemsky 1.1.2.5 good=false; 304 bdemsky 1.1.2.5 break; 305 bdemsky 1.1.2.5 } 306 bdemsky 1.1.2.1 } 307 bdemsky 1.1.2.1 //Need one induction variable and constants 308 bdemsky 1.1.2.5 if ((invar==1)&&(good)) { 309 bdemsky 1.1.2.1 changed=true; 310 bdemsky 1.1.2.1 //***************** 311 bdemsky 1.1.2.1 Induction tmp=new Induction((Induction)inductions.get(tm.tempMap(q.operands(index)))); 312 bdemsky 1.1.2.1 for (int i=0;i<q.operandsLength();i++) 313 bdemsky 1.1.2.1 if (i!=index) { 314 bdemsky 1.1.2.4 Temp t=tm.tempMap(q.operands(i)); 315 bdemsky 1.1.2.4 visitor.reset(); 316 cananian 1.1.2.6 ((Quad)ud.defMap(hc,t)[0]).accept(visitor); 317 bdemsky 1.1.2.4 if (visitor.resetstatus()) 318 bdemsky 1.1.2.4 tmp=tmp.multiply( 319 bdemsky 1.1.2.4 ((Integer)((CONST)ud.defMap(hc,t)[0]).value()).intValue()); 320 bdemsky 1.1.2.4 else 321 bdemsky 1.1.2.4 tmp=tmp.multiply(tm.tempMap(q.operands(i))); 322 bdemsky 1.1.2.1 } 323 bdemsky 1.1.2.1 inductions.put(q.dst(),tmp); 324 bdemsky 1.1.2.1 } else 325 bdemsky 1.1.2.1 changed=false; 326 bdemsky 1.1.2.1 break; 327 bdemsky 1.1.2.1 328 bdemsky 1.1.2.1 case Qop.INEG: 329 bdemsky 1.1.2.1 case LQop.PNEG: 330 bdemsky 1.1.2.1 //Unary operators 331 bdemsky 1.1.2.1 332 bdemsky 1.1.2.1 if (inductions.containsKey(tm.tempMap(q.operands(0)))) { 333 bdemsky 1.1.2.1 changed=true; 334 bdemsky 1.1.2.1 //**************** 335 bdemsky 1.1.2.4 Induction tmp=((Induction)inductions.get(tm.tempMap(q.operands(0)))).negate(); 336 bdemsky 1.1.2.1 inductions.put(q.dst(),tmp); 337 bdemsky 1.1.2.1 } else 338 bdemsky 1.1.2.1 changed=false; 339 bdemsky 1.1.2.1 break; 340 bdemsky 1.1.2.1 default: 341 bdemsky 1.1.2.1 } 342 bdemsky 1.1.2.1 } 343 bdemsky 1.1.2.1 } 344 bdemsky 1.1.2.2 345 bdemsky 1.1.2.2 /** InstanceofCONSTVisitor allows <code>CompleteVisitor</code> to do its 346 bdemsky 1.1.2.2 * work without using an INSTANCEOF. */ 347 bdemsky 1.1.2.1 348 bdemsky 1.1.2.1 class InstanceofCONSTVisitor extends LowQuadVisitor { 349 bdemsky 1.1.2.1 boolean reset; 350 bdemsky 1.1.2.1 public InstanceofCONSTVisitor() { 351 bdemsky 1.1.2.1 reset=true; 352 bdemsky 1.1.2.1 } 353 bdemsky 1.1.2.1 354 bdemsky 1.1.2.1 public boolean resetstatus() { 355 bdemsky 1.1.2.1 return reset; 356 bdemsky 1.1.2.1 } 357 bdemsky 1.1.2.1 358 bdemsky 1.1.2.1 public void reset() { 359 bdemsky 1.1.2.1 reset=true; 360 bdemsky 1.1.2.1 } 361 bdemsky 1.1.2.1 362 bdemsky 1.1.2.1 public void visit(Quad q) { 363 bdemsky 1.1.2.1 reset=false; 364 bdemsky 1.1.2.1 } 365 bdemsky 1.1.2.1 366 bdemsky 1.1.2.1 public void visit(CONST q) { 367 bdemsky 1.1.2.1 } 368 bdemsky 1.1.2.1 } 369 cananian 1.2 }