1 bdemsky  1.1.2.2  // ReHandler.java, created Tue Aug 3 23:30:32 1999 by bdemsky
   2 cananian 1.1.2.3  // Copyright (C) 1998 Brian Demsky <bdemsky@mit.edu>
   3 cananian 1.1.2.3  // Licensed under the terms of the GNU GPL; see COPYING for details.
   4 bdemsky  1.1.2.1  package harpoon.IR.Quads;
   5 bdemsky  1.1.2.1  
   6 bdemsky  1.1.2.1  import harpoon.ClassFile.HClass;
   7 bdemsky  1.1.2.10 import harpoon.ClassFile.HCode;
   8 bdemsky  1.1.2.10 import harpoon.ClassFile.HCodeElement;
   9 cananian 1.1.2.44 import harpoon.ClassFile.Linker;
  10 bdemsky  1.1.2.1  import harpoon.Temp.CloningTempMap;
  11 bdemsky  1.1.2.1  import harpoon.Temp.Temp;
  12 bdemsky  1.1.2.4  import harpoon.Temp.TempMap;
  13 bdemsky  1.1.2.1  import harpoon.Util.Util;
  14 bdemsky  1.1.2.1  import harpoon.IR.Quads.HANDLER.ProtectedSet;
  15 cananian 1.1.2.50 import harpoon.Analysis.Quads.SSIToSSAMap;
  16 bdemsky  1.1.2.4  import harpoon.Analysis.UseDef;
  17 cananian 1.1.2.24 import harpoon.Analysis.Quads.TypeInfo;
  18 bdemsky  1.1.2.5  import harpoon.Util.Tuple;
  19 cananian 1.1.2.49 import harpoon.Util.Collections.WorkSet;
  20 bdemsky  1.1.2.12 import harpoon.Analysis.Maps.TypeMap;
  21 bdemsky  1.1.2.1  
  22 bdemsky  1.1.2.1  import java.util.Arrays;
  23 bdemsky  1.1.2.1  import java.util.ArrayList;
  24 bdemsky  1.1.2.1  import java.util.HashMap;
  25 bdemsky  1.1.2.1  import java.util.HashSet;
  26 bdemsky  1.1.2.1  import java.util.Iterator;
  27 bdemsky  1.1.2.1  import java.util.List;
  28 bdemsky  1.1.2.1  import java.util.Map;
  29 bdemsky  1.1.2.4  import java.util.Set;
  30 bdemsky  1.1.2.19 import java.util.Enumeration;
  31 bdemsky  1.1.2.21 import java.util.Stack;
  32 bdemsky  1.1.2.1  /**
  33 bdemsky  1.1.2.2   * <code>ReHandler</code> make exception handling implicit and adds
  34 bdemsky  1.1.2.1   * the <code>HANDLER</code> quads from the graph.
  35 bdemsky  1.1.2.1   * 
  36 bdemsky  1.1.2.2   * @author  Brian Demsky <bdemsky@mit.edu>
  37 cananian 1.7       * @version $Id: ReHandler.java,v 1.7 2004/02/08 03:21:24 cananian Exp $
  38 bdemsky  1.1.2.1   */
  39 bdemsky  1.1.2.1  final class ReHandler {
  40 bdemsky  1.1.2.15     /* <code>rehandler</code> takes in a <code>QuadFactory</code> and a 
  41 cananian 1.1.2.22      * <code>QuadSSI</code> and returns the first <code>Quad</code> of
  42 bdemsky  1.1.2.15      * a <code>QuadWithTry</code> IR. */
  43 bdemsky  1.1.2.15 
  44 cananian 1.1.2.31     public static QuadMapPair rehandler(final QuadFactory qf, final QuadSSI code) {
  45 bdemsky  1.1.2.15         //clone the original
  46 cananian 1.1.2.46         QuadSSI ncode=(QuadSSI)code.clone(code.getMethod()).hcode();
  47 bdemsky  1.1.2.36         //make it SSA & return TypeMap
  48 bdemsky  1.1.2.36         TypeMap ti=buildSSAMap(ncode);  
  49 bdemsky  1.1.2.36 
  50 bdemsky  1.1.2.15         //add in TYPECAST as necessary to make the bytecode verifier happy
  51 bdemsky  1.1.2.15         //does dataflow analysis, etc...
  52 bdemsky  1.1.2.12         analyzeTypes(ncode, ti);
  53 bdemsky  1.1.2.16 
  54 bdemsky  1.1.2.15         //Do pattern matching to make exceptions implicit...
  55 bdemsky  1.1.2.16 
  56 bdemsky  1.1.2.5          WorkSet callset=new WorkSet();
  57 bdemsky  1.1.2.7          WorkSet throwset=new WorkSet();
  58 bdemsky  1.1.2.16         WorkSet phiold=new WorkSet();
  59 bdemsky  1.1.2.10         WorkSet instanceset=new WorkSet();
  60 bdemsky  1.1.2.15         //Do actual pattern matching here
  61 bdemsky  1.1.2.16         HashMapList handlermap=analyze(ncode,callset,throwset, instanceset, phiold);
  62 bdemsky  1.1.2.4  
  63 bdemsky  1.1.2.1          final QuadMap qm = new QuadMap();
  64 bdemsky  1.1.2.4          final HEADER old_header = (HEADER)ncode.getRootElement();
  65 bdemsky  1.1.2.1          final METHOD old_method = (METHOD) old_header.next(1);
  66 bdemsky  1.1.2.4          final CloningTempMap ctm = new CloningTempMap(ncode.qf.tempFactory(),
  67 bdemsky  1.1.2.1                                                        qf.tempFactory());
  68 bdemsky  1.1.2.1          final ArrayList al = new ArrayList();
  69 bdemsky  1.1.2.1          final StaticState ss = new StaticState(qf, qm, ctm, al);
  70 bdemsky  1.1.2.5          WorkSet phiset=new WorkSet();
  71 bdemsky  1.1.2.10         WorkSet cjmpset=new WorkSet();
  72 bdemsky  1.1.2.15 
  73 bdemsky  1.1.2.27         //build a typemap
  74 bdemsky  1.1.2.27         HashMap typemap=new HashMap();
  75 bdemsky  1.1.2.15         //this visitor just clones and classifies the quads
  76 bdemsky  1.1.2.27         //also builds the first typemap
  77 bdemsky  1.1.2.27         visitAll(new Visitor(ss, handlermap, phiset, instanceset, cjmpset, ncode,typemap, ti), old_header);
  78 bdemsky  1.1.2.4  
  79 bdemsky  1.1.2.15         // now qm contains mappings from old to new, we just have to link them.
  80 bdemsky  1.1.2.4          for (Iterator e = ncode.getElementsI(); e.hasNext(); ) {
  81 bdemsky  1.1.2.1              Quad old = (Quad) e.next();
  82 bdemsky  1.1.2.1              // link next.
  83 bdemsky  1.1.2.1              Edge[] el = old.nextEdge();
  84 cananian 1.1.2.32             
  85 cananian 1.1.2.32             for (int i=0; i<(callset.contains(old)?1:el.length); i++) {
  86 bdemsky  1.1.2.4                      Quad.addEdge(qm.getFoot((Quad)el[i].from()),el[i].which_succ(),
  87 bdemsky  1.1.2.4                                   qm.getHead((Quad)el[i].to()), el[i].which_pred());
  88 bdemsky  1.1.2.4              }
  89 bdemsky  1.1.2.1          }
  90 bdemsky  1.1.2.4  
  91 bdemsky  1.1.2.15         //Need to iterate through the call statements
  92 cananian 1.7              for (Object callO : callset) {
  93 cananian 1.7                  CALL call = (CALL) callO;
  94 bdemsky  1.1.2.4              boolean linkold=true;
  95 bdemsky  1.1.2.4              HandInfo next;
  96 bdemsky  1.1.2.15             //see if the call is covered by a handler
  97 bdemsky  1.1.2.4              if(handlermap.containsKey(call)) {
  98 bdemsky  1.1.2.15                 //iterate through the handlers covering the call
  99 bdemsky  1.1.2.4                  Iterator iterate=handlermap.get(call).iterator();
 100 bdemsky  1.1.2.7                  boolean any=false;
 101 bdemsky  1.1.2.7                  while (iterate.hasNext()) {
 102 bdemsky  1.1.2.7                      HandInfo hi=(HandInfo)iterate.next();
 103 bdemsky  1.1.2.15                     //see if the any case is handled
 104 bdemsky  1.1.2.15                     //if so, we can't simply omit more specific handlers
 105 bdemsky  1.1.2.15                     //that just rethrow the exception
 106 bdemsky  1.1.2.16                     if (hi.anyhandler())
 107 bdemsky  1.1.2.16                         if (!any) 
 108 bdemsky  1.1.2.16                             any=removable(throwset, phiold, hi, call);
 109 bdemsky  1.1.2.7                  }
 110 bdemsky  1.1.2.15                 //iterate through the handlers again
 111 bdemsky  1.1.2.7                  iterate=handlermap.get(call).iterator();
 112 bdemsky  1.1.2.4                  while(iterate.hasNext()) {
 113 cananian 1.1.2.47                     ProtectedSet protlist=new HANDLER.HashProtectSet();
 114 bdemsky  1.1.2.4                      protlist.insert(qm.getHead(call));
 115 bdemsky  1.1.2.4                      List handlers=handlermap.get(call);
 116 bdemsky  1.1.2.4                      HandInfo nexth=(HandInfo)iterate.next();
 117 bdemsky  1.1.2.15                     //cover any handler if it is needed
 118 bdemsky  1.1.2.11                     if (nexth.anyhandler()&&!any)
 119 cananian 1.1.2.32                         makeanyhandler(qf, ss, qm, call, nexth, protlist, phiset,typemap, ti, callset);
 120 bdemsky  1.1.2.15                     //cover other handlers
 121 bdemsky  1.1.2.11                     if (nexth.specificex()) 
 122 bdemsky  1.1.2.28                         makespechandler(qf, ss, qm, call, throwset, nexth, protlist, phiset, phiold, any,typemap, ti);
 123 bdemsky  1.1.2.10                 }
 124 bdemsky  1.1.2.4              }
 125 bdemsky  1.1.2.4          }
 126 bdemsky  1.1.2.4  
 127 bdemsky  1.1.2.20         //reachable is needed to find out what phi functions have incoming
 128 bdemsky  1.1.2.20         //edges that can't ever be used....
 129 bdemsky  1.1.2.20         //Only puts in handlers edges that are reachable
 130 bdemsky  1.1.2.20         //ie...have reachable elements in their protectQuad set...
 131 bdemsky  1.1.2.20         //this is all handlers for now...
 132 bdemsky  1.1.2.19 
 133 bdemsky  1.1.2.20         Edge e = old_method.nextEdge(0);
 134 bdemsky  1.1.2.19         WorkSet reachable=new WorkSet();
 135 bdemsky  1.1.2.19         WorkSet todo=new WorkSet();
 136 bdemsky  1.1.2.19         todo.push(qm.getHead((Quad)e.to()));
 137 bdemsky  1.1.2.19         boolean  change=true;
 138 bdemsky  1.1.2.38         ArrayList handlerset=new ArrayList();
 139 bdemsky  1.1.2.19         while (change) {
 140 bdemsky  1.1.2.19             while(!todo.isEmpty()) {
 141 bdemsky  1.1.2.19                 Quad quad=(Quad)todo.pop();
 142 bdemsky  1.1.2.19                 if (!reachable.contains(quad)) {
 143 bdemsky  1.1.2.19                     reachable.push(quad);
 144 bdemsky  1.1.2.19                     for (int i=0;i<quad.next().length;i++) {
 145 bdemsky  1.1.2.19                         todo.push(quad.next(i));
 146 bdemsky  1.1.2.19                     }
 147 bdemsky  1.1.2.19                 }
 148 bdemsky  1.1.2.19             }
 149 bdemsky  1.1.2.19             change=false;
 150 cananian 1.7                  for (Object hO : ss.al) {
 151 cananian 1.7                      HANDLER h = (HANDLER) hO;
 152 bdemsky  1.1.2.19                 if (!reachable.contains(h)) {
 153 cananian 1.5                          Enumeration _enum_=h.protectedQuads();
 154 cananian 1.5                          while (_enum_.hasMoreElements()) {
 155 cananian 1.5                              if (reachable.contains(_enum_.nextElement())) {
 156 bdemsky  1.1.2.19                             todo.push(h);
 157 bdemsky  1.1.2.38                             handlerset.add(h);
 158 bdemsky  1.1.2.19                             change=true;
 159 bdemsky  1.1.2.19                             break;
 160 bdemsky  1.1.2.19                         }
 161 bdemsky  1.1.2.19                     }
 162 bdemsky  1.1.2.19                 }
 163 bdemsky  1.1.2.19             }
 164 bdemsky  1.1.2.19         }
 165 bdemsky  1.1.2.19 
 166 bdemsky  1.1.2.34 
 167 bdemsky  1.1.2.34 
 168 bdemsky  1.1.2.27         METHOD oldM=(METHOD)qm.getHead(old_method);
 169 bdemsky  1.1.2.27         Temp[] qMp = oldM.params();
 170 bdemsky  1.1.2.1          final METHOD qM = new METHOD(qf, old_method, qMp,
 171 bdemsky  1.1.2.19                                      1 + handlerset.size());
 172 bdemsky  1.1.2.27 
 173 bdemsky  1.1.2.27         for(int i=0;i<qMp.length; i++) {
 174 bdemsky  1.1.2.27             typemap.put(new Tuple(new Object[]{qM, qMp[i]}),
 175 bdemsky  1.1.2.27                         typemap.get(new Tuple(new Object[]{oldM,qMp[i]})));
 176 bdemsky  1.1.2.27         }
 177 bdemsky  1.1.2.27 
 178 bdemsky  1.1.2.1          final HEADER qH = (HEADER)qm.getHead(old_header);
 179 bdemsky  1.1.2.20         reachable.add(qM);
 180 bdemsky  1.1.2.1          Quad.addEdge(qH, 1, qM, 0);
 181 bdemsky  1.1.2.1          Quad.addEdge(qM, 0, qm.getHead((Quad)e.to()), e.which_pred());
 182 bdemsky  1.1.2.19         Iterator iterate=handlerset.iterator();
 183 bdemsky  1.1.2.38         for (int i=1; iterate.hasNext();i++) {
 184 bdemsky  1.1.2.43             Quad ij=(Quad)iterate.next();
 185 bdemsky  1.1.2.43             Quad.addEdge(qM, i,ij,0);
 186 bdemsky  1.1.2.38             //      Quad.addEdge(qM, i, (Quad)iterate.next(),0);
 187 bdemsky  1.1.2.38         }
 188 bdemsky  1.1.2.5  
 189 bdemsky  1.1.2.19 
 190 bdemsky  1.1.2.5          // Modify this new CFG by emptying PHI nodes
 191 bdemsky  1.1.2.15         // Need to make NoSSA for QuadWithTry
 192 bdemsky  1.1.2.35         // Also empties out phi edges that can't be reached.
 193 bdemsky  1.1.2.28         PHVisitor v = new PHVisitor(qf, reachable, typemap);
 194 cananian 1.7              for (Object qO : phiset) {
 195 cananian 1.7                  Quad q = (Quad) qO;
 196 bdemsky  1.1.2.26             if (reachable.contains(q))
 197 bdemsky  1.1.2.26                 q.accept(v);
 198 bdemsky  1.1.2.26         }
 199 cananian 1.1.2.31         return new QuadMapPair(qH, typemap);
 200 cananian 1.1.2.31     }
 201 bdemsky  1.1.2.36 
 202 bdemsky  1.1.2.36     static TypeMap buildSSAMap(QuadSSI ncode) {
 203 bdemsky  1.1.2.36         final HashMap newType=new HashMap();
 204 cananian 1.6              UseDef<Quad> ud=new UseDef<Quad>();
 205 bdemsky  1.1.2.36         //Make TypeInfo really dumb
 206 bdemsky  1.1.2.36         TypeInfo titemp=new TypeInfo(ncode,ud,true);
 207 cananian 1.6              SSIToSSAMap ssitossamap=new SSIToSSAMap(ncode);
 208 bdemsky  1.1.2.36         Iterator iterateQuad=ncode.getElementsI();
 209 bdemsky  1.1.2.36         while (iterateQuad.hasNext()) {
 210 bdemsky  1.1.2.36             Quad q=(Quad)iterateQuad.next();
 211 bdemsky  1.1.2.36             Temp[] defs=q.def();
 212 bdemsky  1.1.2.36             for(int i=0;i<defs.length;i++) {
 213 bdemsky  1.1.2.36                 Temp t=defs[i];
 214 bdemsky  1.1.2.36                 Temp t2=ssitossamap.tempMap(t);
 215 bdemsky  1.1.2.36                 if (!newType.containsKey(t2))
 216 bdemsky  1.1.2.36                     newType.put(t2, titemp.typeMap(q,t));
 217 bdemsky  1.1.2.36                 else {
 218 bdemsky  1.1.2.36                     HClass currType=(HClass)newType.get(t2);
 219 bdemsky  1.1.2.36                     HClass thisType=titemp.typeMap(q,t);
 220 bdemsky  1.1.2.45                     if (thisType==null)
 221 bdemsky  1.1.2.45                         System.out.println("XXXXX: ERROR typing "+q+" : "+t);
 222 bdemsky  1.1.2.45                     if (currType==null)
 223 bdemsky  1.1.2.45                         System.out.println("XXXXX: ERROR curr typing "+t2);
 224 bdemsky  1.1.2.36                     //Void policy
 225 bdemsky  1.1.2.36                     if (thisType!=HClass.Void)
 226 cananian 1.1.2.44                         newType.put(t2, merge(ncode.qf.getLinker(),
 227 cananian 1.1.2.44                                               currType, thisType));
 228 bdemsky  1.1.2.36                 }
 229 bdemsky  1.1.2.36             }
 230 bdemsky  1.1.2.36         }
 231 cananian 1.1.2.48         (new ReHandlerToSSA(ssitossamap)).optimize(ncode);
 232 bdemsky  1.1.2.36         return new TypeMap() {
 233 bdemsky  1.1.2.36             public HClass typeMap(HCodeElement hc, Temp t) {
 234 bdemsky  1.1.2.36                 return (HClass)newType.get(t);
 235 bdemsky  1.1.2.36             }
 236 bdemsky  1.1.2.36         };
 237 bdemsky  1.1.2.36     }
 238 bdemsky  1.1.2.36     
 239 cananian 1.1.2.44     static HClass merge(Linker linker, HClass tcurr, HClass t2) {
 240 bdemsky  1.1.2.36         while((tcurr!=null)&&(!tcurr.isAssignableFrom(t2))) {
 241 bdemsky  1.1.2.36             tcurr=tcurr.getSuperclass();
 242 bdemsky  1.1.2.36         }
 243 bdemsky  1.1.2.36         if (tcurr==null)
 244 cananian 1.1.2.44             tcurr=linker.forName("java.lang.Object");
 245 bdemsky  1.1.2.36         return tcurr;
 246 bdemsky  1.1.2.36     }
 247 bdemsky  1.1.2.36 
 248 cananian 1.1.2.31     static class QuadMapPair {
 249 cananian 1.1.2.31         public final Quad quad;
 250 cananian 1.1.2.31         public final Map  map;
 251 cananian 1.1.2.31         QuadMapPair(Quad q, Map m) { this.quad=q; this.map = m; }
 252 bdemsky  1.1.2.1      }
 253 bdemsky  1.1.2.11 
 254 bdemsky  1.1.2.16     private static boolean removable(Set throwset, Set phiset, HandInfo hi, CALL call) {
 255 bdemsky  1.1.2.16         boolean any=false;
 256 bdemsky  1.1.2.16         if (throwset.contains(hi.handler())) {
 257 bdemsky  1.1.2.16             Temp t=((THROW)hi.handler()).throwable();
 258 bdemsky  1.1.2.16             if (hi.map().containsKey(t))
 259 bdemsky  1.1.2.16                 t=(Temp)hi.map().get(t);
 260 bdemsky  1.1.2.16             if (t==call.retex())
 261 bdemsky  1.1.2.16                 any=true;
 262 bdemsky  1.1.2.16         }
 263 bdemsky  1.1.2.16         Quad handler=hi.handler();
 264 bdemsky  1.1.2.16         Temp ctemp=call.retex();
 265 bdemsky  1.1.2.16         int edge=hi.handleredge();
 266 bdemsky  1.1.2.16         boolean first=true;
 267 bdemsky  1.1.2.16         
 268 bdemsky  1.1.2.16         while (phiset.contains(handler)) {
 269 bdemsky  1.1.2.16             PHI phi=(PHI)handler;
 270 bdemsky  1.1.2.16             int phinum=-1;
 271 bdemsky  1.1.2.16             for (int i=0;i<phi.numPhis();i++) {
 272 bdemsky  1.1.2.16                 Temp t=phi.src(i, edge);
 273 bdemsky  1.1.2.16                 if (first&&hi.map().containsKey(t))
 274 bdemsky  1.1.2.16                     t=(Temp)hi.map().get(t);
 275 bdemsky  1.1.2.16                 if (ctemp==t) {
 276 bdemsky  1.1.2.16                     phinum=i;
 277 bdemsky  1.1.2.16                     break;
 278 bdemsky  1.1.2.16                 }
 279 bdemsky  1.1.2.16             }
 280 bdemsky  1.1.2.16 
 281 bdemsky  1.1.2.16             edge=phi.nextEdge(0).which_pred();
 282 bdemsky  1.1.2.16 
 283 bdemsky  1.1.2.16             if (phinum!=-1) {
 284 bdemsky  1.1.2.16                 ctemp=phi.dst(phinum);
 285 bdemsky  1.1.2.16                 first=false;
 286 bdemsky  1.1.2.16             }
 287 bdemsky  1.1.2.16             
 288 bdemsky  1.1.2.16             if (throwset.contains(handler.next(0))) {
 289 bdemsky  1.1.2.16                 Temp t=((THROW)handler.next(0)).throwable();
 290 bdemsky  1.1.2.16                 if (first&&hi.map().containsKey(t))
 291 bdemsky  1.1.2.16                     t=(Temp)hi.map().get(t);
 292 bdemsky  1.1.2.16                 if (t==ctemp)
 293 bdemsky  1.1.2.16                     any=true;
 294 bdemsky  1.1.2.16             }
 295 bdemsky  1.1.2.16             handler=handler.next(0);
 296 bdemsky  1.1.2.16         }
 297 bdemsky  1.1.2.16             
 298 bdemsky  1.1.2.16         return any;
 299 bdemsky  1.1.2.16     }
 300 bdemsky  1.1.2.16 
 301 bdemsky  1.1.2.11 
 302 bdemsky  1.1.2.15     //makes an exit for the anyhandler
 303 cananian 1.1.2.47     private static void makeanyhandler(final QuadFactory qf, final StaticState ss, final QuadMap qm, CALL call, HandInfo nexth, ProtectedSet protlist, Set phiset, Map ntypemap, TypeMap otypemap, Set callset) {
 304 bdemsky  1.1.2.11         Quad newhandler = new HANDLER(qf, qm.getHead(call),
 305 bdemsky  1.1.2.11                                       Quad.map(ss.ctm, call.retex()),
 306 bdemsky  1.1.2.11                                       null, protlist);
 307 bdemsky  1.1.2.28         ntypemap.put(new Tuple(new Object[]{newhandler, Quad.map(ss.ctm, call.retex()) }),
 308 bdemsky  1.1.2.28                      otypemap.typeMap(call, call.retex()));
 309 bdemsky  1.1.2.11         ss.al.add(newhandler);
 310 bdemsky  1.1.2.11         Map phimap=nexth.map();
 311 bdemsky  1.1.2.11         Temp[] dst=new Temp[phimap.size()];
 312 bdemsky  1.1.2.11         Temp[][] src=new Temp[phimap.size()][2];
 313 bdemsky  1.1.2.11         Iterator ksit=phimap.keySet().iterator();
 314 bdemsky  1.1.2.11         int count=0;
 315 bdemsky  1.1.2.11         while (ksit.hasNext()) {
 316 bdemsky  1.1.2.11             Temp t=(Temp)ksit.next();
 317 bdemsky  1.1.2.11             dst[count]=Quad.map(ss.ctm, t);
 318 bdemsky  1.1.2.11             src[count][0]=Quad.map(ss.ctm,(Temp)phimap.get(t));
 319 bdemsky  1.1.2.11             src[count][1]=Quad.map(ss.ctm, t);
 320 bdemsky  1.1.2.11             count++;
 321 bdemsky  1.1.2.11         }
 322 bdemsky  1.1.2.11         Quad phi = new PHI(qf, qm.getHead(call), dst, src, 2);
 323 bdemsky  1.1.2.28         ksit=phimap.keySet().iterator();
 324 bdemsky  1.1.2.28         while (ksit.hasNext()) {
 325 bdemsky  1.1.2.28             Temp t=(Temp)ksit.next();
 326 bdemsky  1.1.2.28             Temp t2=(Temp)phimap.get(t);
 327 bdemsky  1.1.2.28             HClass type=otypemap.typeMap(null, t),
 328 bdemsky  1.1.2.28                 type2=otypemap.typeMap(null, t2);
 329 bdemsky  1.1.2.28             ntypemap.put(new Tuple(new Object[] {phi, Quad.map(ss.ctm,t)}), type);
 330 bdemsky  1.1.2.28             ntypemap.put(new Tuple(new Object[] {phi, Quad.map(ss.ctm,t2)}), type2);
 331 bdemsky  1.1.2.28         }
 332 bdemsky  1.1.2.11         phiset.add(phi);
 333 bdemsky  1.1.2.11         Quad.addEdge(newhandler,0, phi, 0);
 334 cananian 1.1.2.32         if (callset.contains((nexth.handler()).prev(nexth.handleredge()))) {
 335 cananian 1.1.2.32             //This is the case that the previous node we is
 336 cananian 1.1.2.32             //a call statement...we don't want to link to this edge, because it
 337 cananian 1.1.2.32             //is no longer here.
 338 cananian 1.1.2.32         }
 339 cananian 1.1.2.32         else
 340 cananian 1.1.2.32             Quad.addEdge(qm.getHead(nexth.handler()).prev(nexth.handleredge()),
 341 cananian 1.1.2.32                          qm.getHead(nexth.handler()).prevEdge(nexth.handleredge()).which_succ(),phi,1);
 342 bdemsky  1.1.2.11         Quad.addEdge(phi, 0, qm.getHead(nexth.handler()), nexth.handleredge());
 343 bdemsky  1.1.2.11     }
 344 bdemsky  1.1.2.11 
 345 bdemsky  1.1.2.11 
 346 bdemsky  1.1.2.16 
 347 bdemsky  1.1.2.16     //makes a specific handler    
 348 cananian 1.1.2.47     private static void makespechandler(final QuadFactory qf, final StaticState ss, final QuadMap qm, CALL call, Set throwset, HandInfo nexth, ProtectedSet protlist, Set phiset, Set phiold, boolean any, Map ntypemap, TypeMap otypemap) {
 349 bdemsky  1.1.2.11         boolean needhand=true;
 350 bdemsky  1.1.2.16      
 351 bdemsky  1.1.2.16         if (any)
 352 bdemsky  1.1.2.16             needhand=!removable(throwset, phiold, nexth, call);
 353 bdemsky  1.1.2.16         
 354 bdemsky  1.1.2.11         if (throwset.contains(nexth.handler())&&any) {
 355 bdemsky  1.1.2.11             Temp t=((THROW)nexth.handler()).throwable();
 356 bdemsky  1.1.2.11             if (nexth.map().containsKey(t))
 357 bdemsky  1.1.2.11                 t=(Temp)nexth.map().get(t);
 358 bdemsky  1.1.2.11             if (t==call.retex())
 359 bdemsky  1.1.2.11                 needhand=false;
 360 bdemsky  1.1.2.11         }
 361 bdemsky  1.1.2.11         if (needhand) {
 362 bdemsky  1.1.2.11             Quad newhandler = new HANDLER(qf, qm.getHead(call), 
 363 bdemsky  1.1.2.11                                           Quad.map(ss.ctm, call.retex()),
 364 bdemsky  1.1.2.11                                           nexth.hclass(), protlist);
 365 bdemsky  1.1.2.28             ntypemap.put(new Tuple(new Object[] {newhandler, Quad.map(ss.ctm, call.retex()) }),
 366 bdemsky  1.1.2.28                          otypemap.typeMap(call, call.retex()));
 367 bdemsky  1.1.2.11             ss.al.add(newhandler);
 368 bdemsky  1.1.2.11             Map phimap=nexth.map();
 369 bdemsky  1.1.2.11             Temp[] dst=new Temp[phimap.size()];
 370 bdemsky  1.1.2.11             Temp[][] src=new Temp[phimap.size()][2];
 371 bdemsky  1.1.2.11             Iterator ksit=phimap.keySet().iterator();
 372 bdemsky  1.1.2.11             int count=0;
 373 bdemsky  1.1.2.11             while (ksit.hasNext()) {
 374 bdemsky  1.1.2.11                 Temp t=(Temp)ksit.next();
 375 bdemsky  1.1.2.11                 dst[count]=Quad.map(ss.ctm, t);
 376 bdemsky  1.1.2.11                 src[count][0]=Quad.map(ss.ctm, (Temp)phimap.get(t));
 377 bdemsky  1.1.2.11                 src[count][1]=Quad.map(ss.ctm, t);
 378 bdemsky  1.1.2.11                 count++;
 379 bdemsky  1.1.2.11             }
 380 bdemsky  1.1.2.11             Quad phi = new PHI(qf, qm.getHead(call), dst, src, 2);
 381 bdemsky  1.1.2.28             ksit=phimap.keySet().iterator();
 382 bdemsky  1.1.2.28             while (ksit.hasNext()) {
 383 bdemsky  1.1.2.28                 Temp t=(Temp)ksit.next();
 384 bdemsky  1.1.2.28                 Temp t2=(Temp)phimap.get(t);
 385 bdemsky  1.1.2.28                 HClass type=otypemap.typeMap(null, t),
 386 bdemsky  1.1.2.28                     type2=otypemap.typeMap(null, t2);
 387 bdemsky  1.1.2.28                 ntypemap.put(new Tuple(new Object[] {phi, Quad.map(ss.ctm,t)}), type);
 388 bdemsky  1.1.2.28                 ntypemap.put(new Tuple(new Object[] {phi, Quad.map(ss.ctm,t2)}), type2);
 389 bdemsky  1.1.2.28             }
 390 bdemsky  1.1.2.11             phiset.add(phi);
 391 bdemsky  1.1.2.11             Quad.addEdge(newhandler,0, phi, 0);
 392 bdemsky  1.1.2.11             Quad.addEdge(qm.getHead(nexth.handler()).prev(nexth.handleredge()),
 393 bdemsky  1.1.2.11                          qm.getHead(nexth.handler()).prevEdge(nexth.handleredge()).which_succ(),phi,1);
 394 bdemsky  1.1.2.11             Quad.addEdge(phi, 0, qm.getHead(nexth.handler()), nexth.handleredge());
 395 bdemsky  1.1.2.11         }
 396 bdemsky  1.1.2.11     }
 397 bdemsky  1.1.2.11 
 398 bdemsky  1.1.2.15 
 399 bdemsky  1.1.2.15     /** <code>analyzeTypes</code> implements analysis to determine
 400 bdemsky  1.1.2.15      *  what <code>TYPECAST</code> are implicit in the Quads.
 401 bdemsky  1.1.2.15      *  Then each outgoing edge of every quad is checked to see
 402 bdemsky  1.1.2.15      *  if a new implicit <code>TYPECAST</code> appears across it.  If so
 403 bdemsky  1.1.2.15      *  an explicit <code>TYPECAST</code> is added.*/
 404 bdemsky  1.1.2.15 
 405 cananian 1.1.2.22     static void analyzeTypes(final QuadSSI code, TypeMap ti) {
 406 bdemsky  1.1.2.12         HCodeElement start=code.getRootElement();
 407 bdemsky  1.1.2.12         WorkSet todo=new WorkSet();
 408 bdemsky  1.1.2.12         todo.add(start);
 409 bdemsky  1.1.2.15         //set up visitor for analysis
 410 bdemsky  1.1.2.40         TypeVisitor visitor=new TypeVisitor(ti, todo,code);
 411 bdemsky  1.1.2.15         //do the analysis
 412 bdemsky  1.1.2.12         visitanalyze(todo, visitor);
 413 bdemsky  1.1.2.15 
 414 bdemsky  1.1.2.12         Quad ql[]=(Quad[]) code.getElements();
 415 bdemsky  1.1.2.12         Map typecast=visitor.typecast();
 416 bdemsky  1.1.2.15         //loop through quads and their next quads
 417 bdemsky  1.1.2.15         //looking to see if we need a TYPECAST
 418 bdemsky  1.1.2.12         for (int i=0; i<ql.length; i++)
 419 bdemsky  1.1.2.12             for (int j=0;j<ql[i].nextLength(); j++) {
 420 bdemsky  1.1.2.12                 //Need to check to see if ql[i].next(j)
 421 bdemsky  1.1.2.12                 //has more types than ql[i]
 422 bdemsky  1.1.2.12                 //if so, add in the necessary typecasts...
 423 bdemsky  1.1.2.12                 Set oldcasts=(Set)typecast.get(ql[i]);
 424 bdemsky  1.1.2.12                 Set newcasts=(Set)typecast.get(ql[i].next(j));
 425 cananian 1.7                      for (Object castO : newcasts) {
 426 cananian 1.7                          Tuple cast = (Tuple) castO;
 427 bdemsky  1.1.2.12                     if (!oldcasts.contains(cast)) {
 428 bdemsky  1.1.2.12                         //gotta see if we have cast or not
 429 bdemsky  1.1.2.12                         Temp t=(Temp)cast.asList().get(0);
 430 bdemsky  1.1.2.12                         Iterator iterate2=oldcasts.iterator();
 431 bdemsky  1.1.2.12                         boolean found=false;
 432 bdemsky  1.1.2.12                         while (iterate2.hasNext()) {
 433 bdemsky  1.1.2.12                             Tuple tple=(Tuple)iterate2.next();
 434 bdemsky  1.1.2.12                             if ((tple.asList().get(0))==t)
 435 bdemsky  1.1.2.42                                 if (((HClass)cast.asList().get(1)).isArray()) {
 436 bdemsky  1.1.2.42                                     if (((HClass)cast.asList().get(1)).compareTo((HClass)tple.asList().get(1))==0) {
 437 bdemsky  1.1.2.42                                         found=true;
 438 bdemsky  1.1.2.42                                         break;
 439 bdemsky  1.1.2.42                                     }
 440 bdemsky  1.1.2.42                                 } else
 441 bdemsky  1.1.2.42                                     if (((HClass)cast.asList().get(1)).isAssignableFrom((HClass)tple.asList().get(1))) {
 442 bdemsky  1.1.2.42                                         found=true;
 443 bdemsky  1.1.2.42                                         break;
 444 bdemsky  1.1.2.42                                     }
 445 bdemsky  1.1.2.12                         }
 446 bdemsky  1.1.2.12                         if (!found) {
 447 bdemsky  1.1.2.12                             //Gotta add TYPECAST 'cast' quad
 448 bdemsky  1.1.2.13                             //No typecasting to primitives...
 449 bdemsky  1.1.2.13                             if (!((HClass) cast.asList().get(1)).isPrimitive()) {
 450 bdemsky  1.1.2.13                                 TYPECAST tc=new TYPECAST(ql[i].getFactory(),
 451 bdemsky  1.1.2.13                                       ql[i], (Temp) cast.asList().get(0),
 452 bdemsky  1.1.2.13                                       (HClass) cast.asList().get(1));
 453 bdemsky  1.1.2.13                                 Quad.addEdge(tc,0, ql[i].next(j),ql[i].nextEdge(j).which_pred());
 454 bdemsky  1.1.2.13                                 Quad.addEdge(ql[i], j, tc, 0);
 455 bdemsky  1.1.2.13                             }
 456 bdemsky  1.1.2.12                         }
 457 bdemsky  1.1.2.12                     }
 458 bdemsky  1.1.2.12                 }
 459 bdemsky  1.1.2.12             }
 460 bdemsky  1.1.2.12     }
 461 bdemsky  1.1.2.5  
 462 bdemsky  1.1.2.15     //Worklist based approac
 463 bdemsky  1.1.2.15     //Keep visiting quads until the list is empty...
 464 bdemsky  1.1.2.12     static void visitanalyze(WorkSet todo, TypeVisitor visitor) {
 465 bdemsky  1.1.2.12         while(!todo.isEmpty()) {
 466 bdemsky  1.1.2.12                 Quad next=(Quad)todo.pop();
 467 bdemsky  1.1.2.17                 //System.out.println(next.toString());
 468 bdemsky  1.1.2.45                 //System.out.println(next+"IN="+visitor.typecast().get(next));
 469 cananian 1.1.2.25                 next.accept(visitor);
 470 bdemsky  1.1.2.45                 //System.out.println(next+"OUT="+visitor.typecast().get(next));
 471 bdemsky  1.1.2.45                 //if (!(next instanceof HEADER))
 472 bdemsky  1.1.2.45                 //    System.out.println(next+".PREV OUT="+visitor.typecast().get(next.prev(0)));
 473 bdemsky  1.1.2.45                 //System.out.println();
 474 bdemsky  1.1.2.12         }
 475 bdemsky  1.1.2.12     }
 476 bdemsky  1.1.2.15     
 477 bdemsky  1.1.2.15     //This method does the pattern matching on calls
 478 bdemsky  1.1.2.15     //to determine HANDLERS
 479 bdemsky  1.1.2.16     private static HashMapList analyze(final Code code, Set callset, Set throwset, Set instanceset, Set phiset) {
 480 bdemsky  1.1.2.16         CALLVisitor cv=new CALLVisitor(callset, throwset, instanceset, phiset);
 481 bdemsky  1.1.2.5          for (Iterator e =  code.getElementsI(); e.hasNext(); )
 482 cananian 1.1.2.25             ((Quad)e.next()).accept(cv);
 483 bdemsky  1.1.2.4          HashMapList callhand=new HashMapList();
 484 bdemsky  1.1.2.4          AnalysingVisitor avisitor=new AnalysingVisitor(callhand,code);
 485 bdemsky  1.1.2.5          analyzevisit(avisitor, callset);
 486 bdemsky  1.1.2.4          return callhand;
 487 bdemsky  1.1.2.4      }
 488 bdemsky  1.1.2.1  
 489 bdemsky  1.1.2.1      /** Recursively visit all quads starting at <code>start</code>. */
 490 bdemsky  1.1.2.1      private static final void visitAll(Visitor v, Quad start) {
 491 cananian 1.1.2.25         start.accept(v);
 492 bdemsky  1.1.2.1          final StaticState ss = v.ss;
 493 cananian 1.3.2.1          assert ss.qm.contains(start);
 494 bdemsky  1.1.2.1          Quad[] ql = start.next();
 495 bdemsky  1.1.2.1          for (int i=0; i<ql.length; i++) {
 496 bdemsky  1.1.2.1              if (ss.qm.contains(ql[i])) continue; // skip if already done.
 497 bdemsky  1.1.2.4              visitAll(v, ql[i]);
 498 bdemsky  1.1.2.1          }
 499 bdemsky  1.1.2.1      }
 500 bdemsky  1.1.2.4  
 501 bdemsky  1.1.2.15     //This method visits all the calls to do pattern matching
 502 bdemsky  1.1.2.5      private static final void analyzevisit(AnalysingVisitor v, Set callset) {
 503 bdemsky  1.1.2.5          Iterator iterate=callset.iterator();
 504 bdemsky  1.1.2.5          while (iterate.hasNext()) {
 505 bdemsky  1.1.2.5              WorkSet qm=new WorkSet();
 506 bdemsky  1.1.2.5              Quad ptr=(Quad) iterate.next();
 507 bdemsky  1.1.2.5              v.reset();
 508 cananian 1.1.2.25             ptr.accept(v);
 509 cananian 1.1.2.32             int edge=1;
 510 bdemsky  1.1.2.5              while (v.more()&&(!qm.contains(ptr))) {
 511 bdemsky  1.1.2.17                 //System.out.println("**"+v.more());
 512 bdemsky  1.1.2.17                 //System.out.println("Visiting:" +ptr.toString());
 513 bdemsky  1.1.2.5                  qm.add(ptr);
 514 cananian 1.1.2.32                 ptr = ptr.next(edge);
 515 cananian 1.1.2.32                 edge=0;
 516 cananian 1.1.2.25                 ptr.accept(v);
 517 bdemsky  1.1.2.17                 //System.out.println(v.more());
 518 bdemsky  1.1.2.5              }
 519 bdemsky  1.1.2.4          }
 520 bdemsky  1.1.2.12     }
 521 bdemsky  1.1.2.1  
 522 bdemsky  1.1.2.1      /** mapping from old quads to new quads. */
 523 bdemsky  1.1.2.1      private static class QuadMap {
 524 bdemsky  1.1.2.1          final private Map h = new HashMap();
 525 bdemsky  1.1.2.1          void put(Quad old, Quad new_header, Quad new_footer) {
 526 bdemsky  1.1.2.1              h.put(old, new Quad[] { new_header, new_footer });
 527 bdemsky  1.1.2.1          }
 528 bdemsky  1.1.2.1          Quad getHead(Quad old) {
 529 bdemsky  1.1.2.1              Quad[] ql=(Quad[])h.get(old); return (ql==null)?null:ql[0];
 530 bdemsky  1.1.2.1          }
 531 bdemsky  1.1.2.1          Quad getFoot(Quad old) {
 532 bdemsky  1.1.2.1              Quad[] ql=(Quad[])h.get(old); return (ql==null)?null:ql[1];
 533 bdemsky  1.1.2.1          }
 534 bdemsky  1.1.2.1          boolean contains(Quad old) { return h.containsKey(old); }
 535 bdemsky  1.1.2.1      }
 536 bdemsky  1.1.2.1  
 537 bdemsky  1.1.2.1      /** Static state for visitor. */
 538 bdemsky  1.1.2.1      private static final class StaticState {
 539 bdemsky  1.1.2.1          final QuadFactory qf;
 540 bdemsky  1.1.2.1          final QuadMap qm;
 541 bdemsky  1.1.2.1          final CloningTempMap ctm;
 542 bdemsky  1.1.2.1          final List al;
 543 bdemsky  1.1.2.1          StaticState(QuadFactory qf, QuadMap qm,
 544 bdemsky  1.1.2.1                      CloningTempMap ctm, List al) {
 545 bdemsky  1.1.2.1              this.qf = qf; this.qm = qm; this.ctm = ctm;
 546 bdemsky  1.1.2.1              this.al = al;
 547 bdemsky  1.1.2.1          }
 548 bdemsky  1.1.2.1      }
 549 bdemsky  1.1.2.1  
 550 bdemsky  1.1.2.15     //This visitor creates sets of the THROW, INSTANCEOF, and CALL quads
 551 bdemsky  1.1.2.5      private static final class CALLVisitor extends QuadVisitor {
 552 bdemsky  1.1.2.5          Set callset;
 553 bdemsky  1.1.2.7          Set throwset;
 554 bdemsky  1.1.2.10         Set instanceset;
 555 bdemsky  1.1.2.16         Set phiset;
 556 bdemsky  1.1.2.5  
 557 bdemsky  1.1.2.16         CALLVisitor(Set callset, Set throwset, Set instanceset, Set phiset) {
 558 bdemsky  1.1.2.5              this.callset=callset;
 559 bdemsky  1.1.2.7              this.throwset=throwset;
 560 bdemsky  1.1.2.10             this.instanceset=instanceset;
 561 bdemsky  1.1.2.16             this.phiset=phiset;
 562 bdemsky  1.1.2.5          }
 563 bdemsky  1.1.2.5          public void visit(Quad q) {}
 564 bdemsky  1.1.2.5  
 565 bdemsky  1.1.2.16         public void visit(PHI q) {
 566 bdemsky  1.1.2.16             phiset.add(q);
 567 bdemsky  1.1.2.16         }
 568 bdemsky  1.1.2.16 
 569 bdemsky  1.1.2.7          public void visit(THROW q) {
 570 bdemsky  1.1.2.7              throwset.add(q);
 571 bdemsky  1.1.2.7          }
 572 bdemsky  1.1.2.10         
 573 bdemsky  1.1.2.10         public void visit(INSTANCEOF q) {
 574 bdemsky  1.1.2.10             instanceset.add(q);
 575 bdemsky  1.1.2.10         }
 576 bdemsky  1.1.2.7  
 577 bdemsky  1.1.2.5          public void visit(CALL q) {
 578 bdemsky  1.1.2.5              callset.add(q);
 579 bdemsky  1.1.2.5          }
 580 bdemsky  1.1.2.5      }
 581 bdemsky  1.1.2.5  
 582 bdemsky  1.1.2.5  
 583 bdemsky  1.1.2.1      /** Guts of the algorithm: map from old to new quads, putting the
 584 bdemsky  1.1.2.1       *  result in the QuadMap. */
 585 bdemsky  1.1.2.1      private static final class Visitor extends QuadVisitor {
 586 bdemsky  1.1.2.1          final QuadFactory qf;
 587 bdemsky  1.1.2.1          // which Temps are non-null/arrays of known length/integer constants
 588 bdemsky  1.1.2.1          // various bits of static state.
 589 bdemsky  1.1.2.1          final StaticState ss;
 590 bdemsky  1.1.2.5          final Set phiset;
 591 bdemsky  1.1.2.4          final HashMapList handlermap;
 592 bdemsky  1.1.2.10         final Set instanceset;
 593 bdemsky  1.1.2.10         final Set cjmpset;
 594 bdemsky  1.1.2.10         final HCode hc;
 595 bdemsky  1.1.2.10         UseDef ud;
 596 bdemsky  1.1.2.27         Map ntypemap;
 597 bdemsky  1.1.2.27         TypeMap otypemap;
 598 bdemsky  1.1.2.1  
 599 bdemsky  1.1.2.27         Visitor(StaticState ss, HashMapList handlermap, Set phiset, Set instanceset, Set cjmpset, HCode hc, Map ntypemap, TypeMap otypemap) { 
 600 bdemsky  1.1.2.15             this.qf = ss.qf;
 601 bdemsky  1.1.2.15             this.ss = ss;
 602 bdemsky  1.1.2.4              this.handlermap=handlermap;
 603 bdemsky  1.1.2.5              this.phiset=phiset;
 604 bdemsky  1.1.2.10             this.instanceset=instanceset;
 605 bdemsky  1.1.2.10             this.cjmpset=cjmpset;
 606 bdemsky  1.1.2.10             this.ud=new UseDef();
 607 bdemsky  1.1.2.10             this.hc=hc;
 608 bdemsky  1.1.2.27             this.ntypemap=ntypemap;
 609 bdemsky  1.1.2.27             this.otypemap=otypemap;
 610 bdemsky  1.1.2.27         }
 611 bdemsky  1.1.2.27 
 612 bdemsky  1.1.2.27         private void updatemap(Quad old, Quad nq) {
 613 bdemsky  1.1.2.27             Temp[] uses=old.use(), defs=old.def();
 614 bdemsky  1.1.2.27             for (int i=0;i<uses.length;i++) {
 615 bdemsky  1.1.2.27                 Temp ntemp=Quad.map(ss.ctm, uses[i]);
 616 bdemsky  1.1.2.27                 ntypemap.put(new Tuple(new Object[]{nq, ntemp}),otypemap.typeMap(old, uses[i]));
 617 bdemsky  1.1.2.27             }
 618 bdemsky  1.1.2.27             for (int i=0;i<defs.length;i++) {
 619 bdemsky  1.1.2.27                 Temp ntemp=Quad.map(ss.ctm, defs[i]);
 620 bdemsky  1.1.2.27                 ntypemap.put(new Tuple(new Object[]{nq, ntemp}),otypemap.typeMap(old, defs[i]));
 621 bdemsky  1.1.2.27             }
 622 bdemsky  1.1.2.4          }
 623 bdemsky  1.1.2.1  
 624 bdemsky  1.1.2.1          /** By default, just clone and set all destinations to top. */
 625 bdemsky  1.1.2.1          public void visit(Quad q) {
 626 bdemsky  1.1.2.1              Quad nq = (Quad) q.clone(qf, ss.ctm);
 627 bdemsky  1.1.2.27             updatemap(q,nq);
 628 bdemsky  1.1.2.1              ss.qm.put(q, nq, nq);
 629 bdemsky  1.1.2.1          }
 630 bdemsky  1.1.2.1  
 631 bdemsky  1.1.2.10         public void visit(CJMP q) {
 632 bdemsky  1.1.2.10             Quad nq = (Quad) q.clone(qf, ss.ctm);
 633 bdemsky  1.1.2.27             updatemap(q,nq);
 634 bdemsky  1.1.2.10             ss.qm.put(q, nq, nq);
 635 bdemsky  1.1.2.10             HCodeElement[] hce=ud.defMap(hc, q.test());
 636 cananian 1.3.2.1              assert hce.length==1;
 637 bdemsky  1.1.2.10             if (instanceset.contains(hce[0]))
 638 bdemsky  1.1.2.10                 cjmpset.add(q);
 639 bdemsky  1.1.2.10         }
 640 bdemsky  1.1.2.10 
 641 bdemsky  1.1.2.5          public void visit(PHI q) {
 642 bdemsky  1.1.2.5              Quad nq = (Quad) q.clone(qf, ss.ctm);
 643 bdemsky  1.1.2.27             updatemap(q,nq);
 644 bdemsky  1.1.2.5              ss.qm.put(q, nq, nq);
 645 bdemsky  1.1.2.5              phiset.add(nq);
 646 bdemsky  1.1.2.5          }
 647 bdemsky  1.1.2.5  
 648 bdemsky  1.1.2.1          public void visit(CALL q) {
 649 bdemsky  1.1.2.1              Quad nq, head;
 650 cananian 1.1.2.32             // if retex!=null, add the proper checks.
 651 bdemsky  1.1.2.1              if (q.retex()==null) nq=head=(Quad)q.clone(qf, ss.ctm);
 652 bdemsky  1.1.2.1              else {
 653 cananian 1.1.2.32                 //same old type of call intended...
 654 bdemsky  1.1.2.1                  head = new CALL(qf, q, q.method, Quad.map(ss.ctm, q.params()),
 655 bdemsky  1.1.2.1                                  Quad.map(ss.ctm, q.retval()), 
 656 cananian 1.1.2.33                                 null, q.isVirtual(), q.isTailCall(),
 657 cananian 1.1.2.33                                 new Temp[0]);
 658 bdemsky  1.1.2.4                  Quad q0 = new CONST(qf, q, Quad.map(ss.ctm, q.retex()),
 659 bdemsky  1.1.2.1                                      null, HClass.Void);
 660 bdemsky  1.1.2.27                 updatemap(q,head);
 661 bdemsky  1.1.2.27                 updatemap(q,q0);
 662 bdemsky  1.1.2.4                  Quad.addEdge(head, 0, q0, 0);
 663 bdemsky  1.1.2.4                  nq = q0;
 664 bdemsky  1.1.2.1              }
 665 bdemsky  1.1.2.1              ss.qm.put(q, head, nq);
 666 bdemsky  1.1.2.1          }
 667 bdemsky  1.1.2.1      }
 668 bdemsky  1.1.2.4  
 669 bdemsky  1.1.2.15     /** <code>AnalysingVisitor</code> implements most of pattern matching
 670 bdemsky  1.1.2.15      *  for CALL statements.*/
 671 bdemsky  1.1.2.15 
 672 bdemsky  1.1.2.4      private static final class AnalysingVisitor extends QuadVisitor {
 673 bdemsky  1.1.2.4          HashMapList handlermap;
 674 bdemsky  1.1.2.4          CALL callquad;
 675 bdemsky  1.1.2.4          HashMap callmap;
 676 bdemsky  1.1.2.4          Quad anyhandler;
 677 bdemsky  1.1.2.4          int anyedge;
 678 bdemsky  1.1.2.4          Code code;
 679 bdemsky  1.1.2.4          UseDef ud;
 680 bdemsky  1.1.2.5          boolean reset;
 681 bdemsky  1.1.2.5          HashMap phimap;
 682 bdemsky  1.1.2.8          HashMap oldphimap;
 683 bdemsky  1.1.2.5          Quad last;
 684 bdemsky  1.1.2.34         int laste;
 685 bdemsky  1.1.2.5          boolean flag;
 686 bdemsky  1.1.2.4  
 687 bdemsky  1.1.2.4          AnalysingVisitor(HashMapList handlermap, Code code) {
 688 bdemsky  1.1.2.4              this.handlermap=handlermap;
 689 bdemsky  1.1.2.4              this.callquad=null;
 690 bdemsky  1.1.2.4              this.anyhandler=null;
 691 bdemsky  1.1.2.4              this.anyedge=0;
 692 bdemsky  1.1.2.4              this.code=code;
 693 bdemsky  1.1.2.4              this.ud=new UseDef();
 694 bdemsky  1.1.2.5              this.reset=true;
 695 bdemsky  1.1.2.5              this.phimap=new HashMap();
 696 bdemsky  1.1.2.5              this.last=null;
 697 bdemsky  1.1.2.34             this.laste=0;
 698 bdemsky  1.1.2.8              this.oldphimap=null;
 699 bdemsky  1.1.2.5          }
 700 bdemsky  1.1.2.5  
 701 bdemsky  1.1.2.5          private Temp remap(Temp orig) {
 702 bdemsky  1.1.2.5              if (phimap.containsKey(orig))
 703 bdemsky  1.1.2.5                  return (Temp) phimap.get(orig);
 704 bdemsky  1.1.2.5              else
 705 bdemsky  1.1.2.5                  return orig;
 706 bdemsky  1.1.2.5          }
 707 bdemsky  1.1.2.5  
 708 bdemsky  1.1.2.5          public void reset() {
 709 bdemsky  1.1.2.5              phimap=new HashMap();
 710 bdemsky  1.1.2.16             anyhandler=null;
 711 bdemsky  1.1.2.16             anyedge=0;
 712 bdemsky  1.1.2.5              last=null;
 713 bdemsky  1.1.2.34             laste=0;
 714 bdemsky  1.1.2.5              reset=true;
 715 bdemsky  1.1.2.8              oldphimap=null;
 716 bdemsky  1.1.2.4          }
 717 bdemsky  1.1.2.4  
 718 bdemsky  1.1.2.5          private void standard(Quad q) {
 719 bdemsky  1.1.2.5              last=q;
 720 bdemsky  1.1.2.34             laste=0;
 721 bdemsky  1.1.2.5              flag=true;
 722 bdemsky  1.1.2.4          }
 723 bdemsky  1.1.2.4  
 724 bdemsky  1.1.2.5          boolean more() {
 725 bdemsky  1.1.2.5              return flag;
 726 bdemsky  1.1.2.4          }
 727 bdemsky  1.1.2.4  
 728 bdemsky  1.1.2.4          private void weird(Quad q) {
 729 bdemsky  1.1.2.4              if (anyhandler!=null) {
 730 bdemsky  1.1.2.9                  handlermap.add(callquad, new HandInfo(true, anyhandler, anyedge, new HashMap(oldphimap)));
 731 bdemsky  1.1.2.4                  anyhandler=null;
 732 bdemsky  1.1.2.4                  anyedge=0;
 733 bdemsky  1.1.2.4              }
 734 bdemsky  1.1.2.5              flag=false;
 735 bdemsky  1.1.2.5              last=q;
 736 bdemsky  1.1.2.34             laste=0;
 737 bdemsky  1.1.2.4          }
 738 bdemsky  1.1.2.4  
 739 bdemsky  1.1.2.4          public void visit(Quad q) {
 740 bdemsky  1.1.2.4              //Might have done something useful
 741 bdemsky  1.1.2.4              weird(q);
 742 bdemsky  1.1.2.4          }
 743 bdemsky  1.1.2.4  
 744 bdemsky  1.1.2.4          public void visit(CALL q) {
 745 bdemsky  1.1.2.4              //Reset last call pointer
 746 bdemsky  1.1.2.5              last=q;
 747 bdemsky  1.1.2.34             laste=1;
 748 bdemsky  1.1.2.5              if (reset) {
 749 bdemsky  1.1.2.5                  reset=false;
 750 bdemsky  1.1.2.5                  if (q.retex()!=null) {
 751 cananian 1.1.2.32                     anyhandler=q.next(1);
 752 cananian 1.1.2.32                     anyedge=q.nextEdge(1).which_pred();
 753 bdemsky  1.1.2.5                      callquad=q;
 754 cananian 1.1.2.32                     oldphimap=new HashMap(phimap);
 755 bdemsky  1.1.2.5                      callmap=new HashMap();
 756 bdemsky  1.1.2.5                      flag=true;
 757 bdemsky  1.1.2.5                  } else {
 758 bdemsky  1.1.2.5                      flag=false;
 759 bdemsky  1.1.2.5                      anyhandler=null;
 760 bdemsky  1.1.2.5                      anyedge=0;
 761 bdemsky  1.1.2.5                  }
 762 bdemsky  1.1.2.5              } else
 763 bdemsky  1.1.2.5                  weird(q);
 764 bdemsky  1.1.2.5          }
 765 bdemsky  1.1.2.5  
 766 bdemsky  1.1.2.5          public void visit(PHI q) {
 767 cananian 1.3.2.1              assert last!=null;
 768 bdemsky  1.1.2.34             //Don't want to follow edge 0 if last was a call
 769 bdemsky  1.1.2.34             int ent=last.nextEdge(laste).which_pred();
 770 bdemsky  1.1.2.5              for (int i=0;i<q.numPhis();i++) {
 771 bdemsky  1.1.2.5                  phimap.put(q.dst(i),remap(q.src(i,ent)));
 772 bdemsky  1.1.2.5                  phimap.remove(q.src(i,ent));
 773 bdemsky  1.1.2.4              }
 774 bdemsky  1.1.2.5              standard(q);
 775 bdemsky  1.1.2.4          }
 776 bdemsky  1.1.2.4  
 777 bdemsky  1.1.2.4          public void visit(INSTANCEOF q) {
 778 bdemsky  1.1.2.4              Temp dest=q.dst();
 779 bdemsky  1.1.2.4              if ((ud.useMap(code,dest).length==1)&&(callquad!=null)) {
 780 bdemsky  1.1.2.4                  //make sure it is only used once
 781 bdemsky  1.1.2.5                  if (remap(q.src())==callquad.retex()) {
 782 bdemsky  1.1.2.17                     //System.out.println("***instanceof");
 783 bdemsky  1.1.2.4                      callmap.put(q.dst(),q.hclass());
 784 bdemsky  1.1.2.4                      standard(q);
 785 bdemsky  1.1.2.4                  }
 786 bdemsky  1.1.2.4                  else weird(q);
 787 bdemsky  1.1.2.4              } else weird(q);
 788 bdemsky  1.1.2.4          }
 789 bdemsky  1.1.2.4          
 790 bdemsky  1.1.2.4          public void visit(CJMP q) {
 791 bdemsky  1.1.2.4              if (callquad!=null)
 792 bdemsky  1.1.2.4                  if (callmap.containsKey(q.test())) {
 793 cananian 1.1.2.32                     //we have an exception
 794 cananian 1.1.2.32                     //next[1] is the case of this exception
 795 cananian 1.1.2.32                     handlermap.add(callquad, 
 796 cananian 1.1.2.32                                    new HandInfo((HClass)callmap.get(q.test()), q.next(1), q.nextEdge(1).which_pred(),new HashMap(phimap)));
 797 cananian 1.1.2.32                     oldphimap=new HashMap(phimap);
 798 cananian 1.1.2.32                     anyhandler=q.next(0);
 799 cananian 1.1.2.32                     anyedge=q.nextEdge(0).which_pred();
 800 bdemsky  1.1.2.16                     standard(q);
 801 bdemsky  1.1.2.4                  } else weird(q);
 802 bdemsky  1.1.2.4          }
 803 bdemsky  1.1.2.4      }
 804 cananian 1.1.2.32 
 805 bdemsky  1.1.2.5  
 806 bdemsky  1.1.2.5  /**
 807 bdemsky  1.1.2.5   * Performs the second phase of the transformation to NoSSA form:
 808 bdemsky  1.1.2.5   * the removal of the PHI nodes.  This is done by actually modifying
 809 bdemsky  1.1.2.5   * the CFG directly, so it is advisable to use this visitor only
 810 bdemsky  1.1.2.5   * on a clone of the actual CFG you wish to translate.  
 811 bdemsky  1.1.2.5   */
 812 cananian 1.1.2.32 static class PHVisitor extends QuadVisitor // this is an inner class
 813 bdemsky  1.1.2.5  {
 814 bdemsky  1.1.2.5      private QuadFactory     m_qf;
 815 bdemsky  1.1.2.18     private Set             reachable;
 816 bdemsky  1.1.2.28     private Map             typemap;
 817 bdemsky  1.1.2.5  
 818 bdemsky  1.1.2.28     public PHVisitor(QuadFactory qf, Set reachable, Map typemap)
 819 bdemsky  1.1.2.5      {     
 820 bdemsky  1.1.2.5          m_qf          = qf;
 821 bdemsky  1.1.2.18         this.reachable=reachable;
 822 bdemsky  1.1.2.28         this.typemap=typemap;
 823 bdemsky  1.1.2.5      }
 824 bdemsky  1.1.2.5  
 825 bdemsky  1.1.2.5      public void visit(Quad q) { }
 826 bdemsky  1.1.2.5  
 827 bdemsky  1.1.2.5      public void visit(AGET q)    { visit((Quad)q); }
 828 bdemsky  1.1.2.5      public void visit(ASET q)    { visit((Quad)q); }
 829 bdemsky  1.1.2.5      public void visit(CALL q)    { visit((Quad)q); }
 830 bdemsky  1.1.2.5      public void visit(GET q)     { visit((Quad)q); }
 831 bdemsky  1.1.2.5      public void visit(HANDLER q) { visit((Quad)q); }
 832 bdemsky  1.1.2.5      public void visit(OPER q)    { visit((Quad)q); }
 833 bdemsky  1.1.2.5      public void visit(SET q)     { visit((Quad)q); }
 834 bdemsky  1.1.2.5    
 835 bdemsky  1.1.2.5      public void visit(LABEL q)
 836 bdemsky  1.1.2.5      {
 837 bdemsky  1.1.2.18         int count=0;
 838 bdemsky  1.1.2.18         boolean[] info=new boolean[q.arity()];
 839 bdemsky  1.1.2.18         for (int i=0;i<q.arity();i++) {
 840 bdemsky  1.1.2.26             if (q.prevEdge(i)!=null)
 841 bdemsky  1.1.2.26                 if (reachable.contains(q.prev(i))) {
 842 bdemsky  1.1.2.26                     count++;
 843 bdemsky  1.1.2.26                     info[i]=true;
 844 bdemsky  1.1.2.26                 } else
 845 bdemsky  1.1.2.26                     info[i]=false;
 846 bdemsky  1.1.2.26             else
 847 bdemsky  1.1.2.18                 info[i]=false;
 848 bdemsky  1.1.2.18         }
 849 bdemsky  1.1.2.18         LABEL label = new LABEL(m_qf, q, q.label(), new Temp[0], count);
 850 bdemsky  1.1.2.18         reachable.add(label);
 851 bdemsky  1.1.2.5          int numPhis = q.numPhis(), arity = q.arity();
 852 bdemsky  1.1.2.5  
 853 bdemsky  1.1.2.5          for (int i=0; i<numPhis; i++)
 854 bdemsky  1.1.2.5              for (int j=0; j<arity; j++)
 855 bdemsky  1.1.2.19                 if (info[j])
 856 bdemsky  1.1.2.5                  pushBack(q, i, j);
 857 bdemsky  1.1.2.5        
 858 bdemsky  1.1.2.5          //removePHIs(q, new LABEL(m_qf, q, q.label(), new Temp[] {}, q.arity()));
 859 bdemsky  1.1.2.5          removeTuples(q);  // Updates derivation table
 860 bdemsky  1.1.2.5  
 861 bdemsky  1.1.2.5          Quad []prev=q.prev();
 862 cananian 1.3.2.1          Quad []next=q.next(); assert next.length==1;
 863 bdemsky  1.1.2.18         int recount=0;
 864 bdemsky  1.1.2.19         if (count!=1) {
 865 bdemsky  1.1.2.19             for(int i=0;i<prev.length;i++) {
 866 bdemsky  1.1.2.19                 if (info[i])
 867 bdemsky  1.1.2.19                     Quad.addEdge(prev[i],q.prevEdge(i).which_succ(),label,recount++);
 868 bdemsky  1.1.2.19             }       
 869 bdemsky  1.1.2.19             Quad.addEdge(label,0,next[0],q.nextEdge(0).which_pred());
 870 bdemsky  1.1.2.19         } else {
 871 bdemsky  1.1.2.19             int i=0;
 872 bdemsky  1.1.2.19             while (!info[i])
 873 bdemsky  1.1.2.19                 i++;
 874 bdemsky  1.1.2.19             Quad.addEdge(prev[i], q.prevEdge(i).which_succ(), next[0], q.nextEdge(0).which_pred());
 875 bdemsky  1.1.2.5          }
 876 bdemsky  1.1.2.5      }
 877 bdemsky  1.1.2.5        
 878 bdemsky  1.1.2.5      public void visit(PHI q)
 879 bdemsky  1.1.2.5      {
 880 bdemsky  1.1.2.18         int count=0;
 881 bdemsky  1.1.2.18         boolean[] info=new boolean[q.arity()];
 882 bdemsky  1.1.2.18         for (int i=0;i<q.arity();i++) {
 883 bdemsky  1.1.2.26             if (q.prevEdge(i)!=null)
 884 bdemsky  1.1.2.26                 if (reachable.contains(q.prev(i))) {
 885 bdemsky  1.1.2.26                     count++;
 886 bdemsky  1.1.2.26                     info[i]=true;
 887 bdemsky  1.1.2.26                 } else
 888 bdemsky  1.1.2.26                     info[i]=false;
 889 bdemsky  1.1.2.26             else
 890 bdemsky  1.1.2.18                 info[i]=false;
 891 bdemsky  1.1.2.18         }
 892 bdemsky  1.1.2.18         PHI phi = new PHI(q.getFactory(), q, new Temp[0], count);
 893 bdemsky  1.1.2.18         reachable.add(phi);
 894 bdemsky  1.1.2.5          int numPhis = q.numPhis(), arity = q.arity();
 895 bdemsky  1.1.2.5          for (int i=0; i<numPhis; i++)
 896 bdemsky  1.1.2.5              for (int j=0; j<arity; j++)
 897 bdemsky  1.1.2.19                 if (info[j])
 898 bdemsky  1.1.2.19                     pushBack(q, i, j);
 899 bdemsky  1.1.2.5  
 900 bdemsky  1.1.2.5          //removePHIs(q, new PHI(m_qf, q, new Temp[] {}, q.arity()));
 901 bdemsky  1.1.2.5          removeTuples(q);  // Updates derivation table
 902 bdemsky  1.1.2.5  
 903 bdemsky  1.1.2.5          Quad []prev=q.prev();
 904 cananian 1.3.2.1          Quad []next=q.next(); assert next.length==1;
 905 bdemsky  1.1.2.18         int recount=0;
 906 bdemsky  1.1.2.19         if (count!=1) {
 907 bdemsky  1.1.2.19             for(int i=0;i<prev.length;i++) {
 908 bdemsky  1.1.2.19                 if (info[i])
 909 bdemsky  1.1.2.19                     Quad.addEdge(prev[i],q.prevEdge(i).which_succ(),phi,recount++);
 910 bdemsky  1.1.2.19             }
 911 bdemsky  1.1.2.19             Quad.addEdge(phi,0,next[0],q.nextEdge(0).which_pred());
 912 bdemsky  1.1.2.19         } else {
 913 bdemsky  1.1.2.19             int i=0;
 914 bdemsky  1.1.2.19             while (!info[i])
 915 bdemsky  1.1.2.19                 i++;
 916 bdemsky  1.1.2.19             Quad.addEdge(prev[i], q.prevEdge(i).which_succ(), next[0], q.nextEdge(0).which_pred());
 917 bdemsky  1.1.2.5          }
 918 bdemsky  1.1.2.5      }
 919 bdemsky  1.1.2.5  
 920 bdemsky  1.1.2.5      private void removePHIs(PHI q, PHI q0)
 921 bdemsky  1.1.2.5      {
 922 bdemsky  1.1.2.5          Edge[] el;
 923 bdemsky  1.1.2.5        
 924 bdemsky  1.1.2.5          el = q.prevEdge();
 925 bdemsky  1.1.2.5          for (int i=0; i<el.length; i++)
 926 bdemsky  1.1.2.5              Quad.addEdge(q.prev(i), q.prevEdge(i).which_succ(),
 927 bdemsky  1.1.2.5                           q0, q.prevEdge(i).which_pred());
 928 bdemsky  1.1.2.5        
 929 bdemsky  1.1.2.5          el = q.nextEdge();
 930 bdemsky  1.1.2.5          for (int i=0; i<el.length; i++) {
 931 bdemsky  1.1.2.5              Quad.addEdge(q0, q.nextEdge(i).which_pred(),
 932 bdemsky  1.1.2.5                           q.next(i), q.nextEdge(i).which_succ());
 933 bdemsky  1.1.2.5          }
 934 bdemsky  1.1.2.5      }
 935 bdemsky  1.1.2.5  
 936 bdemsky  1.1.2.5      private void removeTuples(Quad q)
 937 bdemsky  1.1.2.5      {
 938 bdemsky  1.1.2.5          Temp[] tDef = q.def(), tUse = q.use();       
 939 bdemsky  1.1.2.5          Tuple t;
 940 bdemsky  1.1.2.5  
 941 bdemsky  1.1.2.5          for (int i=0; i<tDef.length; i++) {
 942 bdemsky  1.1.2.5              t = new Tuple(new Object[] { q, tDef[i] });
 943 bdemsky  1.1.2.5          }
 944 bdemsky  1.1.2.5          for (int i=0; i<tUse.length; i++) {
 945 bdemsky  1.1.2.5              t = new Tuple(new Object[] { q, tUse[i] });
 946 bdemsky  1.1.2.5          }
 947 bdemsky  1.1.2.5      }
 948 bdemsky  1.1.2.5    
 949 bdemsky  1.1.2.5      private void pushBack(PHI q, int dstIndex, int srcIndex)
 950 bdemsky  1.1.2.5      {
 951 bdemsky  1.1.2.6          if (q.dst(dstIndex)!=q.src(dstIndex, srcIndex)) {
 952 bdemsky  1.1.2.6              Edge from = q.prevEdge(srcIndex);
 953 bdemsky  1.1.2.6              MOVE m    = new MOVE(m_qf, q, q.dst(dstIndex), 
 954 bdemsky  1.1.2.6                                   q.src(dstIndex, srcIndex));
 955 bdemsky  1.1.2.28             typemap.put(new Tuple(new Object[] {m,q.dst(dstIndex)}),
 956 bdemsky  1.1.2.28                         typemap.get(new Tuple(new Object[]{q,q.dst(dstIndex)})));
 957 bdemsky  1.1.2.28             typemap.put(new Tuple(new Object[] {m,q.src(dstIndex,srcIndex)}),
 958 bdemsky  1.1.2.28                         typemap.get(new Tuple(new Object[] {q,q.src(dstIndex,srcIndex)})));
 959 bdemsky  1.1.2.19             reachable.add(m);
 960 bdemsky  1.1.2.6              Quad.addEdge(q.prev(srcIndex), from.which_succ(), m, 0);
 961 bdemsky  1.1.2.6              Quad.addEdge(m, 0, q, from.which_pred());
 962 bdemsky  1.1.2.6          }
 963 bdemsky  1.1.2.5      }
 964 bdemsky  1.1.2.12 }
 965 bdemsky  1.1.2.12 
 966 bdemsky  1.1.2.15 /** <code>TypeVisitor</code> determines what implicit <code>TYPECAST</code>
 967 bdemsky  1.1.2.15  *  exist. */
 968 bdemsky  1.1.2.15 
 969 cananian 1.1.2.32 static class TypeVisitor extends QuadVisitor { // this is an inner class
 970 bdemsky  1.1.2.12     TypeMap ti;
 971 bdemsky  1.1.2.12     HashMap typecast;
 972 bdemsky  1.1.2.12     Set visited;
 973 bdemsky  1.1.2.12     Set todo;
 974 bdemsky  1.1.2.40     HCode hc;
 975 bdemsky  1.1.2.36     HClass otype;
 976 bdemsky  1.1.2.40     TypeVisitor(TypeMap ti, Set todo, HCode hc) {
 977 bdemsky  1.1.2.40         this.hc=hc;
 978 bdemsky  1.1.2.12         this.ti=ti;
 979 bdemsky  1.1.2.12         this.todo=todo;
 980 bdemsky  1.1.2.12         this.typecast=new HashMap();
 981 bdemsky  1.1.2.12         this.visited=new WorkSet();
 982 cananian 1.1.2.44         this.otype=((Code)hc).qf.getLinker().forDescriptor("[Ljava/lang/Object;");
 983 bdemsky  1.1.2.12     }
 984 bdemsky  1.1.2.12 
 985 bdemsky  1.1.2.12     public Map typecast() {
 986 bdemsky  1.1.2.12         return typecast;
 987 bdemsky  1.1.2.12     }
 988 bdemsky  1.1.2.12     
 989 bdemsky  1.1.2.13     public void visit(HEADER q) {
 990 bdemsky  1.1.2.13         if (!visited.contains(q)) {
 991 bdemsky  1.1.2.13             WorkSet ourcasts=new WorkSet();
 992 bdemsky  1.1.2.13             typecast.put(q, ourcasts);
 993 bdemsky  1.1.2.13             visited.add(q);
 994 bdemsky  1.1.2.13             for (int i=0;i<q.nextLength();i++)
 995 bdemsky  1.1.2.13                 todo.add(q.next(i));    
 996 bdemsky  1.1.2.13         }
 997 bdemsky  1.1.2.13     }
 998 bdemsky  1.1.2.13 
 999 bdemsky  1.1.2.15     //This method handles generic quads...
1000 bdemsky  1.1.2.15     //Equation for it is out=in.
1001 bdemsky  1.1.2.12     public void visit(Quad q) {
1002 bdemsky  1.1.2.12         boolean changed=false;
1003 bdemsky  1.1.2.12         if (visited.contains(q)) {
1004 bdemsky  1.1.2.12             Quad pred=q.prev(0);
1005 bdemsky  1.1.2.12             Set casts=(Set)typecast.get(pred);
1006 bdemsky  1.1.2.12             Set ourcasts=(Set)typecast.get(q);
1007 cananian 1.7                  for (Object castO : casts) {
1008 cananian 1.7                      Tuple cast = (Tuple) castO;
1009 bdemsky  1.1.2.12                 if (!ourcasts.contains(cast)) {
1010 bdemsky  1.1.2.12                     changed=true;
1011 bdemsky  1.1.2.12                     ourcasts.add(cast);
1012 bdemsky  1.1.2.12                 }
1013 bdemsky  1.1.2.12             }
1014 bdemsky  1.1.2.12             if (changed) {
1015 bdemsky  1.1.2.12                 //push our descendants
1016 bdemsky  1.1.2.12                 for (int i=0;i<q.nextLength();i++) {
1017 bdemsky  1.1.2.12                     todo.add(q.next(i));
1018 bdemsky  1.1.2.12                 }
1019 bdemsky  1.1.2.12             }
1020 bdemsky  1.1.2.12         }
1021 bdemsky  1.1.2.12         else {
1022 bdemsky  1.1.2.12             //never seen yet...
1023 bdemsky  1.1.2.12             Set parentcast=(Set)typecast.get(q.prev(0));
1024 bdemsky  1.1.2.12             WorkSet ourcasts=new WorkSet(parentcast);
1025 bdemsky  1.1.2.12             typecast.put(q, ourcasts);
1026 bdemsky  1.1.2.12             visited.add(q);
1027 bdemsky  1.1.2.12             for (int i=0;i<q.nextLength();i++)
1028 bdemsky  1.1.2.12                 todo.add(q.next(i));
1029 bdemsky  1.1.2.12         }
1030 bdemsky  1.1.2.12     }
1031 bdemsky  1.1.2.12     
1032 bdemsky  1.1.2.15     //This handles MOVE quads...
1033 bdemsky  1.1.2.15     //Equation for it is out=in union gen
1034 bdemsky  1.1.2.15     //where gen=any typecast for dst that were typecast for src in in.
1035 bdemsky  1.1.2.13     public void visit(MOVE q) {
1036 bdemsky  1.1.2.13         boolean changed=false;
1037 bdemsky  1.1.2.13         if (visited.contains(q)) {
1038 bdemsky  1.1.2.13             Quad pred=q.prev(0);
1039 bdemsky  1.1.2.13             Set casts=(Set)typecast.get(pred);
1040 bdemsky  1.1.2.13             Set ourcasts=(Set)typecast.get(q);
1041 cananian 1.7                  for (Object castO : casts) {
1042 cananian 1.7                      Tuple cast = (Tuple) castO;
1043 bdemsky  1.1.2.13                 if (!ourcasts.contains(cast)) {
1044 bdemsky  1.1.2.13                     changed=true;
1045 bdemsky  1.1.2.13                     ourcasts.add(cast);
1046 bdemsky  1.1.2.13                     if (((Temp)cast.asList().get(0))==q.src())
1047 bdemsky  1.1.2.13                         ourcasts.add(new Tuple(new Object[] {q.dst(), (HClass) cast.asList().get(1)}));
1048 bdemsky  1.1.2.13                 }
1049 bdemsky  1.1.2.13             }
1050 bdemsky  1.1.2.13             if (changed) {
1051 bdemsky  1.1.2.13                 //push our descendants
1052 bdemsky  1.1.2.13                 for (int i=0;i<q.nextLength();i++) {
1053 bdemsky  1.1.2.13                     todo.add(q.next(i));
1054 bdemsky  1.1.2.13                 }
1055 bdemsky  1.1.2.13             }
1056 bdemsky  1.1.2.13         }
1057 bdemsky  1.1.2.13         else {
1058 bdemsky  1.1.2.13             //never seen yet...
1059 bdemsky  1.1.2.13             Set parentcast=(Set)typecast.get(q.prev(0));
1060 bdemsky  1.1.2.13             WorkSet ourcasts=new WorkSet();
1061 bdemsky  1.1.2.13             typecast.put(q, ourcasts);
1062 cananian 1.7                  for (Object castO : parentcast) {
1063 cananian 1.7                      Tuple cast = (Tuple) castO;
1064 bdemsky  1.1.2.13                 ourcasts.add(cast);
1065 bdemsky  1.1.2.13                 if (((Temp)cast.asList().get(0))==q.src())
1066 bdemsky  1.1.2.13                     ourcasts.add(new Tuple(new Object[] {q.dst(), (HClass) cast.asList().get(1)}));
1067 bdemsky  1.1.2.13             }
1068 bdemsky  1.1.2.13             visited.add(q);
1069 bdemsky  1.1.2.13             for (int i=0;i<q.nextLength();i++)
1070 bdemsky  1.1.2.13                 todo.add(q.next(i));
1071 bdemsky  1.1.2.13         }
1072 bdemsky  1.1.2.13     }
1073 bdemsky  1.1.2.13 
1074 bdemsky  1.1.2.15     //Method for SET
1075 bdemsky  1.1.2.15     //out=in union gen
1076 bdemsky  1.1.2.15     //where gen=any cast required by SET [not already in in]
1077 bdemsky  1.1.2.12     public void visit(SET q) {
1078 bdemsky  1.1.2.12         //q.objectref() is the object to use
1079 bdemsky  1.1.2.12         //q.src() is the temp to put in the q.field() of this object
1080 bdemsky  1.1.2.12         //need to make sure that:
1081 bdemsky  1.1.2.12         //1) q.field().getDeclaringClass() is assignable from q.objectref()
1082 bdemsky  1.1.2.12         //2) q.field().getType() is assignable from q.src()
1083 bdemsky  1.1.2.12         
1084 bdemsky  1.1.2.12         boolean changed=false;
1085 bdemsky  1.1.2.12         if (visited.contains(q)) {
1086 bdemsky  1.1.2.12             Quad pred=q.prev(0);
1087 bdemsky  1.1.2.12             Set casts=(Set)typecast.get(pred);
1088 bdemsky  1.1.2.12             Set ourcasts=(Set)typecast.get(q);
1089 cananian 1.7                  for (Object castO : casts) {
1090 cananian 1.7                      Tuple cast = (Tuple) castO;
1091 bdemsky  1.1.2.12                 if (!ourcasts.contains(cast)) {
1092 bdemsky  1.1.2.12                     changed=true;
1093 bdemsky  1.1.2.12                     ourcasts.add(cast);
1094 bdemsky  1.1.2.12                 }
1095 bdemsky  1.1.2.12             }
1096 bdemsky  1.1.2.12             if (changed) {
1097 bdemsky  1.1.2.12                 //push our descendants
1098 bdemsky  1.1.2.12                 for (int i=0;i<q.nextLength();i++) {
1099 bdemsky  1.1.2.12                     todo.add(q.next(i));
1100 bdemsky  1.1.2.12                 }
1101 bdemsky  1.1.2.12             }
1102 bdemsky  1.1.2.12         }
1103 bdemsky  1.1.2.12         else {
1104 bdemsky  1.1.2.12             //never seen yet...
1105 bdemsky  1.1.2.12             Set parentcast=(Set)typecast.get(q.prev(0));
1106 bdemsky  1.1.2.12             WorkSet ourcasts=new WorkSet(parentcast);
1107 bdemsky  1.1.2.14             if (!q.isStatic())
1108 bdemsky  1.1.2.13                 if (!q.field().getDeclaringClass().isAssignableFrom(ti.typeMap(null,q.objectref()))) {
1109 bdemsky  1.1.2.13                     //Need typecast??
1110 bdemsky  1.1.2.13                     Iterator iterate=ourcasts.iterator();
1111 bdemsky  1.1.2.13                     boolean foundcast=false;
1112 bdemsky  1.1.2.13                     while (iterate.hasNext()) {
1113 bdemsky  1.1.2.13                         Tuple cast=(Tuple)iterate.next();
1114 bdemsky  1.1.2.13                         List list=cast.asList();
1115 bdemsky  1.1.2.13                         if (list.get(0)==q.objectref()) {
1116 bdemsky  1.1.2.13                             HClass hc=(HClass)list.get(1);
1117 bdemsky  1.1.2.13                             if (q.field().getDeclaringClass().isAssignableFrom(hc)) {
1118 bdemsky  1.1.2.13                                 foundcast=true;
1119 bdemsky  1.1.2.13                                 break;
1120 bdemsky  1.1.2.13                             }
1121 bdemsky  1.1.2.12                         }
1122 bdemsky  1.1.2.12                     }
1123 bdemsky  1.1.2.13                     if (!foundcast) {
1124 bdemsky  1.1.2.13                         //Add typecast
1125 bdemsky  1.1.2.13                         ourcasts.add(new Tuple(new Object[]{q.objectref(),q.field().getDeclaringClass() }));
1126 bdemsky  1.1.2.13                     }
1127 bdemsky  1.1.2.12                 }
1128 bdemsky  1.1.2.45             if (ti.typeMap(null, q.src())!=HClass.Void) {
1129 bdemsky  1.1.2.45                 if (ti.typeMap(null,q.src())==null) {
1130 bdemsky  1.1.2.45                     System.out.println("XXXXXXXXXXXXX");
1131 bdemsky  1.1.2.45                     System.out.println(q);
1132 bdemsky  1.1.2.45                     System.out.println(q.field().getType());
1133 bdemsky  1.1.2.45                     System.out.println(q.src());
1134 bdemsky  1.1.2.45                     System.out.println(hc.getMethod());
1135 bdemsky  1.1.2.45                     java.io.PrintWriter out = new java.io.PrintWriter(System.out, true);
1136 bdemsky  1.1.2.45                     hc.print(out);
1137 bdemsky  1.1.2.45                 }
1138 bdemsky  1.1.2.13                 if (!q.field().getType().isAssignableFrom(ti.typeMap(null, q.src()))) {
1139 bdemsky  1.1.2.13                     //Need typecast??
1140 bdemsky  1.1.2.13                     Iterator iterate=ourcasts.iterator();
1141 bdemsky  1.1.2.13                     boolean foundcast=false;
1142 bdemsky  1.1.2.13                     while (iterate.hasNext()) {
1143 bdemsky  1.1.2.13                         Tuple cast=(Tuple)iterate.next();
1144 bdemsky  1.1.2.13                         List list=cast.asList();
1145 bdemsky  1.1.2.13                         if (list.get(0)==q.src()) {
1146 bdemsky  1.1.2.13                             HClass hc=(HClass)list.get(1);
1147 bdemsky  1.1.2.13                             if (q.field().getType().isAssignableFrom(hc)) {
1148 bdemsky  1.1.2.13                                 foundcast=true;
1149 bdemsky  1.1.2.13                                 break;
1150 bdemsky  1.1.2.13                             }
1151 bdemsky  1.1.2.12                         }
1152 bdemsky  1.1.2.12                     }
1153 bdemsky  1.1.2.13                     if (!foundcast) {
1154 bdemsky  1.1.2.13                         //Add typecast
1155 bdemsky  1.1.2.13                         ourcasts.add(new Tuple(new Object[]{q.src(),q.field().getType() }));
1156 bdemsky  1.1.2.13                     }
1157 bdemsky  1.1.2.12                 }
1158 bdemsky  1.1.2.45             }
1159 bdemsky  1.1.2.36             typecast.put(q, ourcasts);
1160 bdemsky  1.1.2.36             visited.add(q);
1161 bdemsky  1.1.2.36             for (int i=0;i<q.nextLength();i++)
1162 bdemsky  1.1.2.36                 todo.add(q.next(i));
1163 bdemsky  1.1.2.36         }
1164 bdemsky  1.1.2.36     }
1165 bdemsky  1.1.2.36 
1166 bdemsky  1.1.2.36     //Method for ASET
1167 bdemsky  1.1.2.36     //out=in union gen
1168 bdemsky  1.1.2.36     //where gen=any cast required by ASET [not already in in]
1169 bdemsky  1.1.2.36     public void visit(ASET q) {
1170 bdemsky  1.1.2.36         //q.objectref() is the array to use
1171 bdemsky  1.1.2.36         //need to make sure that:
1172 bdemsky  1.1.2.36         //1) Object[] is assignable from q.objectref()
1173 bdemsky  1.1.2.36         
1174 bdemsky  1.1.2.36         boolean changed=false;
1175 bdemsky  1.1.2.36         if (visited.contains(q)) {
1176 bdemsky  1.1.2.36             Quad pred=q.prev(0);
1177 bdemsky  1.1.2.36             Set casts=(Set)typecast.get(pred);
1178 bdemsky  1.1.2.36             Set ourcasts=(Set)typecast.get(q);
1179 cananian 1.7                  for (Object castO : casts) {
1180 cananian 1.7                      Tuple cast = (Tuple) castO;
1181 bdemsky  1.1.2.36                 if (!ourcasts.contains(cast)) {
1182 bdemsky  1.1.2.36                     changed=true;
1183 bdemsky  1.1.2.36                     ourcasts.add(cast);
1184 bdemsky  1.1.2.36                 }
1185 bdemsky  1.1.2.36             }
1186 bdemsky  1.1.2.36             if (changed) {
1187 bdemsky  1.1.2.36                 //push our descendants
1188 bdemsky  1.1.2.36                 for (int i=0;i<q.nextLength();i++) {
1189 bdemsky  1.1.2.36                     todo.add(q.next(i));
1190 bdemsky  1.1.2.36                 }
1191 bdemsky  1.1.2.36             }
1192 bdemsky  1.1.2.36         }
1193 bdemsky  1.1.2.36         else {
1194 bdemsky  1.1.2.36             //never seen yet...
1195 bdemsky  1.1.2.36             Set parentcast=(Set)typecast.get(q.prev(0));
1196 bdemsky  1.1.2.36             WorkSet ourcasts=new WorkSet(parentcast);
1197 bdemsky  1.1.2.42             if ((!(ti.typeMap(null,q.objectref())).isArray())||
1198 bdemsky  1.1.2.42                 (!(ti.typeMap(null,q.objectref())).getComponentType().isAssignableFrom(ti.typeMap(null,q.src())))) {
1199 bdemsky  1.1.2.36                 //Need typecast??
1200 bdemsky  1.1.2.36                 Iterator iterate=ourcasts.iterator();
1201 bdemsky  1.1.2.36                 boolean foundcast=false;
1202 bdemsky  1.1.2.42                 while (iterate.hasNext()&&(foundcast==false)) {
1203 bdemsky  1.1.2.36                     Tuple cast=(Tuple)iterate.next();
1204 bdemsky  1.1.2.36                     List list=cast.asList();
1205 bdemsky  1.1.2.36                     if (list.get(0)==q.objectref()) {
1206 bdemsky  1.1.2.36                         HClass hc=(HClass)list.get(1);
1207 bdemsky  1.1.2.42                         if (hc.isArray()&&
1208 bdemsky  1.1.2.42                             hc.getComponentType().isAssignableFrom(ti.typeMap(null,q.src()))) {
1209 bdemsky  1.1.2.36                             foundcast=true;
1210 bdemsky  1.1.2.36                             break;
1211 bdemsky  1.1.2.42                         } else {
1212 bdemsky  1.1.2.42                             Iterator iterate2=ourcasts.iterator();
1213 bdemsky  1.1.2.42                             while (iterate2.hasNext()) {
1214 bdemsky  1.1.2.42                                 Tuple cast2=(Tuple)iterate.next();
1215 bdemsky  1.1.2.42                                 List list2=cast2.asList();
1216 bdemsky  1.1.2.42                                 if (list2.get(0)==q.src()) {
1217 bdemsky  1.1.2.42                                     HClass hc2=(HClass)list.get(1);
1218 bdemsky  1.1.2.42                                     if ((ti.typeMap(null,q.objectref())).isArray()&&
1219 bdemsky  1.1.2.42                                         (ti.typeMap(null,q.objectref())).getComponentType().isAssignableFrom(hc2)) {
1220 bdemsky  1.1.2.42                                         foundcast=true;
1221 bdemsky  1.1.2.42                                         break;
1222 bdemsky  1.1.2.42                                     }
1223 bdemsky  1.1.2.42                                     if (hc.isArray()&&
1224 bdemsky  1.1.2.42                                         hc.getComponentType().isAssignableFrom(hc2)) {
1225 bdemsky  1.1.2.42                                         foundcast=true;
1226 bdemsky  1.1.2.42                                         break;
1227 bdemsky  1.1.2.42                                     }
1228 bdemsky  1.1.2.42                                 }
1229 bdemsky  1.1.2.42                             }
1230 bdemsky  1.1.2.36                         }
1231 bdemsky  1.1.2.36                     }
1232 bdemsky  1.1.2.36                 }
1233 bdemsky  1.1.2.36                 if (!foundcast) {
1234 bdemsky  1.1.2.36                     //Add typecast
1235 bdemsky  1.1.2.42                     if (!(ti.typeMap(null,q.objectref())).isArray())
1236 bdemsky  1.1.2.42                         ourcasts.add(new Tuple(new Object[]{q.objectref(), otype}));
1237 bdemsky  1.1.2.42                     else
1238 bdemsky  1.1.2.42                         ourcasts.add(new Tuple(new Object[]{q.src(), (ti.typeMap(null,q.objectref())).getComponentType()}));
1239 bdemsky  1.1.2.36                 }
1240 bdemsky  1.1.2.36             }
1241 bdemsky  1.1.2.36             typecast.put(q, ourcasts);
1242 bdemsky  1.1.2.36             visited.add(q);
1243 bdemsky  1.1.2.36             for (int i=0;i<q.nextLength();i++)
1244 bdemsky  1.1.2.36                 todo.add(q.next(i));
1245 bdemsky  1.1.2.36         }
1246 bdemsky  1.1.2.36     }
1247 bdemsky  1.1.2.36 
1248 bdemsky  1.1.2.36     //Method for ALENGTH
1249 bdemsky  1.1.2.36     //out=in union gen
1250 bdemsky  1.1.2.36     //where gen=any cast required by ALENGTH [not already in in]
1251 bdemsky  1.1.2.36     public void visit(ALENGTH q) {
1252 bdemsky  1.1.2.36         //q.objectref() is the array to use
1253 bdemsky  1.1.2.36         //need to make sure that:
1254 bdemsky  1.1.2.36         //1) Object[] is assignable from q.objectref()
1255 bdemsky  1.1.2.36         
1256 bdemsky  1.1.2.36         boolean changed=false;
1257 bdemsky  1.1.2.36         if (visited.contains(q)) {
1258 bdemsky  1.1.2.36             Quad pred=q.prev(0);
1259 bdemsky  1.1.2.36             Set casts=(Set)typecast.get(pred);
1260 bdemsky  1.1.2.36             Set ourcasts=(Set)typecast.get(q);
1261 cananian 1.7                  for (Object castO : casts) {
1262 cananian 1.7                      Tuple cast = (Tuple) castO;
1263 bdemsky  1.1.2.36                 if (!ourcasts.contains(cast)) {
1264 bdemsky  1.1.2.36                     changed=true;
1265 bdemsky  1.1.2.36                     ourcasts.add(cast);
1266 bdemsky  1.1.2.36                 }
1267 bdemsky  1.1.2.36             }
1268 bdemsky  1.1.2.36             if (changed) {
1269 bdemsky  1.1.2.36                 //push our descendants
1270 bdemsky  1.1.2.36                 for (int i=0;i<q.nextLength();i++) {
1271 bdemsky  1.1.2.36                     todo.add(q.next(i));
1272 bdemsky  1.1.2.36                 }
1273 bdemsky  1.1.2.36             }
1274 bdemsky  1.1.2.36         }
1275 bdemsky  1.1.2.36         else {
1276 bdemsky  1.1.2.36             //never seen yet...
1277 bdemsky  1.1.2.36             Set parentcast=(Set)typecast.get(q.prev(0));
1278 bdemsky  1.1.2.36             WorkSet ourcasts=new WorkSet(parentcast);
1279 bdemsky  1.1.2.37             if (!(ti.typeMap(null,q.objectref)).isArray()) {
1280 bdemsky  1.1.2.36                 //Need typecast??
1281 bdemsky  1.1.2.36                 Iterator iterate=ourcasts.iterator();
1282 bdemsky  1.1.2.36                 boolean foundcast=false;
1283 bdemsky  1.1.2.36                 while (iterate.hasNext()) {
1284 bdemsky  1.1.2.36                     Tuple cast=(Tuple)iterate.next();
1285 bdemsky  1.1.2.36                     List list=cast.asList();
1286 bdemsky  1.1.2.36                     if (list.get(0)==q.objectref()) {
1287 bdemsky  1.1.2.36                         HClass hc=(HClass)list.get(1);
1288 bdemsky  1.1.2.36                         if (otype.isAssignableFrom(hc)) {
1289 bdemsky  1.1.2.36                             foundcast=true;
1290 bdemsky  1.1.2.36                             break;
1291 bdemsky  1.1.2.36                         }
1292 bdemsky  1.1.2.36                     }
1293 bdemsky  1.1.2.36                 }
1294 bdemsky  1.1.2.36                 if (!foundcast) {
1295 bdemsky  1.1.2.36                     //Add typecast
1296 bdemsky  1.1.2.36                     ourcasts.add(new Tuple(new Object[]{q.objectref(), otype}));
1297 bdemsky  1.1.2.36                 }
1298 bdemsky  1.1.2.36             }
1299 bdemsky  1.1.2.36             typecast.put(q, ourcasts);
1300 bdemsky  1.1.2.36             visited.add(q);
1301 bdemsky  1.1.2.36             for (int i=0;i<q.nextLength();i++)
1302 bdemsky  1.1.2.36                 todo.add(q.next(i));
1303 bdemsky  1.1.2.36         }
1304 bdemsky  1.1.2.36     }
1305 bdemsky  1.1.2.36 
1306 bdemsky  1.1.2.40     //Method for RETURN
1307 bdemsky  1.1.2.40     //out=in union gen
1308 bdemsky  1.1.2.40     //where gen=any cast required by AGET [not already in in]
1309 bdemsky  1.1.2.40     public void visit(RETURN q) {
1310 bdemsky  1.1.2.40         //q.objectref() is the array to use
1311 bdemsky  1.1.2.40         //need to make sure that:
1312 bdemsky  1.1.2.40         //1) Object[] is assignable from q.objectref()
1313 bdemsky  1.1.2.40         
1314 bdemsky  1.1.2.40         boolean changed=false;
1315 bdemsky  1.1.2.40         if (visited.contains(q)) {
1316 bdemsky  1.1.2.40             Quad pred=q.prev(0);
1317 bdemsky  1.1.2.40             Set casts=(Set)typecast.get(pred);
1318 bdemsky  1.1.2.40             Set ourcasts=(Set)typecast.get(q);
1319 cananian 1.7                  for (Object castO : casts) {
1320 cananian 1.7                      Tuple cast = (Tuple) castO;
1321 bdemsky  1.1.2.40                 if (!ourcasts.contains(cast)) {
1322 bdemsky  1.1.2.40                     changed=true;
1323 bdemsky  1.1.2.40                     ourcasts.add(cast);
1324 bdemsky  1.1.2.40                 }
1325 bdemsky  1.1.2.40             }
1326 bdemsky  1.1.2.40             if (changed) {
1327 bdemsky  1.1.2.40                 //push our descendants
1328 bdemsky  1.1.2.40                 for (int i=0;i<q.nextLength();i++) {
1329 bdemsky  1.1.2.40                     todo.add(q.next(i));
1330 bdemsky  1.1.2.40                 }
1331 bdemsky  1.1.2.40             }
1332 bdemsky  1.1.2.40         }
1333 bdemsky  1.1.2.40         else {
1334 bdemsky  1.1.2.41             if ((q.retval()!=null)&&(ti.typeMap(q,q.retval())!=HClass.Void)) {
1335 bdemsky  1.1.2.40                 HClass rettype=hc.getMethod().getReturnType();
1336 bdemsky  1.1.2.40                 Set parentcast=(Set)typecast.get(q.prev(0));
1337 bdemsky  1.1.2.40                 WorkSet ourcasts=new WorkSet(parentcast);
1338 bdemsky  1.1.2.40                 if (!rettype.isAssignableFrom(ti.typeMap(q,q.retval()))) {
1339 bdemsky  1.1.2.40                     //Need typecast??
1340 bdemsky  1.1.2.40                     Iterator iterate=ourcasts.iterator();
1341 bdemsky  1.1.2.40                     boolean foundcast=false;
1342 bdemsky  1.1.2.40                     while (iterate.hasNext()) {
1343 bdemsky  1.1.2.40                         Tuple cast=(Tuple)iterate.next();
1344 bdemsky  1.1.2.40                         List list=cast.asList();
1345 bdemsky  1.1.2.40                         if (list.get(0)==q.retval()) {
1346 bdemsky  1.1.2.40                             HClass hc=(HClass)list.get(1);
1347 bdemsky  1.1.2.40                             if (rettype.isAssignableFrom(hc)) {
1348 bdemsky  1.1.2.40                                 foundcast=true;
1349 bdemsky  1.1.2.40                                 break;
1350 bdemsky  1.1.2.40                             }
1351 bdemsky  1.1.2.40                         }
1352 bdemsky  1.1.2.40                     }
1353 bdemsky  1.1.2.40                     if (!foundcast) {
1354 bdemsky  1.1.2.40                         //Add typecast
1355 bdemsky  1.1.2.40                         ourcasts.add(new Tuple(new Object[]{q.retval(),rettype }));
1356 bdemsky  1.1.2.40                     }
1357 bdemsky  1.1.2.40                 }
1358 bdemsky  1.1.2.40                 typecast.put(q, ourcasts);
1359 bdemsky  1.1.2.40                 visited.add(q);
1360 bdemsky  1.1.2.40                 for (int i=0;i<q.nextLength();i++)
1361 bdemsky  1.1.2.40                     todo.add(q.next(i));
1362 bdemsky  1.1.2.40             } else {
1363 bdemsky  1.1.2.40                 //never seen yet...
1364 bdemsky  1.1.2.40                 Set parentcast=(Set)typecast.get(q.prev(0));
1365 bdemsky  1.1.2.40                 WorkSet ourcasts=new WorkSet(parentcast);
1366 bdemsky  1.1.2.40                 typecast.put(q, ourcasts);
1367 bdemsky  1.1.2.40                 visited.add(q);
1368 bdemsky  1.1.2.40                 for (int i=0;i<q.nextLength();i++)
1369 bdemsky  1.1.2.40                     todo.add(q.next(i));
1370 bdemsky  1.1.2.40             }
1371 bdemsky  1.1.2.40         }
1372 bdemsky  1.1.2.40     }
1373 bdemsky  1.1.2.36 
1374 bdemsky  1.1.2.36     //Method for AGET
1375 bdemsky  1.1.2.36     //out=in union gen
1376 bdemsky  1.1.2.36     //where gen=any cast required by AGET [not already in in]
1377 bdemsky  1.1.2.36     public void visit(AGET q) {
1378 bdemsky  1.1.2.36         //q.objectref() is the array to use
1379 bdemsky  1.1.2.36         //need to make sure that:
1380 bdemsky  1.1.2.36         //1) Object[] is assignable from q.objectref()
1381 bdemsky  1.1.2.36         
1382 bdemsky  1.1.2.36         boolean changed=false;
1383 bdemsky  1.1.2.36         if (visited.contains(q)) {
1384 bdemsky  1.1.2.36             Quad pred=q.prev(0);
1385 bdemsky  1.1.2.36             Set casts=(Set)typecast.get(pred);
1386 bdemsky  1.1.2.36             Set ourcasts=(Set)typecast.get(q);
1387 cananian 1.7                  for (Object castO : casts) {
1388 cananian 1.7                      Tuple cast = (Tuple) castO;
1389 bdemsky  1.1.2.36                 if (!ourcasts.contains(cast)) {
1390 bdemsky  1.1.2.36                     changed=true;
1391 bdemsky  1.1.2.36                     ourcasts.add(cast);
1392 bdemsky  1.1.2.36                 }
1393 bdemsky  1.1.2.36             }
1394 bdemsky  1.1.2.36             if (changed) {
1395 bdemsky  1.1.2.36                 //push our descendants
1396 bdemsky  1.1.2.36                 for (int i=0;i<q.nextLength();i++) {
1397 bdemsky  1.1.2.36                     todo.add(q.next(i));
1398 bdemsky  1.1.2.36                 }
1399 bdemsky  1.1.2.36             }
1400 bdemsky  1.1.2.36         }
1401 bdemsky  1.1.2.36         else {
1402 bdemsky  1.1.2.36             //never seen yet...
1403 bdemsky  1.1.2.36             Set parentcast=(Set)typecast.get(q.prev(0));
1404 bdemsky  1.1.2.36             WorkSet ourcasts=new WorkSet(parentcast);
1405 bdemsky  1.1.2.45             if (!(ti.typeMap(null,q.objectref())).isArray()) {
1406 bdemsky  1.1.2.36                 //Need typecast??
1407 bdemsky  1.1.2.36                 Iterator iterate=ourcasts.iterator();
1408 bdemsky  1.1.2.36                 boolean foundcast=false;
1409 bdemsky  1.1.2.36                 while (iterate.hasNext()) {
1410 bdemsky  1.1.2.36                     Tuple cast=(Tuple)iterate.next();
1411 bdemsky  1.1.2.36                     List list=cast.asList();
1412 bdemsky  1.1.2.36                     if (list.get(0)==q.objectref()) {
1413 bdemsky  1.1.2.36                         HClass hc=(HClass)list.get(1);
1414 bdemsky  1.1.2.36                         if (otype.isAssignableFrom(hc)) {
1415 bdemsky  1.1.2.36                             foundcast=true;
1416 bdemsky  1.1.2.36                             break;
1417 bdemsky  1.1.2.36                         }
1418 bdemsky  1.1.2.36                     }
1419 bdemsky  1.1.2.36                 }
1420 bdemsky  1.1.2.36                 if (!foundcast) {
1421 bdemsky  1.1.2.36                     //Add typecast
1422 bdemsky  1.1.2.36                     ourcasts.add(new Tuple(new Object[]{q.objectref(), otype}));
1423 bdemsky  1.1.2.36                 }
1424 bdemsky  1.1.2.36             }
1425 bdemsky  1.1.2.12             typecast.put(q, ourcasts);
1426 bdemsky  1.1.2.12             visited.add(q);
1427 bdemsky  1.1.2.12             for (int i=0;i<q.nextLength();i++)
1428 bdemsky  1.1.2.12                 todo.add(q.next(i));
1429 bdemsky  1.1.2.12         }
1430 bdemsky  1.1.2.12     }
1431 bdemsky  1.1.2.15 
1432 bdemsky  1.1.2.15     //method for GET...
1433 bdemsky  1.1.2.15     //equations same as SET...
1434 bdemsky  1.1.2.12     public void visit(GET q) {
1435 bdemsky  1.1.2.12         //q.objectref() is the object to use
1436 bdemsky  1.1.2.12         //q.dst() is the temp to get from the q.field() of this object
1437 bdemsky  1.1.2.12         //need to make sure that:
1438 bdemsky  1.1.2.12         //1) q.field().getDeclaringClass() is assignable from q.objectref()
1439 bdemsky  1.1.2.12         boolean changed=false;
1440 bdemsky  1.1.2.12         if (visited.contains(q)) {
1441 bdemsky  1.1.2.12             Quad pred=q.prev(0);
1442 bdemsky  1.1.2.12             Set casts=(Set)typecast.get(pred);
1443 bdemsky  1.1.2.12             Set ourcasts=(Set)typecast.get(q);
1444 cananian 1.7                  for (Object castO : casts) {
1445 cananian 1.7                      Tuple cast = (Tuple) castO;
1446 bdemsky  1.1.2.12                 if (!ourcasts.contains(cast)) {
1447 bdemsky  1.1.2.12                     changed=true;
1448 bdemsky  1.1.2.12                     ourcasts.add(cast);
1449 bdemsky  1.1.2.12                 }
1450 bdemsky  1.1.2.12             }
1451 bdemsky  1.1.2.12             if (changed) {
1452 bdemsky  1.1.2.12                 //push our descendants
1453 bdemsky  1.1.2.12                 for (int i=0;i<q.nextLength();i++) {
1454 bdemsky  1.1.2.12                     todo.add(q.next(i));
1455 bdemsky  1.1.2.12                 }
1456 bdemsky  1.1.2.12             }
1457 bdemsky  1.1.2.12         }
1458 bdemsky  1.1.2.12         else {
1459 bdemsky  1.1.2.12             //never seen yet...
1460 bdemsky  1.1.2.12             Set parentcast=(Set)typecast.get(q.prev(0));
1461 bdemsky  1.1.2.12             WorkSet ourcasts=new WorkSet(parentcast);
1462 bdemsky  1.1.2.14             if (!q.isStatic())
1463 bdemsky  1.1.2.13                 if (!q.field().getDeclaringClass().isAssignableFrom(ti.typeMap(q,q.objectref()))) {
1464 bdemsky  1.1.2.13                     //Need typecast??
1465 bdemsky  1.1.2.13                     Iterator iterate=ourcasts.iterator();
1466 bdemsky  1.1.2.13                     boolean foundcast=false;
1467 bdemsky  1.1.2.13                     while (iterate.hasNext()) {
1468 bdemsky  1.1.2.13                         Tuple cast=(Tuple)iterate.next();
1469 bdemsky  1.1.2.13                         List list=cast.asList();
1470 bdemsky  1.1.2.13                         if (list.get(0)==q.objectref()) {
1471 bdemsky  1.1.2.13                             HClass hc=(HClass)list.get(1);
1472 bdemsky  1.1.2.13                             if (q.field().getDeclaringClass().isAssignableFrom(hc)) {
1473 bdemsky  1.1.2.13                                 foundcast=true;
1474 bdemsky  1.1.2.13                                 break;
1475 bdemsky  1.1.2.13                             }
1476 bdemsky  1.1.2.12                         }
1477 bdemsky  1.1.2.12                     }
1478 bdemsky  1.1.2.13                     if (!foundcast) {
1479 bdemsky  1.1.2.13                         //Add typecast
1480 bdemsky  1.1.2.13                         ourcasts.add(new Tuple(new Object[]{q.objectref(),q.field().getDeclaringClass() }));
1481 bdemsky  1.1.2.13                     }
1482 bdemsky  1.1.2.12                 }
1483 bdemsky  1.1.2.12             typecast.put(q, ourcasts);
1484 bdemsky  1.1.2.12             visited.add(q);
1485 bdemsky  1.1.2.12             for (int i=0;i<q.nextLength();i++)
1486 bdemsky  1.1.2.12                 todo.add(q.next(i));
1487 bdemsky  1.1.2.12         }
1488 bdemsky  1.1.2.12     }
1489 bdemsky  1.1.2.12     
1490 bdemsky  1.1.2.15 
1491 bdemsky  1.1.2.15     //method for call
1492 bdemsky  1.1.2.15     //same basic idea
1493 bdemsky  1.1.2.12     public void visit(CALL q) {
1494 bdemsky  1.1.2.12         boolean changed=false;
1495 bdemsky  1.1.2.12         if (visited.contains(q)) {
1496 bdemsky  1.1.2.12             Quad pred=q.prev(0);
1497 bdemsky  1.1.2.12             Set casts=(Set)typecast.get(pred);
1498 bdemsky  1.1.2.12             Set ourcasts=(Set)typecast.get(q);
1499 cananian 1.7                  for (Object castO : casts) {
1500 cananian 1.7                      Tuple cast = (Tuple) castO;
1501 bdemsky  1.1.2.12                 if (!ourcasts.contains(cast)) {
1502 bdemsky  1.1.2.12                     changed=true;
1503 bdemsky  1.1.2.12                     ourcasts.add(cast);
1504 bdemsky  1.1.2.12                 }
1505 bdemsky  1.1.2.12             }
1506 bdemsky  1.1.2.12             if (changed) {
1507 bdemsky  1.1.2.12                 //push our descendants
1508 bdemsky  1.1.2.12                 for (int i=0;i<q.nextLength();i++) {
1509 bdemsky  1.1.2.12                     todo.add(q.next(i));
1510 bdemsky  1.1.2.12                 }
1511 bdemsky  1.1.2.12             }
1512 bdemsky  1.1.2.12         }
1513 bdemsky  1.1.2.12         else {
1514 bdemsky  1.1.2.12             //never seen yet...
1515 bdemsky  1.1.2.12             Set parentcast=(Set)typecast.get(q.prev(0));
1516 bdemsky  1.1.2.12             WorkSet ourcasts=new WorkSet(parentcast);
1517 bdemsky  1.1.2.45             //XXXXXXXX DEBUG
1518 bdemsky  1.1.2.45             //System.out.println(q);
1519 bdemsky  1.1.2.12             for (int i=0; i<q.paramsLength();i++) {
1520 bdemsky  1.1.2.12                 Temp param=q.params(i);
1521 bdemsky  1.1.2.12                 HClass type=typeOf(q, param);
1522 bdemsky  1.1.2.12                 HClass neededclass=q.paramType(i);
1523 bdemsky  1.1.2.13                 if (type!=HClass.Void)
1524 bdemsky  1.1.2.13                     if (!neededclass.isAssignableFrom(type)) {
1525 bdemsky  1.1.2.13                         //Need typecast??
1526 bdemsky  1.1.2.13                         Iterator iterate=ourcasts.iterator();
1527 bdemsky  1.1.2.13                         boolean foundcast=false;
1528 bdemsky  1.1.2.13                         while (iterate.hasNext()) {
1529 bdemsky  1.1.2.13                             Tuple cast=(Tuple)iterate.next();
1530 bdemsky  1.1.2.13                             List list=cast.asList();
1531 bdemsky  1.1.2.13                             if (list.get(0)==q.params(i)) {
1532 bdemsky  1.1.2.13                                 HClass hc=(HClass)list.get(1);
1533 bdemsky  1.1.2.13                                 if (neededclass.isAssignableFrom(hc)) {
1534 bdemsky  1.1.2.13                                     foundcast=true;
1535 bdemsky  1.1.2.13                                     break;
1536 bdemsky  1.1.2.13                                 }
1537 bdemsky  1.1.2.12                             }
1538 bdemsky  1.1.2.12                         }
1539 bdemsky  1.1.2.13                         if (!foundcast) {
1540 bdemsky  1.1.2.13                             //Add typecast
1541 bdemsky  1.1.2.13                             ourcasts.add(new Tuple(new Object[]{q.params(i),neededclass }));
1542 bdemsky  1.1.2.13                         }
1543 bdemsky  1.1.2.12                     }
1544 bdemsky  1.1.2.12             }
1545 bdemsky  1.1.2.12             typecast.put(q, ourcasts);
1546 bdemsky  1.1.2.12             visited.add(q);
1547 bdemsky  1.1.2.12             for (int i=0;i<q.nextLength();i++)
1548 bdemsky  1.1.2.12                 todo.add(q.next(i));
1549 bdemsky  1.1.2.12         }
1550 bdemsky  1.1.2.12     }
1551 bdemsky  1.1.2.12     
1552 bdemsky  1.1.2.15     //PHI method...
1553 bdemsky  1.1.2.15     //merges TYPECAST...
1554 bdemsky  1.1.2.15     //Does it by taking intersection of all incoming in's....
1555 bdemsky  1.1.2.12     public void visit(PHI q) {
1556 bdemsky  1.1.2.12         WorkSet casts=new WorkSet();
1557 bdemsky  1.1.2.12         int firstv;
1558 bdemsky  1.1.2.12         Quad first=q.prev(0);
1559 bdemsky  1.1.2.12         if (visited.contains(first)) {
1560 bdemsky  1.1.2.12             Set firstcast=(Set)typecast.get(first);
1561 bdemsky  1.1.2.12             Iterator iterate=firstcast.iterator();
1562 bdemsky  1.1.2.12             while (iterate.hasNext()) {
1563 bdemsky  1.1.2.12                 List cast=((Tuple)iterate.next()).asList();
1564 bdemsky  1.1.2.12                 Temp t=(Temp)cast.get(0);
1565 bdemsky  1.1.2.12                 HClass hclass=(HClass)cast.get(1);
1566 bdemsky  1.1.2.12                 checkphi(q, null, t, casts, hclass);
1567 bdemsky  1.1.2.12             }
1568 bdemsky  1.1.2.12             for (int i=0;i<q.numPhis(); i++) {
1569 bdemsky  1.1.2.12                 iterate=firstcast.iterator();
1570 bdemsky  1.1.2.12                 while (iterate.hasNext()) {
1571 bdemsky  1.1.2.12                     List cast=((Tuple)iterate.next()).asList();
1572 bdemsky  1.1.2.12                     if (q.dst(i)==(Temp)cast.get(0))
1573 bdemsky  1.1.2.12                         checkphi(q, q.src(i), q.dst(i), casts, (HClass) cast.get(1));
1574 bdemsky  1.1.2.12                 }
1575 bdemsky  1.1.2.12             }
1576 bdemsky  1.1.2.12         }
1577 bdemsky  1.1.2.12         if (visited.contains(q)) {
1578 bdemsky  1.1.2.12             boolean changed=false;
1579 bdemsky  1.1.2.12             Set ourcasts=(Set)typecast.get(q);
1580 cananian 1.7                  for (Object castO : casts) {
1581 cananian 1.7                      Tuple cast = (Tuple) castO;
1582 bdemsky  1.1.2.12                 if (!ourcasts.contains(cast)) {
1583 bdemsky  1.1.2.12                     changed=true;
1584 bdemsky  1.1.2.12                     ourcasts.add(cast);
1585 bdemsky  1.1.2.12                 }
1586 bdemsky  1.1.2.12             }
1587 bdemsky  1.1.2.12             if (changed) {
1588 bdemsky  1.1.2.12                 //push our descendants
1589 bdemsky  1.1.2.12                 for (int i=0;i<q.nextLength();i++) {
1590 bdemsky  1.1.2.12                     todo.add(q.next(i));
1591 bdemsky  1.1.2.12                 }
1592 bdemsky  1.1.2.12             }
1593 bdemsky  1.1.2.12         }
1594 bdemsky  1.1.2.12         else {
1595 bdemsky  1.1.2.12             //never seen yet...
1596 bdemsky  1.1.2.12             typecast.put(q, casts);
1597 bdemsky  1.1.2.12             visited.add(q);
1598 bdemsky  1.1.2.12             for (int i=0;i<q.nextLength();i++)
1599 bdemsky  1.1.2.12                 todo.add(q.next(i));
1600 bdemsky  1.1.2.12         }
1601 bdemsky  1.1.2.12     }
1602 bdemsky  1.1.2.12 
1603 bdemsky  1.1.2.12     private void checkphi(PHI q, Temp[] map, Temp tf,Set casts, HClass hclass) {
1604 cananian 1.1.2.44         Linker linker = q.getFactory().getLinker();
1605 bdemsky  1.1.2.12         boolean good=true;
1606 bdemsky  1.1.2.12         for (int i=1;i<q.arity();i++) {
1607 bdemsky  1.1.2.12             if (typecast.containsKey(q.prev(i))) {
1608 bdemsky  1.1.2.12                 Set prevcasts=(Set)typecast.get(q.prev(i));
1609 bdemsky  1.1.2.12                 Iterator previter=prevcasts.iterator();
1610 bdemsky  1.1.2.12                 HClass best=null;
1611 bdemsky  1.1.2.12                 while (previter.hasNext()) {
1612 bdemsky  1.1.2.12                     List ctuple=((Tuple)previter.next()).asList();
1613 bdemsky  1.1.2.12                     Temp t=null;
1614 bdemsky  1.1.2.12                     if (map!=null)
1615 bdemsky  1.1.2.12                         t=map[i];
1616 bdemsky  1.1.2.12                     else
1617 bdemsky  1.1.2.12                         t=tf;
1618 bdemsky  1.1.2.12                     if (((Temp)ctuple.get(0))==t) {
1619 bdemsky  1.1.2.12                         HClass tclass=(HClass)ctuple.get(1);
1620 bdemsky  1.1.2.12                         HClass tc=hclass;
1621 bdemsky  1.1.2.35                         while((tc!=null)&&(!tc.isAssignableFrom(tclass))) {
1622 bdemsky  1.1.2.43                             //System.out.println("=======");
1623 bdemsky  1.1.2.43                             //System.out.println(tclass);
1624 bdemsky  1.1.2.43                             //System.out.println(q);
1625 bdemsky  1.1.2.43                             //System.out.println(hclass);
1626 bdemsky  1.1.2.43                             //System.out.println(tc);
1627 bdemsky  1.1.2.43                             //System.out.println(tc.getSuperclass());
1628 bdemsky  1.1.2.12                             tc=tc.getSuperclass();
1629 bdemsky  1.1.2.35                         }
1630 bdemsky  1.1.2.35                         //Its safe to assume object for interfaces...
1631 bdemsky  1.1.2.35                         //because the interface has to be for some sort of
1632 bdemsky  1.1.2.35                         //real object
1633 cananian 1.1.2.44                         if (tc==null)
1634 cananian 1.1.2.44                             tc=linker.forName("java.lang.Object");
1635 bdemsky  1.1.2.13                         if (best==null)
1636 bdemsky  1.1.2.13                             best=tc;
1637 bdemsky  1.1.2.13                         else if (best.isAssignableFrom(tc))
1638 bdemsky  1.1.2.12                             best=tc;
1639 bdemsky  1.1.2.12                     }
1640 bdemsky  1.1.2.12                 }
1641 bdemsky  1.1.2.13                 if (best==null) {
1642 bdemsky  1.1.2.13                     good=false;
1643 bdemsky  1.1.2.13                     break;
1644 bdemsky  1.1.2.13                 } else
1645 bdemsky  1.1.2.13                     hclass=best;
1646 bdemsky  1.1.2.12             } else
1647 bdemsky  1.1.2.12                 good=false;
1648 bdemsky  1.1.2.12         }
1649 bdemsky  1.1.2.12         if (good) {
1650 bdemsky  1.1.2.12             //Add in typecast (t, hclass)
1651 bdemsky  1.1.2.12             Tuple tple=new Tuple(new Object[] {tf, hclass});
1652 bdemsky  1.1.2.12             if (!casts.contains(tple))
1653 bdemsky  1.1.2.12                 casts.add(tple);
1654 bdemsky  1.1.2.12         }
1655 bdemsky  1.1.2.12     }
1656 bdemsky  1.1.2.12 
1657 bdemsky  1.1.2.12     private HClass typeOf(Quad q, Temp t) {
1658 bdemsky  1.1.2.12         return ti.typeMap(q, t);
1659 bdemsky  1.1.2.12     }
1660 bdemsky  1.1.2.12 
1661 bdemsky  1.1.2.19 }
1662 bdemsky  1.1.2.19 
1663 bdemsky  1.1.2.39 public static void clean(QuadWithTry code) {
1664 bdemsky  1.1.2.39     HEADER h=(HEADER) code.getRootElement();
1665 bdemsky  1.1.2.39     METHOD m=(METHOD) h.next(1);
1666 bdemsky  1.1.2.39     WorkSet handlerset=new WorkSet();
1667 bdemsky  1.1.2.39     for (int i=1;i<m.nextLength();i++)
1668 bdemsky  1.1.2.39         handlerset.add(m.next(i));
1669 bdemsky  1.1.2.39 
1670 bdemsky  1.1.2.39     WorkSet todo=new WorkSet(code.getElementsL());
1671 bdemsky  1.1.2.39     CleanVisitor cv=new CleanVisitor(handlerset, todo);
1672 bdemsky  1.1.2.39 
1673 bdemsky  1.1.2.39     while(!todo.isEmpty()) {
1674 bdemsky  1.1.2.39         Quad q=(Quad)todo.pop();
1675 bdemsky  1.1.2.39         q.accept(cv);
1676 bdemsky  1.1.2.39     }
1677 bdemsky  1.1.2.39     Set useful=cv.useful();
1678 bdemsky  1.1.2.39     Iterator iterate=code.getElementsI();
1679 bdemsky  1.1.2.39     while (iterate.hasNext()) {
1680 bdemsky  1.1.2.39         Quad q=(Quad)iterate.next();
1681 bdemsky  1.1.2.39         if (!useful.contains(q)) {
1682 bdemsky  1.1.2.43             //System.out.println("Cleaning " + q);
1683 bdemsky  1.1.2.39             Quad.addEdge(q.prev(0), q.prevEdge(0).which_succ(), q.next(0), q.nextEdge(0).which_pred());
1684 bdemsky  1.1.2.39         }
1685 bdemsky  1.1.2.39     }
1686 bdemsky  1.1.2.39 }
1687 bdemsky  1.1.2.39 
1688 bdemsky  1.1.2.20 
1689 bdemsky  1.1.2.39 static class CleanVisitor extends QuadVisitor {
1690 bdemsky  1.1.2.39     HashMap in;
1691 bdemsky  1.1.2.39     WorkSet useful;
1692 bdemsky  1.1.2.39     Set todo;
1693 bdemsky  1.1.2.39     WorkSet usefulS;
1694 bdemsky  1.1.2.39     Set handlerset;
1695 bdemsky  1.1.2.39     WorkSet protectedquads;
1696 bdemsky  1.1.2.39 
1697 bdemsky  1.1.2.39     CleanVisitor(Set handlerset, Set todo) {
1698 bdemsky  1.1.2.39         this.useful=new WorkSet();
1699 bdemsky  1.1.2.39         this.in=new HashMap();
1700 bdemsky  1.1.2.39         this.handlerset=handlerset;
1701 bdemsky  1.1.2.39         this.protectedquads=new WorkSet();
1702 bdemsky  1.1.2.20         this.todo=todo;
1703 cananian 1.7              for (Object hO : handlerset) {
1704 cananian 1.7                  HANDLER h = (HANDLER) hO;
1705 cananian 1.5                  for (Enumeration _enum_=h.protectedQuads();
1706 cananian 1.5                       _enum_.hasMoreElements();)
1707 cananian 1.5                      protectedquads.add(_enum_.nextElement());           
1708 bdemsky  1.1.2.39         }
1709 bdemsky  1.1.2.20     }
1710 bdemsky  1.1.2.20 
1711 bdemsky  1.1.2.39     public Set useful() {
1712 bdemsky  1.1.2.39         return useful;
1713 bdemsky  1.1.2.20     }
1714 bdemsky  1.1.2.20 
1715 bdemsky  1.1.2.39     public void visit(Quad q) {
1716 bdemsky  1.1.2.39         useful(q,false);
1717 bdemsky  1.1.2.39     }
1718 bdemsky  1.1.2.39     public void visit(MOVE q) {
1719 bdemsky  1.1.2.39         maybeuseful(q);
1720 bdemsky  1.1.2.39     }
1721 bdemsky  1.1.2.39     public void visit(CONST q) {
1722 bdemsky  1.1.2.39         maybeuseful(q);
1723 bdemsky  1.1.2.39     }
1724 bdemsky  1.1.2.20     public void visit(HANDLER q) {
1725 bdemsky  1.1.2.20         useful(q, true);
1726 bdemsky  1.1.2.20     }
1727 bdemsky  1.1.2.20 
1728 bdemsky  1.1.2.39     void useful(Quad q, boolean ishandler) {
1729 bdemsky  1.1.2.39         WorkSet livein=new WorkSet();
1730 bdemsky  1.1.2.39         useful.add(q);
1731 bdemsky  1.1.2.39         for (int i=0;i<q.nextLength();i++) {
1732 bdemsky  1.1.2.39             if (in.containsKey(q.next(i))) {
1733 bdemsky  1.1.2.39                 WorkSet ini=(WorkSet) in.get(q.next(i));
1734 bdemsky  1.1.2.39                 for(Iterator iterate=ini.iterator();iterate.hasNext();)
1735 bdemsky  1.1.2.39                     livein.add(iterate.next());
1736 bdemsky  1.1.2.39             }
1737 bdemsky  1.1.2.39         }
1738 bdemsky  1.1.2.39         if (protectedquads.contains(q)) {
1739 cananian 1.7                  for (Object hO : handlerset) {
1740 cananian 1.7                      HANDLER h = (HANDLER) hO;
1741 bdemsky  1.1.2.39                 if (h.isProtected(q))
1742 bdemsky  1.1.2.39                     if (in.containsKey(h)) {
1743 bdemsky  1.1.2.39                         WorkSet ini=(WorkSet) in.get(h);
1744 bdemsky  1.1.2.39                         for(Iterator iterate=ini.iterator();iterate.hasNext();)
1745 bdemsky  1.1.2.39                             livein.add(iterate.next());
1746 bdemsky  1.1.2.20                     }
1747 bdemsky  1.1.2.20             }
1748 bdemsky  1.1.2.39         }
1749 bdemsky  1.1.2.39         //out-defs
1750 bdemsky  1.1.2.39         Temp defs[]=q.def();
1751 bdemsky  1.1.2.39         for (int i=0;i<defs.length;i++)
1752 bdemsky  1.1.2.39             livein.remove(defs[i]);
1753 bdemsky  1.1.2.39         //+uses
1754 bdemsky  1.1.2.39         Temp uses[]=q.use();
1755 bdemsky  1.1.2.39         for (int i=0;i<uses.length;i++)
1756 bdemsky  1.1.2.39             livein.add(uses[i]);
1757 bdemsky  1.1.2.39         int oldsize=0;
1758 bdemsky  1.1.2.39         if (in.containsKey(q))
1759 bdemsky  1.1.2.39             oldsize=((WorkSet)in.get(q)).size();
1760 bdemsky  1.1.2.39         if (oldsize!=livein.size()) {
1761 bdemsky  1.1.2.39             //Things have changed
1762 bdemsky  1.1.2.39             //Add our set in
1763 bdemsky  1.1.2.39             in.put(q, livein);
1764 bdemsky  1.1.2.39             //Put our predecessors in the todo list
1765 bdemsky  1.1.2.39             for(int i=0;i<q.prevLength();i++)
1766 bdemsky  1.1.2.39                 todo.add(q.prev(i));
1767 bdemsky  1.1.2.39             if (ishandler) {
1768 bdemsky  1.1.2.39                 //notify the handled quads
1769 cananian 1.5                      for (Enumeration _enum_=((HANDLER) q).protectedQuads();
1770 cananian 1.5                           _enum_.hasMoreElements();)
1771 cananian 1.5                          todo.add(_enum_.nextElement());
1772 bdemsky  1.1.2.20             }
1773 bdemsky  1.1.2.20         }
1774 bdemsky  1.1.2.19     }
1775 bdemsky  1.1.2.20 
1776 bdemsky  1.1.2.39     void maybeuseful(Quad q) {
1777 bdemsky  1.1.2.39         if (useful.contains(q)) 
1778 bdemsky  1.1.2.23             useful(q,false);
1779 bdemsky  1.1.2.39         else {
1780 bdemsky  1.1.2.39             WorkSet livein=new WorkSet();
1781 bdemsky  1.1.2.39             for (int i=0;i<q.nextLength();i++) {
1782 bdemsky  1.1.2.39                 if (in.containsKey(q.next(i))) {
1783 bdemsky  1.1.2.39                     WorkSet ini=(WorkSet) in.get(q.next(i));
1784 bdemsky  1.1.2.39                     for(Iterator iterate=ini.iterator();iterate.hasNext();)
1785 bdemsky  1.1.2.39                         livein.add(iterate.next());
1786 bdemsky  1.1.2.39                 }
1787 bdemsky  1.1.2.39             }
1788 bdemsky  1.1.2.39             if (protectedquads.contains(q)) {
1789 cananian 1.7                      for (Object hO : handlerset) {
1790 cananian 1.7                          HANDLER h = (HANDLER) hO;
1791 bdemsky  1.1.2.39                     if (h.isProtected(q))
1792 bdemsky  1.1.2.39                         if (in.containsKey(h)) {
1793 bdemsky  1.1.2.39                             WorkSet ini=(WorkSet) in.get(h);
1794 bdemsky  1.1.2.39                             for(Iterator iterate=ini.iterator();iterate.hasNext();)
1795 bdemsky  1.1.2.39                                 livein.add(iterate.next());
1796 bdemsky  1.1.2.20                         }
1797 bdemsky  1.1.2.20                 }
1798 bdemsky  1.1.2.23             }
1799 bdemsky  1.1.2.39             //out-defs
1800 bdemsky  1.1.2.39             Temp defs[]=q.def();
1801 bdemsky  1.1.2.39             boolean hasuse=false;
1802 bdemsky  1.1.2.39             
1803 bdemsky  1.1.2.39             for (int i=0;i<defs.length;i++)
1804 bdemsky  1.1.2.39                 if (livein.contains(defs[i])) {
1805 bdemsky  1.1.2.39                     hasuse=true;
1806 bdemsky  1.1.2.39                     break;
1807 bdemsky  1.1.2.20                 }
1808 bdemsky  1.1.2.39             if (hasuse) {
1809 bdemsky  1.1.2.39                 useful.add(q);
1810 bdemsky  1.1.2.39                 useful(q,false);
1811 bdemsky  1.1.2.39             } else {
1812 bdemsky  1.1.2.39                 int oldsize=0;
1813 bdemsky  1.1.2.39                 if (in.containsKey(q))
1814 bdemsky  1.1.2.39                     oldsize=((WorkSet)in.get(q)).size();
1815 bdemsky  1.1.2.39                 if (oldsize!=livein.size()) {
1816 bdemsky  1.1.2.39                     //Things have changed
1817 bdemsky  1.1.2.39                     //Add our set in
1818 bdemsky  1.1.2.39                     in.put(q, livein);
1819 bdemsky  1.1.2.39                     //Put our predecessors in the todo list
1820 bdemsky  1.1.2.39                     for(int i=0;i<q.prevLength();i++)
1821 bdemsky  1.1.2.39                         todo.add(q.prev(i));
1822 bdemsky  1.1.2.20                 }
1823 bdemsky  1.1.2.20             }
1824 bdemsky  1.1.2.20         }
1825 bdemsky  1.1.2.19     }
1826 bdemsky  1.1.2.4  }
1827 cananian 1.1.2.32 
1828 cananian 1.1.2.32 } // close the ReHandler class (yes, the indentation's screwed up,
1829 cananian 1.2        // but I don't feel like re-indenting all this code) [CSA]