1 cananian 1.1.2.1  // QuadSSI.java, created Fri Aug  7 13:45:29 1998 by cananian
  2 cananian 1.1.2.1  // Copyright (C) 1998 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.9  import harpoon.Analysis.AllocationInformationMap;
  7 cananian 1.1.2.9  import harpoon.Analysis.Maps.AllocationInformation;
  8 cananian 1.1.2.3  import harpoon.Analysis.Quads.DeadCode;
  9 cananian 1.1.2.1  import harpoon.ClassFile.HCode;
 10 cananian 1.1.2.11 import harpoon.ClassFile.HCodeAndMaps;
 11 cananian 1.1.2.1  import harpoon.ClassFile.HCodeFactory;
 12 cananian 1.1.2.1  import harpoon.ClassFile.HMethod;
 13 cananian 1.1.2.9  import harpoon.Temp.TempMap;
 14 cananian 1.1.2.1  import harpoon.Util.Util;
 15 cananian 1.1.2.1  
 16 cananian 1.1.2.9  import java.util.Iterator;
 17 cananian 1.1.2.9  import java.util.Map;
 18 salcianu 1.6      import java.util.HashMap;
 19 cananian 1.1.2.1  /**
 20 cananian 1.1.2.8   * <code>Quads.QuadSSI</code> is a code view in SSI form.
 21 cananian 1.1.2.8   * Quad form exposes the details of
 22 cananian 1.1.2.8   * the java classfile bytecodes in a pseudo-quadruple format.  Implementation
 23 cananian 1.1.2.1   * details of the stack-based JVM are hidden in favor of a flat consistent
 24 cananian 1.1.2.1   * temporary-variable based approach.  The generated quadruples adhere
 25 cananian 1.1.2.2   * to an SSI form; that is, every variable has exactly one definition,
 26 cananian 1.1.2.2   * and <code>PHI</code> and <code>SIGMA</code> functions are used where
 27 cananian 1.1.2.2   * control flow merges or splits, respectively.
 28 cananian 1.1.2.1   * 
 29 cananian 1.1.2.1   * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 30 cananian 1.10      * @version $Id: QuadSSI.java,v 1.10 2004/02/08 03:21:24 cananian Exp $
 31 cananian 1.1.2.1   */
 32 cananian 1.1.2.1  public class QuadSSI extends Code /* which extends HCode */ {
 33 cananian 1.1.2.1      /** The name of this code view. */
 34 cananian 1.1.2.1      public static final String codename = "quad-ssi";
 35 cananian 1.1.2.1  
 36 ovy      1.3          /* shameless hack
 37 ovy      1.3             keep new-to-old quad mapping
 38 ovy      1.3          */
 39 ovy      1.3          public static boolean KEEP_QUAD_MAP_HACK = false;
 40 ovy      1.3      
 41 salcianu 1.6          /** Map from old no-ssa quads to new ssi quads. */
 42 salcianu 1.6          private Map mapNoSSA2SSI;
 43 salcianu 1.6          /** Map from new ssi quads to old no-ssa quads. */
 44 salcianu 1.6          private Map mapSSI2NoSSA;
 45 salcianu 1.6      
 46 salcianu 1.6          /** Every QuadSSI is built from a QuadNoSSA.  This method returns
 47 salcianu 1.6              a map from the original NoSSA quads to the SSI quads of
 48 salcianu 1.6              <code>this</code> codeview.
 49 salcianu 1.6              
 50 salcianu 1.6              @return a map original NoSSA quads -> SSI quads
 51 ovy      1.3      
 52 salcianu 1.6              @see QuadSSI#getQuadMapSSI2NoSSA */
 53 salcianu 1.6          public Map getQuadMapNoSSA2SSI() {
 54 salcianu 1.8              assert mapNoSSA2SSI != null :
 55 salcianu 1.8                  "You should set KEEP_QUAD_MAP_HACK if you need this";
 56 salcianu 1.6              return mapNoSSA2SSI;
 57 salcianu 1.6          }
 58 salcianu 1.6      
 59 salcianu 1.6          /** Returns the reverse of the map returned by
 60 salcianu 1.6              <code>getQuadMapNoSSA2SSI</code>. 
 61 salcianu 1.6      
 62 salcianu 1.6              @return a map SSI quads -> original NoSSA quads
 63 salcianu 1.6      
 64 salcianu 1.6              @see QuadSSI#getQuadMapNoSSA2SSI */
 65 salcianu 1.6          public Map getQuadMapSSI2NoSSA() {
 66 salcianu 1.8              assert mapSSI2NoSSA != null :
 67 salcianu 1.8                  "You should set KEEP_QUAD_MAP_HACK if you need this";
 68 salcianu 1.6              return mapSSI2NoSSA;
 69 salcianu 1.6          }
 70 ovy      1.3      
 71 salcianu 1.6          /** Update the QuadNoSSA to QuadSSI mappings when the SSI quad
 72 salcianu 1.6              <code>oldquad</code> is replaced of <code>this</code> is
 73 salcianu 1.6              replaced with the new SSI quad <code>newquad</code>. */
 74 salcianu 1.7          public void notifyReplace(Quad oldquad, Quad newquad, TempMap tm) {
 75 salcianu 1.6              if(mapSSI2NoSSA != null) { // mappings exist
 76 salcianu 1.6                  Quad quad_nossa = (Quad) mapSSI2NoSSA.get(oldquad);
 77 salcianu 1.6                  // replace quad_nossa <-> oldquad with 
 78 salcianu 1.6                  //         quad_nossa <-> newquad
 79 salcianu 1.6                  mapNoSSA2SSI.put(quad_nossa, newquad);
 80 salcianu 1.6                  mapSSI2NoSSA.remove(oldquad);
 81 salcianu 1.6                  mapSSI2NoSSA.put(newquad, quad_nossa);
 82 salcianu 1.6              }
 83 ovy      1.3          }
 84 ovy      1.3      
 85 cananian 1.1.2.1      /** Creates a <code>Code</code> object from a bytecode object. */
 86 kkz      1.9          public QuadSSI(QuadNoSSA qns) {
 87 kkz      1.9              this((Code)qns);
 88 kkz      1.9          }
 89 kkz      1.9      
 90 kkz      1.9          /** Creates a <code>Code</code> object from a resilient-no-ssa
 91 kkz      1.9           *  object. */
 92 kkz      1.9          public QuadSSI(ResilientNoSSA rns) {
 93 kkz      1.9              this((Code)rns);
 94 kkz      1.9          }
 95 kkz      1.9      
 96 kkz      1.9          /** Creates a <code>Code</code> object from either a quad-no-ssa
 97 kkz      1.9           *  or a resilient-no-ssa object. */
 98 kkz      1.9          private QuadSSI(Code qns) {
 99 cananian 1.1.2.1          super(qns.getMethod(), null);
100 cananian 1.1.2.10         SSIRename rt0 = new SSIRename(qns, qf);
101 cananian 1.1.2.9          quads = rt0.rootQuad;
102 cananian 1.1.2.10         setAllocationInformation(rt0.allocInfo);
103 cananian 1.1.2.9          // get rid of unused phi/sigmas.
104 cananian 1.1.2.9          AllocationInformationMap aim =
105 cananian 1.1.2.9              (getAllocationInformation()==null) ? null :
106 cananian 1.1.2.9              new AllocationInformationMap();
107 ovy      1.3      
108 ovy      1.3              if (KEEP_QUAD_MAP_HACK) {
109 salcianu 1.6                  mapNoSSA2SSI = rt0.quadMap;
110 salcianu 1.6                  mapSSI2NoSSA = new HashMap();
111 cananian 1.10                 for(Object entryO : mapNoSSA2SSI.entrySet()) {
112 cananian 1.10                     Map.Entry entry = (Map.Entry) entryO;
113 salcianu 1.6                      mapSSI2NoSSA.put(entry.getValue(), entry.getKey());
114 salcianu 1.6                  }
115 salcianu 1.6              }
116 ovy      1.3      
117 salcianu 1.6              DeadCode.optimize(this, aim);
118 cananian 1.1.2.9          setAllocationInformation(aim);
119 cananian 1.1.2.1      }
120 cananian 1.1.2.1  
121 cananian 1.1.2.1      /** 
122 cananian 1.1.2.1       * Create a new code object given a quadruple representation
123 cananian 1.1.2.1       * of the method instructions.
124 cananian 1.1.2.1       */
125 bdemsky  1.1.2.6      protected QuadSSI(HMethod parent, Quad quads) {
126 cananian 1.1.2.1          super(parent, quads);
127 cananian 1.1.2.1      }
128 cananian 1.1.2.1  
129 cananian 1.1.2.1      /** Clone this code representation. The clone has its own
130 cananian 1.1.2.1       *  copy of the quad graph. */
131 cananian 1.5          public HCodeAndMaps<Quad> clone(HMethod newMethod) {
132 cananian 1.1.2.11         return cloneHelper(new QuadSSI(newMethod, null));
133 cananian 1.1.2.1      }
134 cananian 1.1.2.1  
135 cananian 1.1.2.1      /**
136 cananian 1.1.2.1       * Return the name of this code view.
137 cananian 1.1.2.1       * @return the string <code>"quad-ssi"</code>.
138 cananian 1.1.2.1       */
139 cananian 1.1.2.1      public String getName() { return codename; }
140 cananian 1.1.2.1      
141 cananian 1.1.2.1      /** Return a code factory for <code>QuadSSI</code>, given a code
142 cananian 1.1.2.1       *  factory for <code>QuadNoSSA</code>.  Given a code factory for
143 cananian 1.1.2.1       *  <code>Bytecode</code> or <code>QuadWithTry</code>, chain
144 cananian 1.1.2.1       *  through <code>QuadNoSSA.codeFactory()</code>.
145 cananian 1.1.2.1       */
146 cananian 1.1.2.1      public static HCodeFactory codeFactory(final HCodeFactory hcf) {
147 cananian 1.1.2.12         if (hcf.getCodeName().equals(codename)) return hcf;
148 cananian 1.1.2.1          if (hcf.getCodeName().equals(QuadNoSSA.codename)) {
149 cananian 1.1.2.1              return new harpoon.ClassFile.SerializableCodeFactory() {
150 cananian 1.1.2.1                  public HCode convert(HMethod m) {
151 cananian 1.1.2.1                      HCode c = hcf.convert(m);
152 cananian 1.1.2.1                      return (c==null)?null:new QuadSSI((QuadNoSSA)c);
153 cananian 1.1.2.1                  }
154 cananian 1.1.2.1                  public void clear(HMethod m) { hcf.clear(m); }
155 cananian 1.1.2.1                  public String getCodeName() { return codename; }
156 cananian 1.1.2.1              };
157 cananian 1.1.2.1          } else if (hcf.getCodeName().equals(harpoon.IR.Bytecode.Code.codename)
158 cananian 1.1.2.14                    || hcf.getCodeName().equals(QuadWithTry.codename)
159 cananian 1.1.2.14                    || hcf.getCodeName().equals(QuadRSSx.codename)
160 cananian 1.1.2.14                    || hcf.getCodeName().equals(QuadSSA.codename)) {
161 cananian 1.1.2.1              // do some implicit chaining.
162 cananian 1.1.2.1              return codeFactory(QuadNoSSA.codeFactory(hcf));
163 kkz      1.9              } else if (hcf.getCodeName().equals(ResilientNoSSA.codename)) {
164 kkz      1.9                  return new harpoon.ClassFile.SerializableCodeFactory() {
165 kkz      1.9                      public HCode convert(HMethod m) {
166 kkz      1.9                          HCode c = hcf.convert(m);
167 kkz      1.9                          return (c==null)?null:new QuadSSI((ResilientNoSSA)c);
168 kkz      1.9                      }
169 kkz      1.9                      public void clear(HMethod m) { hcf.clear(m); }
170 kkz      1.9                      public String getCodeName() { return codename; }
171 kkz      1.9                  };
172 cananian 1.1.2.1          } else throw new Error("don't know how to make " + codename + 
173 cananian 1.1.2.1                                 " from " + hcf.getCodeName());
174 cananian 1.1.2.1      }
175 cananian 1.1.2.1      /** Return a code factory for QuadSSI, using the default code factory
176 cananian 1.1.2.1       *  for QuadNoSSA. */
177 cananian 1.1.2.1      public static HCodeFactory codeFactory() {
178 cananian 1.1.2.1          return codeFactory(QuadNoSSA.codeFactory());
179 cananian 1.1.2.1      }
180 cananian 1.2      }