1 bdemsky 1.1.2.1 // LoopAnalysis.java, created Thu Jun 24 11:45:07 1998 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 bdemsky 1.1.2.1 import harpoon.Analysis.UseDef; 7 bdemsky 1.1.2.1 import harpoon.Analysis.Loops.LoopFinder; 8 cananian 1.5 import net.cscott.jutil.WorkSet; 9 bdemsky 1.1.2.16 import harpoon.ClassFile.HCodeElement; 10 bdemsky 1.1.2.16 import harpoon.ClassFile.HCode; 11 bdemsky 1.1.2.16 import harpoon.IR.Quads.AGET; 12 bdemsky 1.1.2.16 import harpoon.IR.Quads.ALENGTH; 13 bdemsky 1.1.2.16 import harpoon.IR.Quads.ANEW; 14 bdemsky 1.1.2.16 import harpoon.IR.Quads.ARRAYINIT; 15 bdemsky 1.1.2.16 import harpoon.IR.Quads.ASET; 16 bdemsky 1.1.2.16 import harpoon.IR.Quads.CALL; 17 bdemsky 1.1.2.16 import harpoon.IR.Quads.CJMP; 18 bdemsky 1.1.2.16 import harpoon.IR.Quads.COMPONENTOF; 19 bdemsky 1.1.2.16 import harpoon.IR.Quads.CONST; 20 bdemsky 1.1.2.16 import harpoon.IR.Quads.GET; 21 bdemsky 1.1.2.16 import harpoon.IR.Quads.INSTANCEOF; 22 bdemsky 1.1.2.16 import harpoon.IR.Quads.MONITORENTER; 23 bdemsky 1.1.2.16 import harpoon.IR.Quads.MONITOREXIT; 24 bdemsky 1.1.2.16 import harpoon.IR.Quads.MOVE; 25 bdemsky 1.1.2.16 import harpoon.IR.Quads.NEW; 26 bdemsky 1.1.2.16 import harpoon.IR.Quads.Quad; 27 bdemsky 1.1.2.16 import harpoon.IR.Quads.Qop; 28 bdemsky 1.1.2.16 import harpoon.IR.Quads.RETURN; 29 bdemsky 1.1.2.16 import harpoon.IR.Quads.SET; 30 bdemsky 1.1.2.18 import harpoon.IR.Quads.SIGMA; 31 bdemsky 1.1.2.16 import harpoon.IR.Quads.THROW; 32 bdemsky 1.1.2.16 import harpoon.IR.Quads.TYPECAST; 33 bdemsky 1.1.2.16 import harpoon.IR.Quads.OPER; 34 bdemsky 1.1.2.16 import harpoon.IR.Quads.PHI; 35 bdemsky 1.1.2.18 import harpoon.IR.Quads.QuadKind; 36 bdemsky 1.1.2.16 import harpoon.IR.LowQuad.LowQuadVisitor; 37 bdemsky 1.1.2.16 import harpoon.IR.LowQuad.POPER; 38 bdemsky 1.1.2.16 import harpoon.IR.LowQuad.PCALL; 39 bdemsky 1.1.2.16 import harpoon.IR.LowQuad.PGET; 40 bdemsky 1.1.2.16 import harpoon.IR.LowQuad.PSET; 41 bdemsky 1.1.2.16 import harpoon.IR.LowQuad.PARRAY; 42 bdemsky 1.1.2.16 import harpoon.IR.LowQuad.PFIELD; 43 bdemsky 1.1.2.16 import harpoon.IR.LowQuad.PMETHOD; 44 bdemsky 1.1.2.16 import harpoon.IR.LowQuad.PCONST; 45 bdemsky 1.1.2.16 import harpoon.IR.LowQuad.PAOFFSET; 46 bdemsky 1.1.2.16 import harpoon.IR.LowQuad.PFOFFSET; 47 bdemsky 1.1.2.16 import harpoon.IR.LowQuad.PMOFFSET; 48 bdemsky 1.1.2.16 import harpoon.IR.LowQuad.PFCONST; 49 bdemsky 1.1.2.16 import harpoon.IR.LowQuad.PMCONST; 50 bdemsky 1.1.2.18 import harpoon.IR.LowQuad.LowQuadKind; 51 bdemsky 1.1.2.16 import harpoon.Analysis.Loops.LoopFinder; 52 bdemsky 1.1.2.16 import harpoon.Analysis.Loops.Loops; 53 bdemsky 1.1.2.1 import harpoon.Temp.Temp; 54 bdemsky 1.1.2.1 import harpoon.Temp.TempMap; 55 cananian 1.1.2.20 import harpoon.IR.Properties.CFGraphable; 56 bdemsky 1.1.2.2 import harpoon.Analysis.LowQuad.Loop.AllInductions; 57 bdemsky 1.1.2.4 import harpoon.Analysis.LowQuad.Loop.BasicInductions; 58 bdemsky 1.1.2.2 import harpoon.Analysis.LowQuad.Loop.LoopInvariance; 59 bdemsky 1.1.2.5 import harpoon.Analysis.Maps.AllInductionsMap; 60 bdemsky 1.1.2.5 import harpoon.Analysis.Maps.BasicInductionsMap; 61 bdemsky 1.1.2.5 import harpoon.Analysis.Maps.InvariantsMap; 62 bdemsky 1.1.2.12 import harpoon.Util.Util; 63 bdemsky 1.1.2.2 64 bdemsky 1.1.2.2 import java.util.HashMap; 65 bdemsky 1.1.2.9 import java.util.Map; 66 bdemsky 1.1.2.2 import java.util.ArrayList; 67 bdemsky 1.1.2.1 import java.util.Set; 68 bdemsky 1.1.2.1 import java.util.Iterator; 69 bdemsky 1.1.2.5 70 bdemsky 1.1.2.1 /** 71 bdemsky 1.1.2.5 * <code>LoopAnalysis</code> implements <code>AllInductionsMap</code>, 72 bdemsky 1.1.2.5 * <code>BasicInductionsMap</code>, and <code>InvariantsMap</code>. 73 bdemsky 1.1.2.1 * 74 cananian 1.1.2.23 * @author Brian Demsky <bdemsky@mit.edu> 75 cananian 1.5 * @version $Id: LoopAnalysis.java,v 1.5 2004/02/08 01:52:54 cananian Exp $ 76 bdemsky 1.1.2.1 */ 77 bdemsky 1.1.2.1 78 bdemsky 1.1.2.5 public class LoopAnalysis implements AllInductionsMap, BasicInductionsMap, InvariantsMap { 79 bdemsky 1.1.2.1 80 bdemsky 1.1.2.5 HCode lasthc; 81 bdemsky 1.1.2.1 TempMap tm; 82 bdemsky 1.1.2.5 HashMap aimap, bimap, invmap; 83 bdemsky 1.1.2.5 LoopFinder rtloop; 84 bdemsky 1.1.2.12 UseDef ud; 85 bdemsky 1.1.2.1 86 bdemsky 1.1.2.11 /** Creates a <code>LoopAnalysis</code>. Takes in a TempMap 87 bdemsky 1.1.2.11 that for SSI forms needs to map SSI->SSA.*/ 88 bdemsky 1.1.2.1 public LoopAnalysis(TempMap tm) { 89 bdemsky 1.1.2.1 this.tm=tm; 90 bdemsky 1.1.2.12 this.ud=new UseDef(); 91 bdemsky 1.1.2.1 } 92 bdemsky 1.1.2.1 93 bdemsky 1.1.2.1 /*-----------------------------*/ 94 bdemsky 1.1.2.1 // Class state. 95 bdemsky 1.1.2.1 96 bdemsky 1.1.2.1 /*---------------------------*/ 97 bdemsky 1.1.2.1 // public information accessor methods. 98 bdemsky 1.1.2.1 99 bdemsky 1.1.2.5 public Loops rootloop(HCode hc) { 100 bdemsky 1.1.2.5 analyze(hc); 101 bdemsky 1.1.2.5 return rtloop; 102 bdemsky 1.1.2.5 } 103 bdemsky 1.1.2.5 104 bdemsky 1.1.2.9 public Map allInductionsMap(HCode hc, Loops lp) { 105 bdemsky 1.1.2.5 analyze(hc); 106 bdemsky 1.1.2.8 return (HashMap) aimap.get(lp.loopEntrances().toArray()[0]); 107 bdemsky 1.1.2.5 } 108 bdemsky 1.1.2.5 109 bdemsky 1.1.2.9 public Map basicInductionsMap(HCode hc, Loops lp) { 110 bdemsky 1.1.2.5 analyze(hc); 111 bdemsky 1.1.2.8 return (HashMap) bimap.get(lp.loopEntrances().toArray()[0]); 112 bdemsky 1.1.2.5 } 113 bdemsky 1.1.2.5 114 bdemsky 1.1.2.5 public Set invariantsMap(HCode hc, Loops lp) { 115 bdemsky 1.1.2.1 analyze(hc); 116 bdemsky 1.1.2.7 return (Set) invmap.get(lp.loopEntrances().toArray()[0]); 117 bdemsky 1.1.2.1 } 118 bdemsky 1.1.2.1 119 bdemsky 1.1.2.12 120 bdemsky 1.1.2.12 /** <code>initialTemp</code> takes in a <code>Temp</code> t that needs to be a basic 121 bdemsky 1.1.2.12 * induction variable, a <code>Loops</code> that is the loop that t is an 122 bdemsky 1.1.2.12 * induction variable in and returns a <code>Temp</code> with its initial value. */ 123 bdemsky 1.1.2.12 124 bdemsky 1.1.2.12 Temp initialTemp(HCode hc, Temp t, Loops lp) { 125 cananian 1.1.2.22 Set loopelements=lp.loopIncElements(); 126 cananian 1.3.2.1 assert lp.loopEntrances().size()==1 : "Loop must have one entrance"; 127 bdemsky 1.1.2.12 PHI q=(PHI)(lp.loopEntrances()).toArray()[0]; 128 bdemsky 1.1.2.12 129 bdemsky 1.1.2.12 int j=0; 130 bdemsky 1.1.2.12 for (;j<q.numPhis();j++) { 131 bdemsky 1.1.2.12 if (q.dst(j)==t) break; 132 bdemsky 1.1.2.12 } 133 bdemsky 1.1.2.12 Temp[] uses=q.src(j); 134 cananian 1.3.2.1 assert uses.length==2; 135 bdemsky 1.1.2.12 Temp initial=null; 136 bdemsky 1.1.2.12 for(int i=0;i<uses.length;i++) { 137 bdemsky 1.1.2.12 HCodeElement[] sources=ud.defMap(hc,tm.tempMap(uses[i])); 138 cananian 1.3.2.1 assert sources.length==1; 139 bdemsky 1.1.2.12 if (!loopelements.contains(sources[0])) { 140 bdemsky 1.1.2.12 initial=uses[i]; 141 bdemsky 1.1.2.12 break; 142 bdemsky 1.1.2.12 } 143 bdemsky 1.1.2.12 } 144 bdemsky 1.1.2.12 return initial; 145 bdemsky 1.1.2.12 } 146 bdemsky 1.1.2.12 147 bdemsky 1.1.2.12 /** <code>findIncrement</code> finds out how much the basic induction variable is 148 bdemsky 1.1.2.12 * incremented by.*/ 149 bdemsky 1.1.2.12 150 bdemsky 1.1.2.12 Temp findIncrement(HCode hc, Temp t, Loops lp) { 151 cananian 1.1.2.22 Set loopelements=lp.loopIncElements(); 152 cananian 1.3.2.1 assert lp.loopEntrances().size()==1 : "Loop must have one entrance"; 153 bdemsky 1.1.2.12 PHI oheader=(PHI)(lp.loopEntrances()).toArray()[0]; 154 bdemsky 1.1.2.12 Quad q=addQuad(hc, oheader, t,loopelements); 155 bdemsky 1.1.2.12 HCodeElement []source=ud.defMap(hc,tm.tempMap(t)); 156 cananian 1.3.2.1 assert source.length==1; 157 bdemsky 1.1.2.12 PHI qq=(PHI)source[0]; 158 bdemsky 1.1.2.12 Temp[] uses=q.use(); 159 bdemsky 1.1.2.12 Temp result=null; 160 bdemsky 1.1.2.12 161 bdemsky 1.1.2.12 for (int i=0;i<uses.length;i++) { 162 bdemsky 1.1.2.12 HCodeElement []sources=ud.defMap(hc,tm.tempMap(uses[i])); 163 cananian 1.3.2.1 assert sources.length==1; 164 bdemsky 1.1.2.12 if (sources[0]!=qq) { 165 bdemsky 1.1.2.12 result=uses[i]; 166 bdemsky 1.1.2.12 break; 167 bdemsky 1.1.2.12 } 168 bdemsky 1.1.2.12 } 169 bdemsky 1.1.2.12 return result; 170 bdemsky 1.1.2.12 } 171 bdemsky 1.1.2.12 172 bdemsky 1.1.2.12 /** <code>addQuad</code> takes in a <code>Temp</code> t that needs to be a basic 173 bdemsky 1.1.2.12 * induction variable, and returns the <code>Quad</code> that does the adding. */ 174 bdemsky 1.1.2.12 175 bdemsky 1.1.2.12 Quad addQuad(HCode hc, PHI q,Temp t, Set loopelements) { 176 bdemsky 1.1.2.12 int j=0; 177 bdemsky 1.1.2.12 for (;j<q.numPhis();j++) { 178 bdemsky 1.1.2.12 if (q.dst(j)==t) break; 179 bdemsky 1.1.2.12 } 180 bdemsky 1.1.2.12 Temp[] uses=q.src(j); 181 cananian 1.3.2.1 assert uses.length==2; 182 bdemsky 1.1.2.12 Temp initial=null; 183 bdemsky 1.1.2.12 for(int i=0;i<uses.length;i++) { 184 bdemsky 1.1.2.12 HCodeElement[] sources=ud.defMap(hc,tm.tempMap(uses[i])); 185 cananian 1.3.2.1 assert sources.length==1; 186 bdemsky 1.1.2.12 if (loopelements.contains(sources[0])) { 187 bdemsky 1.1.2.12 initial=uses[i]; 188 bdemsky 1.1.2.12 break; 189 bdemsky 1.1.2.12 } 190 bdemsky 1.1.2.12 } 191 bdemsky 1.1.2.12 HCodeElement[] sources=ud.defMap(hc,tm.tempMap(initial)); 192 cananian 1.3.2.1 assert sources.length==1; 193 bdemsky 1.1.2.12 return (Quad)sources[0]; 194 bdemsky 1.1.2.12 } 195 bdemsky 1.1.2.5 196 bdemsky 1.1.2.1 /*---------------------------*/ 197 bdemsky 1.1.2.1 // Analysis code. 198 bdemsky 1.1.2.1 199 bdemsky 1.1.2.1 /** Set of analyzed methods. */ 200 bdemsky 1.1.2.1 201 bdemsky 1.1.2.1 /** Main analysis method. */ 202 bdemsky 1.1.2.1 void analyze(HCode hc) { 203 bdemsky 1.1.2.5 if (lasthc!=hc) { 204 bdemsky 1.1.2.5 invmap=new HashMap(); 205 bdemsky 1.1.2.5 aimap=new HashMap(); 206 bdemsky 1.1.2.5 bimap=new HashMap(); 207 bdemsky 1.1.2.5 lasthc=hc; 208 bdemsky 1.1.2.5 rtloop=new LoopFinder(hc); 209 bdemsky 1.1.2.5 analyzetree(hc,rtloop,""); 210 bdemsky 1.1.2.5 } 211 bdemsky 1.1.2.1 } // end analysis. 212 bdemsky 1.1.2.1 213 bdemsky 1.1.2.5 void analyzetree(HCode hc, Loops lp, String st) { 214 bdemsky 1.1.2.1 WorkSet kids=(WorkSet)lp.nestedLoops(); 215 bdemsky 1.1.2.1 Iterator iterate=kids.iterator(); 216 bdemsky 1.1.2.5 217 bdemsky 1.1.2.1 while (iterate.hasNext()) { 218 bdemsky 1.1.2.5 analyzetree(hc, (Loops)iterate.next(),st+" "); 219 bdemsky 1.1.2.1 } 220 bdemsky 1.1.2.5 221 bdemsky 1.1.2.27 /* throw assertion if loop has no entrance (root loop) */ 222 cananian 1.3.2.1 assert !lp.loopEntrances().isEmpty(); 223 bdemsky 1.1.2.27 224 ovy 1.1.2.26 225 bdemsky 1.1.2.1 //Find loop invariants 226 cananian 1.1.2.22 WorkSet elements=(WorkSet)lp.loopIncElements(); 227 bdemsky 1.1.2.2 LoopInvariance invar=new LoopInvariance(tm,hc); 228 bdemsky 1.1.2.2 WorkSet invariants=invar.invariants(elements); 229 bdemsky 1.1.2.1 230 bdemsky 1.1.2.1 //Find basic induction variables 231 bdemsky 1.1.2.5 232 bdemsky 1.1.2.4 BasicInductions binductor=new BasicInductions(tm,hc); 233 bdemsky 1.1.2.6 HashMap basicinductions=binductor.doInduction(lp,invariants); 234 bdemsky 1.1.2.1 235 bdemsky 1.1.2.5 236 bdemsky 1.1.2.5 //Find all induction variables 237 bdemsky 1.1.2.2 AllInductions ainductor=new AllInductions(tm,hc); 238 bdemsky 1.1.2.5 HashMap allInductions=ainductor.doAllInductions(lp, invariants, basicinductions); 239 bdemsky 1.1.2.1 240 bdemsky 1.1.2.5 //Add to our maps 241 bdemsky 1.1.2.7 aimap.put(lp.loopEntrances().toArray()[0], allInductions); 242 bdemsky 1.1.2.7 bimap.put(lp.loopEntrances().toArray()[0], basicinductions); 243 bdemsky 1.1.2.7 invmap.put(lp.loopEntrances().toArray()[0], invariants); 244 bdemsky 1.1.2.1 245 bdemsky 1.1.2.1 246 bdemsky 1.1.2.5 //Show the user everything 247 bdemsky 1.1.2.10 //iterate=invariants.iterator(); 248 bdemsky 1.1.2.10 //System.out.println(st+"Invariants:"); 249 bdemsky 1.1.2.10 //while (iterate.hasNext()) { 250 bdemsky 1.1.2.10 // System.out.println(st+((Quad)iterate.next()).toString()); 251 bdemsky 1.1.2.10 //} 252 bdemsky 1.1.2.10 //iterate=elements.iterator(); 253 bdemsky 1.1.2.10 //System.out.println(st+"Noninvariants:"); 254 bdemsky 1.1.2.10 //while (iterate.hasNext()) { 255 bdemsky 1.1.2.10 // System.out.println(st+((Quad)iterate.next()).toString()); 256 bdemsky 1.1.2.10 //} 257 bdemsky 1.1.2.10 //iterate=(basicinductions.keySet()).iterator(); 258 bdemsky 1.1.2.10 259 bdemsky 1.1.2.10 //System.out.println(st+"Basic induction variables:"); 260 bdemsky 1.1.2.10 //while (iterate.hasNext()) { 261 bdemsky 1.1.2.10 // Temp tmp=(Temp) iterate.next(); 262 bdemsky 1.1.2.10 // System.out.println(st+tmp.toString()); 263 bdemsky 1.1.2.10 // System.out.println(st+((Induction)basicinductions.get(tmp)).toString()); 264 bdemsky 1.1.2.10 //} 265 bdemsky 1.1.2.10 //iterate=(allInductions.keySet()).iterator(); 266 bdemsky 1.1.2.10 267 bdemsky 1.1.2.10 //System.out.println(st+"All induction variables:"); 268 bdemsky 1.1.2.10 //while (iterate.hasNext()) { 269 bdemsky 1.1.2.10 // Temp tmp=(Temp) iterate.next(); 270 bdemsky 1.1.2.10 // System.out.println(st+tmp.toString()); 271 bdemsky 1.1.2.10 // System.out.println(st+((Induction)allInductions.get(tmp)).toString()); 272 bdemsky 1.1.2.10 //} 273 bdemsky 1.1.2.13 } 274 bdemsky 1.1.2.13 275 bdemsky 1.1.2.13 /** <code>doLooptest</code> moves test conditions from original induction variables 276 bdemsky 1.1.2.13 * to new ones whenever possible.*/ 277 bdemsky 1.1.2.13 278 bdemsky 1.1.2.13 Set doLooptest(HCode hc, Loops lp) { 279 bdemsky 1.1.2.13 //Make sure we have done analysis 280 bdemsky 1.1.2.13 analyze(hc); 281 bdemsky 1.1.2.13 //Create the set of loop elements 282 cananian 1.1.2.22 Set elements=lp.loopIncElements(); 283 bdemsky 1.1.2.13 WorkSet tests=new WorkSet(); 284 bdemsky 1.1.2.13 //Iterate through this set 285 bdemsky 1.1.2.13 Iterator iterate=elements.iterator(); 286 bdemsky 1.1.2.13 287 bdemsky 1.1.2.13 //create sets of loop invariants and map of induction variables 288 bdemsky 1.1.2.13 //to pass to the visitor 289 bdemsky 1.1.2.13 Set loopinvars=(Set)invmap.get(lp.loopEntrances().toArray()[0]); 290 bdemsky 1.1.2.13 Map allinductions=(Map)aimap.get(lp.loopEntrances().toArray()[0]); 291 bdemsky 1.1.2.13 292 bdemsky 1.1.2.13 TestVisitor visitor=new TestVisitor(loopinvars, allinductions, tm,hc, lp, tests); 293 bdemsky 1.1.2.13 //visit the nodes 294 bdemsky 1.1.2.13 while (iterate.hasNext()) { 295 bdemsky 1.1.2.13 Quad q=(Quad) iterate.next(); 296 bdemsky 1.1.2.13 q.accept(visitor); 297 bdemsky 1.1.2.13 } 298 bdemsky 1.1.2.13 return tests; 299 bdemsky 1.1.2.13 } 300 bdemsky 1.1.2.13 301 bdemsky 1.1.2.13 302 bdemsky 1.1.2.13 /**<code>TestVisitor</code> does all the magic for changing test conditions.*/ 303 bdemsky 1.1.2.13 304 bdemsky 1.1.2.13 class TestVisitor extends LowQuadVisitor { 305 bdemsky 1.1.2.13 Set inductvars; 306 bdemsky 1.1.2.13 Set loopinvars; 307 bdemsky 1.1.2.13 Map allinductions; 308 bdemsky 1.1.2.13 TempMap ssitossamap; 309 bdemsky 1.1.2.13 Loops lp; 310 bdemsky 1.1.2.13 HCode hc; 311 bdemsky 1.1.2.13 Set tests; 312 bdemsky 1.1.2.13 313 bdemsky 1.1.2.13 //Create TestVisitor, and inform it of everything. 314 bdemsky 1.1.2.13 TestVisitor(Set loopinvars, Map allinductions, TempMap ssitossamap, HCode hc, Loops lp, Set tests) { 315 bdemsky 1.1.2.13 this.loopinvars=loopinvars; 316 bdemsky 1.1.2.13 this.allinductions=allinductions; 317 bdemsky 1.1.2.13 this.inductvars=allinductions.keySet(); 318 bdemsky 1.1.2.13 this.ssitossamap=ssitossamap; 319 bdemsky 1.1.2.13 this.hc=hc; 320 bdemsky 1.1.2.13 this.lp=lp; 321 bdemsky 1.1.2.13 this.tests=tests; 322 bdemsky 1.1.2.13 } 323 bdemsky 1.1.2.13 324 bdemsky 1.1.2.13 //Default method...do nothing 325 bdemsky 1.1.2.13 public void visit(Quad q) {/* Do nothing*/} 326 bdemsky 1.1.2.13 327 bdemsky 1.1.2.13 //POPER visitor 328 bdemsky 1.1.2.13 //Only look at ICMPEQ, and ICMPGT 329 bdemsky 1.1.2.13 public void visit(harpoon.IR.Quads.AGET q) {} 330 bdemsky 1.1.2.13 331 bdemsky 1.1.2.13 public void visit(harpoon.IR.Quads.ASET q) {} 332 bdemsky 1.1.2.13 333 bdemsky 1.1.2.13 public void visit(harpoon.IR.Quads.CALL q) {} 334 bdemsky 1.1.2.13 335 bdemsky 1.1.2.13 public void visit(harpoon.IR.Quads.GET q) {} 336 bdemsky 1.1.2.13 337 bdemsky 1.1.2.13 // Lets let this error go through...shouldn't see any HANDLERS 338 bdemsky 1.1.2.13 // in a loop. 339 bdemsky 1.1.2.13 // public void visit(harpoon.IR.Quads.HANDLER q) {} 340 bdemsky 1.1.2.13 341 bdemsky 1.1.2.13 public void visit(harpoon.IR.Quads.SET q) {} 342 bdemsky 1.1.2.13 343 bdemsky 1.1.2.13 public void visit(POPER q) { 344 bdemsky 1.1.2.13 switch (q.opcode()) { 345 bdemsky 1.1.2.13 case Qop.ICMPEQ: 346 bdemsky 1.1.2.13 case Qop.ICMPGT: 347 bdemsky 1.1.2.17 case Qop.LCMPEQ: 348 bdemsky 1.1.2.17 case Qop.LCMPGT: 349 bdemsky 1.1.2.13 //look at the POPER 350 bdemsky 1.1.2.13 //return new POPER if we can do stuff 351 bdemsky 1.1.2.13 if (lookat(q)) tests.add(q); 352 bdemsky 1.1.2.13 break; 353 bdemsky 1.1.2.13 default: 354 bdemsky 1.1.2.13 } 355 bdemsky 1.1.2.13 } 356 bdemsky 1.1.2.13 357 bdemsky 1.1.2.13 public void visit(OPER q) { 358 bdemsky 1.1.2.13 switch (q.opcode()) { 359 bdemsky 1.1.2.13 case Qop.ICMPEQ: 360 bdemsky 1.1.2.13 case Qop.ICMPGT: 361 bdemsky 1.1.2.17 case Qop.LCMPEQ: 362 bdemsky 1.1.2.17 case Qop.LCMPGT: 363 bdemsky 1.1.2.13 //look at the OPER 364 bdemsky 1.1.2.13 //return new OPER if we can do stuff 365 bdemsky 1.1.2.13 if (lookat(q)) tests.add(q); 366 bdemsky 1.1.2.13 break; 367 bdemsky 1.1.2.13 default: 368 bdemsky 1.1.2.13 } 369 bdemsky 1.1.2.13 } 370 bdemsky 1.1.2.13 371 bdemsky 1.1.2.13 /**<code>lookat</code> examines a test condition.*/ 372 bdemsky 1.1.2.13 boolean lookat(OPER q) { 373 bdemsky 1.1.2.13 Temp[] operands=q.operands(); 374 cananian 1.3.2.1 assert operands.length==2; 375 bdemsky 1.1.2.13 boolean good=true; 376 bdemsky 1.1.2.13 int flag=-1; 377 bdemsky 1.1.2.13 POPER newpoper=null; 378 ovy 1.1.2.26 Set loopIncElements = lp.loopIncElements(); 379 bdemsky 1.1.2.13 380 bdemsky 1.1.2.13 //Loop through the operands 381 bdemsky 1.1.2.13 //we need one induction variable 382 bdemsky 1.1.2.13 //and one loop invariant 383 bdemsky 1.1.2.13 384 bdemsky 1.1.2.13 for (int i=0;i<operands.length;i++) { 385 bdemsky 1.1.2.13 if (inductvars.contains(ssitossamap.tempMap(operands[i]))) { 386 bdemsky 1.1.2.13 if (flag==-1) 387 bdemsky 1.1.2.13 flag=i; 388 bdemsky 1.1.2.13 else 389 bdemsky 1.1.2.13 good=false; 390 bdemsky 1.1.2.13 } 391 bdemsky 1.1.2.13 else { 392 bdemsky 1.1.2.13 HCodeElement[] sources=ud.defMap(hc,ssitossamap.tempMap(operands[i])); 393 cananian 1.3.2.1 assert sources.length==1; 394 ovy 1.1.2.26 /* good only if defined in invariant or outside the loop */ 395 ovy 1.1.2.26 if (!loopinvars.contains(sources[0]) && 396 ovy 1.1.2.26 loopIncElements.contains(sources[0])) 397 bdemsky 1.1.2.13 good=false; 398 bdemsky 1.1.2.13 } 399 bdemsky 1.1.2.13 } 400 bdemsky 1.1.2.13 return (good&&(flag!=-1)); 401 bdemsky 1.1.2.13 } 402 bdemsky 1.1.2.1 } 403 bdemsky 1.1.2.19 /**<code>forloop</code> takes in an <code>HCode</code> and 404 bdemsky 1.1.2.19 * <code>Loops</code> to analyze. It returns a null if there is 405 bdemsky 1.1.2.19 * no for loop, or a <code>ForLoopInfo</code> if it finds a for loop. 406 bdemsky 1.1.2.19 * It works on Quads and LowQuads on both SSI and SSA forms.*/ 407 bdemsky 1.1.2.14 408 bdemsky 1.1.2.17 public ForLoopInfo forloop(HCode hc, Loops lp) { 409 bdemsky 1.1.2.14 analyze(hc); 410 cananian 1.3.2.1 assert lp.loopEntrances().size()==1 : "Loop must have one entrance"; 411 bdemsky 1.1.2.14 Quad header=(Quad)(lp.loopEntrances()).toArray()[0];; 412 bdemsky 1.1.2.14 Set testsopers=doLooptest(hc,lp); 413 bdemsky 1.1.2.15 ForLoopVisitor flv=new ForLoopVisitor(testsopers, hc, ud, lp, tm); 414 bdemsky 1.1.2.15 for (Quad ptr=header.next(0);!(flv.sideEffects()||flv.done());ptr=ptr.next(0)) { 415 bdemsky 1.1.2.15 ptr.accept(flv); 416 bdemsky 1.1.2.15 } 417 bdemsky 1.1.2.15 if (flv.forLoop()) { 418 bdemsky 1.1.2.17 ForLoopInfo retval=null; 419 bdemsky 1.1.2.17 OPER test=flv.testCondition(); 420 bdemsky 1.1.2.17 CJMP cjmp=flv.cjmpExit(); 421 bdemsky 1.1.2.17 Temp ivar=flv.inductionVar(); 422 bdemsky 1.1.2.17 Temp increment=findIncrement(hc, ivar, lp); 423 bdemsky 1.1.2.17 int bindex=flv.bindex(); 424 bdemsky 1.1.2.17 int cjmpedge=flv.cjmpedge(); 425 bdemsky 1.1.2.17 switch (test.opcode()) { 426 bdemsky 1.1.2.17 case Qop.LCMPEQ: 427 bdemsky 1.1.2.17 case Qop.ICMPEQ: 428 bdemsky 1.1.2.17 if (cjmpedge==1) 429 bdemsky 1.1.2.17 retval=new ForLoopInfo(ForLoopInfo.NEQ,ivar,increment, 430 bdemsky 1.1.2.17 initialTemp(hc, ivar, lp), 431 bdemsky 1.1.2.17 test.operands(1-bindex),test,cjmp); 432 bdemsky 1.1.2.17 break; 433 bdemsky 1.1.2.17 case Qop.LCMPGT: 434 bdemsky 1.1.2.17 case Qop.ICMPGT: 435 bdemsky 1.1.2.17 int cond=0; 436 bdemsky 1.1.2.17 if ((bindex==0)&&(cjmpedge==1)) 437 bdemsky 1.1.2.18 cond=ForLoopInfo.LTE; 438 bdemsky 1.1.2.17 if ((bindex==1)&&(cjmpedge==1)) 439 bdemsky 1.1.2.18 cond=ForLoopInfo.GTE; 440 bdemsky 1.1.2.17 if ((bindex==0)&&(cjmpedge==0)) 441 bdemsky 1.1.2.18 cond=ForLoopInfo.GT; 442 bdemsky 1.1.2.17 if ((bindex==1)&&(cjmpedge==0)) 443 bdemsky 1.1.2.18 cond=ForLoopInfo.LT; 444 bdemsky 1.1.2.17 retval=new ForLoopInfo(cond,ivar,increment, 445 bdemsky 1.1.2.17 initialTemp(hc, ivar, lp), 446 bdemsky 1.1.2.17 test.operands(1-bindex),test,cjmp); 447 bdemsky 1.1.2.17 break; 448 bdemsky 1.1.2.17 default: 449 bdemsky 1.1.2.17 } 450 bdemsky 1.1.2.17 return retval; 451 bdemsky 1.1.2.15 } 452 bdemsky 1.1.2.15 else 453 bdemsky 1.1.2.15 return null; 454 bdemsky 1.1.2.14 } 455 bdemsky 1.1.2.14 456 bdemsky 1.1.2.19 /**<code>ForLoopInfo</code> encapsulated information on a for loop.*/ 457 bdemsky 1.1.2.18 public class ForLoopInfo { 458 bdemsky 1.1.2.17 private int testtype; 459 bdemsky 1.1.2.17 private Temp induction; 460 bdemsky 1.1.2.17 private Temp increment; 461 bdemsky 1.1.2.17 private Temp indinitial; 462 bdemsky 1.1.2.17 private Temp indfinal; 463 bdemsky 1.1.2.17 private OPER testquad; 464 bdemsky 1.1.2.17 private CJMP loopexit; 465 bdemsky 1.1.2.17 ForLoopInfo(int testtype,Temp induction, Temp increment,Temp indinitial, Temp indfinal, OPER testoper, CJMP loopexit) { 466 bdemsky 1.1.2.17 this.testtype=testtype; 467 bdemsky 1.1.2.17 this.induction=induction; 468 bdemsky 1.1.2.17 this.indinitial=indinitial; 469 bdemsky 1.1.2.17 this.indfinal=indfinal; 470 bdemsky 1.1.2.17 this.testquad=testquad; 471 bdemsky 1.1.2.17 this.loopexit=loopexit; 472 bdemsky 1.1.2.17 this.increment=increment; 473 bdemsky 1.1.2.17 } 474 bdemsky 1.1.2.19 /**<code>testtype</code> tells the type of test used. This is the 475 bdemsky 1.1.2.19 * condition to continue in the loop.*/ 476 bdemsky 1.1.2.17 public int testtype() { 477 bdemsky 1.1.2.17 return testtype; 478 bdemsky 1.1.2.17 } 479 bdemsky 1.1.2.19 /**<code>increment</code> gives the temp with the loop invariant 480 bdemsky 1.1.2.19 * value to increment the induction variable by.*/ 481 bdemsky 1.1.2.17 public Temp increment() { 482 bdemsky 1.1.2.17 return increment; 483 bdemsky 1.1.2.17 } 484 bdemsky 1.1.2.19 /**<code>induction</code> gives the temp with the induction variable 485 bdemsky 1.1.2.19 * of the for loop.*/ 486 bdemsky 1.1.2.17 public Temp induction() { 487 bdemsky 1.1.2.17 return induction; 488 bdemsky 1.1.2.17 } 489 bdemsky 1.1.2.19 /**<code>indInitial</code> gives the initial value of the induction 490 bdemsky 1.1.2.19 * variable.*/ 491 bdemsky 1.1.2.17 public Temp indInitial() { 492 bdemsky 1.1.2.17 return indinitial; 493 bdemsky 1.1.2.17 } 494 bdemsky 1.1.2.19 /**<code>indFinal</code> gives the final value of the induction 495 bdemsky 1.1.2.19 * variable.*/ 496 bdemsky 1.1.2.17 public Temp indFinal() { 497 bdemsky 1.1.2.17 return indfinal; 498 bdemsky 1.1.2.17 } 499 bdemsky 1.1.2.19 /**<code>testOPER</code> gives the <code>OPER</code> containing the 500 bdemsky 1.1.2.19 * for loop test condition.*/ 501 bdemsky 1.1.2.17 public OPER testOPER() { 502 bdemsky 1.1.2.17 return testquad; 503 bdemsky 1.1.2.17 } 504 bdemsky 1.1.2.19 /**<code>loopExit</code> gives the <code>CJMP</code> that is the 505 bdemsky 1.1.2.19 * first exit of the loop.*/ 506 bdemsky 1.1.2.17 public CJMP loopExit() { 507 bdemsky 1.1.2.17 return loopexit; 508 bdemsky 1.1.2.17 } 509 bdemsky 1.1.2.19 /** != case */ 510 bdemsky 1.1.2.17 public final static int NEQ = 0; 511 bdemsky 1.1.2.19 /** < case */ 512 bdemsky 1.1.2.17 public final static int LT = 1; 513 bdemsky 1.1.2.19 /** <= case */ 514 bdemsky 1.1.2.17 public final static int LTE = 2; 515 bdemsky 1.1.2.19 /** > case */ 516 bdemsky 1.1.2.17 public final static int GT = 3; 517 bdemsky 1.1.2.19 /** >= case */ 518 bdemsky 1.1.2.17 public final static int GTE = 4; 519 bdemsky 1.1.2.19 /** <code>toString</code> returns a string representation of the 520 bdemsky 1.1.2.19 * for loop.*/ 521 bdemsky 1.1.2.17 public String toString() { 522 bdemsky 1.1.2.17 String ttype=null; 523 bdemsky 1.1.2.17 switch(testtype) { 524 bdemsky 1.1.2.17 case NEQ: 525 bdemsky 1.1.2.17 ttype="!="; 526 bdemsky 1.1.2.17 break; 527 bdemsky 1.1.2.17 case LT: 528 bdemsky 1.1.2.17 ttype="<"; 529 bdemsky 1.1.2.17 break; 530 bdemsky 1.1.2.17 case LTE: 531 bdemsky 1.1.2.17 ttype="<="; 532 bdemsky 1.1.2.17 break; 533 bdemsky 1.1.2.17 case GT: 534 bdemsky 1.1.2.17 ttype=">"; 535 bdemsky 1.1.2.17 break; 536 bdemsky 1.1.2.17 case GTE: 537 bdemsky 1.1.2.17 ttype=">="; 538 bdemsky 1.1.2.17 break; 539 bdemsky 1.1.2.17 default: 540 bdemsky 1.1.2.17 } 541 bdemsky 1.1.2.17 return new String(induction+"="+indinitial+ 542 bdemsky 1.1.2.17 ";"+induction+ttype+indfinal+";" 543 bdemsky 1.1.2.17 +induction+"+="+increment); 544 bdemsky 1.1.2.17 } 545 bdemsky 1.1.2.17 } 546 bdemsky 1.1.2.17 547 bdemsky 1.1.2.17 548 bdemsky 1.1.2.14 /* NOTE: Assumption is made that no quad can go wrong, otherwise 549 bdemsky 1.1.2.14 there would have been an explicity test before it...*/ 550 bdemsky 1.1.2.14 class ForLoopVisitor extends LowQuadVisitor { 551 bdemsky 1.1.2.14 private WorkSet track; 552 bdemsky 1.1.2.14 private boolean sideeffects; 553 bdemsky 1.1.2.14 private Set testsopers; 554 bdemsky 1.1.2.14 private UseDef ud; 555 bdemsky 1.1.2.14 private HCode hc; 556 bdemsky 1.1.2.14 private Loops lp; 557 bdemsky 1.1.2.14 private TempMap ssitossamap; 558 bdemsky 1.1.2.15 private boolean analysisdone; 559 bdemsky 1.1.2.15 private Temp inductionvar; 560 bdemsky 1.1.2.15 private OPER testcondition; 561 bdemsky 1.1.2.17 private int bindex; 562 bdemsky 1.1.2.17 private int cjmpedge; 563 bdemsky 1.1.2.17 private CJMP cjmp; 564 bdemsky 1.1.2.14 565 bdemsky 1.1.2.14 ForLoopVisitor(Set testsopers, HCode hc, UseDef ud, Loops lp, TempMap ssitossamap) { 566 bdemsky 1.1.2.14 this.track=new WorkSet(); 567 bdemsky 1.1.2.14 this.sideeffects=false; 568 bdemsky 1.1.2.14 this.testsopers=testsopers; 569 bdemsky 1.1.2.14 this.ud=ud; 570 bdemsky 1.1.2.14 this.hc=hc; 571 bdemsky 1.1.2.14 this.lp=lp; 572 bdemsky 1.1.2.14 this.ssitossamap=ssitossamap; 573 bdemsky 1.1.2.15 this.analysisdone=false; 574 bdemsky 1.1.2.15 this.inductionvar=null; 575 bdemsky 1.1.2.15 this.testcondition=null; 576 bdemsky 1.1.2.17 this.cjmpedge=-1; 577 bdemsky 1.1.2.17 } 578 bdemsky 1.1.2.17 579 bdemsky 1.1.2.17 int cjmpedge() { 580 bdemsky 1.1.2.17 return cjmpedge; 581 bdemsky 1.1.2.15 } 582 bdemsky 1.1.2.15 583 bdemsky 1.1.2.15 boolean done() { 584 bdemsky 1.1.2.15 return analysisdone; 585 bdemsky 1.1.2.14 } 586 bdemsky 1.1.2.14 587 bdemsky 1.1.2.14 boolean sideEffects() { 588 bdemsky 1.1.2.14 return sideeffects; 589 bdemsky 1.1.2.14 } 590 bdemsky 1.1.2.14 591 bdemsky 1.1.2.15 boolean forLoop() { 592 bdemsky 1.1.2.15 return (analysisdone&&(inductionvar!=null)); 593 bdemsky 1.1.2.15 } 594 bdemsky 1.1.2.15 595 bdemsky 1.1.2.17 CJMP cjmpExit() { 596 bdemsky 1.1.2.17 return cjmp; 597 bdemsky 1.1.2.17 } 598 bdemsky 1.1.2.17 599 bdemsky 1.1.2.15 OPER testCondition() { 600 bdemsky 1.1.2.15 return testcondition; 601 bdemsky 1.1.2.15 } 602 bdemsky 1.1.2.15 603 bdemsky 1.1.2.15 Temp inductionVar() { 604 bdemsky 1.1.2.15 return inductionvar; 605 bdemsky 1.1.2.15 } 606 bdemsky 1.1.2.15 607 bdemsky 1.1.2.17 int bindex() { 608 bdemsky 1.1.2.17 return bindex; 609 bdemsky 1.1.2.17 } 610 bdemsky 1.1.2.17 611 bdemsky 1.1.2.14 public void visit(Quad q) { 612 bdemsky 1.1.2.14 System.out.println("Error in ForLoopVisitor"); 613 bdemsky 1.1.2.14 System.out.println(q.toString()+" unhandled"); 614 bdemsky 1.1.2.14 } 615 bdemsky 1.1.2.14 616 bdemsky 1.1.2.14 public void visit(AGET q) { trackuses(q); } 617 bdemsky 1.1.2.14 public void visit(ALENGTH q) { trackuses(q); } 618 bdemsky 1.1.2.14 public void visit(ANEW q) { trackuses(q); } 619 bdemsky 1.1.2.14 //These two may have side effects.... 620 bdemsky 1.1.2.14 //Need to complete more complicated analysis on them... 621 bdemsky 1.1.2.14 public void visit(ARRAYINIT q) { sideeffects(q); } 622 bdemsky 1.1.2.14 public void visit(ASET q) { sideeffects(q); } 623 bdemsky 1.1.2.14 624 bdemsky 1.1.2.14 //Calls have side efects 625 bdemsky 1.1.2.14 public void visit(CALL q) { sideeffects(q); } 626 bdemsky 1.1.2.14 627 bdemsky 1.1.2.14 //CJMP stops search 628 bdemsky 1.1.2.14 public void visit(CJMP q) { 629 bdemsky 1.1.2.14 //is this a test condition? 630 bdemsky 1.1.2.14 Temp test=q.test(); 631 bdemsky 1.1.2.14 Quad[] defs=(Quad[])ud.defMap(hc, test); 632 cananian 1.3.2.1 assert defs.length==1 : "We work only with SSA/SSI"; 633 bdemsky 1.1.2.15 Temp binvar=null; 634 bdemsky 1.1.2.14 if (testsopers.contains(defs[0])) { 635 bdemsky 1.1.2.14 //Need to see if it: 636 bdemsky 1.1.2.14 //1) Is on a basic induction variable! 637 bdemsky 1.1.2.14 //2) That the jump leaves the loop 638 bdemsky 1.1.2.14 //3) None of the trackuses set gets used outside of the loop 639 bdemsky 1.1.2.14 //4) None of the sigma defines gets used outside of the loop 640 bdemsky 1.1.2.14 //5) That the increment of the basic induction variable doesn't 641 bdemsky 1.1.2.14 //get used at any point other than the phi function... 642 bdemsky 1.1.2.17 int exit=analyzecjmp(q); 643 bdemsky 1.1.2.17 if (exit!=-1) { 644 bdemsky 1.1.2.14 //finished #2, setup track for #3, 4... 645 bdemsky 1.1.2.14 //See if we have a basic induction varible... 646 bdemsky 1.1.2.14 OPER testoper=(OPER)defs[0]; 647 bdemsky 1.1.2.14 Map bamap=(Map)bimap.get(lp.loopEntrances().toArray()[0]); 648 bdemsky 1.1.2.14 for (int i=0;i<testoper.operandsLength();i++) { 649 bdemsky 1.1.2.17 if (bamap.containsKey(ssitossamap.tempMap(testoper.operands(i)))) { 650 bdemsky 1.1.2.15 binvar=ssitossamap.tempMap(testoper.operands(i)); 651 bdemsky 1.1.2.17 bindex=i; 652 bdemsky 1.1.2.17 } 653 bdemsky 1.1.2.14 //have a basic induction variable [#1 finished] 654 bdemsky 1.1.2.14 } 655 bdemsky 1.1.2.15 if (binvar!=null) { 656 bdemsky 1.1.2.14 //Still need to verify track set [#3, #4] 657 bdemsky 1.1.2.14 //Still need to check uses of increment [#5] 658 bdemsky 1.1.2.15 PHI header=(PHI)(lp.loopEntrances()).toArray()[0]; 659 cananian 1.1.2.22 OPER addquad=(OPER)addQuad(hc, header,binvar, lp.loopIncElements()); 660 bdemsky 1.1.2.15 Temp nextinc=addquad.dst(); 661 bdemsky 1.1.2.18 boolean otheruse=false; 662 bdemsky 1.1.2.18 WorkSet tocheck=new WorkSet(); 663 bdemsky 1.1.2.18 WorkSet done=new WorkSet(); 664 bdemsky 1.1.2.18 tocheck.add(nextinc); 665 bdemsky 1.1.2.18 boolean good=true; 666 bdemsky 1.1.2.18 while(good&&(!tocheck.isEmpty())) { 667 bdemsky 1.1.2.18 Temp tuse=(Temp)tocheck.pop(); 668 bdemsky 1.1.2.18 done.add(tuse); 669 bdemsky 1.1.2.18 HCodeElement[] niuses=ud.useMap(hc, tuse); 670 bdemsky 1.1.2.18 for (int i=0;i<niuses.length;i++) 671 bdemsky 1.1.2.18 if (niuses[i]!=header) { 672 bdemsky 1.1.2.18 int kind=((Quad)niuses[i]).kind(); 673 bdemsky 1.1.2.18 if ((kind==QuadKind.CJMP)|| 674 cananian 1.1.2.21 (kind==QuadKind.SWITCH)|| 675 cananian 1.1.2.21 (kind==QuadKind.TYPESWITCH)) { 676 bdemsky 1.1.2.18 SIGMA sigma=(SIGMA)niuses[i]; 677 bdemsky 1.1.2.18 for(int j=0;j<sigma.numSigmas();j++) 678 bdemsky 1.1.2.18 if(sigma.src(j)==tuse) { 679 bdemsky 1.1.2.18 for(int k=0;k<sigma.arity();k++) 680 bdemsky 1.1.2.18 if (!done.contains(sigma.dst(j,k))) 681 bdemsky 1.1.2.18 tocheck.add(sigma.dst(j,k)); 682 bdemsky 1.1.2.18 } 683 bdemsky 1.1.2.18 } else if(kind==QuadKind.CALL) { 684 bdemsky 1.1.2.18 CALL csigma=(CALL)niuses[i]; 685 bdemsky 1.1.2.18 for(int l=0;l<csigma.paramsLength();l++) 686 bdemsky 1.1.2.18 if (csigma.params(i)==tuse) { 687 bdemsky 1.1.2.18 good=false; 688 bdemsky 1.1.2.18 break; 689 bdemsky 1.1.2.18 } 690 bdemsky 1.1.2.18 if (good) 691 bdemsky 1.1.2.18 for(int j=0;j<csigma.numSigmas();j++) 692 bdemsky 1.1.2.18 if(csigma.src(j)==tuse) { 693 bdemsky 1.1.2.18 for(int k=0;k<csigma.arity();k++) 694 bdemsky 1.1.2.18 if (!done.contains(csigma.dst(j,k))) 695 bdemsky 1.1.2.18 tocheck.add(csigma.dst(j,k)); 696 bdemsky 1.1.2.18 } 697 bdemsky 1.1.2.18 } else if(kind==LowQuadKind.PCALL) { 698 bdemsky 1.1.2.18 PCALL psigma=(PCALL)niuses[i]; 699 bdemsky 1.1.2.18 for(int l=0;l<psigma.paramsLength();l++) 700 bdemsky 1.1.2.18 if (psigma.params(i)==tuse) { 701 bdemsky 1.1.2.18 good=false; 702 bdemsky 1.1.2.18 break; 703 bdemsky 1.1.2.18 } 704 bdemsky 1.1.2.18 if (good) 705 bdemsky 1.1.2.18 for(int j=0;j<psigma.numSigmas();j++) 706 bdemsky 1.1.2.18 if(psigma.src(j)==tuse) { 707 bdemsky 1.1.2.18 for(int k=0;k<psigma.arity();k++) 708 bdemsky 1.1.2.18 if (!done.contains(psigma.dst(j,k))) 709 bdemsky 1.1.2.18 tocheck.add(psigma.dst(j,k)); 710 bdemsky 1.1.2.18 } 711 bdemsky 1.1.2.18 } else if(kind==QuadKind.PHI) { 712 bdemsky 1.1.2.18 PHI phi=(PHI)niuses[i]; 713 bdemsky 1.1.2.18 for (int j=0;j<phi.numPhis();j++) 714 bdemsky 1.1.2.18 for (int k=0;k<phi.numPhis();k++) { 715 bdemsky 1.1.2.18 if (tuse==phi.src(j,k)) { 716 bdemsky 1.1.2.18 if (!done.contains(phi.dst(j))) 717 bdemsky 1.1.2.18 tocheck.add(phi.dst(j)); 718 bdemsky 1.1.2.18 } 719 bdemsky 1.1.2.18 } 720 bdemsky 1.1.2.18 } else 721 bdemsky 1.1.2.18 good=false; 722 bdemsky 1.1.2.18 723 bdemsky 1.1.2.18 } 724 bdemsky 1.1.2.18 } 725 bdemsky 1.1.2.18 if (good) 726 bdemsky 1.1.2.15 //condition #5 satisfied 727 bdemsky 1.1.2.15 if (checktracks()) { 728 bdemsky 1.1.2.15 inductionvar=binvar; 729 bdemsky 1.1.2.17 cjmpedge=exit; 730 bdemsky 1.1.2.15 testcondition=testoper; 731 bdemsky 1.1.2.17 cjmp=q; 732 bdemsky 1.1.2.15 } 733 bdemsky 1.1.2.15 //conditions 3&4 satisfied 734 bdemsky 1.1.2.15 } 735 bdemsky 1.1.2.15 } 736 bdemsky 1.1.2.15 } 737 bdemsky 1.1.2.15 analysisdone=true; 738 bdemsky 1.1.2.15 } 739 bdemsky 1.1.2.14 740 bdemsky 1.1.2.15 boolean checktracks() { 741 bdemsky 1.1.2.15 Iterator trackiterate=track.iterator(); 742 bdemsky 1.1.2.15 boolean go=true; 743 cananian 1.1.2.22 Set loopset=lp.loopIncElements(); 744 bdemsky 1.1.2.15 while (trackiterate.hasNext()&&go) { 745 bdemsky 1.1.2.15 Temp temptocheck=(Temp)trackiterate.next(); 746 bdemsky 1.1.2.15 HCodeElement[] uses=ud.useMap(hc, temptocheck); 747 bdemsky 1.1.2.15 for (int i=0;i<uses.length;i++) { 748 bdemsky 1.1.2.15 if (!loopset.contains(uses[i])) { 749 bdemsky 1.1.2.15 go=false; 750 bdemsky 1.1.2.15 break; 751 bdemsky 1.1.2.14 } 752 bdemsky 1.1.2.14 } 753 bdemsky 1.1.2.14 } 754 bdemsky 1.1.2.15 return go; 755 bdemsky 1.1.2.14 } 756 bdemsky 1.1.2.15 757 bdemsky 1.1.2.17 int analyzecjmp(CJMP q) { 758 bdemsky 1.1.2.17 int exit=-1; 759 bdemsky 1.1.2.14 for (int i=0;i<q.nextLength();i++) 760 cananian 1.1.2.22 if (!lp.loopIncElements().contains(q.next(i))) { 761 bdemsky 1.1.2.14 //we've found the way out... 762 bdemsky 1.1.2.14 //we only add things in if 763 bdemsky 1.1.2.14 //they were not generated in front of us... 764 bdemsky 1.1.2.15 //might create confusing semantics, 765 bdemsky 1.1.2.14 //but gotta do it to find any for loops at all that 766 bdemsky 1.1.2.14 //allow lv to escape 767 bdemsky 1.1.2.14 for(int j=0;j<q.numSigmas();j++) 768 bdemsky 1.1.2.14 if (track.contains(q.src(j))) 769 bdemsky 1.1.2.14 track.add(q.dst(j,i)); 770 bdemsky 1.1.2.17 exit=i; 771 bdemsky 1.1.2.14 } 772 bdemsky 1.1.2.14 return exit; 773 bdemsky 1.1.2.14 } 774 bdemsky 1.1.2.14 775 bdemsky 1.1.2.14 public void visit(COMPONENTOF q) { trackuses(q); } 776 bdemsky 1.1.2.14 public void visit(CONST q) { trackuses(q); } 777 bdemsky 1.1.2.14 778 bdemsky 1.1.2.14 public void visit(GET q) { trackuses(q); } 779 bdemsky 1.1.2.14 780 bdemsky 1.1.2.14 //Our friend... 781 bdemsky 1.1.2.14 public void visit(INSTANCEOF q) { trackuses(q); } 782 bdemsky 1.1.2.14 783 bdemsky 1.1.2.14 public void visit(MONITORENTER q) { sideeffects(q); } 784 bdemsky 1.1.2.14 public void visit(MONITOREXIT q) { sideeffects(q); } 785 bdemsky 1.1.2.14 public void visit(MOVE q) { trackuses(q); } 786 bdemsky 1.1.2.14 public void visit(NEW q) { trackuses(q); } 787 bdemsky 1.1.2.14 788 bdemsky 1.1.2.14 public void visit(POPER q) { checkopers(q); } 789 bdemsky 1.1.2.14 public void visit(OPER q) { checkopers(q); } 790 bdemsky 1.1.2.14 791 bdemsky 1.1.2.19 //See if we have division by 0 792 bdemsky 1.1.2.14 private void checkopers(OPER q) { 793 bdemsky 1.1.2.14 switch (q.opcode()) { 794 bdemsky 1.1.2.14 case Qop.IDIV: 795 bdemsky 1.1.2.14 case Qop.IREM: 796 bdemsky 1.1.2.14 case Qop.LDIV: 797 bdemsky 1.1.2.14 case Qop.LREM: 798 bdemsky 1.1.2.14 sideeffects(q); 799 bdemsky 1.1.2.14 break; 800 bdemsky 1.1.2.14 default: 801 bdemsky 1.1.2.14 trackuses(q); 802 bdemsky 1.1.2.14 break; 803 bdemsky 1.1.2.14 } 804 bdemsky 1.1.2.14 } 805 bdemsky 1.1.2.14 806 bdemsky 1.1.2.14 //Might want to do something different here.... 807 bdemsky 1.1.2.14 //IE..Only add if track.cotnains(src of the phi function)... 808 bdemsky 1.1.2.14 //Not done yet, would complicate things... 809 bdemsky 1.1.2.14 public void visit(PHI q) { trackuses(q); } 810 bdemsky 1.1.2.14 public void visit(RETURN q) { sideeffects(q); } 811 bdemsky 1.1.2.14 //Have to do more complicated analysis... 812 bdemsky 1.1.2.14 public void visit(SET q) { sideeffects(q); } 813 bdemsky 1.1.2.14 814 bdemsky 1.1.2.14 public void visit(THROW q) { sideeffects(q); } 815 bdemsky 1.1.2.14 public void visit(TYPECAST q) { trackuses(q); } 816 bdemsky 1.1.2.14 817 bdemsky 1.1.2.14 public void visit(PCALL q) { sideeffects(q); } 818 bdemsky 1.1.2.14 public void visit(PGET q) { trackuses(q); } 819 bdemsky 1.1.2.14 //Need more complicated analysis... 820 bdemsky 1.1.2.14 public void visit(PSET q) { sideeffects(q); } 821 bdemsky 1.1.2.14 822 bdemsky 1.1.2.14 // PPTR: 823 bdemsky 1.1.2.14 public void visit(PARRAY q) { trackuses(q); } 824 bdemsky 1.1.2.14 public void visit(PFIELD q) { trackuses(q); } 825 bdemsky 1.1.2.14 public void visit(PMETHOD q) { trackuses(q); } 826 bdemsky 1.1.2.14 // PCONST: 827 bdemsky 1.1.2.14 public void visit(PCONST q) { trackuses(q); } 828 bdemsky 1.1.2.14 public void visit(PAOFFSET q) { trackuses(q); } 829 bdemsky 1.1.2.14 public void visit(PFOFFSET q) { trackuses(q); } 830 bdemsky 1.1.2.14 public void visit(PMOFFSET q) { trackuses(q); } 831 bdemsky 1.1.2.14 public void visit(PFCONST q) { trackuses(q); } 832 bdemsky 1.1.2.14 public void visit(PMCONST q) { trackuses(q); } 833 bdemsky 1.1.2.14 void trackuses(Quad q) { 834 bdemsky 1.1.2.14 Temp[] defs=q.def(); 835 bdemsky 1.1.2.14 for (int i=0;i<defs.length;i++) { 836 bdemsky 1.1.2.14 track.add(defs[i]); 837 bdemsky 1.1.2.14 } 838 bdemsky 1.1.2.14 } 839 bdemsky 1.1.2.14 void sideeffects(Quad q) { 840 bdemsky 1.1.2.14 sideeffects=true; 841 bdemsky 1.1.2.14 } 842 bdemsky 1.1.2.14 } 843 bdemsky 1.1.2.1 } 844 bdemsky 1.1.2.14 845 bdemsky 1.1.2.3 846 cananian 1.2