1 cananian 1.1.2.1 // CoalescingToNoSSA.java, created Thu Nov 23 14:52:08 2000 by cananian 2 cananian 1.1.2.1 // Copyright (C) 2000 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.Analysis.Quads; 5 cananian 1.1.2.1 6 cananian 1.1.2.1 import harpoon.Analysis.Transformation.MethodMutator; 7 cananian 1.1.2.1 import harpoon.ClassFile.HCode; 8 cananian 1.1.2.1 import harpoon.ClassFile.HCodeAndMaps; 9 cananian 1.1.2.1 import harpoon.ClassFile.HCodeFactory; 10 cananian 1.1.2.1 import harpoon.ClassFile.HMethod; 11 cananian 1.1.2.1 import harpoon.IR.Quads.CALL; 12 cananian 1.1.2.1 import harpoon.IR.Quads.CJMP; 13 cananian 1.1.2.1 import harpoon.IR.Quads.Code; 14 cananian 1.1.2.1 import harpoon.IR.Quads.Edge; 15 cananian 1.1.2.1 import harpoon.IR.Quads.FOOTER; 16 cananian 1.1.2.1 import harpoon.IR.Quads.HEADER; 17 cananian 1.1.2.1 import harpoon.IR.Quads.MOVE; 18 cananian 1.1.2.1 import harpoon.IR.Quads.PHI; 19 cananian 1.1.2.1 import harpoon.IR.Quads.Quad; 20 cananian 1.1.2.1 import harpoon.IR.Quads.QuadFactory; 21 cananian 1.1.2.1 import harpoon.IR.Quads.QuadNoSSA; 22 cananian 1.1.2.1 import harpoon.IR.Quads.QuadRSSx; 23 cananian 1.1.2.1 import harpoon.IR.Quads.QuadSSA; 24 cananian 1.1.2.1 import harpoon.IR.Quads.QuadSSI; 25 cananian 1.1.2.1 import harpoon.IR.Quads.QuadVisitor; 26 cananian 1.1.2.1 import harpoon.IR.Quads.SIGMA; 27 cananian 1.1.2.1 import harpoon.IR.Quads.SWITCH; 28 cananian 1.1.2.1 import harpoon.IR.Quads.TYPESWITCH; 29 cananian 1.1.2.1 import harpoon.Temp.Temp; 30 cananian 1.1.2.1 import harpoon.Temp.TempMap; 31 cananian 1.5 import net.cscott.jutil.DisjointSet; 32 cananian 1.1.2.1 import harpoon.Util.Util; 33 cananian 1.1.2.1 34 cananian 1.1.2.1 import java.util.Iterator; 35 cananian 1.1.2.1 /** 36 cananian 1.1.2.1 * <code>CoalescingToNoSSA</code> converts SSA, SSI, and RSSx forms 37 cananian 1.1.2.1 * to No-SSA form, *coalescing* variables mentioned in phi and sigma 38 cananian 1.1.2.1 * statements where possible instead of inserting moves. 39 cananian 1.1.2.1 * 40 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 41 cananian 1.5 * @version $Id: CoalescingToNoSSA.java,v 1.5 2004/02/08 01:53:14 cananian Exp $ 42 cananian 1.1.2.1 */ 43 cananian 1.1.2.1 public class CoalescingToNoSSA extends MethodMutator { 44 cananian 1.1.2.1 45 cananian 1.1.2.1 /** Creates a <code>CoalescingToNoSSA</code>. */ 46 cananian 1.1.2.1 public CoalescingToNoSSA(HCodeFactory parent) { 47 cananian 1.1.2.1 super(parent); 48 cananian 1.1.2.1 } 49 cananian 1.1.2.1 private static class MyNoSSA extends QuadNoSSA { 50 cananian 1.1.2.1 private MyNoSSA(HMethod m) { super(m, null); } 51 cananian 1.1.2.1 public static HCodeAndMaps cloneToNoSSA(harpoon.IR.Quads.Code c, 52 cananian 1.1.2.1 HMethod m) { 53 cananian 1.1.2.1 MyNoSSA r = new MyNoSSA(m); 54 cananian 1.1.2.1 return r.cloneHelper(c, r); 55 cananian 1.1.2.1 } 56 cananian 1.1.2.1 } 57 cananian 1.1.2.1 protected String mutateCodeName(String codeName) { 58 cananian 1.3.2.1 assert codeName.equals(QuadSSA.codename) || 59 cananian 1.1.2.1 codeName.equals(QuadSSI.codename) || 60 cananian 1.3.2.1 codeName.equals(QuadRSSx.codename); 61 cananian 1.1.2.1 return MyNoSSA.codename; 62 cananian 1.1.2.1 } 63 cananian 1.1.2.1 protected HCodeAndMaps cloneHCode(HCode hc, HMethod newmethod) { 64 cananian 1.3.2.1 assert hc.getName().equals(QuadSSA.codename) || 65 cananian 1.1.2.1 hc.getName().equals(QuadSSI.codename) || 66 cananian 1.3.2.1 hc.getName().equals(QuadRSSx.codename); 67 cananian 1.1.2.1 return MyNoSSA.cloneToNoSSA((harpoon.IR.Quads.Code)hc, newmethod); 68 cananian 1.1.2.1 } 69 cananian 1.1.2.1 protected HCode mutateHCode(HCodeAndMaps input) { 70 cananian 1.1.2.1 Code hc = (Code) input.hcode(); 71 cananian 1.3.2.1 assert hc.getName().equals(QuadNoSSA.codename); 72 cananian 1.1.2.1 QuadVisitor qv = new TransformVisitor(hc); 73 cananian 1.1.2.1 Quad[] qa = (Quad[]) hc.getElements(); 74 cananian 1.1.2.1 for (int i=0; i<qa.length; i++) 75 cananian 1.1.2.1 qa[i].accept(qv); 76 cananian 1.1.2.1 return hc; 77 cananian 1.1.2.1 } 78 cananian 1.1.2.1 private static class RenameVisitor extends QuadVisitor { 79 cananian 1.1.2.1 public final DisjointSet ds = new DisjointSet(); 80 cananian 1.1.2.1 public final QuadInterferenceGraph qig; 81 cananian 1.1.2.1 RenameVisitor(Code hc) { 82 cananian 1.1.2.1 this.qig = new QuadInterferenceGraph(hc); 83 cananian 1.1.2.1 for (Iterator it=hc.getElementsI(); it.hasNext(); ) 84 cananian 1.1.2.1 ((Quad) it.next()).accept(this); 85 cananian 1.1.2.1 } 86 cananian 1.1.2.1 public void visit(Quad q) { /* do nothing */ } 87 cananian 1.1.2.1 public void visit(PHI q) { 88 cananian 1.1.2.1 for (int i=0; i<q.numPhis(); i++) 89 cananian 1.1.2.1 for (int j=0; j<q.arity(); j++) 90 cananian 1.1.2.1 if (!qig.isEdge(q.dst(i), q.src(i, j))) 91 cananian 1.1.2.1 if (!ds.find(q.dst(i)).equals(ds.find(q.src(i, j)))) 92 cananian 1.1.2.1 ds.union(q.dst(i), q.src(i, j)); 93 cananian 1.1.2.1 } 94 cananian 1.1.2.1 public void visit(SIGMA q) { 95 cananian 1.1.2.1 for (int i=0; i<q.numSigmas(); i++) 96 cananian 1.1.2.1 for (int j=0; j<q.arity(); j++) 97 cananian 1.1.2.1 if (!qig.isEdge(q.dst(i, j), q.src(i))) 98 cananian 1.1.2.1 if (!ds.find(q.dst(i, j)).equals(ds.find(q.src(i)))) 99 cananian 1.1.2.1 ds.union(q.dst(i, j), q.src(i)); 100 cananian 1.1.2.1 } 101 cananian 1.1.2.1 } 102 cananian 1.1.2.1 private static class TransformVisitor extends QuadVisitor { 103 cananian 1.1.2.1 public final TempMap tm; 104 cananian 1.1.2.1 TransformVisitor(Code hc) { 105 cananian 1.1.2.1 final DisjointSet ds = new RenameVisitor(hc).ds; 106 cananian 1.1.2.1 this.tm = new TempMap() { 107 cananian 1.1.2.1 public Temp tempMap(Temp t) { 108 cananian 1.1.2.1 return (Temp) ds.find(t); 109 cananian 1.1.2.1 } 110 cananian 1.1.2.1 }; 111 cananian 1.1.2.1 } 112 cananian 1.1.2.1 private Edge addAt(Edge e, Quad q) { return addAt(e, 0, q, 0); } 113 cananian 1.1.2.1 private Edge addAt(Edge e, int which_pred, Quad q, int which_succ) { 114 cananian 1.1.2.1 Quad frm = (Quad) e.from(); int frm_succ = e.which_succ(); 115 cananian 1.1.2.1 Quad to = (Quad) e.to(); int to_pred = e.which_pred(); 116 cananian 1.1.2.1 Quad.addEdge(frm, frm_succ, q, which_pred); 117 cananian 1.1.2.1 Quad.addEdge(q, which_succ, to, to_pred); 118 cananian 1.1.2.1 return to.prevEdge(to_pred); 119 cananian 1.1.2.1 } 120 cananian 1.1.2.1 public void visit(Quad q) { Quad.replace(q, q.rename(tm, tm)); } 121 cananian 1.1.2.1 public void visit(HEADER q) { /* do nothing. */ } 122 cananian 1.1.2.1 public void visit(FOOTER q) { /* do nothing. */ } 123 cananian 1.1.2.1 public void visit(PHI q) { 124 cananian 1.1.2.1 QuadFactory qf = q.getFactory(); 125 cananian 1.1.2.1 Quad nq = new PHI(qf, q, new Temp[0], q.arity()); 126 cananian 1.1.2.1 Quad.replace(q, nq); 127 cananian 1.1.2.1 for (int i=0; i<q.numPhis(); i++) 128 cananian 1.1.2.1 for (int j=0; j<q.arity(); j++) { 129 cananian 1.1.2.1 Temp d = map(q.dst(i)); 130 cananian 1.1.2.1 Temp s = map(q.src(i, j)); 131 cananian 1.1.2.1 if (!d.equals(s)) 132 cananian 1.1.2.1 addAt(nq.prevEdge(j), new MOVE(qf, q, d, s)); 133 cananian 1.1.2.1 } 134 cananian 1.1.2.1 } 135 cananian 1.3.2.1 public void visit(SIGMA q) { assert false; } 136 cananian 1.1.2.1 private void dosigma(QuadFactory qf, SIGMA q, SIGMA nq) { 137 cananian 1.1.2.1 Quad.replace(q, nq); 138 cananian 1.1.2.1 for (int i=0; i<q.numSigmas(); i++) 139 cananian 1.1.2.1 for (int j=0; j<q.arity(); j++) { 140 cananian 1.1.2.1 Temp d = map(q.dst(i, j)); 141 cananian 1.1.2.1 Temp s = map(q.src(i)); 142 cananian 1.1.2.1 if (!d.equals(s)) 143 cananian 1.1.2.1 addAt(nq.nextEdge(j), new MOVE(qf, q, d, s)); 144 cananian 1.1.2.1 } 145 cananian 1.1.2.1 } 146 cananian 1.1.2.1 public void visit(CJMP q) { 147 cananian 1.1.2.1 QuadFactory qf = q.getFactory(); 148 cananian 1.1.2.1 dosigma(qf, q, new CJMP(qf, q, map(q.test()), new Temp[0])); 149 cananian 1.1.2.1 } 150 cananian 1.1.2.1 public void visit(SWITCH q) { 151 cananian 1.1.2.1 QuadFactory qf = q.getFactory(); 152 cananian 1.1.2.1 dosigma(qf, q, new SWITCH(qf, q, map(q.index()), q.keys(), 153 cananian 1.1.2.1 new Temp[0])); 154 cananian 1.1.2.1 } 155 cananian 1.1.2.1 public void visit(TYPESWITCH q) { 156 cananian 1.1.2.1 QuadFactory qf = q.getFactory(); 157 cananian 1.1.2.1 dosigma(qf, q, new TYPESWITCH(qf, q, map(q.index()), q.keys(), 158 cananian 1.1.2.1 new Temp[0], q.hasDefault())); 159 cananian 1.1.2.1 } 160 cananian 1.1.2.1 public void visit(CALL q) { 161 cananian 1.1.2.1 QuadFactory qf = q.getFactory(); 162 cananian 1.1.2.1 dosigma(qf, q, new CALL(qf, q, q.method(), map(q.params()), 163 cananian 1.1.2.1 map(q.retval()), map(q.retex()), 164 cananian 1.1.2.1 q.isVirtual(), q.isTailCall(), 165 cananian 1.1.2.1 new Temp[0])); 166 cananian 1.1.2.1 } 167 cananian 1.1.2.1 private Temp map(Temp t) { return (t==null) ? null : tm.tempMap(t); } 168 cananian 1.1.2.1 private Temp[] map(Temp[] ta) { 169 cananian 1.1.2.1 Temp[] r = new Temp[ta.length]; 170 cananian 1.1.2.1 for (int i=0; i<r.length; i++) 171 cananian 1.1.2.1 r[i] = tm.tempMap(ta[i]); 172 cananian 1.1.2.1 return r; 173 cananian 1.1.2.1 } 174 cananian 1.1.2.1 } 175 cananian 1.2 }