1 cananian 1.1.2.16 // ToNoSSA.java, created Wed Feb 3 16:18:56 1999 by duncan 2 cananian 1.1.2.15 // Copyright (C) 1998 Duncan Bryce <duncan@lcs.mit.edu> 3 cananian 1.1.2.15 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 duncan 1.1.2.1 package harpoon.IR.Quads; 5 duncan 1.1.2.1 6 cananian 1.1.2.32 import harpoon.Analysis.AllocationInformationMap; 7 cananian 1.1.2.32 import harpoon.Analysis.Maps.AllocationInformation; 8 cananian 1.1.2.27 import harpoon.Analysis.Maps.Derivation; 9 cananian 1.1.2.27 import harpoon.Analysis.Maps.Derivation.DList; 10 duncan 1.1.2.5 import harpoon.Analysis.Maps.TypeMap; 11 pnkfelix 1.1.2.34 import harpoon.Analysis.Maps.TypeMap.TypeNotKnownException; 12 duncan 1.1.2.5 import harpoon.ClassFile.HClass; 13 duncan 1.1.2.1 import harpoon.ClassFile.HCode; 14 duncan 1.1.2.5 import harpoon.ClassFile.HCodeElement; 15 cananian 1.1.2.20 import harpoon.IR.LowQuad.PCALL; 16 cananian 1.1.2.20 import harpoon.IR.LowQuad.LowQuadFactory; 17 duncan 1.1.2.1 import harpoon.IR.LowQuad.LowQuadVisitor; 18 cananian 1.1.2.38 import harpoon.IR.Quads.Edge; 19 cananian 1.1.2.2 import harpoon.Temp.CloningTempMap; 20 duncan 1.1.2.1 import harpoon.Temp.Temp; 21 cananian 1.1.2.37 import harpoon.Temp.TempFactory; 22 duncan 1.1.2.1 import harpoon.Temp.TempMap; 23 cananian 1.5 import net.cscott.jutil.Default; 24 cananian 1.5 import net.cscott.jutil.DisjointSet; 25 duncan 1.1.2.1 import harpoon.Util.Util; 26 duncan 1.1.2.1 27 duncan 1.1.2.17 import java.util.HashMap; 28 duncan 1.1.2.17 import java.util.Iterator; 29 cananian 1.1.2.38 import java.util.List; 30 duncan 1.1.2.17 import java.util.Map; 31 duncan 1.1.2.3 32 duncan 1.1.2.1 /** 33 duncan 1.1.2.1 * The <code>ToNoSSA</code> class implements the translation between SSA 34 duncan 1.1.2.1 * and No-SSA form. 35 duncan 1.1.2.1 * 36 duncan 1.1.2.1 * @author Duncan Bryce <duncan@lcs.mit.edu> 37 cananian 1.5 * @version $Id: ToNoSSA.java,v 1.5 2004/02/08 01:55:25 cananian Exp $ 38 duncan 1.1.2.1 */ 39 cananian 1.1.2.31 public class ToNoSSA 40 duncan 1.1.2.1 { 41 cananian 1.1.2.37 private NameMap m_ctm; 42 bdemsky 1.1.2.14 private Derivation m_derivation; 43 bdemsky 1.1.2.14 private Quad m_quads; 44 cananian 1.1.2.32 private AllocationInformationMap m_allocInfoMap; 45 pnkfelix 1.1.2.13 46 cananian 1.1.2.31 private static interface SerializableDerivation 47 cananian 1.1.2.31 extends Derivation, java.io.Serializable { /* declare only */ } 48 cananian 1.1.2.31 49 cananian 1.1.2.31 private static class NullDerivation implements SerializableDerivation { 50 duncan 1.1.2.17 public DList derivation(HCodeElement hce, Temp t) { 51 cananian 1.3.2.1 assert hce!=null && t!=null; 52 cananian 1.1.2.26 throw new TypeNotKnownException(hce, t); 53 duncan 1.1.2.17 } 54 cananian 1.1.2.26 public HClass typeMap(HCodeElement hce, Temp t) { 55 cananian 1.3.2.1 assert hce!=null && t!=null; 56 cananian 1.1.2.26 throw new TypeNotKnownException(hce, t); 57 cananian 1.1.2.26 } 58 pnkfelix 1.1.2.13 } 59 cananian 1.1.2.31 private static class MapDerivation implements SerializableDerivation { 60 cananian 1.1.2.31 final Map dT; 61 cananian 1.1.2.31 MapDerivation(Map dT) { this.dT = dT; } 62 cananian 1.1.2.31 public DList derivation(HCodeElement hce, Temp t) { 63 cananian 1.3.2.1 assert hce!=null && t!=null; 64 cananian 1.3.2.1 assert t.tempFactory() == 65 cananian 1.3.2.1 ((Quad)hce).getFactory().tempFactory(); 66 cananian 1.1.2.38 Object type = dT.get(Default.pair(hce, t)); 67 cananian 1.1.2.31 if (type instanceof HClass) return null; 68 cananian 1.1.2.31 if (type instanceof DList) return (DList) type; 69 cananian 1.1.2.31 throw new TypeNotKnownException(hce, t); 70 cananian 1.1.2.31 } 71 cananian 1.1.2.31 public HClass typeMap(HCodeElement hce, Temp t) { 72 cananian 1.3.2.1 assert hce!=null && t!=null; 73 cananian 1.3.2.1 assert t.tempFactory() == 74 cananian 1.3.2.1 ((Quad)hce).getFactory().tempFactory(); 75 cananian 1.1.2.38 Object type = dT.get(Default.pair(hce, t)); 76 cananian 1.1.2.31 if (type instanceof HClass) return (HClass)type; 77 cananian 1.1.2.31 if (type instanceof DList) return null; 78 cananian 1.1.2.31 throw new TypeNotKnownException(hce, t); 79 cananian 1.1.2.31 } 80 cananian 1.1.2.31 } 81 duncan 1.1.2.5 82 bdemsky 1.1.2.14 public ToNoSSA(QuadFactory newQF, Code code) 83 duncan 1.1.2.5 { 84 cananian 1.1.2.26 this(newQF, code, null, false); 85 pnkfelix 1.1.2.13 } 86 cananian 1.1.2.26 public ToNoSSA(QuadFactory newQF, Code code, final TypeMap typeMap) 87 cananian 1.1.2.26 { 88 cananian 1.1.2.31 this(newQF, code, typeMap==null ? null : new SerializableDerivation() { 89 cananian 1.1.2.26 public HClass typeMap(HCodeElement hce, Temp t) { 90 cananian 1.1.2.26 // proxy given typeMap 91 cananian 1.1.2.26 return typeMap.typeMap(hce, t); 92 cananian 1.1.2.26 } 93 cananian 1.1.2.26 public DList derivation(HCodeElement hce, Temp t) { 94 cananian 1.1.2.26 // return null (indicating base pointer) iff typeMap is okay. 95 cananian 1.1.2.26 if (typeMap(hce,t)!=null) return null; 96 cananian 1.1.2.26 throw new TypeNotKnownException(hce, t); 97 cananian 1.1.2.26 } 98 cananian 1.1.2.26 }, typeMap!=null); 99 duncan 1.1.2.5 } 100 cananian 1.1.2.26 public ToNoSSA(QuadFactory newQF, Code code, Derivation derivation) { 101 cananian 1.1.2.26 this(newQF, code, derivation, derivation!=null); 102 cananian 1.1.2.26 } 103 cananian 1.1.2.26 private ToNoSSA(QuadFactory newQF, Code code, Derivation derivation, 104 cananian 1.1.2.26 boolean validDerivation) { 105 cananian 1.3.2.1 assert code.getName().equals(harpoon.IR.Quads.QuadSSI.codename) || 106 cananian 1.1.2.30 code.getName().equals(harpoon.IR.LowQuad.LowQuadSSI.codename) || 107 cananian 1.3.2.1 code.getName().equals(harpoon.IR.Quads.QuadWithTry.codename); 108 duncan 1.1.2.7 109 cananian 1.1.2.26 final Map dT = validDerivation ? new HashMap() : null; 110 duncan 1.1.2.5 111 cananian 1.1.2.32 m_allocInfoMap = (code.getAllocationInformation()==null) ? null : 112 cananian 1.1.2.32 new AllocationInformationMap(); 113 cananian 1.1.2.37 m_ctm = new NameMap 114 bdemsky 1.1.2.14 (((Quad)code.getRootElement()).getFactory().tempFactory(), 115 bdemsky 1.1.2.14 newQF.tempFactory()); 116 cananian 1.1.2.26 m_quads = translate(newQF, derivation, dT, code); 117 cananian 1.1.2.31 m_derivation = validDerivation 118 cananian 1.1.2.31 ? (Derivation) new MapDerivation(dT) 119 cananian 1.1.2.31 : (Derivation) new NullDerivation(); 120 bdemsky 1.1.2.14 } 121 duncan 1.1.2.5 122 bdemsky 1.1.2.14 public Quad getQuads() { return m_quads; } 123 cananian 1.1.2.31 public Derivation getDerivation() { return m_derivation; } 124 cananian 1.1.2.32 public AllocationInformation getAllocationInformation() { 125 cananian 1.1.2.32 return m_allocInfoMap; 126 cananian 1.1.2.32 } 127 bdemsky 1.1.2.14 128 bdemsky 1.1.2.14 /** 129 cananian 1.1.2.38 * Translates the code in the supplied codeview from SSx to No-SSA form, 130 duncan 1.1.2.17 * returning the new root <code>Quad</code>. The <code>Map</code> 131 bdemsky 1.1.2.14 * parameter is used to maintain derivation information. 132 bdemsky 1.1.2.14 * 133 cananian 1.1.2.21 * @param qf the <code>QuadFactory</code> which will manufacture the 134 bdemsky 1.1.2.14 * translated <code>Quad</code>s. 135 cananian 1.1.2.21 * @param dT a <code>Map</code> in which to place the updated 136 bdemsky 1.1.2.14 * derivation information. 137 cananian 1.1.2.21 * @param code the codeview containing the <code>Quad</code>s to 138 bdemsky 1.1.2.14 * translate. 139 bdemsky 1.1.2.14 */ 140 bdemsky 1.1.2.14 private Quad translate(QuadFactory qf, Derivation derivation, 141 cananian 1.1.2.26 Map dT, Code code) 142 bdemsky 1.1.2.14 { 143 bdemsky 1.1.2.14 Quad old_header, qTmp; 144 bdemsky 1.1.2.14 QuadMap qm; 145 bdemsky 1.1.2.14 LowQuadVisitor v; 146 bdemsky 1.1.2.14 147 bdemsky 1.1.2.14 old_header = (Quad)code.getRootElement(); 148 cananian 1.1.2.26 qm = new QuadMap(m_ctm, derivation, dT); 149 bdemsky 1.1.2.14 150 cananian 1.1.2.37 // Merge src/dst of all SIGMAS 151 cananian 1.1.2.37 v = new SIGMAMergeVisitor(m_ctm); 152 cananian 1.1.2.37 for (Iterator i = code.getElementsI(); i.hasNext();) 153 cananian 1.1.2.37 ((Quad)i.next()).accept(v); 154 cananian 1.1.2.37 155 bdemsky 1.1.2.14 // Remove all SIGMAs from the code 156 cananian 1.1.2.37 v = new SIGMAVisitor(m_ctm, qf, qm); 157 duncan 1.1.2.17 for (Iterator i = code.getElementsI(); i.hasNext();) 158 cananian 1.1.2.19 ((Quad)i.next()).accept(v); 159 bdemsky 1.1.2.14 160 cananian 1.1.2.26 // note that there's no need to rename variables to account for 161 cananian 1.1.2.26 // removed sigmas, as the variables split by a sigma simply 162 cananian 1.1.2.26 // revert to their original type & definition point above the sigma. 163 cananian 1.1.2.26 // (and this *is* SSA/SSI form we're converting from: no redefinitions 164 cananian 1.1.2.26 // of SIGMA'ed variables elsewhere). 165 bdemsky 1.1.2.14 166 bdemsky 1.1.2.14 // Connect the edges of these new Quads 167 duncan 1.1.2.17 for (Iterator i = code.getElementsI(); i.hasNext();) { 168 duncan 1.1.2.17 qTmp = (Quad)i.next(); 169 bdemsky 1.1.2.14 Edge[] el = qTmp.nextEdge(); 170 duncan 1.1.2.17 for (int n=0; n<el.length; n++) 171 duncan 1.1.2.17 Quad.addEdge(qm.get((Quad)el[n].from()), 172 duncan 1.1.2.17 el[n].which_succ(), 173 duncan 1.1.2.17 qm.get((Quad)el[n].to()), 174 duncan 1.1.2.17 el[n].which_pred()); 175 bdemsky 1.1.2.14 } 176 duncan 1.1.2.3 177 bdemsky 1.1.2.14 // Modify this new CFG by emptying PHI nodes 178 cananian 1.1.2.37 v = new PHIVisitor(qf, dT); 179 duncan 1.1.2.17 for (Iterator i = code.getElementsI(); i.hasNext();) 180 cananian 1.1.2.19 qm.get((Quad)i.next()).accept(v); 181 cananian 1.1.2.32 182 cananian 1.1.2.32 // Update AllocationInformation 183 cananian 1.1.2.32 if (m_allocInfoMap!=null) { 184 cananian 1.1.2.32 AllocationInformation oldai = code.getAllocationInformation(); 185 cananian 1.1.2.32 for (Iterator it = code.getElementsI(); it.hasNext(); ) { 186 cananian 1.1.2.32 Quad oldquad = (Quad) it.next(); 187 cananian 1.1.2.32 Quad newquad = qm.get(oldquad); 188 cananian 1.1.2.32 if (oldquad instanceof ANEW || oldquad instanceof NEW) 189 cananian 1.1.2.32 m_allocInfoMap.transfer(newquad, oldquad, m_ctm, oldai); 190 cananian 1.1.2.32 } 191 cananian 1.1.2.32 } 192 duncan 1.1.2.3 193 bdemsky 1.1.2.14 // Return the head of the new CFG 194 bdemsky 1.1.2.14 return qm.get(old_header); 195 duncan 1.1.2.1 } 196 duncan 1.1.2.5 197 cananian 1.1.2.37 /** first touch all the SIGMAs to merge their definitions */ 198 cananian 1.1.2.37 static class SIGMAMergeVisitor extends LowQuadVisitor // this is an inner class 199 cananian 1.1.2.37 { 200 cananian 1.1.2.37 private final NameMap m_nm; 201 cananian 1.1.2.37 public SIGMAMergeVisitor(NameMap nm) { 202 cananian 1.1.2.37 super(false/*non-strict*/); 203 cananian 1.1.2.37 m_nm = nm; 204 cananian 1.1.2.37 } 205 cananian 1.1.2.37 public void visit(Quad q) { /* do nothing */ } 206 cananian 1.1.2.37 public void visit(SIGMA q) { 207 cananian 1.1.2.37 for (int i=0; i<q.numSigmas(); i++) 208 cananian 1.1.2.37 for (int j=0; j<q.arity(); j++) 209 cananian 1.1.2.37 m_nm.map(q.dst(i, j), q.src(i)); 210 cananian 1.1.2.37 } 211 cananian 1.1.2.37 } 212 duncan 1.1.2.3 /* 213 duncan 1.1.2.3 * Performs the first phase of the transformation to NoSSA form: 214 duncan 1.1.2.3 * removing the SIGMAs. This visitor also serves the purpose of cloning 215 duncan 1.1.2.3 * the quads in the codeview, which is necessary because the PHIVisitor 216 duncan 1.1.2.3 * will actually modify these quads, and we do not want these effects 217 duncan 1.1.2.3 * to propagate outside of the ToNoSSA class. 218 duncan 1.1.2.1 */ 219 cananian 1.1.2.20 static class SIGMAVisitor extends LowQuadVisitor // this is an inner class 220 duncan 1.1.2.1 { 221 bdemsky 1.1.2.14 private CloningTempMap m_ctm; 222 bdemsky 1.1.2.14 private QuadFactory m_qf; 223 bdemsky 1.1.2.14 private QuadMap m_qm; 224 bdemsky 1.1.2.14 225 cananian 1.1.2.37 public SIGMAVisitor(CloningTempMap ctm, 226 bdemsky 1.1.2.14 QuadFactory qf, QuadMap qm) 227 bdemsky 1.1.2.14 { 228 cananian 1.1.2.33 super(false/*non-strict*/); 229 bdemsky 1.1.2.14 m_ctm = ctm; 230 bdemsky 1.1.2.14 m_qf = qf; 231 bdemsky 1.1.2.14 m_qm = qm; 232 duncan 1.1.2.1 } 233 duncan 1.1.2.1 234 bdemsky 1.1.2.14 public void visit(Quad q) 235 duncan 1.1.2.1 { 236 bdemsky 1.1.2.14 Quad qm = (Quad)(q.clone(m_qf, m_ctm)); 237 bdemsky 1.1.2.14 m_qm.put(q, qm); 238 duncan 1.1.2.1 } 239 duncan 1.1.2.3 240 cananian 1.1.2.20 public void visit(CALL q) 241 cananian 1.1.2.20 { 242 cananian 1.1.2.20 SIGMA q0; 243 cananian 1.1.2.20 int arity, numSigmas; 244 cananian 1.1.2.20 Temp[] nparams; 245 cananian 1.1.2.20 246 cananian 1.1.2.20 nparams = new Temp[q.paramsLength()]; 247 cananian 1.1.2.20 for (int i=0; i<nparams.length; i++) 248 cananian 1.1.2.20 nparams[i] = map(q.params(i)); 249 cananian 1.1.2.20 q0 = new CALL(m_qf, q, q.method(), nparams, 250 cananian 1.1.2.20 (q.retval()!=null)?map(q.retval()):null, 251 cananian 1.1.2.22 map(q.retex()), q.isVirtual(), q.isTailCall(), 252 cananian 1.1.2.22 new Temp[0]); 253 cananian 1.1.2.20 m_qm.put(q, q0); 254 cananian 1.1.2.20 } 255 cananian 1.1.2.20 256 cananian 1.1.2.20 public void visit(PCALL q) // handle low-quads, too. 257 cananian 1.1.2.20 { 258 cananian 1.1.2.20 SIGMA q0; 259 cananian 1.1.2.20 int arity, numSigmas; 260 cananian 1.1.2.20 Temp[] nparams; 261 cananian 1.1.2.20 262 cananian 1.1.2.20 nparams = new Temp[q.paramsLength()]; 263 cananian 1.1.2.20 for (int i=0; i<nparams.length; i++) 264 cananian 1.1.2.20 nparams[i] = map(q.params(i)); 265 cananian 1.1.2.20 q0 = new PCALL((LowQuadFactory)m_qf, q, map(q.ptr()), nparams, 266 cananian 1.1.2.20 (q.retval()!=null)?map(q.retval()):null, 267 cananian 1.1.2.25 map(q.retex()), new Temp[0], 268 cananian 1.1.2.22 q.isVirtual(), q.isTailCall()); 269 cananian 1.1.2.20 m_qm.put(q, q0); 270 cananian 1.1.2.20 } 271 cananian 1.1.2.20 272 bdemsky 1.1.2.14 public void visit(CJMP q) 273 duncan 1.1.2.1 { 274 bdemsky 1.1.2.14 SIGMA q0; 275 bdemsky 1.1.2.14 int arity, numSigmas; 276 duncan 1.1.2.3 277 bdemsky 1.1.2.14 q0 = new CJMP(m_qf, q, map(q.test()), new Temp[] {}); 278 bdemsky 1.1.2.14 m_qm.put(q, q0); 279 duncan 1.1.2.1 } 280 duncan 1.1.2.3 281 bdemsky 1.1.2.14 public void visit(SWITCH q) 282 duncan 1.1.2.1 { 283 bdemsky 1.1.2.14 SIGMA q0; 284 bdemsky 1.1.2.14 int arity, numSigmas; 285 bdemsky 1.1.2.14 int[] keys; 286 duncan 1.1.2.1 287 bdemsky 1.1.2.14 keys = new int[q.keysLength()]; 288 bdemsky 1.1.2.14 System.arraycopy(q.keys(), 0, keys, 0, q.keysLength()); 289 bdemsky 1.1.2.14 q0 = new SWITCH(m_qf, q, map(q.index()), keys, new Temp[] {}); 290 cananian 1.1.2.35 m_qm.put(q, q0); 291 cananian 1.1.2.35 } 292 cananian 1.1.2.35 293 cananian 1.1.2.35 public void visit(TYPESWITCH q) 294 cananian 1.1.2.35 { 295 cananian 1.1.2.35 SIGMA q0; 296 cananian 1.1.2.35 int arity, numSigmas; 297 cananian 1.1.2.35 298 cananian 1.1.2.35 q0 = new TYPESWITCH(m_qf, q, map(q.index()), q.keys(), 299 cananian 1.1.2.36 new Temp[] {}, q.hasDefault()); 300 bdemsky 1.1.2.14 m_qm.put(q, q0); 301 duncan 1.1.2.1 } 302 duncan 1.1.2.3 303 bdemsky 1.1.2.14 private Temp map(Temp t) { return (t==null)?null:m_ctm.tempMap(t); } 304 duncan 1.1.2.3 } 305 duncan 1.1.2.1 306 duncan 1.1.2.3 /** 307 duncan 1.1.2.3 * Performs the second phase of the transformation to NoSSA form: 308 duncan 1.1.2.3 * the removal of the PHI nodes. This is done by actually modifying 309 duncan 1.1.2.3 * the CFG directly, so it is advisable to use this visitor only 310 duncan 1.1.2.3 * on a clone of the actual CFG you wish to translate. 311 duncan 1.1.2.3 */ 312 cananian 1.1.2.20 static class PHIVisitor extends LowQuadVisitor // this is an inner class 313 duncan 1.1.2.3 { 314 duncan 1.1.2.17 private Map m_dT; 315 bdemsky 1.1.2.14 private QuadFactory m_qf; 316 duncan 1.1.2.3 317 cananian 1.1.2.37 public PHIVisitor(QuadFactory qf, Map dT) 318 duncan 1.1.2.3 { 319 cananian 1.1.2.33 super(false/*non-strict*/); 320 bdemsky 1.1.2.14 m_dT = dT; 321 bdemsky 1.1.2.14 m_qf = qf; 322 duncan 1.1.2.3 } 323 duncan 1.1.2.3 324 bdemsky 1.1.2.14 public void visit(Quad q) { } 325 bdemsky 1.1.2.14 326 bdemsky 1.1.2.14 public void visit(LABEL q) 327 duncan 1.1.2.1 { 328 cananian 1.1.2.38 pushBack(q); 329 cananian 1.1.2.38 Quad.replace(q, new LABEL(m_qf, q, q.label(), new Temp[0], q.arity())); 330 duncan 1.1.2.1 } 331 duncan 1.1.2.3 332 bdemsky 1.1.2.14 public void visit(PHI q) 333 duncan 1.1.2.3 { 334 cananian 1.1.2.38 pushBack(q); 335 cananian 1.1.2.38 Quad.replace(q, new PHI(q.getFactory(), q, new Temp[0], q.arity())); 336 duncan 1.1.2.3 } 337 duncan 1.1.2.3 338 cananian 1.1.2.38 private static Edge addAt(Edge e, Quad q) { return addAt(e, 0, q, 0); } 339 cananian 1.1.2.38 private static Edge addAt(Edge e, int which_pred, Quad q, int which_succ) { 340 cananian 1.1.2.38 Quad frm = (Quad) e.from(); int frm_succ = e.which_succ(); 341 cananian 1.1.2.38 Quad to = (Quad) e.to(); int to_pred = e.which_pred(); 342 cananian 1.1.2.38 Quad.addEdge(frm, frm_succ, q, which_pred); 343 cananian 1.1.2.38 Quad.addEdge(q, which_succ, to, to_pred); 344 cananian 1.1.2.38 return to.prevEdge(to_pred); 345 cananian 1.1.2.38 } 346 cananian 1.1.2.38 private Edge addMoveAt(Edge e, HCodeElement source, Temp dst, Temp src, 347 cananian 1.1.2.38 Object type) { 348 cananian 1.1.2.38 MOVE m = new MOVE(m_qf, source, dst, src); 349 cananian 1.1.2.38 if (type!=null) m_dT.put(Default.pair(m, dst), type); 350 cananian 1.1.2.38 return addAt(e, m); 351 cananian 1.1.2.38 } 352 cananian 1.1.2.26 // insert MOVE on edge into PHI & update derivation table. 353 cananian 1.1.2.38 private void pushBack(PHI q) { 354 cananian 1.1.2.39 boolean hasConflicts = q.hasConflicts(); 355 cananian 1.1.2.38 Edge[] in = q.prevEdge(); 356 cananian 1.1.2.38 Edge out = q.nextEdge(0); 357 cananian 1.1.2.38 for (int i=0; i<q.numPhis(); i++) { 358 cananian 1.1.2.38 Temp Tdst = q.dst(i); 359 cananian 1.1.2.38 Object type = null; 360 cananian 1.1.2.38 if (m_dT!=null) { 361 cananian 1.1.2.38 type = m_dT.remove(Default.pair(q, Tdst)); 362 cananian 1.3.2.1 assert type!=null : "No type for "+Tdst+" in "+q; 363 cananian 1.1.2.38 } 364 cananian 1.1.2.39 Temp Tt = Tdst; 365 cananian 1.1.2.39 if (hasConflicts) { 366 cananian 1.1.2.39 Tt = new Temp(Tdst); 367 cananian 1.1.2.39 out = addMoveAt(out, q, Tdst, Tt, type); 368 cananian 1.1.2.39 } 369 cananian 1.1.2.38 for (int j=0; j<in.length; j++) 370 cananian 1.1.2.38 in[j] = addMoveAt(in[j], q, Tt, q.src(i, j), type); 371 cananian 1.1.2.26 } 372 duncan 1.1.2.3 } 373 duncan 1.1.2.1 } 374 duncan 1.1.2.1 375 duncan 1.1.2.1 376 cananian 1.1.2.20 static class QuadMap // this is an inner class 377 duncan 1.1.2.1 { 378 bdemsky 1.1.2.14 private CloningTempMap m_ctm; 379 bdemsky 1.1.2.14 private Derivation m_derivation; 380 duncan 1.1.2.17 private Map m_dT; 381 duncan 1.1.2.5 382 duncan 1.1.2.17 final private Map h = new HashMap(); 383 duncan 1.1.2.1 384 cananian 1.1.2.26 QuadMap(CloningTempMap ctm, Derivation derivation, Map dT) 385 duncan 1.1.2.1 { 386 bdemsky 1.1.2.14 m_ctm = ctm; 387 bdemsky 1.1.2.14 m_derivation = derivation; 388 bdemsky 1.1.2.14 m_dT = dT; 389 duncan 1.1.2.1 } 390 duncan 1.1.2.1 391 bdemsky 1.1.2.14 boolean contains(Quad old) { return h.containsKey(old); } 392 duncan 1.1.2.11 393 bdemsky 1.1.2.14 Quad get(Quad old) { 394 bdemsky 1.1.2.14 return (Quad)h.get(old); 395 bdemsky 1.1.2.14 } 396 duncan 1.1.2.1 397 bdemsky 1.1.2.14 void put(Quad qOld, Quad qNew) 398 duncan 1.1.2.1 { 399 bdemsky 1.1.2.14 h.put(qOld, qNew); 400 cananian 1.1.2.26 if (m_dT!=null) updateDTInfo(qOld, qNew); 401 duncan 1.1.2.1 } 402 duncan 1.1.2.1 403 bdemsky 1.1.2.14 /* UTILITY METHODS FOLLOW */ 404 duncan 1.1.2.1 405 bdemsky 1.1.2.14 private Temp map(Temp t) 406 duncan 1.1.2.5 { return (t==null)?null:m_ctm.tempMap(t); } 407 duncan 1.1.2.5 408 bdemsky 1.1.2.14 private void updateDTInfo(Quad qOld, Quad qNew) 409 duncan 1.1.2.5 { 410 cananian 1.3.2.1 assert qOld!=null && qNew != null; 411 duncan 1.1.2.11 412 cananian 1.1.2.26 Temp[] defs = qOld.def(); 413 cananian 1.1.2.26 for (int i=0; i<defs.length; i++) { 414 cananian 1.1.2.38 List tuple = Default.pair( qNew, map(defs[i]) ); 415 cananian 1.1.2.26 HClass hc = m_derivation.typeMap(qOld, defs[i]); 416 cananian 1.1.2.26 if (hc!=null) { // not a derived pointer. 417 cananian 1.1.2.26 m_dT.put(tuple, hc); 418 cananian 1.1.2.26 continue; 419 cananian 1.1.2.26 } // else, is a derived pointer. 420 cananian 1.1.2.26 DList dl = m_derivation.derivation(qOld, defs[i]); 421 cananian 1.3.2.1 assert dl!=null : "No type information for "+defs[i]+" in "+qOld; 422 cananian 1.1.2.26 m_dT.put(tuple, dl); 423 duncan 1.1.2.7 } 424 duncan 1.1.2.5 } 425 duncan 1.1.2.9 } 426 duncan 1.1.2.9 427 cananian 1.1.2.37 static class NameMap extends CloningTempMap { 428 cananian 1.1.2.37 private final TempFactory old_tf; 429 cananian 1.1.2.37 NameMap(TempFactory old_tf, TempFactory new_tf) { 430 cananian 1.1.2.37 super(old_tf, new_tf); 431 cananian 1.1.2.37 this.old_tf = old_tf; 432 cananian 1.1.2.37 } 433 cananian 1.1.2.37 private DisjointSet mergeMap = new DisjointSet(); 434 cananian 1.1.2.37 private boolean merging=true; 435 bdemsky 1.1.2.14 public Temp tempMap(Temp t) { 436 cananian 1.1.2.37 if (merging) merging=false; 437 cananian 1.1.2.37 return super.tempMap((Temp)mergeMap.find(t)); 438 cananian 1.1.2.37 } 439 cananian 1.1.2.37 public void map(Temp Told, Temp Tnew) { 440 cananian 1.3.2.1 assert merging; // no merging is valid after we start tempMapping 441 cananian 1.3.2.1 assert Told.tempFactory()==old_tf; 442 cananian 1.3.2.1 assert Tnew.tempFactory()==old_tf; 443 cananian 1.1.2.37 mergeMap.union(Told, Tnew); 444 bdemsky 1.1.2.14 } 445 duncan 1.1.2.1 } 446 duncan 1.1.2.9 447 cananian 1.1.2.20 } // close the ToNoSSA class (yes, the indentation's screwed up, 448 cananian 1.2 // but I don't feel like re-indenting all this code) [CSA]