1 salcianu 1.1  // CodeGenerator.java, created Wed Apr  2 14:17:32 2003 by salcianu
  2 salcianu 1.1  // Copyright (C) 2003 Alexandru Salcianu <salcianu@MIT.EDU>
  3 salcianu 1.1  // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 salcianu 1.1  package harpoon.Main;
  5 salcianu 1.1  
  6 salcianu 1.1  import harpoon.ClassFile.Linker;
  7 salcianu 1.1  import harpoon.ClassFile.HMethod;
  8 salcianu 1.1  import harpoon.ClassFile.HClass;
  9 salcianu 1.1  import harpoon.ClassFile.HCode;
 10 salcianu 1.1  import harpoon.ClassFile.HData;
 11 salcianu 1.1  import harpoon.ClassFile.HCodeFactory;
 12 salcianu 1.1  
 13 salcianu 1.1  import harpoon.Analysis.ClassHierarchy;
 14 salcianu 1.1  
 15 salcianu 1.1  import harpoon.Backend.Backend;
 16 salcianu 1.1  import harpoon.Backend.Generic.Frame;
 17 salcianu 1.1  
 18 salcianu 1.1  import harpoon.IR.Tree.Data;
 19 salcianu 1.1  import harpoon.IR.Assem.Instr;
 20 salcianu 1.1  import harpoon.IR.Assem.InstrFactory;
 21 salcianu 1.1  
 22 salcianu 1.1  import harpoon.Analysis.Instr.RegAlloc;
 23 salcianu 1.1  import harpoon.Analysis.Instr.RegAllocOpts;
 24 salcianu 1.1  
 25 salcianu 1.1  import harpoon.Temp.TempFactory;
 26 salcianu 1.1  
 27 cananian 1.11 import net.cscott.jutil.Default;
 28 cananian 1.11 import net.cscott.jutil.CombineIterator;
 29 salcianu 1.4  import harpoon.Util.Options.Option;
 30 salcianu 1.1  
 31 salcianu 1.1  import harpoon.Analysis.MemOpt.PreallocOpt;
 32 salcianu 1.1  import harpoon.Analysis.Realtime.Realtime;
 33 salcianu 1.1  
 34 salcianu 1.1  import java.lang.reflect.Modifier;
 35 salcianu 1.1  import java.util.Arrays;
 36 salcianu 1.1  import java.util.Collections;
 37 salcianu 1.1  import java.util.Collection;
 38 salcianu 1.1  import java.util.HashSet;
 39 salcianu 1.1  import java.util.Iterator;
 40 salcianu 1.1  import java.util.List;
 41 salcianu 1.4  import java.util.LinkedList;
 42 salcianu 1.1  import java.util.Set;
 43 salcianu 1.1  import java.util.TreeSet;
 44 salcianu 1.1  import java.util.Map;
 45 salcianu 1.1  import java.util.HashMap;
 46 salcianu 1.1  import java.io.BufferedInputStream;
 47 salcianu 1.1  import java.io.BufferedReader;
 48 salcianu 1.1  import java.io.BufferedWriter;
 49 salcianu 1.1  import java.io.File;
 50 salcianu 1.1  import java.io.FileInputStream;
 51 salcianu 1.1  import java.io.FileOutputStream;
 52 salcianu 1.1  import java.io.FileReader;
 53 salcianu 1.1  import java.io.FileWriter;
 54 salcianu 1.1  import java.io.InputStream;
 55 salcianu 1.1  import java.io.InputStreamReader;
 56 salcianu 1.1  import java.io.IOException;
 57 salcianu 1.1  import java.io.LineNumberReader;
 58 salcianu 1.1  import java.io.ObjectInputStream;
 59 salcianu 1.1  import java.io.ObjectOutputStream;
 60 salcianu 1.1  import java.io.OptionalDataException;
 61 salcianu 1.1  import java.io.PrintStream;
 62 salcianu 1.1  import java.io.PrintWriter;
 63 salcianu 1.1  
 64 salcianu 1.1  
 65 salcianu 1.1  /**
 66 salcianu 1.1   * <code>CodeGenerator</code>
 67 salcianu 1.1   * 
 68 salcianu 1.1   * @author  Alexandru Salcianu <salcianu@MIT.EDU>
 69 cananian 1.11  * @version $Id: CodeGenerator.java,v 1.11 2004/02/08 01:58:13 cananian Exp $
 70 salcianu 1.1   */
 71 salcianu 1.4  public class CodeGenerator extends CompilerStage {
 72 salcianu 1.4      
 73 salcianu 1.4      public CodeGenerator() { super("code-generator"); }
 74 salcianu 1.4  
 75 cananian 1.10     public List<Option> getOptions() {
 76 cananian 1.10         List<Option> opts = new LinkedList<Option>();
 77 salcianu 1.4  
 78 salcianu 1.7          if(Boolean.getBoolean("debug.reg-alloc"))
 79 salcianu 1.5              add_debug_options(opts);
 80 salcianu 1.5  
 81 salcianu 1.5          opts.add(new Option("L", "Outputs Local Register Allocated Instr IR") {
 82 salcianu 1.5              public void action() { REG_ALLOC = LOCAL_REG_ALLOC = true; }
 83 salcianu 1.4          });
 84 salcianu 1.5  
 85 salcianu 1.4          opts.add(new Option("H", "Hacked register allocator") {
 86 salcianu 1.4              public void action() { HACKED_REG_ALLOC = true; }
 87 salcianu 1.4          });
 88 salcianu 1.5  
 89 salcianu 1.5          opts.add(new Option
 90 salcianu 1.5                   ("R", "", "<regAllocOptionsFilename>",
 91 salcianu 1.5                    "Read Global Register Allocator options from file") {
 92 salcianu 1.4              public void action() {
 93 salcianu 1.4                  if(getOptionalArg(0) != null)
 94 salcianu 1.4                      regAllocOptionsFilename = getOptionalArg(0);
 95 salcianu 1.4                  REG_ALLOC = true;
 96 salcianu 1.4              }
 97 salcianu 1.4          });
 98 salcianu 1.5  
 99 salcianu 1.4          opts.add(new Option("o", "<outputDir>",
100 salcianu 1.4                              "Output directory for compilation result") {
101 salcianu 1.4              public void action() { 
102 salcianu 1.4                  ASSEM_DIR = new File(getArg(0));
103 salcianu 1.4                  assert ASSEM_DIR.isDirectory() : 
104 salcianu 1.4                      ASSEM_DIR + " must be a directory";
105 salcianu 1.4  
106 salcianu 1.4              }
107 salcianu 1.4          });
108 salcianu 1.5  
109 salcianu 1.4          opts.add(new Option("1", "", "<classname>", "Compiles only a single method or class.  Without a classname, only compiles <class>.main()") {
110 salcianu 1.4              public void action() {
111 salcianu 1.4                  String optclassname = getOptionalArg(0);
112 salcianu 1.4                  if (optclassname != null)
113 salcianu 1.4                      singleClassStr = optclassname;
114 salcianu 1.4                  else
115 salcianu 1.4                      ONLY_COMPILE_MAIN = true;
116 salcianu 1.4              }
117 salcianu 1.4          });
118 salcianu 1.4  
119 salcianu 1.4          return opts;
120 salcianu 1.5      }
121 salcianu 1.5  
122 salcianu 1.5  
123 salcianu 1.5      // These options seem too debug-specific.  Not included by default [AS]
124 salcianu 1.5      private void add_debug_options(List/*<Option>*/ opts) {
125 salcianu 1.5          opts.add(new Option("D", "Outputs DATA information") {
126 salcianu 1.5              public void action() { OUTPUT_INFO = PRINT_DATA = true; }
127 salcianu 1.5          });
128 salcianu 1.5          
129 salcianu 1.5          opts.add(new Option("O", "Outputs Original Tree IR") {
130 salcianu 1.5              public void action() { OUTPUT_INFO = PRINT_ORIG = true; }
131 salcianu 1.5          });
132 salcianu 1.5          
133 salcianu 1.5          opts.add(new Option
134 salcianu 1.5                   ("P", "Outputs Pre-Register Allocated Instr IR") {
135 salcianu 1.5              public void action() { OUTPUT_INFO = PRE_REG_ALLOC = true; }
136 salcianu 1.5          });
137 salcianu 1.5          
138 salcianu 1.5          opts.add(new Option
139 salcianu 1.5                   ("B", "Outputs Abstract Register Allocated Instr IR") {
140 salcianu 1.5              public void action() {
141 salcianu 1.5                  OUTPUT_INFO = ABSTRACT_REG_ALLOC = true;
142 salcianu 1.5              }
143 salcianu 1.5          });
144 salcianu 1.5          
145 salcianu 1.6          opts.add(new Option("A", "Same as -O -P -R") {
146 salcianu 1.5              public void action() {
147 salcianu 1.5                  OUTPUT_INFO = PRE_REG_ALLOC = true;
148 salcianu 1.5                  PRINT_ORIG = REG_ALLOC = true;
149 salcianu 1.5              }
150 salcianu 1.5          });
151 salcianu 1.4      }
152 salcianu 1.4  
153 salcianu 1.1  
154 salcianu 1.4      /** code generation options ([TOO] MANY!) */
155 salcianu 1.1      static boolean PRINT_ORIG = false;
156 salcianu 1.1      static boolean PRINT_DATA = false;
157 salcianu 1.1      static boolean PRE_REG_ALLOC = false;
158 salcianu 1.1      static boolean REG_ALLOC = false;
159 salcianu 1.1      static boolean ABSTRACT_REG_ALLOC = false;
160 salcianu 1.1      static boolean HACKED_REG_ALLOC = false;
161 salcianu 1.1      static boolean LOCAL_REG_ALLOC = false;
162 salcianu 1.1      static boolean OUTPUT_INFO = false;
163 salcianu 1.3      static File ASSEM_DIR;
164 salcianu 1.1  
165 salcianu 1.1      static boolean ONLY_COMPILE_MAIN = false; // for testing small stuff
166 salcianu 1.1      static String  singleClassStr = null; 
167 salcianu 1.1      static HClass  singleClass = null; // for testing single classes
168 salcianu 1.1  
169 salcianu 1.1      // FSK: contains specialization options to be used during
170 salcianu 1.1      // RegAlloc.  Take out when no longer necessary.  
171 salcianu 1.1      // May be null (in which case no options are being passed).
172 salcianu 1.1      static String regAllocOptionsFilename; 
173 salcianu 1.2      private static RegAlloc.Factory regAllocFactory;
174 salcianu 1.8  
175 salcianu 1.8      /** @return <code>true</code> */
176 salcianu 1.8      public boolean enabled() { return true; }
177 salcianu 1.1  
178 salcianu 1.4      public CompilerState action(CompilerState cs) {
179 salcianu 1.4          // always enabled; unpack cs and go to work!
180 salcianu 1.1          mainM = cs.getMain();
181 salcianu 1.1          linker = cs.getLinker();
182 salcianu 1.1          hcf = cs.getCodeFactory();
183 salcianu 1.1          classHierarchy = cs.getClassHierarchy();
184 salcianu 1.1          frame = cs.getFrame();
185 salcianu 1.1  
186 salcianu 1.1          generate_code();
187 salcianu 1.1  
188 salcianu 1.3          mainM = null;
189 salcianu 1.3          linker = null;
190 salcianu 1.3          hcf = null;
191 salcianu 1.3          classHierarchy = null;
192 salcianu 1.3          frame = null;
193 salcianu 1.3  
194 salcianu 1.1          return cs;
195 salcianu 1.1      }
196 salcianu 1.1  
197 salcianu 1.1      private static HMethod mainM;
198 salcianu 1.1      private static Linker linker;
199 salcianu 1.1      private static HCodeFactory hcf;
200 salcianu 1.1      private static ClassHierarchy classHierarchy;
201 salcianu 1.1      private static Frame frame;
202 salcianu 1.1      private static PrintWriter out = new PrintWriter(System.out, true);
203 salcianu 1.1  
204 salcianu 1.1  
205 salcianu 1.1      // take a tree code factory and generate native / preciseC code
206 salcianu 1.4      private void generate_code() {
207 salcianu 1.4          // sahcf = "Strong-Arm HCodeFactory"
208 salcianu 1.1          HCodeFactory sahcf = frame.getCodeFactory(hcf);
209 salcianu 1.1          if (sahcf != null)
210 salcianu 1.1              sahcf = new harpoon.ClassFile.CachingCodeFactory(sahcf);
211 salcianu 1.1          
212 salcianu 1.1          regAllocFactory = LOCAL_REG_ALLOC ? RegAlloc.LOCAL : RegAlloc.GLOBAL;
213 salcianu 1.1          regAllocFactory = (new RegAllocOpts
214 salcianu 1.1                             (regAllocOptionsFilename)).factory(regAllocFactory);
215 salcianu 1.1  
216 salcianu 1.1          Set callableMethods = classHierarchy.callableMethods();
217 salcianu 1.1          Iterator classes = new TreeSet(classHierarchy.classes()).iterator();
218 salcianu 1.1  
219 salcianu 1.1          if (ONLY_COMPILE_MAIN)
220 salcianu 1.1              classes = Default.singletonIterator(mainM.getDeclaringClass());
221 salcianu 1.1          if (singleClassStr != null) {
222 salcianu 1.1              singleClass = linker.forName(singleClassStr);
223 salcianu 1.1              classes = Default.singletonIterator(singleClass);
224 salcianu 1.1          }
225 salcianu 1.1  
226 salcianu 1.1          while(classes.hasNext()) {
227 salcianu 1.1              HClass hclass = (HClass) classes.next();
228 salcianu 1.1              if (singleClass != null && singleClass != hclass) continue; //skip
229 salcianu 1.1              messageln("Compiling: " + hclass.getName());
230 salcianu 1.1              try {
231 salcianu 1.1                  generate_code_for_class(hclass, callableMethods, sahcf);
232 salcianu 1.1              } catch (IOException e) {
233 salcianu 1.1                  System.err.println("Error outputting class "+
234 salcianu 1.1                                     hclass.getName() + ": " + e);
235 salcianu 1.1                  System.exit(1);
236 salcianu 1.1              }
237 salcianu 1.1          }
238 salcianu 1.1          
239 salcianu 1.1          if (Realtime.REALTIME_JAVA)
240 salcianu 1.1              Realtime.printStats();
241 salcianu 1.1  
242 salcianu 1.1          generate_Makefile();
243 salcianu 1.1      }
244 salcianu 1.1  
245 salcianu 1.1  
246 salcianu 1.1      // Generate class data + code for all methods of
247 salcianu 1.1      // <code>hclass</code> that are in the set
248 salcianu 1.1      // <code>callableMethods</code>.
249 salcianu 1.1      // QUESTION: What's <code>sahcf</code>.
250 cananian 1.10     //    "StrongArm HCodeFactory" -- the hcode factory for the backend;
251 cananian 1.10     //    the name is left over from when StrongArm was our only backend. [CSA]
252 salcianu 1.4      private void generate_code_for_class
253 salcianu 1.1          (HClass hclass, Set callableMethods, HCodeFactory sahcf)
254 salcianu 1.1          throws IOException {
255 salcianu 1.1  
256 salcianu 1.1          String filesuffix = (SAMain.BACKEND == Backend.PRECISEC) ? ".c" : ".s";
257 salcianu 1.1          String filename = frame.getRuntime().getNameMap().mangle(hclass);
258 salcianu 1.1          java.io.Writer w;
259 salcianu 1.1          try {
260 salcianu 1.1              w = new FileWriter
261 salcianu 1.1                  (new File(ASSEM_DIR, filename + filesuffix));
262 salcianu 1.1          } catch (java.io.FileNotFoundException ffe) {
263 salcianu 1.1              // filename too long?  try shorter, unique, name.
264 salcianu 1.1              // XXX: sun's doc for File.createTempFile() states
265 salcianu 1.1              // "If the prefix is too long then it will be
266 salcianu 1.1              // truncated" but it is actually not.  We must
267 salcianu 1.1              // truncate it ourselves, for now.  200-chars?
268 salcianu 1.1              if (filename.length()>200)
269 salcianu 1.1                  filename=filename.substring(0, 200);
270 salcianu 1.1              w = new FileWriter
271 salcianu 1.1                  (File.createTempFile(filename, filesuffix, ASSEM_DIR));
272 salcianu 1.1          }
273 salcianu 1.1          out = new PrintWriter(new BufferedWriter(w));
274 salcianu 1.1          
275 salcianu 1.1          if (SAMain.BACKEND == Backend.PRECISEC)
276 salcianu 1.1              out = new harpoon.Backend.PreciseC.TreeToC(out);
277 salcianu 1.1          
278 salcianu 1.1          HMethod[] hmarray = hclass.getDeclaredMethods();
279 cananian 1.10         Set<HMethod> hmset = new TreeSet<HMethod>(Arrays.asList(hmarray));
280 salcianu 1.1          hmset.retainAll(callableMethods);
281 cananian 1.10         Iterator<HMethod> hms = hmset.iterator();
282 salcianu 1.1          if (ONLY_COMPILE_MAIN)
283 salcianu 1.1              hms = Default.singletonIterator(mainM);
284 salcianu 1.1          message("\t");
285 salcianu 1.1          while(hms.hasNext()) {
286 cananian 1.10             HMethod m = hms.next();
287 salcianu 1.1              message(m.getName());
288 salcianu 1.1              if (!Modifier.isAbstract(m.getModifiers()))
289 salcianu 1.1                  outputMethod(m, hcf, sahcf, out);
290 salcianu 1.1              if (hms.hasNext()) message(", ");
291 salcianu 1.1          }
292 salcianu 1.1          messageln("");
293 salcianu 1.1          
294 salcianu 1.1          //out.println();
295 salcianu 1.1          messageln("Writing data for " + hclass.getName());
296 salcianu 1.1          outputClassData(hclass, out);
297 salcianu 1.1         
298 salcianu 1.1          out.close();
299 salcianu 1.1      }
300 salcianu 1.1  
301 salcianu 1.1  
302 salcianu 1.1      // generate the Makefile that can be used to assemble / compile the
303 salcianu 1.1      // generated files into a single executable
304 salcianu 1.4      private void generate_Makefile() {  
305 salcianu 1.1          // put a proper makefile in the directory.
306 salcianu 1.1          File makefile = new File(ASSEM_DIR, "Makefile");
307 salcianu 1.1          InputStream templateStream;
308 salcianu 1.1          String resourceName = "harpoon/Support/nativecode-makefile.template";
309 salcianu 1.1  
310 salcianu 1.1          if (SAMain.BACKEND == Backend.PRECISEC)
311 cananian 1.9              // see TreeToC for more details on the NO_SECTION_SUPPORT option
312 cananian 1.9              resourceName="harpoon/Support/precisec-"+
313 cananian 1.9                  (Boolean.getBoolean("harpoon.precisec.no_sections") ?
314 cananian 1.9                   "no-sect-" : "")+"makefile.template";
315 salcianu 1.1          if (SAMain.BACKEND == Backend.MIPSDA)
316 salcianu 1.1              resourceName="harpoon/Support/mipsda-makefile.template";
317 salcianu 1.1          if (makefile.exists())
318 salcianu 1.1              System.err.println("WARNING: not overwriting pre-existing " +
319 salcianu 1.1                                 "file " + makefile);
320 salcianu 1.1          else if ((templateStream = 
321 salcianu 1.1                    ClassLoader.getSystemResourceAsStream(resourceName)) == null)
322 salcianu 1.1              System.err.println("WARNING: can't find Makefile template.");
323 salcianu 1.1          else try {
324 salcianu 1.1              BufferedReader in = new BufferedReader
325 salcianu 1.1                  (new InputStreamReader(templateStream));
326 salcianu 1.1              out = new PrintWriter
327 salcianu 1.1                  (new BufferedWriter(new FileWriter(makefile)));
328 salcianu 1.1              String line;
329 salcianu 1.1              while ((line=in.readLine()) != null)
330 salcianu 1.1                  out.println(line);
331 salcianu 1.1              in.close(); out.close();
332 salcianu 1.1          } catch (IOException e) {
333 salcianu 1.1              System.err.println("Error writing "+makefile+".");
334 salcianu 1.1              System.exit(1);
335 salcianu 1.1          }
336 salcianu 1.1      }
337 salcianu 1.1  
338 salcianu 1.1  
339 salcianu 1.4      public void outputMethod(final HMethod hmethod, 
340 salcianu 1.4                               final HCodeFactory hcf,
341 salcianu 1.4                               final HCodeFactory sahcf,
342 salcianu 1.4                               final PrintWriter out) throws IOException {
343 salcianu 1.1          if (PRINT_ORIG) {
344 salcianu 1.1              HCode hc = hcf.convert(hmethod);
345 salcianu 1.1              
346 salcianu 1.1              info("\t--- TREE FORM ---");
347 salcianu 1.1              if (hc!=null) hc.print(out); 
348 salcianu 1.1              else 
349 salcianu 1.1                  info("null returned for " + hmethod);
350 salcianu 1.1              info("\t--- end TREE FORM ---");
351 salcianu 1.1              out.println();
352 salcianu 1.1              out.flush();
353 salcianu 1.1          }
354 salcianu 1.1              
355 salcianu 1.1          if (PRE_REG_ALLOC) {
356 salcianu 1.1              HCode hc = sahcf.convert(hmethod);
357 salcianu 1.1              
358 salcianu 1.1              info("\t--- INSTR FORM (no register allocation)  ---");
359 salcianu 1.1              if (hc!=null) {
360 salcianu 1.1                  info("Codeview \""+hc.getName()+"\" for "+
361 salcianu 1.1                       hc.getMethod()+":");
362 salcianu 1.1                  // myPrint avoids register-allocation-dependant
363 salcianu 1.1                  // peephole optimization code in print
364 salcianu 1.1                  ((harpoon.IR.Assem.Code)hc).myPrint(out,false); 
365 salcianu 1.1              } else {
366 salcianu 1.1                  info("null returned for " + hmethod);
367 salcianu 1.1              }
368 salcianu 1.1              info("\t--- end INSTR FORM (no register allocation)  ---");
369 salcianu 1.1              out.println();
370 salcianu 1.1              out.flush();
371 salcianu 1.1          }
372 salcianu 1.1          
373 salcianu 1.1          if (ABSTRACT_REG_ALLOC) {
374 salcianu 1.1              HCode hc = sahcf.convert(hmethod);
375 salcianu 1.1              
376 salcianu 1.1              info("\t--- INSTR FORM (register allocation)  ---");
377 salcianu 1.1              HCodeFactory regAllocCF = 
378 salcianu 1.1                  RegAlloc.abstractSpillFactory(sahcf, frame, regAllocFactory);
379 salcianu 1.1              HCode rhc = regAllocCF.convert(hmethod);
380 salcianu 1.1  
381 salcianu 1.1              if (rhc != null) {
382 salcianu 1.1                  info("Codeview \""+rhc.getName()+"\" for "+
383 salcianu 1.1                       rhc.getMethod()+":");
384 salcianu 1.1                  rhc.print(out);
385 salcianu 1.1              } else {
386 salcianu 1.1                  info("null returned for " + hmethod);
387 salcianu 1.1              }
388 salcianu 1.1              info("\t--- end INSTR FORM (register allocation)  ---");
389 salcianu 1.1              out.println();
390 salcianu 1.1              out.flush();
391 salcianu 1.1          }
392 salcianu 1.1  
393 salcianu 1.1          if (REG_ALLOC) {
394 salcianu 1.1              HCode hc = sahcf.convert(hmethod);
395 salcianu 1.1              info("\t--- INSTR FORM (register allocation)  ---");
396 salcianu 1.1              HCodeFactory regAllocCF;
397 salcianu 1.1              
398 salcianu 1.1              regAllocCF = RegAlloc.codeFactory(sahcf,frame,regAllocFactory);
399 salcianu 1.1  
400 salcianu 1.1              HCode rhc = regAllocCF.convert(hmethod);
401 salcianu 1.1              if(SAMain.BACKEND == Backend.MIPSYP && rhc != null) {
402 salcianu 1.1                  harpoon.Backend.Generic.Code cd = 
403 salcianu 1.1                      (harpoon.Backend.Generic.Code) rhc;
404 salcianu 1.1                  harpoon.Backend.MIPS.BypassLatchSchedule b = 
405 salcianu 1.1                      new harpoon.Backend.MIPS.BypassLatchSchedule(cd, frame);
406 salcianu 1.1              }
407 salcianu 1.1              
408 salcianu 1.1              if (rhc != null) {
409 salcianu 1.1                  info("Codeview \"" + rhc.getName() + "\" for " +
410 salcianu 1.1                       rhc.getMethod() + ":");
411 salcianu 1.1                  rhc.print(out);
412 salcianu 1.1              } else {
413 salcianu 1.1                  info("null returned for " + hmethod);
414 salcianu 1.1              }
415 salcianu 1.1              info("\t--- end INSTR FORM (register allocation)  ---");
416 salcianu 1.1              out.println();
417 salcianu 1.1              out.flush();
418 salcianu 1.1          }
419 salcianu 1.1          
420 salcianu 1.1          if (HACKED_REG_ALLOC) {
421 salcianu 1.1              HCode hc = sahcf.convert(hmethod);
422 salcianu 1.1              info("\t--- INSTR FORM (hacked register allocation)  ---");
423 salcianu 1.1              HCode rhc = (hc==null) ? null :
424 salcianu 1.1                  new harpoon.Backend.CSAHack.RegAlloc.Code
425 salcianu 1.1                  (hmethod, (Instr) hc.getRootElement(),
426 salcianu 1.1                   ((harpoon.IR.Assem.Code) hc).getDerivation(), frame);
427 salcianu 1.1              if (rhc != null) {
428 salcianu 1.1                  info("Codeview \"" + rhc.getName() + "\" for " +
429 salcianu 1.1                       rhc.getMethod() + ":");
430 salcianu 1.1                  rhc.print(out);
431 salcianu 1.1              } else {
432 salcianu 1.1                  info("null returned for " + hmethod);
433 salcianu 1.1              }
434 salcianu 1.1              info("\t--- end INSTR FORM (register allocation)  ---");
435 salcianu 1.1              out.println();
436 salcianu 1.1              out.flush();
437 salcianu 1.1          }
438 salcianu 1.1  
439 salcianu 1.1          if (SAMain.BACKEND == Backend.PRECISEC) {
440 salcianu 1.1              HCode hc = hcf.convert(hmethod);
441 salcianu 1.1              if (hc != null)
442 salcianu 1.1                  ((harpoon.Backend.PreciseC.TreeToC) out).translate(hc);
443 salcianu 1.1          }
444 salcianu 1.1  
445 salcianu 1.1          // free memory associated with this method's IR:
446 salcianu 1.1          hcf.clear(hmethod);
447 salcianu 1.1          if (sahcf!=null) sahcf.clear(hmethod);
448 salcianu 1.1      }
449 salcianu 1.1      
450 salcianu 1.4      public void outputClassData(HClass hclass, PrintWriter out) 
451 salcianu 1.1          throws IOException {
452 cananian 1.10       Iterator<HData> it=frame.getRuntime().classData(hclass).iterator();
453 salcianu 1.1        // output global data with the java.lang.Object class.
454 salcianu 1.1        if (hclass==linker.forName("java.lang.Object")) {
455 salcianu 1.1            HData data=frame.getLocationFactory().makeLocationData(frame);
456 cananian 1.10           it=new CombineIterator<HData>(it, Default.singletonIterator(data));
457 salcianu 1.4            if (WriteBarriers.WB_STATISTICS) {
458 salcianu 1.4                assert WriteBarriers.writeBarrierStats != null :
459 salcianu 1.1                    "WriteBarrierStats need to be run before WriteBarrierData.";
460 salcianu 1.4                HData wbData = 
461 salcianu 1.4                    WriteBarriers.writeBarrierStats.getData(hclass, frame);
462 cananian 1.10               it=new CombineIterator<HData>
463 cananian 1.10                   (it, Default.singletonIterator(wbData));
464 salcianu 1.1            }
465 salcianu 1.1            if(PreallocOpt.PREALLOC_OPT) {
466 salcianu 1.1                HData poData = PreallocOpt.getData(hclass, frame);
467 cananian 1.10               it = new CombineIterator<HData>
468 cananian 1.10                   (it, Default.singletonIterator(poData));
469 salcianu 1.1            }
470 cananian 1.10       }
471 cananian 1.10       // additional data required.
472 cananian 1.10       if (Transactions.DO_TRANSACTIONS) {
473 cananian 1.10           it = Transactions.filterData(frame, it);
474 salcianu 1.1        }
475 salcianu 1.1        while (it.hasNext() ) {
476 salcianu 1.1          final Data data = (Data) it.next();
477 salcianu 1.1          
478 salcianu 1.1          if (PRINT_ORIG) {
479 salcianu 1.1              info("\t--- TREE FORM (for DATA)---");
480 salcianu 1.1              data.print(out);
481 salcianu 1.1              info("\t--- end TREE FORM (for DATA)---");
482 salcianu 1.1          }               
483 salcianu 1.1          
484 salcianu 1.1          if (SAMain.BACKEND == Backend.PRECISEC)
485 salcianu 1.1              ((harpoon.Backend.PreciseC.TreeToC)out).translate(data);
486 salcianu 1.1  
487 salcianu 1.1          if (!PRE_REG_ALLOC && !REG_ALLOC && !HACKED_REG_ALLOC) continue;
488 salcianu 1.1  
489 salcianu 1.1          if (data.getRootElement()==null) continue; // nothing to do here.
490 salcianu 1.1  
491 salcianu 1.1          final Instr instr = 
492 salcianu 1.1              frame.getCodeGen().genData((harpoon.IR.Tree.Data) data,
493 salcianu 1.1                                         new InstrFactory() {
494 salcianu 1.1                  private int id = 0;
495 salcianu 1.1                  public TempFactory tempFactory() { return null; }
496 salcianu 1.1                  public harpoon.IR.Assem.Code getParent() {
497 salcianu 1.1                      return null /*data*/;  // FIXME!
498 salcianu 1.1                  }
499 salcianu 1.1                  public Frame getFrame() {return frame;}
500 salcianu 1.1                  public synchronized int getUniqueID() { return id++; }
501 salcianu 1.1                  public HMethod getMethod() { return null; }
502 salcianu 1.1                  public int hashCode() { return data.hashCode(); }
503 salcianu 1.1              });
504 salcianu 1.1          
505 salcianu 1.1          assert instr != null : 
506 salcianu 1.1              "no instrs generated; check that CodeGen.java was built " +
507 salcianu 1.1              "from spec file";
508 salcianu 1.1          // messageln("First data instruction " + instr);
509 salcianu 1.1  
510 salcianu 1.1  
511 salcianu 1.1          /* trying different method. */
512 salcianu 1.1          Instr di = instr; 
513 salcianu 1.1          info("\t--- INSTR FORM (for DATA)---");
514 salcianu 1.1          while(di!=null) { 
515 salcianu 1.1              //messageln("Writing " + di);
516 salcianu 1.1              out.println(di); 
517 salcianu 1.1              di = di.getNext(); 
518 salcianu 1.1          }
519 salcianu 1.1          info("\t--- end INSTR FORM (for DATA)---");
520 salcianu 1.1        }
521 salcianu 1.1      }
522 salcianu 1.1  
523 salcianu 1.1      protected static void message(String msg) { SAMain.message(msg); }
524 salcianu 1.1      protected static void messageln(String msg) { SAMain.messageln(msg); }
525 salcianu 1.1  
526 salcianu 1.1      protected static void info(String str) {
527 salcianu 1.1          if(OUTPUT_INFO) out.println(str);
528 salcianu 1.1      }
529 salcianu 1.1  }