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      }