1 cananian 1.1.2.1 // ToSSA.java, created Sat Jul  3 01:26:14 1999 by root
  2 cananian 1.1.2.1 // Copyright (C) 1999 Brian Demsky <bdemsky@mit.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.2 import harpoon.Analysis.Quads.SSIToSSAMap;
  7 cananian 1.1.2.1 import harpoon.Temp.TempMap;
  8 cananian 1.1.2.1 import harpoon.Temp.Temp;
  9 cananian 1.1.2.1 import harpoon.ClassFile.HCode;
 10 cananian 1.1.2.1 import harpoon.ClassFile.HCodeFactory;
 11 cananian 1.1.2.1 import harpoon.ClassFile.HMethod;
 12 cananian 1.1.2.1 import harpoon.IR.Quads.AGET;
 13 cananian 1.1.2.1 import harpoon.IR.Quads.ASET;
 14 cananian 1.1.2.1 import harpoon.IR.Quads.CALL;
 15 cananian 1.1.2.1 import harpoon.IR.Quads.CJMP;
 16 cananian 1.1.2.1 import harpoon.IR.Quads.Edge;
 17 cananian 1.1.2.1 import harpoon.IR.Quads.FOOTER;
 18 cananian 1.1.2.1 import harpoon.IR.Quads.GET;
 19 cananian 1.1.2.1 import harpoon.IR.Quads.HANDLER;
 20 cananian 1.1.2.1 import harpoon.IR.Quads.HEADER;
 21 cananian 1.1.2.1 import harpoon.IR.Quads.OPER;
 22 cananian 1.1.2.1 import harpoon.IR.Quads.PHI;
 23 cananian 1.1.2.1 import harpoon.IR.Quads.Quad;
 24 cananian 1.1.2.1 import harpoon.IR.Quads.SET;
 25 cananian 1.1.2.1 import harpoon.IR.Quads.SWITCH;
 26 cananian 1.1.2.1 import harpoon.IR.Quads.TYPESWITCH;
 27 cananian 1.1.2.1 import harpoon.IR.LowQuad.LowQuadFactory;
 28 cananian 1.1.2.1 import harpoon.IR.LowQuad.LowQuadVisitor;
 29 cananian 1.1.2.1 import harpoon.IR.LowQuad.PCALL;
 30 cananian 1.4     import net.cscott.jutil.SnapshotIterator;
 31 cananian 1.1.2.1 
 32 cananian 1.3     import java.util.Iterator;
 33 cananian 1.1.2.1 /**
 34 cananian 1.1.2.1  * <code>ReHandlerToSSA</code>
 35 cananian 1.1.2.1  * Converts SSI to SSA.  Should work on LowQuads and Quads. 
 36 cananian 1.1.2.1  * <b>NOT FOR USE OUTSIDE REHANDLER</b>.  Use SSIToSSA instead.
 37 cananian 1.1.2.1  *
 38 cananian 1.1.2.1  * @author  Brian Demsky <bdemsky@mit.edu>
 39 cananian 1.4      * @version $Id: ReHandlerToSSA.java,v 1.4 2004/02/08 01:55:25 cananian Exp $
 40 cananian 1.1.2.1  */
 41 cananian 1.1.2.1 
 42 cananian 1.1.2.1 final class ReHandlerToSSA {
 43 cananian 1.1.2.1     TempMap ssitossamap;
 44 cananian 1.1.2.1 
 45 cananian 1.1.2.1     /** <code>ToSSA</code> takes in a TempMap and returns a <code>ToSSA</code>
 46 cananian 1.1.2.1      *  object.*/
 47 cananian 1.1.2.1     public ReHandlerToSSA(TempMap ssitossamap) {
 48 cananian 1.1.2.1         this.ssitossamap=ssitossamap;
 49 cananian 1.1.2.1     }
 50 cananian 1.1.2.1 
 51 cananian 1.1.2.1     /** Creates a <code>toSSA</code> codeFactory. */
 52 cananian 1.1.2.1     public static HCodeFactory codeFactory(final HCodeFactory parent) {
 53 cananian 1.1.2.1         return new HCodeFactory() {
 54 cananian 1.1.2.1             public HCode convert(HMethod m) {
 55 cananian 1.1.2.1                 HCode hc = parent.convert(m);
 56 cananian 1.1.2.1                 try {
 57 cananian 1.1.2.1                 hc = hc.clone(m).hcode();
 58 cananian 1.1.2.1                 } catch (CloneNotSupportedException e) {
 59 cananian 1.1.2.1                     System.out.println("Error:  clone not supported on class handed to ToSSA");
 60 cananian 1.1.2.1                 }
 61 cananian 1.1.2.1                 if (hc!=null) {
 62 cananian 1.1.2.2                     (new ReHandlerToSSA(new SSIToSSAMap(hc))).optimize(hc);
 63 cananian 1.1.2.1                 }
 64 cananian 1.1.2.1                 return hc;
 65 cananian 1.1.2.1             }
 66 cananian 1.1.2.1             public String getCodeName() { return parent.getCodeName(); }
 67 cananian 1.1.2.1             public void clear(HMethod m) { parent.clear(m); }
 68 cananian 1.1.2.1         };
 69 cananian 1.1.2.1     }
 70 cananian 1.1.2.1 
 71 cananian 1.1.2.1     /** This method takes in a HCode and transforms it from SSI to SSA.*/
 72 cananian 1.1.2.1     public void optimize(final HCode hc) {
 73 cananian 1.1.2.1         SSAVisitor visitor=new SSAVisitor(ssitossamap);
 74 cananian 1.3             for (Iterator it=new SnapshotIterator(hc.getElementsI());it.hasNext();)
 75 cananian 1.3                 ((Quad)it.next()).accept(visitor);
 76 cananian 1.1.2.1     }
 77 cananian 1.1.2.1 
 78 cananian 1.1.2.1     class SSAVisitor extends LowQuadVisitor {
 79 cananian 1.1.2.1         SSAVisitor(TempMap ssitossamap) {
 80 cananian 1.1.2.1             super(false/*non-strict*/);
 81 cananian 1.1.2.1             this.ssitossamap=ssitossamap;
 82 cananian 1.1.2.1         }
 83 cananian 1.1.2.1         
 84 cananian 1.1.2.1         public void visit(Quad q) {
 85 cananian 1.1.2.1             //Build a new quad and link it in
 86 cananian 1.1.2.1             Quad newquad=q.rename(ssitossamap,ssitossamap);
 87 cananian 1.1.2.1             Quad []prev=q.prev();
 88 cananian 1.1.2.1             Quad []next=q.next();
 89 cananian 1.1.2.1             for(int i=0;i<prev.length;i++) {
 90 cananian 1.1.2.1                 Quad.addEdge(prev[i],q.prevEdge(i).which_succ(),newquad,i);
 91 cananian 1.1.2.1             }
 92 cananian 1.1.2.1             for(int j=0;j<next.length;j++) {
 93 cananian 1.1.2.1                 Quad.addEdge(newquad,j,next[j],q.nextEdge(j).which_pred());
 94 cananian 1.1.2.1             }
 95 cananian 1.1.2.1         }
 96 cananian 1.1.2.1         
 97 cananian 1.1.2.1         public void visit(HEADER q) {
 98 cananian 1.1.2.1             //Do nothing
 99 cananian 1.1.2.1         }
100 cananian 1.1.2.1 
101 cananian 1.1.2.1         public void visit(FOOTER q) {
102 cananian 1.1.2.1             //Do nothing
103 cananian 1.1.2.1         }
104 cananian 1.1.2.1 
105 cananian 1.1.2.1         public void visit(CJMP q) {
106 cananian 1.1.2.1             int arity=q.arity();
107 cananian 1.1.2.1             Temp[] nothing=new Temp[0];
108 cananian 1.1.2.1             CJMP newsigma=new CJMP(q.getFactory(), q, ssitossamap.tempMap(q.test()), nothing);
109 cananian 1.1.2.1             Quad []prev=q.prev();
110 cananian 1.1.2.1             Quad []next=q.next();
111 cananian 1.1.2.1             for(int i=0;i<prev.length;i++) {
112 cananian 1.1.2.1                 Quad.addEdge(prev[i],q.prevEdge(i).which_succ(),newsigma,i);
113 cananian 1.1.2.1             }
114 cananian 1.1.2.1             for(int j=0;j<next.length;j++) {
115 cananian 1.1.2.1                 Quad.addEdge(newsigma,j,next[j],q.nextEdge(j).which_pred());
116 cananian 1.1.2.1             }
117 cananian 1.1.2.1         }
118 cananian 1.1.2.1 
119 cananian 1.1.2.1         public void visit(CALL q) {
120 cananian 1.1.2.1             int arity=q.arity();
121 cananian 1.1.2.1             Temp[] nparams=new Temp[q.paramsLength()];
122 cananian 1.1.2.1             for (int i=0; i<nparams.length; i++)
123 cananian 1.1.2.1                 nparams[i] = ssitossamap.tempMap(q.params(i));
124 cananian 1.1.2.1             CALL newcall=new CALL(q.getFactory(), q, q.method(),
125 cananian 1.1.2.1                                   nparams, ssitossamap.tempMap(q.retval()),
126 cananian 1.1.2.1                                   ssitossamap.tempMap(q.retex()),
127 cananian 1.1.2.1                                   q.isVirtual(), q.isTailCall(), new Temp[0]);
128 cananian 1.1.2.1             Quad []prev=q.prev();
129 cananian 1.1.2.1             Quad []next=q.next();
130 cananian 1.1.2.1             for(int i=0;i<prev.length;i++) {
131 cananian 1.1.2.1                 Quad.addEdge(prev[i],q.prevEdge(i).which_succ(),newcall,i);
132 cananian 1.1.2.1             }
133 cananian 1.1.2.1             for(int j=0;j<next.length;j++) {
134 cananian 1.1.2.1                 Quad.addEdge(newcall,j,next[j],q.nextEdge(j).which_pred());
135 cananian 1.1.2.1             }
136 cananian 1.1.2.1         }
137 cananian 1.1.2.1 
138 cananian 1.1.2.1         public void visit(PCALL q) {
139 cananian 1.1.2.1             int arity=q.arity();
140 cananian 1.1.2.1             Temp[] nparams=new Temp[q.paramsLength()];
141 cananian 1.1.2.1             for (int i=0; i<nparams.length; i++)
142 cananian 1.1.2.1                 nparams[i] = ssitossamap.tempMap(q.params(i));
143 cananian 1.1.2.1             PCALL newcall=new PCALL((LowQuadFactory)q.getFactory(), q, q.ptr(),
144 cananian 1.1.2.1                                   nparams, ssitossamap.tempMap(q.retval()),
145 cananian 1.1.2.1                                   ssitossamap.tempMap(q.retex()),
146 cananian 1.1.2.1                                   new Temp[0], q.isVirtual(), q.isTailCall());
147 cananian 1.1.2.1             Quad []prev=q.prev();
148 cananian 1.1.2.1             Quad []next=q.next();
149 cananian 1.1.2.1             for(int i=0;i<prev.length;i++) {
150 cananian 1.1.2.1                 Quad.addEdge(prev[i],q.prevEdge(i).which_succ(),newcall,i);
151 cananian 1.1.2.1             }
152 cananian 1.1.2.1             for(int j=0;j<next.length;j++) {
153 cananian 1.1.2.1                 Quad.addEdge(newcall,j,next[j],q.nextEdge(j).which_pred());
154 cananian 1.1.2.1             }
155 cananian 1.1.2.1         }
156 cananian 1.1.2.1 
157 cananian 1.1.2.1         public void visit(SWITCH q) {
158 cananian 1.1.2.1             int arity=q.arity();
159 cananian 1.1.2.1             Temp[] nothing=new Temp[0];
160 cananian 1.1.2.1             SWITCH newsigma=new SWITCH(q.getFactory(), q,ssitossamap.tempMap(q.index()), q.keys(),nothing);
161 cananian 1.1.2.1             Quad []prev=q.prev();
162 cananian 1.1.2.1             Quad []next=q.next();
163 cananian 1.1.2.1             for(int i=0;i<prev.length;i++) {
164 cananian 1.1.2.1                 Quad.addEdge(prev[i],q.prevEdge(i).which_succ(),newsigma,i);
165 cananian 1.1.2.1             }
166 cananian 1.1.2.1             for(int j=0;j<next.length;j++) {
167 cananian 1.1.2.1                 Quad.addEdge(newsigma,j,next[j],q.nextEdge(j).which_pred());
168 cananian 1.1.2.1             }
169 cananian 1.1.2.1         }
170 cananian 1.1.2.1 
171 cananian 1.1.2.1         public void visit(TYPESWITCH q) {
172 cananian 1.1.2.1             int arity=q.arity();
173 cananian 1.1.2.1             Temp[] nothing=new Temp[0];
174 cananian 1.1.2.1             TYPESWITCH newsigma=new TYPESWITCH(q.getFactory(), q,ssitossamap.tempMap(q.index()), q.keys(),nothing,q.hasDefault());
175 cananian 1.1.2.1             Quad []prev=q.prev();
176 cananian 1.1.2.1             Quad []next=q.next();
177 cananian 1.1.2.1             for(int i=0;i<prev.length;i++) {
178 cananian 1.1.2.1                 Quad.addEdge(prev[i],q.prevEdge(i).which_succ(),newsigma,i);
179 cananian 1.1.2.1             }
180 cananian 1.1.2.1             for(int j=0;j<next.length;j++) {
181 cananian 1.1.2.1                 Quad.addEdge(newsigma,j,next[j],q.nextEdge(j).which_pred());
182 cananian 1.1.2.1             }
183 cananian 1.1.2.1         }
184 cananian 1.1.2.1 
185 cananian 1.1.2.1         public void visit(PHI q) {
186 cananian 1.1.2.1             //create list of phi temps
187 cananian 1.1.2.1             int numberofphis=q.numPhis();
188 cananian 1.1.2.1             int numberofssa=0;
189 cananian 1.1.2.1             for (int i=0;i<numberofphis;i++) {
190 cananian 1.1.2.1                 Temp check=ssitossamap.tempMap(q.src(i,0));
191 cananian 1.1.2.1                 for (int j=1;j<q.arity();j++) {
192 cananian 1.1.2.1                     if (ssitossamap.tempMap(q.src(i,j))!=check) {
193 cananian 1.1.2.1                         numberofssa++;
194 cananian 1.1.2.1                         break;
195 cananian 1.1.2.1                     }
196 cananian 1.1.2.1                 }
197 cananian 1.1.2.1             }
198 cananian 1.1.2.1             Temp[] dst=new Temp[numberofssa];
199 cananian 1.1.2.1             Temp[][] src=new Temp[numberofssa][q.arity()];
200 cananian 1.1.2.1             numberofssa=0;
201 cananian 1.1.2.1             for (int i=0;i<numberofphis;i++) {
202 cananian 1.1.2.1                 Temp check=ssitossamap.tempMap(q.src(i,0));
203 cananian 1.1.2.1                 for (int j=1;j<q.arity();j++) {
204 cananian 1.1.2.1                     if (ssitossamap.tempMap(q.src(i,j))!=check) {
205 cananian 1.1.2.1                         dst[numberofssa]=q.dst(i);
206 cananian 1.1.2.1                         for (int k=0;k<q.arity();k++) {
207 cananian 1.1.2.1                             src[numberofssa][k]=ssitossamap.tempMap(q.src(i,k));
208 cananian 1.1.2.1                         }
209 cananian 1.1.2.1                         numberofssa++;
210 cananian 1.1.2.1                         break;
211 cananian 1.1.2.1                     }
212 cananian 1.1.2.1                 }
213 cananian 1.1.2.1             }
214 cananian 1.1.2.1             PHI newphi=new PHI(q.getFactory(),q,dst,src,q.arity());
215 cananian 1.1.2.1             Quad []prev=q.prev();
216 cananian 1.1.2.1             Quad []next=q.next();
217 cananian 1.1.2.1             for(int i=0;i<prev.length;i++) {
218 cananian 1.1.2.1                 Quad.addEdge(prev[i],q.prevEdge(i).which_succ(),newphi,i);
219 cananian 1.1.2.1             }
220 cananian 1.1.2.1             for(int j=0;j<next.length;j++) {
221 cananian 1.1.2.1                 Quad.addEdge(newphi,j,next[j],q.nextEdge(j).which_pred());
222 cananian 1.1.2.1             }
223 cananian 1.1.2.1         }
224 cananian 1.1.2.1         TempMap ssitossamap;
225 cananian 1.1.2.1     }
226 cananian 1.1.2.1 }
227 cananian 1.1.2.1 
228 cananian 1.1.2.1 
229 cananian 1.1.2.1 
230 cananian 1.1.2.1 
231 cananian 1.1.2.1 
232 cananian 1.2