1 cananian 1.1.2.1 // SSIRename.java, created Fri Aug 27 17:58:00 1999 by cananian 2 cananian 1.1.2.1 // Copyright (C) 1999 C. Scott Ananian <cananian@alumni.princeton.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.IR.Quads; 5 cananian 1.1.2.1 6 cananian 1.1.2.11 import harpoon.Analysis.AllocationInformationMap; 7 cananian 1.5 import harpoon.Analysis.Liveness; 8 cananian 1.1.2.1 import harpoon.Analysis.Place; 9 cananian 1.1.2.10 import harpoon.Analysis.Maps.AllocationInformation; 10 cananian 1.1.2.10 import harpoon.Analysis.Maps.Derivation; 11 cananian 1.1.2.7 import harpoon.Analysis.Quads.QuadLiveness; 12 cananian 1.1.2.1 import harpoon.ClassFile.HCode; 13 cananian 1.1.2.1 import harpoon.ClassFile.HCodeEdge; 14 cananian 1.1.2.1 import harpoon.ClassFile.HCodeElement; 15 bdemsky 1.1.2.16 import harpoon.ClassFile.HClass; 16 cananian 1.1.2.6 import harpoon.IR.Properties.CFGraphable; 17 cananian 1.1.2.12 import harpoon.IR.LowQuad.DerivationMap; 18 cananian 1.1.2.9 import harpoon.IR.LowQuad.PCALL; 19 cananian 1.1.2.1 import harpoon.Temp.Temp; 20 cananian 1.1.2.1 import harpoon.Temp.TempFactory; 21 cananian 1.1.2.1 import harpoon.Temp.TempMap; 22 cananian 1.1.2.1 import harpoon.Temp.WritableTempMap; 23 cananian 1.5 import net.cscott.jutil.Environment; 24 cananian 1.5 import net.cscott.jutil.HashEnvironment; 25 bdemsky 1.1.2.16 import harpoon.Util.HClassUtil; 26 cananian 1.1.2.1 import harpoon.Util.Util; 27 cananian 1.5 import net.cscott.jutil.WorkSet; 28 bdemsky 1.1.2.16 import harpoon.Util.DataStructs.RelationImpl; 29 cananian 1.1.2.1 30 cananian 1.1.2.2 import java.util.Arrays; 31 cananian 1.1.2.2 import java.util.Collections; 32 cananian 1.1.2.1 import java.util.HashMap; 33 cananian 1.1.2.1 import java.util.HashSet; 34 cananian 1.1.2.1 import java.util.Iterator; 35 cananian 1.1.2.1 import java.util.LinkedList; 36 cananian 1.1.2.1 import java.util.Map; 37 cananian 1.1.2.1 import java.util.Set; 38 cananian 1.1.2.3 import java.util.Stack; 39 bdemsky 1.1.2.16 40 cananian 1.1.2.1 /** 41 cananian 1.1.2.1 * <code>SSIRename</code> is a new, improved, fast SSI-renaming 42 cananian 1.1.2.1 * algorithm. Detailed in the author's thesis. This Java version 43 cananian 1.1.2.1 * is hairy because of the big "efficiency-vs-immutable quads" fight. 44 cananian 1.1.2.12 * Also, we have to keep <code>Derivation</code>s and 45 cananian 1.1.2.12 * <code>AllocationInformation</code> up-to-date. 46 cananian 1.1.2.12 * XXX: DERIVATION INFORMATION FOR PHI/SIGMAS IS CURRENTLY LOST. [CSA] 47 cananian 1.1.2.1 * 48 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 49 cananian 1.6 * @version $Id: SSIRename.java,v 1.6 2004/02/08 03:21:24 cananian Exp $ 50 cananian 1.1.2.1 */ 51 cananian 1.1.2.9 public class SSIRename { 52 cananian 1.1.2.13 private static final boolean DEBUG = false; 53 cananian 1.1.2.2 private static final boolean sort_phisig = false; 54 cananian 1.1.2.10 // RETURN TUPLE FOR THE ALGORITHM 55 cananian 1.1.2.10 /** New root element (of the SSI-form graph) */ 56 cananian 1.1.2.10 public final Quad rootQuad; 57 cananian 1.1.2.10 /** Map from old no-ssa temps to new ssi temps (incomplete). */ 58 cananian 1.1.2.10 public final TempMap tempMap; 59 cananian 1.1.2.10 /** Map from old no-ssa quads to new ssi quads. */ 60 cananian 1.5 public final Map<Quad,Quad> quadMap; 61 cananian 1.1.2.10 /** <code>AllocationInformation</code> for the new quads, or 62 cananian 1.1.2.10 * <code>null</code> if no allocation information for the old 63 cananian 1.1.2.10 * quads was supplied. */ 64 cananian 1.5 public final AllocationInformation<Quad> allocInfo; 65 cananian 1.1.2.10 /** <code>Derivation</code> for the new quads, or <code>null</code> 66 cananian 1.1.2.10 * if no <code>Derivation</code> for the old quads was supplied. */ 67 cananian 1.5 public final Derivation<Quad> derivation; 68 cananian 1.1.2.10 69 cananian 1.1.2.1 /** Return a copy of the given quad graph properly converted to 70 cananian 1.1.2.1 * SSI form. */ 71 cananian 1.1.2.10 public SSIRename(final Code c, final QuadFactory nqf) { 72 cananian 1.1.2.11 final SearchState S = new SearchState(c, nqf, 73 cananian 1.1.2.12 c.getDerivation(), 74 cananian 1.1.2.11 c.getAllocationInformation()); 75 cananian 1.5 this.rootQuad = S.old2new.get(c.getRootElement()); 76 cananian 1.1.2.10 this.tempMap = S.varmap; 77 cananian 1.1.2.10 this.quadMap = S.old2new; 78 cananian 1.1.2.11 this.allocInfo = S.naim; 79 cananian 1.1.2.12 this.derivation = S.nderiv; 80 cananian 1.1.2.8 } 81 cananian 1.1.2.11 82 cananian 1.1.2.1 static class VarMap implements TempMap { 83 cananian 1.1.2.1 final TempFactory tf; 84 cananian 1.5 final Environment<Temp,Temp> vm = new HashEnvironment<Temp,Temp>(); 85 cananian 1.1.2.1 Temp get(Temp t) { 86 cananian 1.1.2.1 if (!vm.containsKey(t)) { vm.put(t, t.clone(tf)); } 87 cananian 1.5 return vm.get(t); 88 cananian 1.1.2.1 } 89 cananian 1.1.2.1 Temp inc(Temp t) { 90 cananian 1.1.2.1 if (!vm.containsKey(t)) { vm.put(t, t.clone(tf)); } 91 cananian 1.1.2.1 else { vm.put(t, get(t).clone()); } 92 cananian 1.1.2.1 return get(t); 93 cananian 1.1.2.1 } 94 cananian 1.1.2.3 // environment interface. 95 cananian 1.5 Stack<Environment.Mark> s = new Stack<Environment.Mark>(); 96 cananian 1.1.2.3 void beginScope() { s.push(vm.getMark()); } 97 cananian 1.5 void endScope() { vm.undoToMark(s.pop()); } 98 cananian 1.1.2.3 99 cananian 1.1.2.1 public Temp tempMap(Temp t) { return get(t); } 100 cananian 1.1.2.1 VarMap(TempFactory tf) { this.tf = tf; } 101 cananian 1.1.2.1 } 102 cananian 1.1.2.1 103 cananian 1.1.2.1 static class SearchState { 104 cananian 1.1.2.1 /** maps no-ssi quads to ssi quads */ 105 cananian 1.5 final Map<Quad,Quad> old2new = new HashMap<Quad,Quad>(); 106 cananian 1.1.2.1 /** shows where to place phi/sigs */ 107 cananian 1.1.2.1 final Place place; 108 cananian 1.1.2.1 /** QuadFactory to use for new Quads. */ 109 cananian 1.1.2.1 final QuadFactory nqf; 110 cananian 1.1.2.11 /** AllocationInformation for old Quads */ 111 cananian 1.5 final AllocationInformation<Quad> oaim; 112 cananian 1.1.2.11 /** AllocationInformationMap for new Quads */ 113 cananian 1.5 final AllocationInformationMap<Quad> naim; 114 cananian 1.1.2.12 /** Derivation for old Quads */ 115 cananian 1.5 final Derivation<Quad> oderiv; 116 cananian 1.1.2.11 /** Derivation map for new Quads */ 117 cananian 1.5 final DerivationMap<Quad> nderiv; 118 bdemsky 1.1.2.16 /** Derivation map for Sigma/Phis */ 119 cananian 1.5 final Map<Temp,DerivType> derivmap; 120 cananian 1.1.2.1 // algorithm state 121 cananian 1.1.2.1 /** maps old variables to new variables */ 122 cananian 1.1.2.1 final VarMap varmap; 123 cananian 1.1.2.3 /** edge stack to unroll dfs recursion. */ 124 cananian 1.5 final Stack<Edge> We = new Stack<Edge>(); 125 cananian 1.1.2.1 /** mark edges as we visit them */ 126 cananian 1.5 final Set<Edge> marked = new HashSet<Edge>(); 127 cananian 1.1.2.1 128 cananian 1.5 SearchState(HCode<Quad> c, QuadFactory nqf, 129 cananian 1.5 Derivation<Quad> oderiv, AllocationInformation<Quad> oaim){ 130 cananian 1.5 this.place = new Place(c, (Liveness) new QuadLiveness(c)); 131 cananian 1.1.2.1 this.varmap= new VarMap(nqf.tempFactory()); 132 cananian 1.1.2.1 this.nqf = nqf; 133 cananian 1.1.2.11 this.oaim = oaim; 134 cananian 1.5 this.naim = (oaim==null) ? null : new AllocationInformationMap<Quad>(); 135 cananian 1.1.2.12 this.oderiv= oderiv; 136 cananian 1.5 this.nderiv= (oderiv==null) ? null : new DerivationMap<Quad>(); 137 cananian 1.5 this.derivmap= (oderiv==null) ? null : new HashMap<Temp,DerivType>(); 138 cananian 1.1.2.1 setup(c); 139 cananian 1.1.2.1 140 cananian 1.6 for (Edge e : c.getRootElement().edgeC()) { 141 cananian 1.5 We.push(e); 142 cananian 1.5 } 143 cananian 1.1.2.1 144 cananian 1.1.2.1 while (!We.isEmpty()) { 145 cananian 1.5 Edge e = We.pop(); 146 cananian 1.1.2.3 if (e==null) { varmap.endScope(); continue; } 147 cananian 1.1.2.3 We.push(null); varmap.beginScope(); 148 cananian 1.1.2.1 search(e); 149 cananian 1.1.2.1 } 150 cananian 1.1.2.1 151 cananian 1.1.2.1 makePhiSig(c); 152 bdemsky 1.1.2.16 if (nderiv!=null) 153 bdemsky 1.1.2.16 fixPhiSigDeriv(c); 154 cananian 1.1.2.1 155 cananian 1.1.2.1 // now link edges 156 cananian 1.5 for (Iterator<Quad> it=c.getElementsI(); it.hasNext(); ) { 157 cananian 1.5 Quad q = it.next(); 158 cananian 1.5 Quad fr = old2new.get(q); 159 cananian 1.1.2.1 for (int i = 0; i < q.nextLength(); i++) { 160 cananian 1.1.2.1 Edge e = q.nextEdge(i); 161 cananian 1.5 Quad to = old2new.get(e.to()); 162 cananian 1.1.2.1 Quad.addEdge(fr, e.which_succ(), to, e.which_pred()); 163 cananian 1.1.2.1 } 164 cananian 1.1.2.13 // check for unreachable code. 165 cananian 1.1.2.13 for (int i = 0; i < q.prevLength(); i++) 166 cananian 1.3.2.1 assert old2new.get(q.prev(i))!=null : (!DEBUG ? "unreachable predecessor" : 167 cananian 1.1.2.13 i+"th predecessor of "+q+" is unreachable"); 168 cananian 1.1.2.1 } 169 cananian 1.1.2.1 } 170 cananian 1.1.2.1 171 cananian 1.1.2.4 final Map lhs = new HashMap();//lhs of phi/sigma 172 cananian 1.1.2.4 final Map rhs = new HashMap();//rhs of phi/sigma 173 cananian 1.1.2.4 final Map arg = new HashMap();//uses in a sigma 174 cananian 1.1.2.4 final Map sdf = new HashMap();//defs in a sigma 175 cananian 1.1.2.1 void setup(HCode c) { 176 cananian 1.1.2.1 for (Iterator it=c.getElementsI(); it.hasNext(); ) { 177 cananian 1.1.2.1 Quad q = (Quad) it.next(); 178 cananian 1.1.2.1 if (q instanceof PHI) { 179 cananian 1.1.2.1 Temp[] l = place.phiNeeded(q); 180 cananian 1.1.2.2 if (sort_phisig) Collections.sort(Arrays.asList(l)); 181 cananian 1.1.2.1 Temp[][] r = new Temp[l.length][((PHI)q).arity()]; 182 cananian 1.1.2.1 for (int i = 0; i < r.length; i++) 183 cananian 1.1.2.1 for (int j = 0; j < r[i].length; j++) 184 cananian 1.1.2.1 r[i][j] = l[i]; 185 cananian 1.1.2.1 lhs.put(q, l); 186 cananian 1.1.2.1 rhs.put(q, r); 187 cananian 1.1.2.1 } else if (q instanceof SIGMA) { 188 cananian 1.1.2.1 Temp[] r = place.sigNeeded(q); 189 cananian 1.1.2.2 if (sort_phisig) Collections.sort(Arrays.asList(r)); 190 cananian 1.1.2.1 Temp[][] l = new Temp[r.length][((SIGMA)q).arity()]; 191 cananian 1.1.2.1 for (int i = 0; i < l.length; i++) 192 cananian 1.1.2.1 for (int j = 0; j < l[i].length; j++) 193 cananian 1.1.2.1 l[i][j] = r[i]; 194 cananian 1.1.2.1 lhs.put(q, l); 195 cananian 1.1.2.1 rhs.put(q, r); 196 cananian 1.1.2.1 } 197 cananian 1.1.2.1 } 198 cananian 1.1.2.1 } 199 cananian 1.1.2.1 200 cananian 1.1.2.1 final WritableTempMap wtm = new WritableTempMap() { 201 cananian 1.5 final Map<Temp,Temp> backing = new HashMap(); 202 cananian 1.5 public Temp tempMap(Temp t) { return backing.get(t); } 203 cananian 1.1.2.1 public void associate(Temp o, Temp n) { backing.put(o,n); } 204 cananian 1.1.2.1 }; 205 cananian 1.1.2.1 void search(Edge e) { 206 cananian 1.3.2.1 assert e.from() instanceof PHI || 207 cananian 1.1.2.1 e.from() instanceof SIGMA || 208 cananian 1.3.2.1 e.from() instanceof HEADER; 209 cananian 1.1.2.3 // handle dfs bookkeeping. 210 cananian 1.3.2.1 assert !marked.contains(e); 211 cananian 1.1.2.3 marked.add(e); 212 cananian 1.1.2.1 // setup 'from' state. 213 cananian 1.5 Quad from = e.from(); 214 cananian 1.1.2.1 if (from instanceof HEADER) { 215 cananian 1.1.2.1 old2new.put(from, from.rename(nqf, null, null)); 216 cananian 1.1.2.1 } else if (from instanceof PHI) { 217 cananian 1.1.2.1 Temp[] l = (Temp[]) lhs.get(from); 218 cananian 1.1.2.1 for (int i=0; i<l.length; i++) 219 cananian 1.1.2.1 l[i] = varmap.inc(l[i]); 220 cananian 1.1.2.1 } else if (from instanceof SIGMA) { 221 cananian 1.1.2.1 Temp[][] l = (Temp[][]) lhs.get(from); 222 cananian 1.1.2.1 int j = e.which_succ(); 223 cananian 1.1.2.1 for (int i=0; i<l.length; i++) 224 cananian 1.1.2.1 l[i][j] = varmap.inc(l[i][j]); 225 cananian 1.1.2.1 } 226 cananian 1.1.2.9 // fixup defs in CALL/PCALL sigma appropriately 227 cananian 1.1.2.9 if (from instanceof CALL || from instanceof PCALL) { 228 cananian 1.1.2.9 Temp retval, retex; 229 cananian 1.1.2.9 if (from instanceof CALL) { 230 cananian 1.1.2.9 retval = ((CALL) from).retval(); 231 cananian 1.1.2.9 retex = ((CALL) from).retex(); 232 cananian 1.1.2.9 } else { 233 cananian 1.1.2.9 retval = ((PCALL) from).retval(); 234 cananian 1.1.2.9 retex = ((PCALL) from).retex(); 235 cananian 1.1.2.9 } 236 cananian 1.1.2.4 Temp[] defs = (Temp[]) sdf.get(from); 237 cananian 1.1.2.4 if (defs==null) { defs=new Temp[2]; sdf.put(from, defs); } 238 cananian 1.1.2.4 // use of inc() below serves to kill any aliases on this path 239 cananian 1.1.2.9 if (e.which_succ()==0 && retval!=null) 240 cananian 1.1.2.9 defs[0]=varmap.inc(retval); 241 cananian 1.1.2.4 if (e.which_succ()==1) 242 cananian 1.1.2.9 defs[1]=varmap.inc(retex); 243 cananian 1.1.2.4 } 244 cananian 1.1.2.1 // now go on renaming inside basic block until we get to a phi 245 cananian 1.1.2.1 // or sigma. 246 cananian 1.1.2.1 for (Quad q; ; e=q.nextEdge(0)) { 247 cananian 1.5 q = e.to(); 248 cananian 1.1.2.1 if (q instanceof PHI) { /* update src */ 249 cananian 1.1.2.1 Temp[][] r = (Temp[][]) rhs.get(q); 250 cananian 1.1.2.1 int j = e.which_pred(); 251 cananian 1.1.2.1 for (int i=0; i < r.length; i++) 252 cananian 1.1.2.1 r[i][j] = varmap.get(r[i][j]); 253 cananian 1.1.2.3 break; 254 cananian 1.1.2.1 } 255 cananian 1.1.2.1 if (q instanceof SIGMA) { /* update src */ 256 cananian 1.1.2.4 // rhs of sigma comes before any defs in the sigma. 257 cananian 1.1.2.1 Temp[] r = (Temp[]) rhs.get(q); 258 cananian 1.1.2.1 for (int i=0; i < r.length; i++) 259 cananian 1.1.2.1 r[i] = varmap.get(r[i]); 260 cananian 1.1.2.1 if (q instanceof CJMP) 261 cananian 1.1.2.1 arg.put(q, varmap.get(((CJMP)q).test())); 262 cananian 1.1.2.1 else if (q instanceof SWITCH) 263 cananian 1.1.2.1 arg.put(q, varmap.get(((SWITCH)q).index())); 264 cananian 1.1.2.14 else if (q instanceof TYPESWITCH) 265 cananian 1.1.2.14 arg.put(q, varmap.get(((TYPESWITCH)q).index())); 266 cananian 1.1.2.4 else if (q instanceof CALL) { 267 cananian 1.1.2.4 CALL Q = (CALL) q; 268 cananian 1.1.2.4 Temp[] args = new Temp[Q.paramsLength()]; 269 cananian 1.1.2.4 for (int i=0; i<Q.paramsLength(); i++) 270 cananian 1.1.2.4 args[i] = varmap.get(Q.params(i)); 271 cananian 1.1.2.4 arg.put(q, args); 272 cananian 1.1.2.9 } else if (q instanceof PCALL) { 273 cananian 1.1.2.9 PCALL Q = (PCALL) q; 274 cananian 1.1.2.9 Temp[] args = new Temp[1+Q.paramsLength()]; 275 cananian 1.1.2.9 for (int i=0; i<Q.paramsLength(); i++) 276 cananian 1.1.2.9 args[i] = varmap.get(Q.params(i)); 277 bdemsky 1.1.2.15 args[Q.paramsLength()] = varmap.get(Q.ptr()); 278 cananian 1.1.2.9 arg.put(q, args); 279 cananian 1.1.2.4 } else throw new Error("Ack!"); 280 cananian 1.1.2.3 break; 281 cananian 1.1.2.1 } 282 cananian 1.1.2.1 /* else, rename src, then rename dst */ 283 cananian 1.1.2.1 Temp u[] = q.use(), d[] = q.def(); 284 cananian 1.1.2.1 for (int i=0; i<u.length; i++) 285 cananian 1.1.2.1 wtm.associate(u[i], varmap.get(u[i])); 286 cananian 1.1.2.1 for (int i=0; i<d.length; i++) 287 cananian 1.1.2.1 varmap.inc(d[i]); 288 cananian 1.1.2.1 Quad nq = q.rename(nqf, varmap, wtm); 289 cananian 1.1.2.1 old2new.put(q, nq); 290 cananian 1.1.2.12 if (nderiv!=null) 291 bdemsky 1.1.2.16 transferderivation(nq, q, q.def(), varmap, oderiv); 292 cananian 1.1.2.11 if (nq instanceof ANEW || nq instanceof NEW) 293 cananian 1.1.2.11 if (naim!=null) naim.transfer(nq, q, varmap, oaim); 294 cananian 1.1.2.3 if (q instanceof FOOTER) break; 295 cananian 1.1.2.3 } 296 cananian 1.5 for (Iterator<Edge> it=e.to().succC().iterator();it.hasNext();) { 297 cananian 1.5 e = it.next(); 298 cananian 1.1.2.3 if (!marked.contains(e)) 299 cananian 1.1.2.3 We.push(e); 300 cananian 1.1.2.1 } 301 cananian 1.1.2.1 } 302 bdemsky 1.1.2.16 303 bdemsky 1.1.2.16 void transferderivation(Quad nq, Quad q, Temp[] defs, TempMap varmap, Derivation oderiv) { 304 bdemsky 1.1.2.16 nderiv.transfer(nq,q,defs,varmap,oderiv); 305 bdemsky 1.1.2.16 for(int i=0;i<defs.length;i++) 306 bdemsky 1.1.2.16 derivmap.put(varmap.tempMap(defs[i]),new DerivType(nderiv.derivation(nq,varmap.tempMap(defs[i])),nderiv.typeMap(nq,varmap.tempMap(defs[i])))); 307 bdemsky 1.1.2.16 } 308 bdemsky 1.1.2.16 309 bdemsky 1.1.2.16 void addType(Quad nq, Temp t,HClass type) { 310 bdemsky 1.1.2.16 nderiv.putType(nq,t,type); 311 bdemsky 1.1.2.16 derivmap.put(t, new DerivType(null,type)); 312 bdemsky 1.1.2.16 } 313 bdemsky 1.1.2.16 314 bdemsky 1.1.2.16 static class DerivType { 315 bdemsky 1.1.2.16 Derivation.DList deriv; 316 bdemsky 1.1.2.16 HClass type; 317 bdemsky 1.1.2.16 DerivType(Derivation.DList deriv,HClass type) { 318 bdemsky 1.1.2.16 this.deriv=deriv; 319 bdemsky 1.1.2.16 this.type=type; 320 bdemsky 1.1.2.16 } 321 bdemsky 1.1.2.16 322 bdemsky 1.1.2.16 DerivType() { 323 bdemsky 1.1.2.16 this.deriv=null; 324 bdemsky 1.1.2.16 this.type=null; 325 bdemsky 1.1.2.16 } 326 bdemsky 1.1.2.16 327 bdemsky 1.1.2.16 void merge(DerivType dt) { 328 bdemsky 1.1.2.16 if (dt!=null) { 329 bdemsky 1.1.2.16 //Merge types 330 bdemsky 1.1.2.16 if ((type!=null)&&(dt.type!=null)) 331 bdemsky 1.1.2.16 type=HClassUtil.commonParent(type,dt.type); 332 bdemsky 1.1.2.16 else if (type==null) 333 bdemsky 1.1.2.16 type=dt.type; 334 bdemsky 1.1.2.16 335 bdemsky 1.1.2.16 //Merge derivations 336 bdemsky 1.1.2.16 if (deriv==null) 337 bdemsky 1.1.2.16 this.deriv=dt.deriv; 338 bdemsky 1.1.2.16 } 339 bdemsky 1.1.2.16 } 340 bdemsky 1.1.2.16 341 bdemsky 1.1.2.16 HClass type() { 342 bdemsky 1.1.2.16 return type; 343 bdemsky 1.1.2.16 } 344 bdemsky 1.1.2.16 345 bdemsky 1.1.2.16 Derivation.DList deriv() { 346 bdemsky 1.1.2.16 return deriv; 347 bdemsky 1.1.2.16 } 348 bdemsky 1.1.2.16 } 349 bdemsky 1.1.2.16 350 bdemsky 1.1.2.16 static class PhiSigFunction { 351 bdemsky 1.1.2.16 Temp[] left,right; 352 bdemsky 1.1.2.16 PhiSigFunction(Temp[] left, Temp[] right) { 353 bdemsky 1.1.2.16 this.left=left; 354 bdemsky 1.1.2.16 this.right=right; 355 bdemsky 1.1.2.16 } 356 bdemsky 1.1.2.16 Temp[] left() { 357 bdemsky 1.1.2.16 return left; 358 bdemsky 1.1.2.16 } 359 bdemsky 1.1.2.16 Temp[] right() { 360 bdemsky 1.1.2.16 return right; 361 bdemsky 1.1.2.16 } 362 bdemsky 1.1.2.16 } 363 bdemsky 1.1.2.16 364 cananian 1.5 void fixPhiSigDeriv(HCode<Quad> c) { 365 bdemsky 1.1.2.16 WorkSet functionSet=new WorkSet(); 366 bdemsky 1.1.2.16 RelationImpl rel=new RelationImpl(); 367 bdemsky 1.1.2.16 HashSet phisig=new HashSet(); 368 bdemsky 1.1.2.16 //Add Phi's and Sigmas to function set 369 bdemsky 1.1.2.16 370 cananian 1.5 for (Iterator<Quad> it=c.getElementsI(); it.hasNext(); ) { 371 cananian 1.5 Quad q = old2new.get(it.next()); 372 bdemsky 1.1.2.16 if (q instanceof PHI) { 373 bdemsky 1.1.2.16 for(int i=0;i<((PHI)q).numPhis();i++) { 374 bdemsky 1.1.2.16 PhiSigFunction psf=new PhiSigFunction(new Temp[]{((PHI)q).dst(i)},((PHI)q).src(i)); 375 bdemsky 1.1.2.16 functionSet.add(psf); 376 bdemsky 1.1.2.16 for(int j=0;j<((PHI)q).arity();j++) { 377 bdemsky 1.1.2.16 rel.add(((PHI)q).src(i,j),psf); 378 bdemsky 1.1.2.16 } 379 bdemsky 1.1.2.16 } 380 bdemsky 1.1.2.16 } else if (q instanceof SIGMA) { 381 bdemsky 1.1.2.16 for(int i=0;i<((SIGMA)q).numSigmas();i++) { 382 bdemsky 1.1.2.16 PhiSigFunction psf=new PhiSigFunction(((SIGMA)q).dst(i),new Temp[]{((SIGMA)q).src(i)}); 383 bdemsky 1.1.2.16 functionSet.add(psf); 384 bdemsky 1.1.2.16 rel.add(((SIGMA)q).src(i),psf); 385 bdemsky 1.1.2.16 } 386 bdemsky 1.1.2.16 } 387 bdemsky 1.1.2.16 } 388 bdemsky 1.1.2.16 while(!functionSet.isEmpty()) { 389 bdemsky 1.1.2.16 PhiSigFunction psf=(PhiSigFunction)functionSet.pop(); 390 bdemsky 1.1.2.16 Temp[] right=psf.right(); 391 bdemsky 1.1.2.16 Temp[] left=psf.left(); 392 bdemsky 1.1.2.16 DerivType best=new DerivType(); 393 bdemsky 1.1.2.16 for(int i=0;i<right.length;i++) { 394 bdemsky 1.1.2.16 best.merge((DerivType)derivmap.get(right[i])); 395 bdemsky 1.1.2.16 } 396 bdemsky 1.1.2.16 for(int i=0;i<left.length;i++) { 397 bdemsky 1.1.2.16 DerivType old=(DerivType)derivmap.get(left[i]); 398 bdemsky 1.1.2.16 if (old==null) { 399 bdemsky 1.1.2.16 derivmap.put(left[i],best); 400 bdemsky 1.1.2.16 Set values=rel.getValues(left[i]); 401 bdemsky 1.1.2.16 Iterator it=values.iterator(); 402 bdemsky 1.1.2.16 while(it.hasNext()) 403 bdemsky 1.1.2.16 functionSet.add(it.next()); 404 bdemsky 1.1.2.16 } else if ((old.type!=best.type)||((best.deriv!=null)&&(old.deriv==null))) { 405 bdemsky 1.1.2.16 derivmap.put(left[i],best); 406 bdemsky 1.1.2.16 Set values=rel.getValues(left[i]); 407 bdemsky 1.1.2.16 Iterator it=values.iterator(); 408 bdemsky 1.1.2.16 while(it.hasNext()) 409 bdemsky 1.1.2.16 functionSet.add(it.next()); 410 bdemsky 1.1.2.16 } 411 bdemsky 1.1.2.16 } 412 bdemsky 1.1.2.16 } 413 bdemsky 1.1.2.16 414 cananian 1.5 for (Iterator<Quad> it=c.getElementsI(); it.hasNext(); ) { 415 cananian 1.5 Quad q = old2new.get(it.next()); 416 bdemsky 1.1.2.16 if (q instanceof PHI) { 417 bdemsky 1.1.2.16 for(int i=0;i<((PHI)q).numPhis();i++) { 418 bdemsky 1.1.2.16 Temp t=((PHI)q).dst(i); 419 bdemsky 1.1.2.16 DerivType dt=(DerivType)derivmap.get(t); 420 bdemsky 1.1.2.16 if (dt.type()!=null) 421 bdemsky 1.1.2.16 nderiv.putType(q,t,dt.type()); 422 bdemsky 1.1.2.16 if (dt.deriv()!=null) 423 bdemsky 1.1.2.16 nderiv.putDerivation(q,t,dt.deriv()); 424 bdemsky 1.1.2.16 } 425 bdemsky 1.1.2.16 } else if (q instanceof SIGMA) { 426 bdemsky 1.1.2.16 for(int i=0;i<((SIGMA)q).numSigmas();i++) { 427 bdemsky 1.1.2.16 for(int j=0;j<((SIGMA)q).arity();j++) { 428 bdemsky 1.1.2.16 Temp t=((SIGMA)q).dst(i,j); 429 bdemsky 1.1.2.16 DerivType dt=(DerivType)derivmap.get(t); 430 bdemsky 1.1.2.16 if (dt.type()!=null) 431 bdemsky 1.1.2.16 nderiv.putType(q,t,dt.type()); 432 bdemsky 1.1.2.16 if (dt.deriv()!=null) 433 bdemsky 1.1.2.16 nderiv.putDerivation(q,t,dt.deriv()); 434 bdemsky 1.1.2.16 } 435 bdemsky 1.1.2.16 } 436 bdemsky 1.1.2.16 } 437 bdemsky 1.1.2.16 } 438 bdemsky 1.1.2.16 } 439 bdemsky 1.1.2.16 440 cananian 1.5 void makePhiSig(HCode<Quad> c) { 441 cananian 1.5 for (Iterator<Quad> it=c.getElementsI(); it.hasNext(); ) { 442 cananian 1.5 Quad q = it.next(); 443 cananian 1.1.2.1 if (q instanceof PHI) { 444 cananian 1.1.2.1 Temp[] l = (Temp[]) lhs.get(q); 445 cananian 1.1.2.1 Temp[][] r = (Temp[][]) rhs.get(q); 446 cananian 1.1.2.1 Quad nq = new PHI(nqf, q, l, r, ((PHI)q).arity()); 447 cananian 1.1.2.1 old2new.put(q, nq); 448 cananian 1.1.2.1 } else if (q instanceof SIGMA) { 449 cananian 1.1.2.1 Temp[][] l = (Temp[][]) lhs.get(q); 450 cananian 1.1.2.1 Temp[] r = (Temp[]) rhs.get(q); 451 cananian 1.1.2.1 Quad nq; 452 cananian 1.1.2.1 if (q instanceof CJMP) 453 cananian 1.1.2.4 nq = new CJMP(nqf, q, (Temp) arg.get(q), l, r); 454 cananian 1.1.2.1 else if (q instanceof SWITCH) 455 cananian 1.1.2.4 nq = new SWITCH(nqf, q, (Temp) arg.get(q), 456 cananian 1.1.2.4 ((SWITCH)q).keys(), l, r); 457 cananian 1.1.2.14 else if (q instanceof TYPESWITCH) 458 cananian 1.1.2.14 nq = new TYPESWITCH(nqf, q, (Temp) arg.get(q), 459 cananian 1.1.2.17 ((TYPESWITCH)q).keys(), l, r, 460 cananian 1.1.2.17 ((TYPESWITCH)q).hasDefault()); 461 cananian 1.1.2.4 else if (q instanceof CALL) { 462 cananian 1.1.2.4 CALL Q = (CALL) q; 463 cananian 1.1.2.4 Temp[] defs = (Temp[]) sdf.get(q); 464 cananian 1.1.2.4 nq = new CALL(nqf, Q, Q.method(), (Temp[]) arg.get(q), 465 cananian 1.1.2.5 defs[0], defs[1], 466 cananian 1.1.2.5 Q.isVirtual(), Q.isTailCall(), 467 cananian 1.1.2.5 l, r); 468 bdemsky 1.1.2.16 if (nderiv!=null) { 469 bdemsky 1.1.2.16 addType(nq,defs[0],oderiv.typeMap(q,((CALL)q).retval())); 470 bdemsky 1.1.2.16 addType(nq,defs[1],oderiv.typeMap(q,((CALL)q).retex())); 471 bdemsky 1.1.2.16 } 472 cananian 1.1.2.9 } else if (q instanceof PCALL) { 473 cananian 1.1.2.9 harpoon.IR.LowQuad.LowQuadFactory lqf = 474 cananian 1.1.2.9 (harpoon.IR.LowQuad.LowQuadFactory) nqf; 475 cananian 1.1.2.9 PCALL Q = (PCALL) q; 476 cananian 1.1.2.9 Temp[] defs = (Temp[]) sdf.get(q); 477 cananian 1.1.2.9 Temp[] argsandptr = (Temp[]) arg.get(q); 478 cananian 1.1.2.9 Temp[] args = new Temp[argsandptr.length - 1]; 479 cananian 1.1.2.9 System.arraycopy(argsandptr,0,args,0,args.length); 480 cananian 1.1.2.9 nq = new PCALL(lqf, Q, argsandptr[args.length], 481 cananian 1.1.2.9 args, defs[0], defs[1], l, r, 482 cananian 1.1.2.9 Q.isVirtual(), Q.isTailCall()); 483 bdemsky 1.1.2.16 if (nderiv!=null) { 484 bdemsky 1.1.2.16 if (defs[0]!=null) 485 bdemsky 1.1.2.16 addType(nq,defs[0],oderiv.typeMap(q,((PCALL)q).retval())); 486 bdemsky 1.1.2.16 if (defs[1]!=null) 487 bdemsky 1.1.2.16 addType(nq,defs[1],oderiv.typeMap(q,((PCALL)q).retex())); 488 bdemsky 1.1.2.16 } 489 cananian 1.1.2.4 } else throw new Error("Ack!"); 490 cananian 1.1.2.1 old2new.put(q, nq); 491 cananian 1.1.2.1 } 492 cananian 1.1.2.1 } 493 cananian 1.1.2.1 } 494 cananian 1.1.2.1 } 495 cananian 1.2 }