1 cananian 1.1.2.1 // ComponentOfReducer.java, created Tue Dec  4 12:33:07 2001 by cananian
  2 cananian 1.1.2.1 // Copyright (C) 2000 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 cananian 1.1.2.1 package harpoon.Analysis.Quads;
  5 cananian 1.1.2.1 
  6 cananian 1.1.2.1 import harpoon.Analysis.ClassHierarchy;
  7 cananian 1.1.2.1 import harpoon.Analysis.Maps.ExactTypeMap;
  8 cananian 1.1.2.1 import harpoon.Analysis.Maps.TypeMap;
  9 cananian 1.1.2.1 import harpoon.Analysis.Quads.SCC.SCCAnalysis;
 10 cananian 1.1.2.1 import harpoon.Analysis.Quads.SCC.SCCOptimize;
 11 cananian 1.1.2.1 import harpoon.Analysis.Transformation.MethodMutator;
 12 cananian 1.1.2.1 import harpoon.Backend.Maps.CHFinalMap;
 13 cananian 1.1.2.1 import harpoon.Backend.Maps.FinalMap;
 14 cananian 1.1.2.1 import harpoon.ClassFile.CachingCodeFactory;
 15 cananian 1.1.2.1 import harpoon.ClassFile.HClass;
 16 cananian 1.1.2.1 import harpoon.ClassFile.HCode;
 17 cananian 1.1.2.1 import harpoon.ClassFile.HCodeAndMaps;
 18 cananian 1.1.2.1 import harpoon.ClassFile.HCodeElement;
 19 cananian 1.1.2.1 import harpoon.ClassFile.HCodeFactory;
 20 cananian 1.1.2.1 import harpoon.ClassFile.HMethod;
 21 cananian 1.1.2.1 import harpoon.IR.Quads.COMPONENTOF;
 22 cananian 1.1.2.1 import harpoon.IR.Quads.INSTANCEOF;
 23 cananian 1.1.2.1 import harpoon.IR.Quads.Quad;
 24 cananian 1.1.2.1 import harpoon.IR.Quads.QuadFactory;
 25 cananian 1.1.2.1 import harpoon.IR.Quads.QuadSSI;
 26 cananian 1.1.2.1 import harpoon.Temp.Temp;
 27 cananian 1.4     import net.cscott.jutil.SnapshotIterator;
 28 cananian 1.1.2.1 import harpoon.Util.HClassUtil;
 29 cananian 1.1.2.1 import harpoon.Util.Util;
 30 cananian 1.1.2.1 
 31 cananian 1.1.2.1 import java.util.HashMap;
 32 cananian 1.3     import java.util.Iterator;
 33 cananian 1.1.2.1 import java.util.Map;
 34 cananian 1.1.2.1 /**
 35 cananian 1.1.2.1  * The <code>ComponentOfReducer</code> pass attempts to transform
 36 cananian 1.1.2.1  * <code>COMPONENTOF</code> operations into (more efficient)
 37 cananian 1.1.2.1  * <code>INSTANCEOF</code> operations, when this is safe to do.
 38 cananian 1.1.2.1  * In particular, it is safe to transform <code>o componentof a</code>
 39 cananian 1.1.2.1  * where a has type <code>T[]</code> into <code>o instanceof T</code>
 40 cananian 1.1.2.1  * if a's type is exact or T is a final type.
 41 cananian 1.1.2.1  * <p>This analysis needs type information for its input factory
 42 cananian 1.1.2.1  * (a <code>TypeMap</code> or <code>ExactTypeMap</code>) and
 43 cananian 1.1.2.1  * final type information (a <code>Backend.Maps.FinalMap</code>).
 44 cananian 1.1.2.1  * 
 45 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 46 cananian 1.4      * @version $Id: ComponentOfReducer.java,v 1.4 2004/02/08 01:53:14 cananian Exp $
 47 cananian 1.1.2.1  */
 48 cananian 1.3     public class ComponentOfReducer extends MethodMutator<Quad> {
 49 cananian 1.3         final ExactTypeMap<Quad> etm;
 50 cananian 1.1.2.1     
 51 cananian 1.1.2.1     /** Creates a <code>ComponentOfReducer</code>. */
 52 cananian 1.1.2.1     public ComponentOfReducer(HCodeFactory hcf,
 53 cananian 1.3                                   final ExactTypeMap<Quad> tm, final FinalMap fm) {
 54 cananian 1.1.2.1         super(hcf);
 55 cananian 1.3             this.etm = new ExactTypeMap<Quad>() {
 56 cananian 1.3                     public boolean isExactType(Quad hce, Temp t)
 57 cananian 1.1.2.1                     throws TypeMap.TypeNotKnownException {
 58 cananian 1.1.2.1                     if (tm.isExactType(hce, t)) return true;
 59 cananian 1.1.2.1                     HClass type = HClassUtil.baseClass(tm.typeMap(hce, t));
 60 cananian 1.1.2.1                     if (fm.isFinal(type)) return true;
 61 cananian 1.1.2.1                     return false;
 62 cananian 1.1.2.1                 }
 63 cananian 1.3                     public HClass typeMap(Quad hce, Temp t)
 64 cananian 1.1.2.1                     throws TypeNotKnownException {
 65 cananian 1.1.2.1                     return tm.typeMap(hce, t);
 66 cananian 1.1.2.1                 }
 67 cananian 1.1.2.1             };
 68 cananian 1.1.2.1     }
 69 cananian 1.1.2.1     public ComponentOfReducer(HCodeFactory hcf,
 70 cananian 1.3                                   final TypeMap<Quad> tm, final FinalMap fm) {
 71 cananian 1.1.2.1         this(hcf,
 72 cananian 1.3                  tm instanceof ExactTypeMap<Quad>? (ExactTypeMap<Quad>)tm: new ExactTypeMap<Quad>() {
 73 cananian 1.3                     public boolean isExactType(Quad hce, Temp t) {
 74 cananian 1.1.2.1                     return false;
 75 cananian 1.1.2.1                 }
 76 cananian 1.3                     public HClass typeMap(Quad hce, Temp t)
 77 cananian 1.1.2.1                     throws TypeNotKnownException {
 78 cananian 1.1.2.1                     return tm.typeMap(hce, t);
 79 cananian 1.1.2.1                 }
 80 cananian 1.1.2.1             }, fm);
 81 cananian 1.1.2.1     }
 82 cananian 1.1.2.1     // convenience constructor.
 83 cananian 1.1.2.1     public ComponentOfReducer(HCodeFactory hcf, ClassHierarchy ch) {
 84 cananian 1.1.2.1         this(new CachingCodeFactory(QuadSSI.codeFactory(hcf)), ch);
 85 cananian 1.1.2.1     }
 86 cananian 1.1.2.1     private ComponentOfReducer(CachingCodeFactory ccf, ClassHierarchy ch) {
 87 cananian 1.1.2.1         // (ccf will also be quadssi!)
 88 cananian 1.1.2.1         this(ccf, new CachingExactTypeMap(ccf), new CHFinalMap(ch));
 89 cananian 1.1.2.1     }
 90 cananian 1.3         private static class CachingExactTypeMap implements ExactTypeMap<Quad> {
 91 cananian 1.1.2.1         final CachingCodeFactory ccf;
 92 cananian 1.3             final Map<HMethod,ExactTypeMap<Quad>> etmMap =
 93 cananian 1.3                 new HashMap<HMethod,ExactTypeMap<Quad>>();
 94 cananian 1.1.2.1         CachingExactTypeMap(CachingCodeFactory ccf) {
 95 cananian 1.1.2.1             this.ccf = ccf;
 96 cananian 1.1.2.1         }
 97 cananian 1.3             ExactTypeMap<Quad> fetchCached(Quad hce) {
 98 cananian 1.1.2.1             // cached?
 99 cananian 1.3                 HMethod hm = hce.getFactory().getMethod();
100 cananian 1.3                 ExactTypeMap<Quad> etm = etmMap.get(hm);
101 cananian 1.1.2.1             if (etm==null) {
102 cananian 1.1.2.1                 // no. =(
103 cananian 1.3                     etm = (ExactTypeMap/*XXX: cast won't be necessary after SCCAnalysis is GJ-ized*/) new SCCAnalysis(ccf.convert(hm));//could use factory here
104 cananian 1.1.2.1                 etmMap.put(hm, etm);
105 cananian 1.1.2.1             }
106 cananian 1.1.2.1             return etm;
107 cananian 1.1.2.1         }
108 cananian 1.3             public boolean isExactType(Quad hce, Temp t)
109 cananian 1.1.2.1             throws TypeNotKnownException {
110 cananian 1.1.2.1             return fetchCached(hce).isExactType(hce, t);
111 cananian 1.1.2.1         }
112 cananian 1.3             public HClass typeMap(Quad hce, Temp t)
113 cananian 1.1.2.1             throws TypeNotKnownException {
114 cananian 1.1.2.1             return fetchCached(hce).typeMap(hce, t);
115 cananian 1.1.2.1         }
116 cananian 1.1.2.1     }
117 cananian 1.1.2.1 
118 cananian 1.1.2.1     // okay, enough playing around.  let's mutate!
119 cananian 1.3         protected HCode<Quad> mutateHCode(HCodeAndMaps<Quad> input) {
120 cananian 1.1.2.1         boolean changed = false;
121 cananian 1.1.2.1         // find COMPONENT OF.
122 cananian 1.3             for (Iterator<Quad> it=new SnapshotIterator<Quad>
123 cananian 1.3                      (input.hcode().getElementsI()); it.hasNext(); ) {
124 cananian 1.3                 Quad thisq = it.next();
125 cananian 1.3                 if (thisq instanceof COMPONENTOF) {
126 cananian 1.3                     COMPONENTOF q = (COMPONENTOF) thisq;
127 cananian 1.1.2.1                 COMPONENTOF qq = (COMPONENTOF)
128 cananian 1.1.2.1                     input.ancestorElementMap().get(q);
129 cananian 1.1.2.1                 // can we change this?
130 cananian 1.1.2.1                 if (etm.isExactType(qq, qq.arrayref())) {
131 cananian 1.1.2.1                     // change it!
132 cananian 1.1.2.1                     HClass T = etm.typeMap(qq, qq.arrayref())
133 cananian 1.1.2.1                         .getComponentType();
134 cananian 1.1.2.1                     QuadFactory qf = q.getFactory();
135 cananian 1.1.2.1                     Quad.replace
136 cananian 1.1.2.1                         (q, new INSTANCEOF(q.getFactory(), q,
137 cananian 1.1.2.1                                            q.dst(), q.objectref(), T));
138 cananian 1.1.2.1                     changed = true;
139 cananian 1.1.2.1                 }
140 cananian 1.1.2.1             }
141 cananian 1.3             }
142 cananian 1.1.2.1         // if anything's been changed...
143 cananian 1.1.2.1         if (changed) {
144 cananian 1.1.2.1             // SCCOptimize this!
145 cananian 1.1.2.1             SCCAnalysis scc = new SCCAnalysis(input.hcode());
146 cananian 1.1.2.1             SCCOptimize sco = new SCCOptimize(scc);
147 cananian 1.1.2.1             sco.optimize(input.hcode());
148 cananian 1.1.2.1         }
149 cananian 1.1.2.1         return input.hcode();
150 cananian 1.1.2.1     }
151 cananian 1.2     }