1 cananian 1.1 // UseDef.java, created Thu Sep 10 15:17:10 1998 by cananian 2 cananian 1.10 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.10 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1 package harpoon.Analysis; 5 cananian 1.1 6 cananian 1.10.2.3 import harpoon.ClassFile.HCode; 7 cananian 1.10.2.3 import harpoon.ClassFile.HCodeElement; 8 cananian 1.1 import harpoon.Temp.Temp; 9 cananian 1.11.2.1 import harpoon.Util.ArrayIterator; 10 cananian 1.14 import net.cscott.jutil.Default; 11 cananian 1.14 import net.cscott.jutil.IteratorEnumerator; 12 cananian 1.1 import harpoon.Util.Util; 13 cananian 1.1 14 cananian 1.1 import java.util.Enumeration; 15 cananian 1.10.2.5 import java.util.HashMap; 16 cananian 1.10.2.5 import java.util.HashSet; 17 cananian 1.10.2.5 import java.util.Iterator; 18 cananian 1.10.2.5 import java.util.Map; 19 cananian 1.10.2.5 import java.util.Set; 20 cananian 1.1 /** 21 cananian 1.5 * <code>UseDef</code> objects map <code>Temp</code>s to the 22 cananian 1.5 * <code>HCodeElement</code>s which use or define 23 cananian 1.5 * them. The <code>UseDef</code> caches its results, so you should 24 cananian 1.5 * throw away your current <code>UseDef</code> object and make 25 cananian 1.5 * another one if you make modifications to the IR. 26 cananian 1.1 * 27 cananian 1.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 28 cananian 1.15 * @version $Id: UseDef.java,v 1.15 2004/02/08 03:19:12 cananian Exp $ 29 cananian 1.1 */ 30 cananian 1.1 31 cananian 1.13 public class UseDef<HCE extends HCodeElement> 32 cananian 1.13 implements harpoon.Analysis.Maps.UseDefMap<HCE> { 33 cananian 1.1 /** Creates a new, empty <code>UseDef</code>. */ 34 cananian 1.1 public UseDef() { } 35 cananian 1.1 36 cananian 1.13 Map<HCode<HCE>,allTempList> analyzed = 37 cananian 1.13 new HashMap<HCode<HCE>,allTempList>(); 38 cananian 1.13 Map<Temp,HCE[]> useMap = new HashMap<Temp,HCE[]>(); 39 cananian 1.13 Map<Temp,HCE[]> defMap = new HashMap<Temp,HCE[]>(); 40 cananian 1.1 41 cananian 1.5 static class allTempList { 42 cananian 1.5 Temp[] used; 43 cananian 1.5 Temp[] defined; 44 cananian 1.9 Temp[] all; 45 cananian 1.9 allTempList(Temp[] used, Temp[] defined, Temp[] all) { 46 cananian 1.9 this.used = used; this.defined = defined; this.all = all; 47 cananian 1.5 } 48 cananian 1.5 } 49 cananian 1.5 50 cananian 1.13 void associate(HCE hce, Temp[] tl, 51 cananian 1.13 Map<Temp,Set<HCE>> map, 52 cananian 1.13 Set<Temp> allTemps1, Set<Temp> allTemps2) { 53 cananian 1.5 for (int i=0; i<tl.length; i++) { 54 cananian 1.13 Set<HCE> s = map.get(tl[i]); 55 cananian 1.13 if (s==null) { s = new HashSet<HCE>(); map.put(tl[i], s); } 56 cananian 1.10.2.5 s.add(hce); 57 cananian 1.10.2.5 allTemps1.add(tl[i]); 58 cananian 1.10.2.5 allTemps2.add(tl[i]); 59 cananian 1.5 } 60 cananian 1.5 } 61 cananian 1.5 62 cananian 1.13 Temp[] set2temps(Set<Temp> s) { 63 cananian 1.13 return s.toArray(new Temp[s.size()]); 64 cananian 1.5 } 65 cananian 1.13 HCE[] set2hces(HCode<HCE> hc, Set<HCE> s) { 66 cananian 1.13 return s.toArray(hc.elementArrayFactory().newArray(s.size())); 67 cananian 1.5 } 68 cananian 1.1 69 cananian 1.13 HCode<HCE> lastHCode = null; 70 cananian 1.13 void analyze(HCode<HCE> code) { 71 cananian 1.5 // make sure we don't analyze an HCode multiple times. 72 cananian 1.7 if (code==lastHCode) return; // we just did this one. 73 cananian 1.7 if (analyzed.containsKey(code)) return; // check the hash table. 74 cananian 1.7 lastHCode = code; 75 cananian 1.5 76 cananian 1.13 HCE[] el = code.getElements(); 77 cananian 1.10.2.6 if (!(el instanceof harpoon.IR.Properties.UseDefable[])) 78 cananian 1.10.2.6 throw new Error(code.getName() + " does not implement UseDefable"); 79 cananian 1.10.2.6 harpoon.IR.Properties.UseDefable[] udl = 80 cananian 1.10.2.6 (harpoon.IR.Properties.UseDefable[]) el; 81 cananian 1.5 82 cananian 1.13 Map<Temp,Set<HCE>> workUse = new HashMap<Temp,Set<HCE>>(); 83 cananian 1.13 Map<Temp,Set<HCE>> workDef = new HashMap<Temp,Set<HCE>>(); 84 cananian 1.13 Set<Temp> defined = new HashSet<Temp>(); 85 cananian 1.13 Set<Temp> used = new HashSet<Temp>(); 86 cananian 1.13 Set<Temp> all = new HashSet<Temp>(); 87 cananian 1.1 88 cananian 1.5 // Scan through and associate uses and defs with their HCodeElements 89 cananian 1.5 for (int i=0; i<el.length; i++) { 90 cananian 1.9 associate(el[i], udl[i].use(), workUse, used, all); 91 cananian 1.9 associate(el[i], udl[i].def(), workDef, defined, all); 92 cananian 1.1 } 93 cananian 1.5 // replace UniqueVectors with HCodeElement arrays to save space. 94 cananian 1.15 for (Temp u : workUse.keySet()) { 95 cananian 1.13 useMap.put(u, set2hces(code, workUse.get(u))); 96 cananian 1.5 } 97 cananian 1.15 for (Temp d : workDef.keySet()) { 98 cananian 1.13 defMap.put(d, set2hces(code, workDef.get(d))); 99 cananian 1.1 } 100 cananian 1.5 // store set of all temps & mark as analyzed. 101 cananian 1.8 analyzed.put(code, new allTempList(set2temps(used), 102 cananian 1.9 set2temps(defined), 103 cananian 1.9 set2temps(all))); 104 cananian 1.5 } 105 cananian 1.2 106 cananian 1.5 /** Return the HCodeElements which define a given Temp. */ 107 cananian 1.13 public HCE[] defMap(HCode<HCE> hc, Temp t) { 108 cananian 1.5 analyze(hc); 109 cananian 1.13 HCE[] r = defMap.get(t); 110 cananian 1.5 return (r == null) ? 111 cananian 1.13 hc.elementArrayFactory().newArray(0) : 112 cananian 1.13 Util.safeCopy(hc.elementArrayFactory(), r); 113 cananian 1.9 } 114 cananian 1.5 /** Return the HCodeElements which use a given Temp. */ 115 cananian 1.13 public HCE[] useMap(HCode<HCE> hc, Temp t) { 116 cananian 1.5 analyze(hc); 117 cananian 1.13 HCE[] r = useMap.get(t); 118 cananian 1.5 return (r == null) ? 119 cananian 1.13 hc.elementArrayFactory().newArray(0) : 120 cananian 1.13 Util.safeCopy(hc.elementArrayFactory(), r); 121 cananian 1.9 } 122 cananian 1.5 /** Return an array of all Temps defined in a given HCode. */ 123 cananian 1.13 public Temp[] allDefs(HCode<HCE> hc) { 124 cananian 1.5 analyze(hc); 125 cananian 1.13 allTempList atl = analyzed.get(hc); 126 cananian 1.13 return Util.safeCopy(Temp.arrayFactory, atl.defined); 127 cananian 1.9 } 128 cananian 1.5 /** Return an array of all Temps used in a given HCode. */ 129 cananian 1.13 public Temp[] allUses(HCode<HCE> hc) { 130 cananian 1.5 analyze(hc); 131 cananian 1.13 allTempList atl = analyzed.get(hc); 132 cananian 1.13 return Util.safeCopy(Temp.arrayFactory, atl.used); 133 cananian 1.9 } 134 cananian 1.9 /** Return an array of all Temps used or defined in a given HCode. */ 135 cananian 1.13 public Temp[] allTemps(HCode<HCE> hc) { 136 cananian 1.9 analyze(hc); 137 cananian 1.13 allTempList atl = analyzed.get(hc); 138 cananian 1.13 return Util.safeCopy(Temp.arrayFactory, atl.all); 139 cananian 1.1 } 140 cananian 1.1 }