1 bdemsky 1.1.2.1 // Induction.java, created Mon Jun 28 13:36:40 1999 by root 2 cananian 1.1.2.7 // 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 bdemsky 1.1.2.1 import harpoon.Temp.Temp; 7 bdemsky 1.1.2.1 import harpoon.ClassFile.HClass; 8 bdemsky 1.1.2.5 import harpoon.Util.Util; 9 bdemsky 1.1.2.1 10 bdemsky 1.1.2.1 import java.util.ArrayList; 11 bdemsky 1.1.2.5 import java.util.Iterator; 12 bdemsky 1.1.2.1 13 bdemsky 1.1.2.1 /** 14 bdemsky 1.1.2.1 * <code>Induction</code> 15 bdemsky 1.1.2.1 * 16 cananian 1.1.2.7 * @author Brian Demsky <bdemsky@mit.edu> 17 cananian 1.4 * @version $Id: Induction.java,v 1.4 2002/04/10 02:59:57 cananian Exp $ 18 bdemsky 1.1.2.3 * This class allows us to store information on Basic/Derived Induction variables. 19 bdemsky 1.1.2.1 */ 20 bdemsky 1.1.2.3 21 bdemsky 1.1.2.1 public class Induction { 22 bdemsky 1.1.2.1 23 bdemsky 1.1.2.1 /* Want to be able to store structures of the form: 24 bdemsky 1.1.2.1 pi+pb 25 bdemsky 1.1.2.1 or 26 bdemsky 1.1.2.1 (i*a+b) 27 bdemsky 1.1.2.1 or 28 bdemsky 1.1.2.1 (i*a+b)*pa+pb 29 bdemsky 1.1.2.1 */ 30 bdemsky 1.1.2.1 31 bdemsky 1.1.2.1 /* pi+pb */ 32 bdemsky 1.1.2.1 33 bdemsky 1.1.2.3 /** Creates basic pointer induction variable.*/ 34 bdemsky 1.1.2.5 Induction(Temp ptrvariable, ArrayList pointeroffset, boolean ptrsign) { 35 bdemsky 1.1.2.5 this.ptrvariable=ptrvariable; 36 bdemsky 1.1.2.1 this.pointeroffset=new ArrayList(pointeroffset); 37 bdemsky 1.1.2.5 this.integers=null; 38 bdemsky 1.1.2.1 this.objectsize=null; 39 bdemsky 1.1.2.5 this.ptrsign=ptrsign; 40 bdemsky 1.1.2.4 this.copied=false; 41 bdemsky 1.1.2.1 } 42 bdemsky 1.1.2.1 43 bdemsky 1.1.2.3 /* Creates basic integer induction variable.*/ 44 bdemsky 1.1.2.1 Induction(Temp variable, int offset, int intmultiplier) { 45 bdemsky 1.1.2.5 this.ptrvariable=null; 46 bdemsky 1.1.2.5 this.integers=new IntMultAdd(variable,intmultiplier,offset); 47 bdemsky 1.1.2.5 this.ptrsign=true; 48 bdemsky 1.1.2.1 this.objectsize=null; 49 bdemsky 1.1.2.1 this.pointeroffset=new ArrayList(); 50 bdemsky 1.1.2.4 this.copied=false; 51 bdemsky 1.1.2.1 } 52 bdemsky 1.1.2.1 53 bdemsky 1.1.2.5 54 bdemsky 1.1.2.5 /** Copy Constructor*/ 55 bdemsky 1.1.2.5 Induction(Induction x) { 56 bdemsky 1.1.2.5 this.ptrvariable=x.ptrvariable; 57 bdemsky 1.1.2.5 this.integers=new IntMultAdd(x.integers); 58 bdemsky 1.1.2.5 this.ptrsign=x.ptrsign; 59 bdemsky 1.1.2.5 this.objectsize=x.objectsize; 60 bdemsky 1.1.2.5 this.pointeroffset=new ArrayList(x.pointeroffset); 61 bdemsky 1.1.2.5 this.copied=false; 62 bdemsky 1.1.2.5 x.copied=true; 63 bdemsky 1.1.2.5 } 64 bdemsky 1.1.2.5 65 bdemsky 1.1.2.5 /** Copy Constructor*/ 66 bdemsky 1.1.2.5 Induction(Induction x, HClass objectsize) { 67 bdemsky 1.1.2.5 this.ptrvariable=x.ptrvariable; 68 bdemsky 1.1.2.5 this.integers=new IntMultAdd(x.integers); 69 bdemsky 1.1.2.5 this.ptrsign=x.ptrsign; 70 bdemsky 1.1.2.1 this.objectsize=objectsize; 71 bdemsky 1.1.2.5 this.pointeroffset=new ArrayList(x.pointeroffset); 72 bdemsky 1.1.2.5 this.copied=false; 73 bdemsky 1.1.2.5 x.copied=true; 74 bdemsky 1.1.2.5 } 75 bdemsky 1.1.2.5 76 bdemsky 1.1.2.5 /** Constant operator*/ 77 bdemsky 1.1.2.5 private Induction(Induction x, boolean operation, int operand) { 78 bdemsky 1.1.2.5 //bool 79 bdemsky 1.1.2.5 this.ptrvariable=x.ptrvariable; 80 bdemsky 1.1.2.5 this.integers=new IntMultAdd(x.integers); 81 bdemsky 1.1.2.5 this.ptrsign=x.ptrsign; 82 bdemsky 1.1.2.5 this.objectsize=x.objectsize; 83 bdemsky 1.1.2.5 this.pointeroffset=new ArrayList(x.pointeroffset); 84 bdemsky 1.1.2.4 this.copied=false; 85 bdemsky 1.1.2.5 x.copied=true; 86 bdemsky 1.1.2.5 if (operation) { 87 bdemsky 1.1.2.5 //Multiply 88 bdemsky 1.1.2.5 if (this.integers.loopinvariant()!=null) { 89 bdemsky 1.1.2.5 this.integers=new IntMultAdd(x.integers, operand,0); 90 bdemsky 1.1.2.5 } else 91 bdemsky 1.1.2.5 this.integers.multiply(operand); 92 bdemsky 1.1.2.5 } else { 93 bdemsky 1.1.2.5 //add 94 bdemsky 1.1.2.5 if (this.integers.loopinvariant()!=null) { 95 bdemsky 1.1.2.5 this.integers=new IntMultAdd(x.integers, 1, operand); 96 bdemsky 1.1.2.5 } else 97 bdemsky 1.1.2.5 this.integers.add(operand); 98 bdemsky 1.1.2.5 } 99 bdemsky 1.1.2.1 } 100 bdemsky 1.1.2.1 101 bdemsky 1.1.2.5 /** Loop invariant operator*/ 102 bdemsky 1.1.2.5 private Induction(Induction x, boolean operation, Temp operand) { 103 bdemsky 1.1.2.5 this.ptrvariable=x.ptrvariable; 104 bdemsky 1.1.2.5 this.integers=new IntMultAdd(x.integers); 105 bdemsky 1.1.2.5 this.ptrsign=x.ptrsign; 106 bdemsky 1.1.2.1 this.objectsize=x.objectsize; 107 bdemsky 1.1.2.1 this.pointeroffset=new ArrayList(x.pointeroffset); 108 bdemsky 1.1.2.4 this.copied=false; 109 bdemsky 1.1.2.4 x.copied=true; 110 bdemsky 1.1.2.5 if (this.integers.loopinvariant()!=null) { 111 bdemsky 1.1.2.5 this.integers=new IntMultAdd(x.integers, operand, operation); 112 bdemsky 1.1.2.5 } else { 113 bdemsky 1.1.2.5 this.integers.loopinvariant(operand); 114 bdemsky 1.1.2.5 this.integers.multiply(operation); 115 bdemsky 1.1.2.5 } 116 bdemsky 1.1.2.5 } 117 bdemsky 1.1.2.5 118 bdemsky 1.1.2.5 119 bdemsky 1.1.2.5 public Induction add(int operand) { 120 bdemsky 1.1.2.5 return new Induction(this, false, operand ); 121 bdemsky 1.1.2.5 } 122 bdemsky 1.1.2.5 123 bdemsky 1.1.2.5 public Induction multiply(int operand) { 124 bdemsky 1.1.2.5 return new Induction(this, true, operand); 125 bdemsky 1.1.2.5 } 126 bdemsky 1.1.2.5 127 bdemsky 1.1.2.5 public Induction add(Temp operand) { 128 bdemsky 1.1.2.5 return new Induction(this, false, operand); 129 bdemsky 1.1.2.5 } 130 bdemsky 1.1.2.5 131 bdemsky 1.1.2.5 public Induction multiply(Temp operand) { 132 bdemsky 1.1.2.5 return new Induction(this, true, operand); 133 bdemsky 1.1.2.5 } 134 bdemsky 1.1.2.5 135 bdemsky 1.1.2.5 public void padd(Temp operand) { 136 bdemsky 1.1.2.5 pointeroffset.add(new Object[] {operand, new Boolean(true)}); 137 bdemsky 1.1.2.5 } 138 bdemsky 1.1.2.5 139 bdemsky 1.1.2.5 public IntMultAdd bottom() { 140 bdemsky 1.1.2.5 return integers.bottom(); 141 bdemsky 1.1.2.5 } 142 bdemsky 1.1.2.5 143 bdemsky 1.1.2.5 public Induction negate() { 144 bdemsky 1.1.2.5 Induction temp=new Induction(this); 145 bdemsky 1.1.2.5 if (temp.ptrvariable!=null) 146 bdemsky 1.1.2.5 temp.ptrsign=(!temp.ptrsign); 147 bdemsky 1.1.2.5 else 148 bdemsky 1.1.2.5 temp.integers.negate(); 149 bdemsky 1.1.2.5 Iterator iterate=temp.pointeroffset.iterator(); 150 bdemsky 1.1.2.5 temp.pointeroffset=new ArrayList(); 151 bdemsky 1.1.2.5 while (iterate.hasNext()) { 152 bdemsky 1.1.2.5 Object[] ptr=(Object[])iterate.next(); 153 bdemsky 1.1.2.5 temp.pointeroffset.add(new Object[] {ptr[0], new Boolean(!((Boolean)ptr[1]).booleanValue())}); 154 bdemsky 1.1.2.5 } 155 bdemsky 1.1.2.5 return temp; 156 bdemsky 1.1.2.2 } 157 bdemsky 1.1.2.2 158 bdemsky 1.1.2.3 /** toString method returns string describing contents of the class.*/ 159 bdemsky 1.1.2.2 public String toString() { 160 bdemsky 1.1.2.2 String temp; 161 bdemsky 1.1.2.5 temp=" iv: "+variable().toString()+" offset: "; 162 bdemsky 1.1.2.6 if (constant()) 163 bdemsky 1.1.2.6 temp+=(new Integer(offset())).toString() +" intmultiplier: "+ 164 bdemsky 1.1.2.6 (new Integer(intmultiplier())).toString(); 165 bdemsky 1.1.2.2 if (objectsize!=null) 166 bdemsky 1.1.2.2 temp+=" os: "+objectsize.toString(); 167 bdemsky 1.1.2.2 if (pointeroffset!=null) 168 bdemsky 1.1.2.2 temp+=" poff: "+pointeroffset.toString(); 169 bdemsky 1.1.2.2 return temp; 170 bdemsky 1.1.2.1 } 171 bdemsky 1.1.2.1 172 bdemsky 1.1.2.5 173 bdemsky 1.1.2.3 /** The <code>pointerindex</code> <code>boolean</code> describes whether 174 bdemsky 1.1.2.5 * the Temp induction variable is a pointer [true] or an 175 bdemsky 1.1.2.5 * integer [false].*/ 176 bdemsky 1.1.2.1 public boolean pointerindex; 177 bdemsky 1.1.2.3 178 bdemsky 1.1.2.5 /** The <code>variable</code> <code>Temp</code> stores the basic 179 bdemsky 1.1.2.5 * induction variable.*/ 180 bdemsky 1.1.2.5 public Temp variable() { 181 bdemsky 1.1.2.5 IntMultAdd ptr=integers; 182 bdemsky 1.1.2.5 while (ptr.child()!=null) 183 bdemsky 1.1.2.5 ptr=ptr.child(); 184 bdemsky 1.1.2.5 return ptr.inductionvar(); 185 bdemsky 1.1.2.5 } 186 bdemsky 1.1.2.3 187 bdemsky 1.1.2.5 public boolean constant() { 188 bdemsky 1.1.2.5 return integers.constant(); 189 bdemsky 1.1.2.5 } 190 bdemsky 1.1.2.4 191 bdemsky 1.1.2.5 public int intmultiplier() { 192 cananian 1.3.2.1 assert this.constant(); 193 bdemsky 1.1.2.5 return integers.intmultiplier(); 194 bdemsky 1.1.2.5 } 195 bdemsky 1.1.2.4 196 bdemsky 1.1.2.5 public int offset() { 197 cananian 1.3.2.1 assert this.constant(); 198 bdemsky 1.1.2.5 return integers.offset(); 199 bdemsky 1.1.2.5 } 200 bdemsky 1.1.2.4 201 bdemsky 1.1.2.5 public int depth() { 202 bdemsky 1.1.2.5 if (integers!=null) 203 bdemsky 1.1.2.5 return integers.depth(); 204 bdemsky 1.1.2.5 else return 0; 205 bdemsky 1.1.2.5 } 206 bdemsky 1.1.2.4 207 bdemsky 1.1.2.5 /** The <code>intmultadd</code> int saves integer arithmetic.*/ 208 bdemsky 1.1.2.5 private IntMultAdd integers; 209 bdemsky 1.1.2.4 210 bdemsky 1.1.2.5 public Temp ptrvariable; 211 bdemsky 1.1.2.4 212 bdemsky 1.1.2.5 /** The <code>ptrsign</code> saves the relative sign. 213 bdemsky 1.1.2.5 * True being the same sign*/ 214 bdemsky 1.1.2.5 public boolean ptrsign; 215 bdemsky 1.1.2.4 216 bdemsky 1.1.2.4 217 bdemsky 1.1.2.5 /** The <code>objectsize</code> <code>HClass</code> 218 bdemsky 1.1.2.5 * saves the array type.*/ 219 bdemsky 1.1.2.5 public HClass objectsize; 220 bdemsky 1.1.2.4 221 bdemsky 1.1.2.4 222 bdemsky 1.1.2.5 /** The <code>ArrayList</code> saves pointer <code>Temp</code>s 223 bdemsky 1.1.2.5 * that are added in.*/ 224 bdemsky 1.1.2.5 public ArrayList pointeroffset; 225 bdemsky 1.1.2.5 public boolean copied; 226 bdemsky 1.1.2.4 227 bdemsky 1.1.2.4 228 bdemsky 1.1.2.5 public class IntMultAdd { 229 bdemsky 1.1.2.5 //Form: 230 bdemsky 1.1.2.5 //(ax+b)?loopinvariant 231 bdemsky 1.1.2.5 IntMultAdd(Temp inductionvar, int intmultiplier, int offset) { 232 bdemsky 1.1.2.5 this.intmultiplier=intmultiplier; 233 bdemsky 1.1.2.5 this.offset=offset; 234 bdemsky 1.1.2.5 this.inductionvar=inductionvar; 235 bdemsky 1.1.2.5 } 236 bdemsky 1.1.2.5 237 bdemsky 1.1.2.5 IntMultAdd(IntMultAdd x, int intmultiplier, int offset) { 238 bdemsky 1.1.2.5 this.intmultiplier=intmultiplier; 239 bdemsky 1.1.2.5 this.offset=offset; 240 bdemsky 1.1.2.5 this.inductionvar=null; 241 bdemsky 1.1.2.5 this.child=new IntMultAdd(x); 242 bdemsky 1.1.2.5 this.child.parent=this; 243 bdemsky 1.1.2.5 } 244 bdemsky 1.1.2.5 245 bdemsky 1.1.2.5 IntMultAdd(IntMultAdd x) { 246 bdemsky 1.1.2.5 this.intmultiplier=x.intmultiplier; 247 bdemsky 1.1.2.5 this.offset=x.offset; 248 bdemsky 1.1.2.5 this.inductionvar=x.inductionvar; 249 bdemsky 1.1.2.5 this.multiply=x.multiply; 250 bdemsky 1.1.2.5 this.loopinvariant=x.loopinvariant; 251 bdemsky 1.1.2.5 this.invariantsign=x.invariantsign; 252 bdemsky 1.1.2.5 if (x.child!=null) { 253 bdemsky 1.1.2.5 this.child=new IntMultAdd(x.child); 254 bdemsky 1.1.2.5 this.child.parent=this; 255 bdemsky 1.1.2.5 } 256 bdemsky 1.1.2.5 else 257 bdemsky 1.1.2.5 this.child=null; 258 bdemsky 1.1.2.5 } 259 bdemsky 1.1.2.5 260 bdemsky 1.1.2.5 IntMultAdd(IntMultAdd x, Temp operand, boolean multiply) { 261 bdemsky 1.1.2.5 this.intmultiplier=1; 262 bdemsky 1.1.2.5 this.offset=0; 263 bdemsky 1.1.2.5 this.inductionvar=null; 264 bdemsky 1.1.2.5 this.loopinvariant=operand; 265 bdemsky 1.1.2.5 this.invariantsign=true; 266 bdemsky 1.1.2.5 this.multiply=multiply; 267 bdemsky 1.1.2.5 this.child=new IntMultAdd(x); 268 bdemsky 1.1.2.5 this.child.parent=this; 269 bdemsky 1.1.2.5 } 270 bdemsky 1.1.2.5 271 bdemsky 1.1.2.5 272 bdemsky 1.1.2.5 public IntMultAdd bottom() { 273 bdemsky 1.1.2.5 IntMultAdd ptr=this; 274 bdemsky 1.1.2.5 while (ptr.child()!=null) 275 bdemsky 1.1.2.5 ptr=ptr.child(); 276 bdemsky 1.1.2.5 return ptr; 277 bdemsky 1.1.2.5 } 278 bdemsky 1.1.2.5 279 bdemsky 1.1.2.5 public int depth() { 280 bdemsky 1.1.2.5 IntMultAdd ptr=this; 281 bdemsky 1.1.2.5 int count=1; 282 bdemsky 1.1.2.5 while (ptr.child()!=null) { 283 bdemsky 1.1.2.5 ptr=ptr.child; 284 bdemsky 1.1.2.5 count++; 285 bdemsky 1.1.2.5 } 286 bdemsky 1.1.2.5 return count; 287 bdemsky 1.1.2.5 } 288 bdemsky 1.1.2.5 289 bdemsky 1.1.2.5 public void multiply(int x) { 290 bdemsky 1.1.2.5 intmultiplier*=x; 291 bdemsky 1.1.2.5 offset*=x; 292 bdemsky 1.1.2.5 } 293 bdemsky 1.1.2.5 294 bdemsky 1.1.2.5 public void add(int x) { 295 bdemsky 1.1.2.5 offset+=x; 296 bdemsky 1.1.2.5 } 297 bdemsky 1.1.2.5 298 bdemsky 1.1.2.5 public void negate() { 299 bdemsky 1.1.2.5 intmultiplier=-intmultiplier; 300 bdemsky 1.1.2.5 offset=-offset; 301 bdemsky 1.1.2.5 invariantsign=!invariantsign; 302 bdemsky 1.1.2.5 } 303 bdemsky 1.1.2.5 304 bdemsky 1.1.2.5 public boolean constant() { 305 bdemsky 1.1.2.5 if ((child==null)&&(loopinvariant==null)) 306 bdemsky 1.1.2.5 return true; 307 bdemsky 1.1.2.5 else 308 bdemsky 1.1.2.5 return false; 309 bdemsky 1.1.2.5 } 310 bdemsky 1.1.2.5 311 bdemsky 1.1.2.5 public IntMultAdd parent() { 312 bdemsky 1.1.2.5 return parent; 313 bdemsky 1.1.2.5 } 314 bdemsky 1.1.2.5 315 bdemsky 1.1.2.5 public int intmultiplier() { 316 bdemsky 1.1.2.5 return intmultiplier; 317 bdemsky 1.1.2.5 } 318 bdemsky 1.1.2.5 319 bdemsky 1.1.2.5 public int offset() { 320 bdemsky 1.1.2.5 return offset; 321 bdemsky 1.1.2.5 } 322 bdemsky 1.1.2.5 323 bdemsky 1.1.2.5 public Temp inductionvar() { 324 bdemsky 1.1.2.5 return inductionvar; 325 bdemsky 1.1.2.5 } 326 bdemsky 1.1.2.5 327 bdemsky 1.1.2.5 public IntMultAdd child() { 328 bdemsky 1.1.2.5 return child; 329 bdemsky 1.1.2.5 } 330 bdemsky 1.1.2.5 331 bdemsky 1.1.2.5 public void multiply(boolean operation) { 332 bdemsky 1.1.2.5 this.multiply=operation; 333 bdemsky 1.1.2.5 } 334 bdemsky 1.1.2.5 335 bdemsky 1.1.2.5 public boolean multiply() { 336 bdemsky 1.1.2.5 return multiply; 337 bdemsky 1.1.2.5 } 338 bdemsky 1.1.2.5 339 bdemsky 1.1.2.5 public Temp loopinvariant() { 340 bdemsky 1.1.2.5 return loopinvariant; 341 bdemsky 1.1.2.5 } 342 bdemsky 1.1.2.5 343 bdemsky 1.1.2.5 public void loopinvariant(Temp loopinvariant) { 344 bdemsky 1.1.2.5 this.loopinvariant=loopinvariant; 345 bdemsky 1.1.2.5 } 346 bdemsky 1.1.2.5 347 bdemsky 1.1.2.5 public boolean invariantsign() { 348 bdemsky 1.1.2.5 return invariantsign; 349 bdemsky 1.1.2.5 } 350 bdemsky 1.1.2.5 351 bdemsky 1.1.2.5 private boolean multiply; //operation true: ?=*/ false: ?=+ 352 bdemsky 1.1.2.5 private Temp loopinvariant; //loop invariant 353 bdemsky 1.1.2.5 private boolean invariantsign; 354 bdemsky 1.1.2.5 355 bdemsky 1.1.2.5 private int intmultiplier;//a 356 bdemsky 1.1.2.5 private int offset;//b 357 bdemsky 1.1.2.5 private IntMultAdd parent; 358 bdemsky 1.1.2.5 private IntMultAdd child;//x 359 bdemsky 1.1.2.5 private Temp inductionvar;//x 360 bdemsky 1.1.2.5 } 361 cananian 1.2 }