1 bdemsky 1.1.2.1 // Loopinvariance.java, created Mon Jun 28 13:33:40 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 bdemsky 1.1.2.1 import harpoon.Analysis.UseDef; 7 cananian 1.1.2.10 import harpoon.ClassFile.HCode; 8 cananian 1.1.2.10 import harpoon.ClassFile.HCodeElement; 9 cananian 1.1.2.10 import harpoon.IR.LowQuad.LowQuadVisitor; 10 cananian 1.1.2.10 import harpoon.IR.LowQuad.PAOFFSET; 11 cananian 1.1.2.10 import harpoon.IR.LowQuad.PARRAY; 12 cananian 1.1.2.10 import harpoon.IR.LowQuad.PCALL; 13 cananian 1.1.2.10 import harpoon.IR.LowQuad.PFCONST; 14 cananian 1.1.2.10 import harpoon.IR.LowQuad.PFIELD; 15 cananian 1.1.2.10 import harpoon.IR.LowQuad.PFOFFSET; 16 cananian 1.1.2.10 import harpoon.IR.LowQuad.PGET; 17 cananian 1.1.2.10 import harpoon.IR.LowQuad.PMCONST; 18 cananian 1.1.2.10 import harpoon.IR.LowQuad.PMETHOD; 19 cananian 1.1.2.10 import harpoon.IR.LowQuad.PMOFFSET; 20 cananian 1.1.2.10 import harpoon.IR.LowQuad.POPER; 21 cananian 1.1.2.10 import harpoon.IR.LowQuad.PSET; 22 cananian 1.1.2.10 import harpoon.IR.Quads.AGET; 23 cananian 1.1.2.10 import harpoon.IR.Quads.ALENGTH; 24 cananian 1.1.2.10 import harpoon.IR.Quads.ANEW; 25 cananian 1.1.2.10 import harpoon.IR.Quads.ARRAYINIT; 26 cananian 1.1.2.10 import harpoon.IR.Quads.ASET; 27 cananian 1.1.2.10 import harpoon.IR.Quads.CALL; 28 cananian 1.1.2.10 import harpoon.IR.Quads.COMPONENTOF; 29 cananian 1.1.2.10 import harpoon.IR.Quads.CONST; 30 cananian 1.1.2.10 import harpoon.IR.Quads.FOOTER; 31 cananian 1.1.2.10 import harpoon.IR.Quads.GET; 32 cananian 1.1.2.10 import harpoon.IR.Quads.HANDLER; 33 cananian 1.1.2.10 import harpoon.IR.Quads.HEADER; 34 cananian 1.1.2.10 import harpoon.IR.Quads.INSTANCEOF; 35 cananian 1.1.2.10 import harpoon.IR.Quads.METHOD; 36 cananian 1.1.2.10 import harpoon.IR.Quads.MONITORENTER; 37 cananian 1.1.2.10 import harpoon.IR.Quads.MONITOREXIT; 38 cananian 1.1.2.10 import harpoon.IR.Quads.MOVE; 39 cananian 1.1.2.10 import harpoon.IR.Quads.NEW; 40 cananian 1.1.2.10 import harpoon.IR.Quads.NOP; 41 cananian 1.1.2.10 import harpoon.IR.Quads.OPER; 42 cananian 1.1.2.10 import harpoon.IR.Quads.PHI; 43 cananian 1.1.2.10 import harpoon.IR.Quads.Qop; 44 cananian 1.1.2.10 import harpoon.IR.Quads.Quad; 45 cananian 1.1.2.10 import harpoon.IR.Quads.RETURN; 46 cananian 1.1.2.10 import harpoon.IR.Quads.SET; 47 cananian 1.1.2.10 import harpoon.IR.Quads.SIGMA; 48 cananian 1.1.2.10 import harpoon.IR.Quads.THROW; 49 bdemsky 1.1.2.1 import harpoon.Temp.TempMap; 50 bdemsky 1.1.2.1 import harpoon.Temp.Temp; 51 cananian 1.3 import net.cscott.jutil.WorkSet; 52 bdemsky 1.1.2.1 53 bdemsky 1.1.2.1 import java.util.Iterator; 54 bdemsky 1.1.2.1 /** 55 bdemsky 1.1.2.1 * <code>LoopInvariance</code> 56 bdemsky 1.1.2.1 * 57 bdemsky 1.1.2.1 * @author Brian Demsky <bdemsky@mit.edu> 58 cananian 1.3 * @version $Id: LoopInvariance.java,v 1.3 2004/02/08 01:52:54 cananian Exp $ 59 bdemsky 1.1.2.1 */ 60 bdemsky 1.1.2.1 public class LoopInvariance { 61 bdemsky 1.1.2.1 62 bdemsky 1.1.2.1 63 bdemsky 1.1.2.1 TempMap tm; 64 bdemsky 1.1.2.1 HCode hc; 65 bdemsky 1.1.2.1 66 bdemsky 1.1.2.2 /** Creates a <code>LoopInvariance</code>. */ 67 bdemsky 1.1.2.1 public LoopInvariance(TempMap tm,HCode hc) { 68 bdemsky 1.1.2.1 this.tm=tm; 69 bdemsky 1.1.2.1 this.hc=hc; 70 bdemsky 1.1.2.1 } 71 bdemsky 1.1.2.1 72 bdemsky 1.1.2.2 /** Creates a <code>WorkSet</code> containing <code>Quad</code>s that 73 bdemsky 1.1.2.2 * are loop invariant. Takes in a <code>WorkSet</code> of 74 bdemsky 1.1.2.2 * <code>Quad</code>s that are in the loop. */ 75 bdemsky 1.1.2.2 76 bdemsky 1.1.2.1 public WorkSet invariants(WorkSet elements) { 77 bdemsky 1.1.2.1 WorkSet invariants=new WorkSet(); 78 bdemsky 1.1.2.1 harpoon.Analysis.UseDef ud = new harpoon.Analysis.UseDef(); 79 bdemsky 1.1.2.1 boolean change=true; 80 bdemsky 1.1.2.1 InvariantVisitor visitor=new InvariantVisitor(ud, elements, invariants); 81 bdemsky 1.1.2.1 while (visitor.change()) { 82 bdemsky 1.1.2.1 visitor.reset(); 83 bdemsky 1.1.2.1 Iterator ourself=elements.iterator(); 84 bdemsky 1.1.2.1 while (ourself.hasNext()) { 85 bdemsky 1.1.2.1 Quad nxt=(Quad)ourself.next(); 86 bdemsky 1.1.2.1 //is this node invariant? 87 cananian 1.1.2.8 nxt.accept(visitor); 88 bdemsky 1.1.2.1 if (visitor.remove()) 89 bdemsky 1.1.2.1 ourself.remove(); 90 bdemsky 1.1.2.1 //doesn't depend on this loop...so add it to invariants 91 bdemsky 1.1.2.1 } 92 bdemsky 1.1.2.1 } 93 bdemsky 1.1.2.1 return invariants; 94 bdemsky 1.1.2.1 } 95 bdemsky 1.1.2.2 96 bdemsky 1.1.2.2 /** <code>InvariantVisitor</code> visits Quads and determines if they are 97 bdemsky 1.1.2.2 * loop invariant.*/ 98 bdemsky 1.1.2.1 99 bdemsky 1.1.2.1 class InvariantVisitor extends LowQuadVisitor { 100 bdemsky 1.1.2.1 UseDef ud; 101 bdemsky 1.1.2.1 WorkSet invariants; 102 bdemsky 1.1.2.1 boolean change; 103 bdemsky 1.1.2.1 WorkSet elements; 104 bdemsky 1.1.2.1 boolean removeflag; 105 bdemsky 1.1.2.1 106 bdemsky 1.1.2.1 InvariantVisitor(UseDef ud, WorkSet elements, WorkSet invariants) { 107 bdemsky 1.1.2.1 this.ud=ud; 108 bdemsky 1.1.2.1 this.invariants=invariants; 109 bdemsky 1.1.2.1 this.elements=elements; 110 bdemsky 1.1.2.1 change=true; 111 bdemsky 1.1.2.1 } 112 bdemsky 1.1.2.1 113 bdemsky 1.1.2.1 public boolean remove() { 114 bdemsky 1.1.2.1 return removeflag; 115 bdemsky 1.1.2.1 } 116 bdemsky 1.1.2.1 117 bdemsky 1.1.2.1 public boolean change() { 118 bdemsky 1.1.2.1 return change; 119 bdemsky 1.1.2.1 } 120 bdemsky 1.1.2.1 121 bdemsky 1.1.2.1 public void reset() { 122 bdemsky 1.1.2.1 change=false; 123 bdemsky 1.1.2.4 } 124 bdemsky 1.1.2.4 125 bdemsky 1.1.2.3 void visitdefault(Quad q) { 126 bdemsky 1.1.2.1 Temp [] uses=q.use(); 127 bdemsky 1.1.2.1 boolean ours=false; 128 bdemsky 1.1.2.1 for (int i=0;i<uses.length;i++) { 129 bdemsky 1.1.2.1 HCodeElement []sources=ud.defMap(hc,tm.tempMap(uses[i])); 130 bdemsky 1.1.2.1 for (int j=0;j<sources.length;j++) { 131 bdemsky 1.1.2.1 if (elements.contains(sources[j])) { 132 bdemsky 1.1.2.1 ours=true; break; 133 bdemsky 1.1.2.1 } 134 bdemsky 1.1.2.1 } 135 bdemsky 1.1.2.6 } 136 bdemsky 1.1.2.1 if (ours==false) { 137 bdemsky 1.1.2.1 change=true; 138 bdemsky 1.1.2.1 removeflag=true; 139 bdemsky 1.1.2.1 invariants.push(q); 140 bdemsky 1.1.2.1 } else 141 bdemsky 1.1.2.1 removeflag=false; 142 bdemsky 1.1.2.1 } 143 bdemsky 1.1.2.1 144 bdemsky 1.1.2.1 145 bdemsky 1.1.2.7 public void visit(Quad q) { 146 bdemsky 1.1.2.7 System.out.println("Not expected in LoopInvariance:" + q.toString()); 147 bdemsky 1.1.2.1 removeflag=false; 148 bdemsky 1.1.2.3 } 149 bdemsky 1.1.2.9 150 bdemsky 1.1.2.9 /* All of these redefined to avoid error messages!*/ 151 bdemsky 1.1.2.9 public void visit(harpoon.IR.Quads.AGET q) { 152 bdemsky 1.1.2.9 removeflag=false; 153 bdemsky 1.1.2.9 } 154 bdemsky 1.1.2.9 155 bdemsky 1.1.2.9 public void visit(harpoon.IR.Quads.ASET q) { 156 bdemsky 1.1.2.9 removeflag=false; 157 bdemsky 1.1.2.9 } 158 bdemsky 1.1.2.9 159 bdemsky 1.1.2.9 public void visit(harpoon.IR.Quads.CALL q) { 160 bdemsky 1.1.2.9 removeflag=false; 161 bdemsky 1.1.2.9 } 162 bdemsky 1.1.2.9 163 bdemsky 1.1.2.9 public void visit(harpoon.IR.Quads.GET q) { 164 bdemsky 1.1.2.9 removeflag=false; 165 bdemsky 1.1.2.9 } 166 bdemsky 1.1.2.9 167 bdemsky 1.1.2.9 public void visit(harpoon.IR.Quads.HANDLER q) { 168 bdemsky 1.1.2.9 //better not be in a loop!!!!!!! 169 bdemsky 1.1.2.9 removeflag=false; 170 bdemsky 1.1.2.9 } 171 bdemsky 1.1.2.9 172 bdemsky 1.1.2.9 public void visit(harpoon.IR.Quads.OPER q) { 173 bdemsky 1.1.2.9 switch (q.opcode()) { 174 bdemsky 1.1.2.9 case Qop.DDIV: 175 bdemsky 1.1.2.9 case Qop.FDIV: 176 bdemsky 1.1.2.9 case Qop.IDIV: 177 bdemsky 1.1.2.9 case Qop.LDIV: 178 bdemsky 1.1.2.9 removeflag=false; 179 bdemsky 1.1.2.9 break; 180 bdemsky 1.1.2.9 default: 181 bdemsky 1.1.2.9 visitdefault(q); 182 bdemsky 1.1.2.9 } 183 bdemsky 1.1.2.9 } 184 bdemsky 1.1.2.9 185 bdemsky 1.1.2.9 public void visit(harpoon.IR.Quads.SET q) { 186 bdemsky 1.1.2.9 removeflag=false; 187 bdemsky 1.1.2.9 } 188 bdemsky 1.1.2.9 189 bdemsky 1.1.2.3 190 bdemsky 1.1.2.7 public void visit(ALENGTH q) { 191 bdemsky 1.1.2.7 visitdefault(q); 192 bdemsky 1.1.2.6 } 193 bdemsky 1.1.2.6 194 bdemsky 1.1.2.7 public void visit(ANEW q) { 195 bdemsky 1.1.2.7 //Not loop invariant 196 bdemsky 1.1.2.5 removeflag=false; 197 bdemsky 1.1.2.5 } 198 bdemsky 1.1.2.5 199 bdemsky 1.1.2.7 public void visit(ARRAYINIT q) { 200 bdemsky 1.1.2.5 removeflag=false; 201 bdemsky 1.1.2.5 } 202 bdemsky 1.1.2.5 203 bdemsky 1.1.2.7 public void visit(COMPONENTOF q) { 204 bdemsky 1.1.2.7 visitdefault(q); 205 bdemsky 1.1.2.5 } 206 bdemsky 1.1.2.5 207 bdemsky 1.1.2.7 public void visit(CONST q) { 208 bdemsky 1.1.2.7 visitdefault(q); 209 bdemsky 1.1.2.1 } 210 bdemsky 1.1.2.1 211 bdemsky 1.1.2.5 public void visit(FOOTER q) { 212 bdemsky 1.1.2.6 removeflag=false; 213 bdemsky 1.1.2.6 } 214 bdemsky 1.1.2.6 215 bdemsky 1.1.2.6 public void visit(HEADER q) { 216 bdemsky 1.1.2.5 removeflag=false; 217 bdemsky 1.1.2.5 } 218 bdemsky 1.1.2.5 219 bdemsky 1.1.2.7 public void visit(INSTANCEOF q) { 220 bdemsky 1.1.2.7 visitdefault(q); 221 bdemsky 1.1.2.7 } 222 bdemsky 1.1.2.7 223 bdemsky 1.1.2.5 public void visit(METHOD q) { 224 bdemsky 1.1.2.5 removeflag=false; 225 bdemsky 1.1.2.5 } 226 bdemsky 1.1.2.5 227 bdemsky 1.1.2.5 public void visit(MONITORENTER q) { 228 bdemsky 1.1.2.5 removeflag=false; 229 bdemsky 1.1.2.5 } 230 bdemsky 1.1.2.5 231 bdemsky 1.1.2.5 public void visit(MONITOREXIT q) { 232 bdemsky 1.1.2.5 removeflag=false; 233 bdemsky 1.1.2.5 } 234 bdemsky 1.1.2.5 235 bdemsky 1.1.2.7 public void visit(MOVE q) { 236 bdemsky 1.1.2.7 visitdefault(q); 237 bdemsky 1.1.2.7 } 238 bdemsky 1.1.2.7 239 bdemsky 1.1.2.7 public void visit(NEW q) { 240 bdemsky 1.1.2.7 removeflag=false; 241 bdemsky 1.1.2.7 } 242 bdemsky 1.1.2.7 243 bdemsky 1.1.2.7 public void visit(NOP q) { 244 bdemsky 1.1.2.7 visitdefault(q); 245 bdemsky 1.1.2.7 } 246 bdemsky 1.1.2.7 247 bdemsky 1.1.2.1 public void visit(PCALL q) { 248 bdemsky 1.1.2.1 //Calls aren't loop invariant... 249 bdemsky 1.1.2.1 //they might have side effects 250 bdemsky 1.1.2.7 removeflag=false; 251 bdemsky 1.1.2.7 } 252 bdemsky 1.1.2.7 253 bdemsky 1.1.2.7 public void visit(PARRAY q) { visitdefault(q); } 254 bdemsky 1.1.2.7 public void visit(PFIELD q) { visitdefault(q); } 255 bdemsky 1.1.2.7 public void visit(PMETHOD q) { visitdefault(q); } 256 bdemsky 1.1.2.7 public void visit(PAOFFSET q) { visitdefault(q); } 257 bdemsky 1.1.2.7 public void visit(PFOFFSET q) { visitdefault(q); } 258 bdemsky 1.1.2.7 public void visit(PMOFFSET q) { visitdefault(q); } 259 bdemsky 1.1.2.7 public void visit(PFCONST q) { visitdefault(q); } 260 bdemsky 1.1.2.7 public void visit(PMCONST q) { visitdefault(q); } 261 bdemsky 1.1.2.7 262 bdemsky 1.1.2.7 public void visit(PGET q) { 263 bdemsky 1.1.2.7 removeflag=false; 264 bdemsky 1.1.2.7 } 265 bdemsky 1.1.2.7 266 bdemsky 1.1.2.7 public void visit(POPER q) { 267 bdemsky 1.1.2.7 switch (q.opcode()) { 268 bdemsky 1.1.2.7 case Qop.DDIV: 269 bdemsky 1.1.2.7 case Qop.FDIV: 270 bdemsky 1.1.2.7 case Qop.IDIV: 271 bdemsky 1.1.2.7 case Qop.LDIV: 272 bdemsky 1.1.2.7 removeflag=false; 273 bdemsky 1.1.2.7 break; 274 bdemsky 1.1.2.7 default: 275 bdemsky 1.1.2.7 visitdefault(q); 276 bdemsky 1.1.2.7 } 277 bdemsky 1.1.2.7 } 278 bdemsky 1.1.2.7 279 bdemsky 1.1.2.7 public void visit(PSET q) { 280 bdemsky 1.1.2.7 removeflag=false; 281 bdemsky 1.1.2.7 } 282 bdemsky 1.1.2.7 283 bdemsky 1.1.2.7 public void visit(RETURN q) { 284 bdemsky 1.1.2.1 removeflag=false; 285 bdemsky 1.1.2.1 } 286 bdemsky 1.1.2.5 287 bdemsky 1.1.2.1 public void visit(SIGMA q) { 288 bdemsky 1.1.2.1 removeflag=false; 289 bdemsky 1.1.2.1 } 290 bdemsky 1.1.2.1 291 bdemsky 1.1.2.5 public void visit(THROW q) { 292 bdemsky 1.1.2.5 removeflag=false; 293 bdemsky 1.1.2.5 } 294 bdemsky 1.1.2.5 295 bdemsky 1.1.2.1 public void visit(PHI q) { 296 bdemsky 1.1.2.1 removeflag=false; 297 bdemsky 1.1.2.1 } 298 bdemsky 1.1.2.1 } 299 bdemsky 1.1.2.1 } 300 cananian 1.2