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 }