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 }