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]