1 pnkfelix 1.1.2.1 // RegAllocOpts.java, created Thu Oct 19 19:14:47 2000 by pnkfelix 2 cananian 1.1.2.6 // Copyright (C) 2000 Felix S. Klock II <pnkfelix@mit.edu> 3 pnkfelix 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 pnkfelix 1.1.2.1 package harpoon.Analysis.Instr; 5 pnkfelix 1.1.2.1 6 pnkfelix 1.1.2.1 import harpoon.ClassFile.HClass; 7 pnkfelix 1.1.2.1 import harpoon.ClassFile.HMethod; 8 pnkfelix 1.1.2.1 import harpoon.ClassFile.HCodeFactory; 9 pnkfelix 1.1.2.1 import harpoon.Backend.Generic.Code; 10 pnkfelix 1.1.2.1 11 pnkfelix 1.1.2.1 import java.io.BufferedInputStream; 12 pnkfelix 1.1.2.1 import java.io.BufferedReader; 13 pnkfelix 1.1.2.1 import java.io.File; 14 pnkfelix 1.1.2.1 import java.io.FileInputStream; 15 pnkfelix 1.1.2.1 import java.io.FileOutputStream; 16 pnkfelix 1.1.2.1 import java.io.FileReader; 17 pnkfelix 1.1.2.1 import java.io.InputStream; 18 pnkfelix 1.1.2.1 import java.io.InputStreamReader; 19 pnkfelix 1.1.2.1 import java.io.IOException; 20 pnkfelix 1.1.2.1 import java.io.LineNumberReader; 21 pnkfelix 1.1.2.1 22 pnkfelix 1.1.2.1 import java.util.HashSet; 23 pnkfelix 1.1.2.3 import java.util.Iterator; 24 pnkfelix 1.1.2.3 import java.util.ArrayList; 25 pnkfelix 1.1.2.1 import java.util.StringTokenizer; 26 pnkfelix 1.1.2.1 27 pnkfelix 1.1.2.1 /** 28 pnkfelix 1.1.2.1 * <code>RegAllocOpts</code> encapsulates a set of modifications to 29 pnkfelix 1.1.2.1 * how register allocation will be performed on a particular set of 30 pnkfelix 1.1.2.1 * methods. The choice of modifications are read in from a seperate 31 pnkfelix 1.1.2.1 * file, and then code factories produced by this will use the options 32 pnkfelix 1.1.2.1 * given the file to change how register allocation is done in certain 33 pnkfelix 1.1.2.1 * cases. 34 pnkfelix 1.1.2.1 * <p> 35 pnkfelix 1.1.2.1 * Currently, the file supports the following options: 36 pnkfelix 1.1.2.1 * <br> "FORCE_LOCAL <em>method name</em> ..." forces the register allocator to 37 pnkfelix 1.1.2.1 * use a local allocation strategy on <em>method name</em> rather than 38 pnkfelix 1.1.2.1 * whatever default strategy is in place. 39 pnkfelix 1.1.2.4 * <br> "DISABLE_REACHING_DEFS <em>method name</em> ..." forces the 40 pnkfelix 1.1.2.4 * register allocator to use a local allocation strategy on <em>method 41 pnkfelix 1.1.2.4 * name</em> rather than whatever default strategy is in place, and 42 pnkfelix 1.1.2.4 * <b>in addition</b> disables ReachingDefs analysis in local register 43 pnkfelix 1.1.2.4 * allocation. This is a sick hack added just to compile certain spec 44 pnkfelix 1.1.2.4 * classes before his deadline. 45 pnkfelix 1.1.2.1 * <br> "FORCE_GLOBAL <em>method name</em> ..." forces the register 46 pnkfelix 1.1.2.1 * allocator to use a global allocation strategy on <em>method 47 pnkfelix 1.1.2.1 * name</em>, rather than whatever default stategy is in place. 48 pnkfelix 1.1.2.1 * <br> "FORCE_COALESCE <em>method name</em> ..." forces global 49 pnkfelix 1.1.2.1 * allocation with non-conservative move coalescing to take place, 50 pnkfelix 1.1.2.1 * even when it might result in additional memory traffic. 51 pnkfelix 1.1.2.4 * <br> "DISABLE_COALESCE <em>method name</em> ..." turns off 52 pnkfelix 1.1.2.4 * move coalescing on global allocation. 53 pnkfelix 1.1.2.5 * <br> "FORCE_APPEL <em>method name</em> ..." forces the register 54 pnkfelix 1.1.2.5 * allocator to use Appel-style register allocation on <em>method 55 pnkfelix 1.1.2.5 * name</em>, rather than whatever default strategy is in place. 56 pnkfelix 1.1.2.8 * <br> "FORCE_FELIX <em>method name</em> ..." forces the register 57 pnkfelix 1.1.2.8 * allocator to use Appel-style register allocation on <em>method 58 pnkfelix 1.1.2.8 * name</em> (with modifications for architectural indepedence), 59 pnkfelix 1.1.2.8 * rather than whatever default strategy is in place. 60 pnkfelix 1.1.2.1 * <br> "# <em>comment</em>" is a comment line (not strictly an 61 pnkfelix 1.1.2.1 * option, since this line is ignored by this, but too useful to omit) 62 pnkfelix 1.1.2.1 * <p> 63 pnkfelix 1.1.2.7 * The method names given in the file should be disjoint; the behavior 64 pnkfelix 1.1.2.7 * of allocation is undefined when a <em>method</em> is listed under 65 pnkfelix 1.1.2.7 * multiple options. 66 pnkfelix 1.1.2.7 * <p> 67 pnkfelix 1.1.2.7 * A set of methods with a common prefix can be passed as the <em>method name</em> argument 68 pnkfelix 1.1.2.7 * to a single option by appending the wildcard character '*' to the prefix. 69 pnkfelix 1.1.2.1 * <p> 70 pnkfelix 1.1.2.1 * After these options have been loaded, this class can be used to 71 pnkfelix 1.1.2.1 * produce wrapper <code>RegAlloc.Factory</code>s around other 72 pnkfelix 1.1.2.1 * <code>RegAlloc.Factory</code>s 73 pnkfelix 1.1.2.1 * 74 cananian 1.1.2.6 * @author Felix S. Klock II <pnkfelix@mit.edu> 75 cananian 1.3 * @version $Id: RegAllocOpts.java,v 1.3 2004/02/08 03:19:37 cananian Exp $ */ 76 pnkfelix 1.1.2.1 public class RegAllocOpts { 77 pnkfelix 1.1.2.2 public static final boolean INFO = false; 78 pnkfelix 1.1.2.4 Filter disableReachingDefs; 79 pnkfelix 1.1.2.3 Filter forceLocal; 80 pnkfelix 1.1.2.3 Filter forceGlobal; 81 pnkfelix 1.1.2.5 Filter forceAppel; 82 pnkfelix 1.1.2.8 Filter forceFelix; 83 pnkfelix 1.1.2.3 Filter forceCoalesce; 84 pnkfelix 1.1.2.4 Filter disableCoalesce; 85 pnkfelix 1.1.2.1 86 pnkfelix 1.1.2.1 /** Creates a <code>RegAllocOpts</code>. */ 87 pnkfelix 1.1.2.1 public RegAllocOpts(String filename) { 88 pnkfelix 1.1.2.4 disableReachingDefs = new Filter(); 89 pnkfelix 1.1.2.3 forceLocal = new Filter(); 90 pnkfelix 1.1.2.3 forceGlobal = new Filter(); 91 pnkfelix 1.1.2.3 forceCoalesce = new Filter(); 92 pnkfelix 1.1.2.5 forceAppel = new Filter(); 93 pnkfelix 1.1.2.8 forceFelix = new Filter(); 94 pnkfelix 1.1.2.4 disableCoalesce = new Filter(); 95 pnkfelix 1.1.2.1 96 pnkfelix 1.1.2.1 if (filename != null) { 97 pnkfelix 1.1.2.1 try { 98 pnkfelix 1.1.2.5 if (INFO) System.out.println("reading options from "+filename); 99 pnkfelix 1.1.2.1 readOptions(filename); 100 pnkfelix 1.1.2.1 } catch (IOException e) { 101 pnkfelix 1.1.2.1 System.out.println(e.getMessage()); 102 pnkfelix 1.1.2.1 System.out.println 103 pnkfelix 1.1.2.1 ("Error reading regalloc options file; no options being used"); 104 pnkfelix 1.1.2.1 forceLocal.clear(); forceGlobal.clear(); forceCoalesce.clear(); 105 pnkfelix 1.1.2.4 disableCoalesce.clear(); 106 pnkfelix 1.1.2.1 } 107 pnkfelix 1.1.2.1 } 108 pnkfelix 1.1.2.1 } 109 pnkfelix 1.1.2.1 110 pnkfelix 1.1.2.1 public RegAlloc.Factory factory(final RegAlloc.Factory hc) { 111 pnkfelix 1.1.2.1 return new RegAlloc.Factory() { 112 pnkfelix 1.1.2.1 public RegAlloc makeRegAlloc(Code c) { 113 pnkfelix 1.1.2.1 String name = nameFor(c).trim(); 114 pnkfelix 1.1.2.1 115 pnkfelix 1.1.2.4 if (disableReachingDefs.contains(name)) { 116 pnkfelix 1.1.2.4 if (INFO) System.out.println(" * USING DRd FOR "+name); 117 pnkfelix 1.1.2.4 return LocalCffRegAlloc.RD_DISABLED_FACTORY.makeRegAlloc(c); 118 pnkfelix 1.1.2.4 } else if (forceLocal.contains(name)) { 119 pnkfelix 1.1.2.2 if (INFO) System.out.println(" * USING FL FOR "+name); 120 pnkfelix 1.1.2.1 return RegAlloc.LOCAL.makeRegAlloc(c); 121 pnkfelix 1.1.2.1 } else if (forceGlobal.contains(name)) { 122 pnkfelix 1.1.2.2 if (INFO) System.out.println(" * USING FG FOR "+name); 123 pnkfelix 1.1.2.1 return RegAlloc.GLOBAL.makeRegAlloc(c); 124 pnkfelix 1.1.2.1 } else if (forceCoalesce.contains(name)) { 125 pnkfelix 1.1.2.2 if (INFO) System.out.println(" * USING FC FOR "+name); 126 pnkfelix 1.1.2.1 return GraphColoringRegAlloc.AGGRESSIVE_FACTORY.makeRegAlloc(c); 127 pnkfelix 1.1.2.5 } else if (forceAppel.contains(name)) { 128 pnkfelix 1.1.2.5 if (INFO) System.out.println(" * USING Appel FOR "+name); 129 pnkfelix 1.1.2.5 return AppelRegAlloc.FACTORY.makeRegAlloc(c); 130 pnkfelix 1.1.2.8 } else if (forceFelix.contains(name)) { 131 pnkfelix 1.1.2.8 if (INFO) System.out.println(" * USING Felix FOR "+name); 132 pnkfelix 1.1.2.8 return AppelRegAllocFsk.FACTORY.makeRegAlloc(c); 133 pnkfelix 1.1.2.4 } else if (disableCoalesce.contains(name)) { 134 pnkfelix 1.1.2.4 if (INFO) System.out.println(" * USING DC FOR "+name); 135 pnkfelix 1.1.2.5 return GraphColoringRegAlloc.BRAINDEAD_FACTORY.makeRegAlloc(c); 136 pnkfelix 1.1.2.1 } else { 137 pnkfelix 1.1.2.2 if (INFO) System.out.println(" * USING NM FOR "+name); 138 pnkfelix 1.1.2.1 return hc.makeRegAlloc(c); 139 pnkfelix 1.1.2.1 } 140 pnkfelix 1.1.2.1 } 141 pnkfelix 1.1.2.1 }; 142 pnkfelix 1.1.2.1 } 143 pnkfelix 1.1.2.1 144 pnkfelix 1.1.2.1 private static String nameFor(Code c) { 145 pnkfelix 1.1.2.1 HMethod hm = c.getMethod(); 146 pnkfelix 1.1.2.1 return hm.getDeclaringClass().getName() +"."+ hm.getName(); 147 pnkfelix 1.1.2.1 } 148 pnkfelix 1.1.2.1 149 pnkfelix 1.1.2.1 private void readOptions(String filename) throws IOException { 150 pnkfelix 1.1.2.1 LineNumberReader r = new LineNumberReader(new FileReader(filename)); 151 pnkfelix 1.1.2.1 String line; 152 pnkfelix 1.1.2.1 while (null != (line=r.readLine())) { 153 pnkfelix 1.1.2.1 line = line.trim(); // remove white space from both sides. 154 pnkfelix 1.1.2.1 155 pnkfelix 1.1.2.1 // allow comments and blank lines. 156 pnkfelix 1.1.2.1 if (line.startsWith("#") || line.length()==0) continue; 157 pnkfelix 1.1.2.1 158 pnkfelix 1.1.2.1 StringTokenizer st = new StringTokenizer(line); 159 pnkfelix 1.1.2.1 String s = st.nextToken(); 160 pnkfelix 1.1.2.3 Filter addToSet = null; 161 pnkfelix 1.1.2.4 if (s.toUpperCase().equals("DISABLE_REACHING_DEFS")) { 162 pnkfelix 1.1.2.4 addToSet = disableReachingDefs; 163 pnkfelix 1.1.2.4 } else if (s.toUpperCase().equals("FORCE_LOCAL")) { 164 pnkfelix 1.1.2.1 addToSet = forceLocal; 165 pnkfelix 1.1.2.1 } else if (s.toUpperCase().equals("FORCE_GLOBAL")) { 166 pnkfelix 1.1.2.1 addToSet = forceGlobal; 167 pnkfelix 1.1.2.1 } else if (s.toUpperCase().equals("FORCE_COALESCE")) { 168 pnkfelix 1.1.2.1 addToSet = forceCoalesce; 169 pnkfelix 1.1.2.5 } else if (s.toUpperCase().equals("FORCE_APPEL")) { 170 pnkfelix 1.1.2.5 addToSet = forceAppel; 171 pnkfelix 1.1.2.8 } else if (s.toUpperCase().equals("FORCE_FELIX")) { 172 pnkfelix 1.1.2.8 addToSet = forceFelix; 173 pnkfelix 1.1.2.4 } else if (s.toUpperCase().equals("DISABLE_COALESCE")) { 174 pnkfelix 1.1.2.4 addToSet = disableCoalesce; 175 pnkfelix 1.1.2.1 } else { 176 pnkfelix 1.1.2.8 System.err.println("unknown RegAlloc option: "+s+ 177 pnkfelix 1.1.2.1 " line: "+r.getLineNumber()); 178 pnkfelix 1.1.2.1 continue; 179 pnkfelix 1.1.2.1 } 180 pnkfelix 1.1.2.1 181 pnkfelix 1.1.2.1 while (st.hasMoreTokens()) { 182 pnkfelix 1.1.2.1 String tkn = st.nextToken(); 183 pnkfelix 1.1.2.1 addToSet.add(tkn); 184 pnkfelix 1.1.2.1 // System.out.println("adding "+tkn+" to "+s); 185 pnkfelix 1.1.2.1 } 186 pnkfelix 1.1.2.1 } 187 pnkfelix 1.1.2.1 188 pnkfelix 1.1.2.1 r.close(); 189 pnkfelix 1.1.2.1 190 pnkfelix 1.1.2.3 } 191 pnkfelix 1.1.2.3 192 pnkfelix 1.1.2.3 /** Filter is a set of strings. */ 193 pnkfelix 1.1.2.3 class Filter { 194 pnkfelix 1.1.2.5 // AF(c) = { s | s in c.names OR exists p in c.prefixMatches 195 pnkfelix 1.1.2.3 // such that s begins-with p } 196 pnkfelix 1.1.2.3 HashSet names = new HashSet(5); 197 pnkfelix 1.1.2.3 ArrayList prefixMatches = new ArrayList(5); 198 pnkfelix 1.1.2.3 199 pnkfelix 1.1.2.3 public boolean contains(String name) { 200 pnkfelix 1.1.2.3 if (names.contains(name)) 201 pnkfelix 1.1.2.3 return true; 202 pnkfelix 1.1.2.3 203 cananian 1.3 for(Object sO : prefixMatches){ 204 cananian 1.3 String s = (String) sO; 205 pnkfelix 1.1.2.5 if (name.startsWith(s)) 206 pnkfelix 1.1.2.3 return true; 207 pnkfelix 1.1.2.3 } 208 pnkfelix 1.1.2.3 209 pnkfelix 1.1.2.3 return false; 210 pnkfelix 1.1.2.3 } 211 pnkfelix 1.1.2.3 212 pnkfelix 1.1.2.3 public void add(String str) { 213 pnkfelix 1.1.2.3 if (!str.endsWith("*")) { 214 pnkfelix 1.1.2.3 addName(str); 215 pnkfelix 1.1.2.3 } else { 216 pnkfelix 1.1.2.3 addPrefix(str.substring(0,str.length()-1)); 217 pnkfelix 1.1.2.3 } 218 pnkfelix 1.1.2.3 } 219 pnkfelix 1.1.2.3 public void addName(String str) { names.add(str); } 220 pnkfelix 1.1.2.3 public void addPrefix(String prefix) { prefixMatches.add(prefix); } 221 pnkfelix 1.1.2.3 222 pnkfelix 1.1.2.3 public void clear() { names.clear(); prefixMatches.clear(); } 223 pnkfelix 1.1.2.1 } 224 pnkfelix 1.1.2.1 225 cananian 1.2 }