1 cananian 1.1.2.4 // InstrFactory.java, created Tue Feb 9 0:45:33 1999 by andyb 2 andyb 1.1.2.1 // Copyright (C) 1999 Andrew Berkheimer <andyb@mit.edu> 3 andyb 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 andyb 1.1.2.1 package harpoon.IR.Assem; 5 andyb 1.1.2.1 6 pnkfelix 1.1.2.21 import harpoon.IR.Properties.CFGrapher; 7 pnkfelix 1.1.2.21 import harpoon.IR.Properties.UseDefer; 8 andyb 1.1.2.3 import harpoon.Backend.Generic.Frame; 9 cananian 1.2.2.1 import harpoon.Temp.Label; 10 andyb 1.1.2.1 import harpoon.Temp.TempFactory; 11 andyb 1.1.2.1 import harpoon.ClassFile.HMethod; 12 andyb 1.1.2.1 import harpoon.ClassFile.HCode; 13 andyb 1.1.2.1 14 pnkfelix 1.1.2.11 import java.util.HashSet; 15 pnkfelix 1.1.2.7 import java.util.HashMap; 16 pnkfelix 1.1.2.7 import java.util.Map; 17 cananian 1.2.2.1 import java.util.Set; 18 pnkfelix 1.1.2.7 19 andyb 1.1.2.1 /** 20 andyb 1.1.2.1 * A <code>InstrFactory</code> is responsible for generating 21 andyb 1.1.2.1 * generic <code>Assem.Instr</code>s used in code generation. 22 andyb 1.1.2.1 * 23 andyb 1.1.2.1 * @author Andrew Berkheimer <andyb@mit.edu> 24 cananian 1.1.2.22 * @author Felix S. Klock II <pnkfelix@mit.edu> 25 cananian 1.3 * @version $Id: InstrFactory.java,v 1.3 2002/04/10 03:04:27 cananian Exp $ 26 andyb 1.1.2.1 */ 27 andyb 1.1.2.1 public abstract class InstrFactory { 28 pnkfelix 1.1.2.8 /** Maintains a 29 pnkfelix 1.1.2.8 <code>Temp.Label</code><code>-></code><code>InstrLABEL</code> 30 pnkfelix 1.1.2.8 <code>Map</code> for <code>Instr</code>s constructed by 31 cananian 1.1.2.20 <code>this</code>. Used in dynamic <code>CFGraphable</code> 32 pnkfelix 1.1.2.10 successor resolution. 33 pnkfelix 1.1.2.8 */ 34 cananian 1.2.2.1 Map<Label,InstrLABEL> labelToInstrLABELmap=new HashMap<Label,InstrLABEL>(); 35 pnkfelix 1.1.2.10 36 pnkfelix 1.1.2.10 /** Maintains a 37 pnkfelix 1.1.2.10 <code>Temp.Label</code> <code>-></code> 38 pnkfelix 1.1.2.10 </code>Set</code><code>[</code> <code>Instr</code> <code>]</code> 39 pnkfelix 1.1.2.10 <code>Map</code> for <code>Instr</code>s constructed by 40 cananian 1.1.2.20 <code>this</code>. Used in dynamic <code>CFGraphable</code> 41 pnkfelix 1.1.2.10 predecessor resolution. 42 pnkfelix 1.1.2.11 Note that the <code>get(label)</code> method for this object 43 pnkfelix 1.1.2.11 will never return <code>null</code>; it will just create new 44 pnkfelix 1.1.2.11 empty sets as needed and return them instead. 45 pnkfelix 1.1.2.10 */ 46 cananian 1.2.2.1 Map<Label,Set<Instr>> labelToBranches = new HashMap<Label,Set<Instr>>() { 47 cananian 1.2.2.1 public Set<Instr> get(final Object key) { 48 cananian 1.2.2.1 Set<Instr> v = super.get(key); 49 pnkfelix 1.1.2.11 if (v != null) { 50 pnkfelix 1.1.2.11 return v; 51 pnkfelix 1.1.2.11 } else { 52 cananian 1.2.2.1 v = new HashSet<Instr>() 53 pnkfelix 1.1.2.15 /* { 54 pnkfelix 1.1.2.15 public boolean add(Object o) { 55 pnkfelix 1.1.2.15 System.out.println("Adding " + o + " to " + this); 56 pnkfelix 1.1.2.15 return super.add(o); 57 pnkfelix 1.1.2.15 } 58 pnkfelix 1.1.2.15 public String toString() { 59 pnkfelix 1.1.2.15 return "Set of Instrs branching->"+key; 60 pnkfelix 1.1.2.15 } 61 pnkfelix 1.1.2.15 } 62 pnkfelix 1.1.2.15 */ ; 63 cananian 1.2.2.1 put((Label)key, v); 64 pnkfelix 1.1.2.11 return v; 65 pnkfelix 1.1.2.11 } 66 pnkfelix 1.1.2.11 } 67 pnkfelix 1.1.2.11 }; 68 pnkfelix 1.1.2.12 69 pnkfelix 1.1.2.12 /** Caches the end of the instruction layout to allow for arbtrary 70 pnkfelix 1.1.2.12 code appending. 71 pnkfelix 1.1.2.12 */ 72 pnkfelix 1.1.2.12 Instr cachedTail = null; 73 pnkfelix 1.1.2.18 public Instr getTail() { 74 pnkfelix 1.1.2.18 if (cachedTail == null) return null; 75 pnkfelix 1.1.2.18 while(cachedTail.next != null) { 76 pnkfelix 1.1.2.18 cachedTail = cachedTail.next; 77 pnkfelix 1.1.2.18 } 78 pnkfelix 1.1.2.18 return cachedTail; 79 pnkfelix 1.1.2.18 } 80 pnkfelix 1.1.2.6 81 andyb 1.1.2.2 /** Returns the <code>TempFactory</code> to use for creating 82 andyb 1.1.2.2 * <code>Temp</code>s which are used as arguments to <code>Instr</code>s 83 andyb 1.1.2.2 * generated by this factory. */ 84 andyb 1.1.2.1 public abstract TempFactory tempFactory(); 85 andyb 1.1.2.1 86 andyb 1.1.2.2 /** Returns the <code>HCode</code> to which all <code>Instr</code>s 87 pnkfelix 1.1.2.5 * generated by this factory belong. 88 pnkfelix 1.1.2.5 */ 89 cananian 1.2.2.1 public abstract Code getParent(); 90 andyb 1.1.2.3 91 andyb 1.1.2.3 /** Returns the <code>Frame</code> which is associated with all 92 andyb 1.1.2.3 * of the <code>Instr</code>s generated by this factory. */ 93 andyb 1.1.2.3 public abstract Frame getFrame(); 94 andyb 1.1.2.1 95 andyb 1.1.2.2 /** Returns the <code>HMethod</code> which corresponds to 96 pnkfelix 1.1.2.5 <code>Instr</code>s generated by this factory. 97 pnkfelix 1.1.2.5 <BR><B>effects:</B> Returns the <code>HMethod</code> 98 pnkfelix 1.1.2.5 associated with <code>this</code>, or <code>null</code> if 99 pnkfelix 1.1.2.5 no such <code>HMethod</code> exists. 100 pnkfelix 1.1.2.5 */ 101 andyb 1.1.2.1 public HMethod getMethod() { return getParent().getMethod(); } 102 andyb 1.1.2.1 103 andyb 1.1.2.2 /** Returns a unique ID number for each new <code>Instr</code> 104 andyb 1.1.2.2 * generated by this factory. */ 105 andyb 1.1.2.2 public abstract int getUniqueID(); 106 andyb 1.1.2.1 107 andyb 1.1.2.2 /** Returns a human-readable representation for this 108 andyb 1.1.2.2 * <code>InstrFactory</code>. */ 109 andyb 1.1.2.1 public String toString() { 110 cananian 1.1.2.17 return "InstrFactory["+getParent()+"]"; 111 andyb 1.1.2.1 } 112 cananian 1.1.2.17 113 cananian 1.1.2.17 public int hashCode() { return getParent().getName().hashCode(); } 114 pnkfelix 1.1.2.21 115 cananian 1.2.2.1 class ToMap extends HashMap<InstrGroup.Type,Map> { 116 cananian 1.2.2.1 public Map getMap(InstrGroup.Type key) { 117 cananian 1.2.2.1 Map m = get(key); 118 pnkfelix 1.1.2.21 if (m == null) { m = new HashMap(); super.put(key, m); } 119 pnkfelix 1.1.2.21 return m; 120 pnkfelix 1.1.2.21 } 121 pnkfelix 1.1.2.21 } 122 pnkfelix 1.1.2.21 private ToMap typeToInstrToGroup = new ToMap(); 123 pnkfelix 1.1.2.21 124 pnkfelix 1.1.2.21 /** Adds information from <code>group</code> to the 125 pnkfelix 1.1.2.21 InstrGroup.Type -> CFGrapher mapping for <code>this</code>. 126 pnkfelix 1.1.2.21 <BR> <B>requires:</B> <code>group</code> has had its entry and 127 pnkfelix 1.1.2.21 exit fields assigned. 128 pnkfelix 1.1.2.21 */ 129 pnkfelix 1.1.2.21 public void addGroup(InstrGroup group) { 130 pnkfelix 1.1.2.21 Map m = typeToInstrToGroup.getMap(group.type); 131 pnkfelix 1.1.2.21 m.put(group.entry, group); 132 pnkfelix 1.1.2.21 m.put(group.exit, group); 133 pnkfelix 1.1.2.21 } 134 pnkfelix 1.1.2.21 135 pnkfelix 1.1.2.21 /** Returns a <code>CFGrapher</code> that treats 136 pnkfelix 1.1.2.21 <code>InstrGroup</code>s of <code>Type</code> 137 pnkfelix 1.1.2.21 <code>t</code> as single atomic elements. 138 pnkfelix 1.1.2.21 */ 139 cananian 1.2.2.1 public CFGrapher<Instr> getGrapherFor(InstrGroup.Type t) { 140 cananian 1.2.2.1 final Map<Instr,InstrGroup> i2g = typeToInstrToGroup.getMap(t); 141 pnkfelix 1.1.2.21 return new InstrGroup.GroupGrapher(i2g); 142 pnkfelix 1.1.2.21 } 143 pnkfelix 1.1.2.21 144 pnkfelix 1.1.2.21 /** Returns a <code>UseDefer</code> that treats 145 pnkfelix 1.1.2.21 <code>InstrGroup</code>s of <code>Type</code> 146 pnkfelix 1.1.2.21 <code>t</code> as single atomic elements. 147 pnkfelix 1.1.2.21 */ 148 cananian 1.2.2.1 public UseDefer<Instr> getUseDeferFor(InstrGroup.Type t) { 149 cananian 1.2.2.1 final Map<Instr,InstrGroup> i2g = typeToInstrToGroup.getMap(t); 150 pnkfelix 1.1.2.21 return new InstrGroup.GroupUseDefer(i2g, t); 151 pnkfelix 1.1.2.21 } 152 pnkfelix 1.1.2.21 153 cananian 1.2 }