1 cananian   1.1.2.21 // Instr.java, created Mon Feb  8  0:33:19 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 andyb      1.1.2.2  import harpoon.ClassFile.HCodeElement;
   7 duncan     1.1.2.66 import harpoon.IR.Properties.CFGEdge;
   8 cananian   1.1.2.61 import harpoon.IR.Properties.CFGraphable;
   9 cananian   1.1.2.84 import harpoon.IR.Properties.UseDefable;
  10 andyb      1.1.2.6  import harpoon.Temp.Label;
  11 andyb      1.1.2.1  import harpoon.Temp.Temp;
  12 andyb      1.1.2.11 import harpoon.Temp.TempMap;
  13 andyb      1.1.2.11 import harpoon.Util.ArrayFactory;
  14 cananian   1.10     import net.cscott.jutil.CombineIterator;
  15 cananian   1.10     import net.cscott.jutil.Default;
  16 andyb      1.1.2.12 import harpoon.Util.Util;
  17 cananian   1.10     import net.cscott.jutil.UnmodifiableIterator;
  18 andyb      1.1.2.12 
  19 cananian   1.9      import java.util.AbstractCollection;
  20 cananian   1.9      import java.util.AbstractList;
  21 cananian   1.9      import java.util.ArrayList;
  22 pnkfelix   1.1.2.34 import java.util.Arrays;
  23 cananian   1.9      import java.util.Collection;
  24 cananian   1.9      import java.util.Collections;
  25 pnkfelix   1.1.2.28 import java.util.Enumeration;
  26 cananian   1.9      import java.util.HashSet;
  27 pnkfelix   1.1.2.28 import java.util.Iterator;
  28 cananian   1.9      import java.util.List;
  29 cananian   1.9      import java.util.Set;
  30 cananian   1.9      import java.util.Vector;
  31 andyb      1.1.2.1  
  32 andyb      1.1.2.1  /**
  33 andyb      1.1.2.12  * <code>Instr</code> is the primary class for representing
  34 andyb      1.1.2.11  * assembly-level instructions used in the Backend.* packages.
  35 andyb      1.1.2.1   *
  36 pnkfelix   1.1.2.67  * Important Note: Most <code>Instr</code>s have only one predecessor.
  37 pnkfelix   1.1.2.67  * One type of <code>Instr</code> with potentially more than one
  38 pnkfelix   1.1.2.67  * predecessor is an <code>InstrLABEL</code>.  In any case, any code
  39 pnkfelix   1.1.2.67  * that relies on the "only one predecessor"-invariant must check each
  40 pnkfelix   1.1.2.67  * <code>Instr</code> with <code>hasMultiplePredecessors()</code>.
  41 pnkfelix   1.1.2.67  * Likewise, extensions of <code>Instr</code> which are designed to
  42 pnkfelix   1.1.2.67  * allow multiple predecessors must override <code>predC()</code> and
  43 pnkfelix   1.1.2.67  * <code>hasMultiplePredecessors()</code>
  44 pnkfelix   1.1.2.35  * 
  45 andyb      1.1.2.1   * @author  Andrew Berkheimer <andyb@mit.edu>
  46 cananian   1.1.2.86  * @author  Felix S. Klock II <pnkfelix@mit.edu>
  47 cananian   1.11      * @version $Id: Instr.java,v 1.11 2004/02/08 05:09:51 cananian Exp $ */
  48 cananian   1.7      public class Instr implements HCodeElement, UseDefable,
  49 cananian   1.7                                    CFGraphable<Instr,InstrEdge> {
  50 pnkfelix   1.1.2.74     private static boolean PRINT_UPDATES_TO_IR = false;
  51 pnkfelix   1.1.2.74     private static boolean PRINT_REPLACES = false || PRINT_UPDATES_TO_IR;
  52 pnkfelix   1.1.2.74     private static boolean PRINT_INSERTS = false || PRINT_UPDATES_TO_IR;
  53 pnkfelix   1.1.2.74     private static boolean PRINT_REMOVES = false || PRINT_UPDATES_TO_IR;
  54 pnkfelix   1.1.2.74 
  55 pnkfelix   1.1.2.63     private final String assem; 
  56 andyb      1.1.2.12     private InstrFactory inf;
  57 andyb      1.1.2.12 
  58 pnkfelix   1.1.2.85     private InstrGroup groupList = null;
  59 pnkfelix   1.1.2.85     boolean partOf(InstrGroup.Type t) {
  60 pnkfelix   1.1.2.85         InstrGroup curr = groupList;
  61 pnkfelix   1.1.2.85         while(curr != null) {
  62 pnkfelix   1.1.2.85             if (curr.type == t) 
  63 pnkfelix   1.1.2.85                 return true;
  64 pnkfelix   1.1.2.85             curr = curr.containedIn;
  65 pnkfelix   1.1.2.85         }
  66 pnkfelix   1.1.2.85         return false;
  67 pnkfelix   1.1.2.85     }
  68 pnkfelix   1.1.2.85     /** Sets the InstrGroup sequence associated with
  69 pnkfelix   1.1.2.85         <code>this</code>.  
  70 pnkfelix   1.1.2.85         <BR><B>requires:</B> <code>this</code> is not 
  71 pnkfelix   1.1.2.85             associated with any group.
  72 pnkfelix   1.1.2.85     */
  73 pnkfelix   1.1.2.85     public void setGroup(InstrGroup seq) {
  74 cananian   1.3.2.1          assert groupList == null || groupList == seq : " current group: "+groupList+
  75 cananian   1.3.2.1                      " setGroup( "+seq+" )";
  76 pnkfelix   1.1.2.85         // this actually isn't as conservative as we could be, since
  77 pnkfelix   1.1.2.85         // <seq> can be null.
  78 pnkfelix   1.1.2.85 
  79 pnkfelix   1.1.2.85         groupList = seq;
  80 pnkfelix   1.1.2.85     }
  81 pnkfelix   1.1.2.85     /** Returns the Set of InstrGroups that this is an element of. */
  82 cananian   1.7          public Set<InstrGroup> getGroups() {
  83 cananian   1.7              Set<InstrGroup> set = new HashSet<InstrGroup>();
  84 pnkfelix   1.1.2.85         InstrGroup curr = groupList;
  85 pnkfelix   1.1.2.85         while(curr != null) {
  86 pnkfelix   1.1.2.85             set.add(curr);
  87 pnkfelix   1.1.2.85             curr = curr.containedIn;
  88 pnkfelix   1.1.2.85         }
  89 pnkfelix   1.1.2.85         return set;
  90 pnkfelix   1.1.2.85     }
  91 pnkfelix   1.1.2.85     /** Returns the entry <code>Instr</code> when the
  92 pnkfelix   1.1.2.85         instructions are being viewed as collected by
  93 pnkfelix   1.1.2.85         <code>type</code>.  Note that if <code>this</code> is not
  94 pnkfelix   1.1.2.85         contained in any member of <code>type</code>, then
  95 pnkfelix   1.1.2.85         <code>this</code> is its own group, and thus
  96 pnkfelix   1.1.2.85         <code>this</code> is returned.
  97 pnkfelix   1.1.2.85      */
  98 pnkfelix   1.1.2.85     public Instr getEntry(InstrGroup.Type type) {
  99 pnkfelix   1.1.2.85         return getRep(type, false);
 100 pnkfelix   1.1.2.85     }
 101 pnkfelix   1.1.2.85     /** Returns the exit <code>Instr</code> when the
 102 pnkfelix   1.1.2.85         instructions are being viewed as collected by
 103 pnkfelix   1.1.2.85         <code>type</code>.  Note that if <code>this</code> is not
 104 pnkfelix   1.1.2.85         contained in any member of <code>type</code>, then
 105 pnkfelix   1.1.2.85         <code>this</code> is its own group, and thus
 106 pnkfelix   1.1.2.85         <code>this</code> is returned.
 107 pnkfelix   1.1.2.85      */
 108 pnkfelix   1.1.2.85     public Instr getExit(InstrGroup.Type type) {
 109 pnkfelix   1.1.2.85         Instr i = getRep(type, true);
 110 pnkfelix   1.1.2.85         return i;
 111 pnkfelix   1.1.2.85     }
 112 pnkfelix   1.1.2.85     private Instr getRep(InstrGroup.Type type, boolean retExit) {
 113 pnkfelix   1.1.2.85         InstrGroup curr = groupList;
 114 pnkfelix   1.1.2.85         while(curr != null) {
 115 pnkfelix   1.1.2.85             if (curr.type == type) {
 116 pnkfelix   1.1.2.85                 return retExit?curr.exit:curr.entry;
 117 pnkfelix   1.1.2.85             } else {
 118 pnkfelix   1.1.2.85                 curr = curr.containedIn;
 119 pnkfelix   1.1.2.85             }
 120 pnkfelix   1.1.2.85         }
 121 pnkfelix   1.1.2.85         // got here, no containing group is a member of <type>
 122 pnkfelix   1.1.2.85         return this;
 123 pnkfelix   1.1.2.85     }
 124 pnkfelix   1.1.2.85 
 125 pnkfelix   1.1.2.78     private final Temp[] dst;
 126 pnkfelix   1.1.2.78     private final Temp[] src;
 127 andyb      1.1.2.3  
 128 andyb      1.1.2.12     private int hashCode;
 129 andyb      1.1.2.12 
 130 andyb      1.1.2.12     // for implementing HCodeElement
 131 andyb      1.1.2.12     private String source_file;
 132 andyb      1.1.2.12     private int source_line;
 133 andyb      1.1.2.12     private int id;
 134 andyb      1.1.2.12 
 135 pnkfelix   1.1.2.29     /** The <code>Instr</code> that is output prior to
 136 pnkfelix   1.1.2.36         <code>this</code>.  Should be <code>null</code> if
 137 pnkfelix   1.1.2.36         <code>this</code> is the first instruction in the method or if
 138 pnkfelix   1.1.2.36         <code>this</code> has not been inserted into an instruction
 139 duncan     1.1.2.66         stream (ie. <code>insertAt(CFGEdge)</code> has not been
 140 pnkfelix   1.1.2.36         called since the last call to <code>remove()</code> or since
 141 pnkfelix   1.1.2.36         construction). 
 142 pnkfelix   1.1.2.29     */
 143 pnkfelix   1.1.2.40     protected Instr prev;
 144 pnkfelix   1.1.2.36 
 145 pnkfelix   1.1.2.29     /** The <code>Instr</code> that is output prior to
 146 pnkfelix   1.1.2.36         <code>this</code>.  Should be <code>null</code> if
 147 pnkfelix   1.1.2.36         <code>this</code> is the first instruction in the method or if
 148 pnkfelix   1.1.2.36         <code>this</code> has not been inserted into an instruction
 149 duncan     1.1.2.66         stream (ie. <code>insertAt(CFGEdge)</code> has not been
 150 pnkfelix   1.1.2.36         called since the last call to <code>remove()</code> or since
 151 pnkfelix   1.1.2.36         construction).
 152 pnkfelix   1.1.2.29     */
 153 pnkfelix   1.1.2.29     public Instr getPrev() { return prev; }
 154 pnkfelix   1.1.2.26 
 155 pnkfelix   1.1.2.26     /** The next <code>Instr</code> to output after
 156 pnkfelix   1.1.2.29         <code>this</code>.  <code>next</code> can be significant
 157 pnkfelix   1.1.2.26         for control flow, depending on if
 158 pnkfelix   1.1.2.29         <code>this.canFallThrough</code>.  Should be <code>null</code>
 159 pnkfelix   1.1.2.36         if <code>this</code> is the last instruction in the method or
 160 pnkfelix   1.1.2.36         if <code>this</code> has not been inserted into an instruction
 161 duncan     1.1.2.66         stream (ie. <code>insertAt(CFGEdge)</code> has not been
 162 pnkfelix   1.1.2.36         called since the last call to <code>remove()</code> or since
 163 pnkfelix   1.1.2.36         construction).
 164 pnkfelix   1.1.2.26     */
 165 pnkfelix   1.1.2.40     protected Instr next;
 166 pnkfelix   1.1.2.35 
 167 pnkfelix   1.1.2.29     /** The next <code>Instr</code> to output after
 168 pnkfelix   1.1.2.29         <code>this</code>.  <code>next</code> can be significant
 169 pnkfelix   1.1.2.29         for control flow, depending on if
 170 pnkfelix   1.1.2.29         <code>this.canFallThrough</code>.  Should be <code>null</code>
 171 pnkfelix   1.1.2.36         if <code>this</code> is the last instruction in the method or
 172 pnkfelix   1.1.2.36         if <code>this</code> has not been inserted into an instruction
 173 duncan     1.1.2.66         stream (ie. <code>insertAt(CFGEdge)</code> has not been
 174 pnkfelix   1.1.2.36         called since the last call to <code>remove()</code> or since
 175 pnkfelix   1.1.2.36         construction).
 176 pnkfelix   1.1.2.36         @see Instr#canFallThrough
 177 pnkfelix   1.1.2.29     */
 178 pnkfelix   1.1.2.29     public Instr getNext() { return next; }
 179 pnkfelix   1.1.2.26 
 180 pnkfelix   1.1.2.26     /** Sets whether control flow can go to <code>this.next</code>.  
 181 pnkfelix   1.1.2.49         Note that if <code>
 182 pnkfelix   1.1.2.51         <nobr>(!this.canFallThrough)</nobr> && 
 183 pnkfelix   1.1.2.51         <nobr>(this.targets == null)</nobr>
 184 pnkfelix   1.1.2.49         </code>
 185 pnkfelix   1.1.2.26         then <code>this</code> represents an exit point for the code
 186 pnkfelix   1.1.2.26         and should be treated as such for data flow analysis, etc.
 187 pnkfelix   1.1.2.36         @see Instr#getNext
 188 pnkfelix   1.1.2.26     */
 189 pnkfelix   1.1.2.29     public final boolean canFallThrough;
 190 pnkfelix   1.1.2.26 
 191 cananian   1.3.2.2      private List<Label> targets;
 192 pnkfelix   1.1.2.26     /** List of target labels that <code>this</code> can branch to.
 193 pnkfelix   1.1.2.29         <code>getTargets()</code> may be empty (in which case control
 194 pnkfelix   1.1.2.26         flow either falls through to the <code>this.next</code> (the
 195 pnkfelix   1.1.2.29         case if <code>this.canFallThrough</code>), or returns to some
 196 pnkfelix   1.1.2.29         unknown <code>Instr</code> (the case for 'return'
 197 pnkfelix   1.1.2.29         statements)). 
 198 pnkfelix   1.1.2.26         @see Instr#canFallThrough
 199 pnkfelix   1.1.2.36         @see Instr#getNext
 200 pnkfelix   1.1.2.50         @see Instr#hasModifiableTargets 
 201 pnkfelix   1.1.2.60         @return A <code>List</code> of <code>Label</code>s.
 202 pnkfelix   1.1.2.26     */
 203 cananian   1.3.2.2      public List<Label> getTargets() {
 204 pnkfelix   1.1.2.29         if (targets != null) {
 205 pnkfelix   1.1.2.29             if (this.hasModifiableTargets()) {
 206 pnkfelix   1.1.2.29                 return targets;
 207 pnkfelix   1.1.2.29             } else {
 208 pnkfelix   1.1.2.29                 return Collections.unmodifiableList(targets);
 209 pnkfelix   1.1.2.29             }
 210 pnkfelix   1.1.2.29         } else {
 211 pnkfelix   1.1.2.29             // (targets == null) ==> empty list
 212 pnkfelix   1.1.2.29             return Collections.EMPTY_LIST;
 213 pnkfelix   1.1.2.29         }
 214 pnkfelix   1.1.2.29     }
 215 pnkfelix   1.1.2.26 
 216 pnkfelix   1.1.2.60     /** Returns the <code>InstrLABEL</code> associated with
 217 pnkfelix   1.1.2.60         <code>l</code> in the <code>InstrFactory</code> for
 218 pnkfelix   1.1.2.60         <code>this</code>. 
 219 pnkfelix   1.1.2.60     */
 220 pnkfelix   1.1.2.60     public InstrLABEL getInstrFor(Label l) {
 221 cananian   1.3.2.2          return inf.labelToInstrLABELmap.get(l);
 222 pnkfelix   1.1.2.60     }
 223 pnkfelix   1.1.2.60 
 224 andyb      1.1.2.12     /** Defines an array factory which can be used to generate
 225 pnkfelix   1.1.2.26         arrays of <code>Instr</code>s. 
 226 pnkfelix   1.1.2.26     */
 227 cananian   1.3.2.2      public static final ArrayFactory<Instr> arrayFactory =
 228 cananian   1.3.2.2          new ArrayFactory<Instr>() {
 229 cananian   1.3.2.2              public Instr[] newArray(int len) { return new Instr[len]; }
 230 andyb      1.1.2.12         };
 231 andyb      1.1.2.12 
 232 andyb      1.1.2.12     // *************** CONSTRUCTORS *****************
 233 andyb      1.1.2.12 
 234 pnkfelix   1.1.2.26     /** Creates an <code>Instr</code> consisting of the
 235 pnkfelix   1.1.2.26         <code>String</code> <code>assem</code> and the list of
 236 pnkfelix   1.1.2.26         destinations and sources in <code>dst</code> and
 237 pnkfelix   1.1.2.26         <code>src</code>.
 238 pnkfelix   1.1.2.26         @param inf <code>InstrFactory</code> for <code>this</code>
 239 pnkfelix   1.1.2.26         @param source <code>HCodeElement</code> that was the source
 240 pnkfelix   1.1.2.36                       for <code>this</code>
 241 pnkfelix   1.1.2.26         @param assem Assembly code string for <code>this</code>
 242 pnkfelix   1.1.2.26         @param dst Set of <code>Temp</code>s that may be written to in
 243 pnkfelix   1.1.2.36                    the execution of <code>this</code>.
 244 pnkfelix   1.1.2.26         @param src Set of <code>Temp</code>s that may be read from in 
 245 pnkfelix   1.1.2.36                    the execution of <code>this</code>.
 246 pnkfelix   1.1.2.26         @param canFallThrough Decides whether control flow could fall
 247 pnkfelix   1.1.2.36                               to <code>this.next</code>.
 248 pnkfelix   1.1.2.39         @param targets List of target <code>Label</code>s that control
 249 pnkfelix   1.1.2.39                        flow could potentially branch to.  If
 250 pnkfelix   1.1.2.39                        <code>targets</code> is <code>null</code>, then
 251 pnkfelix   1.1.2.39                        <code>this</code> is a non-branching instruction.
 252 pnkfelix   1.1.2.26     */
 253 andyb      1.1.2.5      public Instr(InstrFactory inf, HCodeElement source, 
 254 pnkfelix   1.1.2.26                  String assem, Temp[] dst, Temp[] src,
 255 cananian   1.3.2.2                   boolean canFallThrough, List<Label> targets) {
 256 cananian   1.3.2.1          assert !assem.trim().equals("FSK-LD `d0, `s0 `d0, `s0");
 257 pnkfelix   1.1.2.75 
 258 cananian   1.3.2.1          assert inf != null;
 259 cananian   1.3.2.1          assert assem != null;
 260 cananian   1.3.2.1          // assert dst!=null && src!=null : "DST and SRC should not = null";
 261 pnkfelix   1.1.2.14         if (src == null) src = new Temp[0];
 262 pnkfelix   1.1.2.14         if (dst == null) dst = new Temp[0];
 263 andyb      1.1.2.12         
 264 andyb      1.1.2.3          this.source_file = (source != null)?source.getSourceFile():"unknown";
 265 cananian   1.1.2.56         this.source_line = (source != null)?source.getLineNumber(): 0;
 266 andyb      1.1.2.3          this.id = inf.getUniqueID();
 267 andyb      1.1.2.3          this.inf = inf;
 268 pnkfelix   1.1.2.53 
 269 pnkfelix   1.1.2.53         // update tail for instrFactory
 270 pnkfelix   1.1.2.53         if (inf.cachedTail == null) {
 271 pnkfelix   1.1.2.53             inf.cachedTail = this;
 272 pnkfelix   1.1.2.53         }
 273 andyb      1.1.2.3          this.assem = assem; this.dst = dst; this.src = src;
 274 andyb      1.1.2.12 
 275 cananian   1.1.2.48         this.hashCode = (id<<5) + inf.hashCode();
 276 pnkfelix   1.1.2.23         if (inf.getMethod() != null) {
 277 pnkfelix   1.1.2.23             this.hashCode ^= inf.getMethod().hashCode(); 
 278 pnkfelix   1.1.2.23         }
 279 pnkfelix   1.1.2.26 
 280 pnkfelix   1.1.2.29         this.canFallThrough = canFallThrough;
 281 pnkfelix   1.1.2.29         this.targets = targets;
 282 pnkfelix   1.1.2.60 
 283 pnkfelix   1.1.2.74         checkForNull(this.src);
 284 pnkfelix   1.1.2.74         checkForNull(this.dst);
 285 pnkfelix   1.1.2.60     }
 286 pnkfelix   1.1.2.60 
 287 pnkfelix   1.1.2.60     private void checkForNull(Temp[] ts) {
 288 pnkfelix   1.1.2.60         for(int i=0; i<ts.length; i++) {
 289 cananian   1.3.2.1              assert ts[i] != null : "Temp index "+i+" is null in "+ this;
 290 pnkfelix   1.1.2.60         }
 291 pnkfelix   1.1.2.26     }
 292 pnkfelix   1.1.2.26 
 293 pnkfelix   1.1.2.29     /** Creates an <code>Instr</code> consisting of the
 294 pnkfelix   1.1.2.29         <code>String</code> <code>assem</code> and the lists of
 295 pnkfelix   1.1.2.29         destinations and sources in <code>dst</code> and
 296 pnkfelix   1.1.2.29         <code>src</code>. 
 297 pnkfelix   1.1.2.39         <code>canFallThrough</code> is set to <code>true</code> and
 298 pnkfelix   1.1.2.39         <code>targets</code> is set to <code>null</code>. 
 299 pnkfelix   1.1.2.29     */    
 300 pnkfelix   1.1.2.26     public Instr(InstrFactory inf, HCodeElement source, 
 301 pnkfelix   1.1.2.27                  String assem, Temp[] dst, Temp[] src) {
 302 pnkfelix   1.1.2.26         this(inf, source, assem, dst, src, true, null);
 303 andyb      1.1.2.6      }
 304 andyb      1.1.2.6  
 305 andyb      1.1.2.12     /** Creates an <code>Instr</code> consisting of the String assem
 306 pnkfelix   1.1.2.39         and the list of sources in src. The list of destinations is
 307 pnkfelix   1.1.2.39         empty. 
 308 pnkfelix   1.1.2.39         <code>canFallThrough</code> is set to <code>true</code> and
 309 pnkfelix   1.1.2.39         <code>targets</code> is set to <code>null</code>.
 310 pnkfelix   1.1.2.39     */
 311 andyb      1.1.2.6      public Instr(InstrFactory inf, HCodeElement source,
 312 pnkfelix   1.1.2.27                  String assem, Temp[] src) {
 313 andyb      1.1.2.12         this(inf, source, assem, null, src);
 314 andyb      1.1.2.12     }
 315 andyb      1.1.2.6  
 316 andyb      1.1.2.12     /** Creates an <code>Instr</code> consisting of the String assem.
 317 pnkfelix   1.1.2.39         The lists of sources and destinations are empty. 
 318 pnkfelix   1.1.2.39         <code>canFallThrough</code> is set to <code>true</code> and
 319 pnkfelix   1.1.2.39         <code>targets</code> is set to <code>null</code>.
 320 pnkfelix   1.1.2.39     */
 321 andyb      1.1.2.12     public Instr(InstrFactory inf, HCodeElement source, String assem) {
 322 andyb      1.1.2.12         this(inf, source, assem, null, null);
 323 andyb      1.1.2.12     }
 324 andyb      1.1.2.12 
 325 andyb      1.1.2.12     // ********* INSTR METHODS ********
 326 andyb      1.1.2.12 
 327 pnkfelix   1.1.2.16     /** Replaces <code>oldi</code> in the Instruction Stream with
 328 pnkfelix   1.1.2.29         <code>newis</code>.  
 329 pnkfelix   1.1.2.29         <BR> <B>requires:</B> 
 330 pnkfelix   1.1.2.29              <OL>
 331 pnkfelix   1.1.2.29              <LI> <code>oldi</code> is a non-branching instruction 
 332 pnkfelix   1.1.2.29              <LI> <code>newis</code> is a <code>List</code> of
 333 pnkfelix   1.1.2.29              instructions such that the elements of <code>newis</code>
 334 pnkfelix   1.1.2.29              form a basic block. (this constraint may be weakened
 335 pnkfelix   1.1.2.29              later if necessary)  
 336 pnkfelix   1.1.2.29              </OL>
 337 pnkfelix   1.1.2.29         <BR> <B>modifies:</B> <code>oldi.prev</code>, <code>oldi.next</code>
 338 pnkfelix   1.1.2.29         <BR> <B>effects:</B> Modifies the <code>Instr</code>s
 339 pnkfelix   1.1.2.29              immediately dominating and succeeding <code>oldi</code>
 340 pnkfelix   1.1.2.29              as to substitute <code>newis</code> in the place of
 341 pnkfelix   1.1.2.29              <code>oldi</code>.   
 342 pnkfelix   1.1.2.16     */
 343 pnkfelix   1.1.2.64     public static void replaceInstrList(final Instr oldi, final List newis) {
 344 pnkfelix   1.1.2.65         // System.out.println("("+oldi.prev+") "+oldi+" ("+oldi.next+")" + " -> " + newis); 
 345 cananian   1.3.2.1          assert oldi != null && newis != null : "Null Arguments are bad";
 346 cananian   1.3.2.1          assert oldi.canFallThrough &&
 347 cananian   1.3.2.1                      oldi.getTargets().isEmpty() : "oldi must be a nonbranching instruction.";
 348 pnkfelix   1.1.2.65 
 349 pnkfelix   1.1.2.65         // There's something wrong, either with my code or with the
 350 pnkfelix   1.1.2.65         // jikes compiler, but it does CRAZY shit if i leave this in...
 351 cananian   1.3.2.1          //assert isLinear(newis) : "newis must be a basic block: "+pprint(newis);
 352 pnkfelix   1.1.2.29         
 353 cananian   1.6              // increment parent's modification count (for fail-fast iterator)
 354 cananian   1.6              oldi.inf.getParent().modCount++;
 355 cananian   1.6      
 356 pnkfelix   1.1.2.65         Instr last = oldi.prev;
 357 cananian   1.11             for (Object iO : newis) { 
 358 cananian   1.11                 Instr i = (Instr) iO;
 359 pnkfelix   1.1.2.65             if (last != null) last.next = i;
 360 pnkfelix   1.1.2.65             i.prev = last;
 361 pnkfelix   1.1.2.65             last = i;
 362 pnkfelix   1.1.2.46         }
 363 pnkfelix   1.1.2.65         last.next = oldi.next;
 364 pnkfelix   1.1.2.65         if (oldi.next != null) oldi.next.prev = last;
 365 pnkfelix   1.1.2.16     }
 366 pnkfelix   1.1.2.16 
 367 cananian   1.11         private static String pprint(List<Instr> l) {
 368 pnkfelix   1.1.2.41         String s="";
 369 cananian   1.11             for (Instr i : l) {
 370 pnkfelix   1.1.2.41             s += i.toString() + "\n";
 371 pnkfelix   1.1.2.41         }
 372 pnkfelix   1.1.2.41         return s;
 373 pnkfelix   1.1.2.41     }
 374 pnkfelix   1.1.2.41 
 375 pnkfelix   1.1.2.29     /** Helper method to ensure that <code>instrs</code> is
 376 pnkfelix   1.1.2.29         effectively a basic block. 
 377 pnkfelix   1.1.2.41         Checks: each Instr 'i' in 'instrs' has only one successor
 378 pnkfelix   1.1.2.41         (with regards to Control Flow) except for the last, which
 379 pnkfelix   1.1.2.41         should be non-branching and have no next.
 380 pnkfelix   1.1.2.64         
 381 pnkfelix   1.1.2.64         This method actually requires instrs be linear right now;
 382 pnkfelix   1.1.2.64         its more of a assertion macro than an actual information
 383 pnkfelix   1.1.2.64         extraction method. 
 384 pnkfelix   1.1.2.29     */
 385 pnkfelix   1.1.2.29     private static boolean isLinear(List instrs) {
 386 pnkfelix   1.1.2.29         boolean linear = true;
 387 pnkfelix   1.1.2.64         Instr i = (Instr) instrs.get(0);
 388 pnkfelix   1.1.2.29         Instr next = null;
 389 pnkfelix   1.1.2.29 
 390 pnkfelix   1.1.2.64         final Iterator iter = instrs.iterator();
 391 pnkfelix   1.1.2.64         while(iter.hasNext()) {
 392 pnkfelix   1.1.2.64             Instr iterInstr = (Instr) iter.next();
 393 pnkfelix   1.1.2.64             
 394 cananian   1.3.2.1              assert iterInstr == i : "list "+instrs+" is nonlinear";
 395 pnkfelix   1.1.2.64 
 396 pnkfelix   1.1.2.46             int size = i.succC().size();
 397 cananian   1.3.2.1              assert size >= 0 : "size should always be >= 0";
 398 pnkfelix   1.1.2.46             if (size == 0) {
 399 pnkfelix   1.1.2.41                 // reached the end (I hope)
 400 cananian   1.3.2.1                  assert i.next == null : "last should have next == null";
 401 cananian   1.3.2.1                  assert i.targets == null : "last should have targets == null";
 402 cananian   1.3.2.1                  assert !iter.hasNext() : "last should have nothing left in iter "+iter.next();
 403 pnkfelix   1.1.2.41                 break;
 404 pnkfelix   1.1.2.41             }
 405 cananian   1.3.2.2              /* XXX CSA: this code is broken: succC().iterator().next() will
 406 cananian   1.3.2.2               * return an InstrEdge, not an Instr; not quite sure what this
 407 cananian   1.3.2.2               * code was supposed to do/how to fix it. ***
 408 pnkfelix   1.1.2.46             Instr n = (Instr) i.succC().iterator().next();
 409 pnkfelix   1.1.2.46             if (i.next != n ||
 410 pnkfelix   1.1.2.46                 size > 1) {
 411 pnkfelix   1.1.2.29                 linear = false;
 412 cananian   1.3.2.1                  //assert false : "Instr " + i + " is nonlinear";
 413 pnkfelix   1.1.2.41                 break;
 414 pnkfelix   1.1.2.29             }
 415 cananian   1.3.2.2              */assert false : "this code is broken";
 416 pnkfelix   1.1.2.29         }
 417 pnkfelix   1.1.2.29 
 418 pnkfelix   1.1.2.29         return linear;
 419 pnkfelix   1.1.2.29     }
 420 pnkfelix   1.1.2.29     
 421 pnkfelix   1.1.2.41     /** Not implemented yet. */
 422 duncan     1.1.2.66     public static void insertInstrsAt(CFGEdge edge, List instrs) {
 423 cananian   1.3.2.1          assert false;
 424 pnkfelix   1.1.2.41     }
 425 pnkfelix   1.1.2.41 
 426 pnkfelix   1.1.2.40     /** Inserts <code>this</code> at <code>edge</code>.  The purpose 
 427 pnkfelix   1.1.2.51         of this insertion is to modify <I>control flow</I>, rather than just
 428 duncan     1.1.2.66         instruction layout.  See <code>layout(CFGEdge)</code> for
 429 pnkfelix   1.1.2.40         direct modification of layout (which is less constrained than
 430 pnkfelix   1.1.2.40         this method but is not intended for generic program
 431 pnkfelix   1.1.2.40         transformation use.
 432 pnkfelix   1.1.2.29         <BR> <B>requires:</B> <OL>
 433 pnkfelix   1.1.2.29              <LI> <code>edge.from()</code> and <code>edge.to()</code>
 434 pnkfelix   1.1.2.36                   are instances of <code>Instr</code> or one is
 435 pnkfelix   1.1.2.36                   <code>null</code> and the other is an instance of
 436 pnkfelix   1.1.2.36                   <code>Instr</code>.  
 437 pnkfelix   1.1.2.29              <LI> if <code>edge.from()</code> is not
 438 pnkfelix   1.1.2.36                   <code>null</code>, then
 439 pnkfelix   1.1.2.40                   <code>edge.from().hasModifiableTargets()</code>.   
 440 pnkfelix   1.1.2.33              <LI> if <code>edge.from()</code> and
 441 pnkfelix   1.1.2.36                   <code>edge.to()</code> are not <code>null</code>,
 442 pnkfelix   1.1.2.36                   then <code>edge.to()</code> is a successor of    
 443 pnkfelix   1.1.2.36                   <code>edge.from()</code>.
 444 pnkfelix   1.1.2.34              <LI> <code>this</code> is a non-branching instruction
 445 pnkfelix   1.1.2.40                   (ie, <code>this.targets</code> equals
 446 pnkfelix   1.1.2.40                   <code>null</code> and
 447 pnkfelix   1.1.2.40                   <code>this.canFallThrough</code>). 
 448 pnkfelix   1.1.2.36              <LI> <code>this</code> is not currently in an instruction
 449 pnkfelix   1.1.2.51                   stream (ie <code>
 450 pnkfelix   1.1.2.51                   <nobr>this.getPrev() == null</nobr></code> and <code>
 451 pnkfelix   1.1.2.51                   <nobr>this.getNext() == null</nobr></code>).  This
 452 pnkfelix   1.1.2.51                   is true for newly created <code>Instr</code>s and
 453 pnkfelix   1.1.2.51                   for <code>Instr</code> which have just had their
 454 pnkfelix   1.1.2.51                   <code>remove()</code> method called. 
 455 pnkfelix   1.1.2.29         </OL>
 456 pnkfelix   1.1.2.34         <BR> <B>modifies:</B> <code>edge.from()</code>, 
 457 pnkfelix   1.1.2.34              <code>edge.to()</code>, <code>this</code>
 458 pnkfelix   1.1.2.36         <BR> <B>effects:</B> changes <code>edge.from()</code> and 
 459 pnkfelix   1.1.2.29              <code>edge.to()</code> so that after
 460 pnkfelix   1.1.2.34              <code>edge.from()</code> is executed, <code>this</code>
 461 pnkfelix   1.1.2.29              will be executed and then followed by
 462 pnkfelix   1.1.2.29              <code>edge.to()</code>.
 463 pnkfelix   1.1.2.36         @see Instr#remove
 464 pnkfelix   1.1.2.29     */
 465 duncan     1.1.2.66     public void insertAt(CFGEdge edge) {
 466 cananian   1.3.2.1          assert this.next == null &&
 467 cananian   1.3.2.1                      this.prev == null : "next and prev fields should be null";
 468 cananian   1.3.2.1          assert this.getTargets().isEmpty() &&
 469 cananian   1.3.2.1                      this.canFallThrough : "this should be nonbranching";
 470 cananian   1.3.2.1          assert edge.to() != null ||
 471 cananian   1.3.2.1                      edge.from() != null : "edge shouldn't have null for both to and from";
 472 pnkfelix   1.1.2.32 
 473 pnkfelix   1.1.2.40         Instr from = null, to = null;
 474 pnkfelix   1.1.2.33         if (edge.from() != null) {
 475 pnkfelix   1.1.2.40             from = (Instr) edge.from();
 476 cananian   1.3.2.1              assert from.targets==null || 
 477 cananian   1.3.2.1                          from.hasModifiableTargets() : ("from: "+from+", if it branches, should have mutable target list");
 478 cananian   1.3.2.1              assert edge.to() == null || 
 479 cananian   1.3.2.1                           from.edgeC().contains(edge) : "edge: "+edge+" should be in <from>.edges(): " + 
 480 cananian   1.3.2.1                           Util.print(from.edgeC());
 481 pnkfelix   1.1.2.16         }
 482 pnkfelix   1.1.2.33         if (edge.to() != null) {
 483 pnkfelix   1.1.2.40             to = (Instr) edge.to();
 484 cananian   1.3.2.1              assert edge.from() == null || 
 485 cananian   1.3.2.1                           to.edgeC().contains(edge) : "edge should be in <to>.edges()";
 486 pnkfelix   1.1.2.33         }
 487 pnkfelix   1.1.2.52         
 488 pnkfelix   1.1.2.40         // TODO: add code that will check if edge.from().next !=
 489 pnkfelix   1.1.2.40         // edge.to(), in which case frame should create a new InstrLabel
 490 pnkfelix   1.1.2.40         // and a new branch, and then we'll find a place to put them
 491 pnkfelix   1.1.2.40         // in the code.  (add a pointer to the tail of the instruction
 492 pnkfelix   1.1.2.40         // stream to InstrFactory)
 493 pnkfelix   1.1.2.40         // then do: edge.from() -> newInstrLabel -> this -> 
 494 pnkfelix   1.1.2.40         //          newBranch -> edge.to()
 495 pnkfelix   1.1.2.52         if (from != null &&
 496 pnkfelix   1.1.2.52             from.next != edge.to()) {
 497 cananian   1.3.2.1              assert this.inf != null : "InstrFactory should never be null";
 498 pnkfelix   1.1.2.53             Instr last = this.inf.getTail();
 499 cananian   1.3.2.1              assert last != null : "cachedTail should not be null";
 500 cananian   1.3.2.1              assert last.next == null : ("last Instr: "+last+" should really be LAST, "+
 501 pnkfelix   1.1.2.52                         "but it has next: " + last.next);
 502 pnkfelix   1.1.2.52             
 503 pnkfelix   1.1.2.52             // Oh shit.  How should we design a way to insert
 504 pnkfelix   1.1.2.52             // arbitrary code with a method in the *ARCHITECTURE
 505 pnkfelix   1.1.2.52             // INDEPENDANT* Instr class? 
 506 cananian   1.3.2.1              assert false;
 507 pnkfelix   1.1.2.52         } else { // edge.from() falls through to edge.to() 
 508 pnkfelix   1.1.2.52             layout(from, to);
 509 pnkfelix   1.1.2.52         }
 510 cananian   1.6      
 511 cananian   1.6              // increment parent's modification count (for fail-fast iterator)
 512 cananian   1.6              this.inf.getParent().modCount++;
 513 andyb      1.1.2.13     }
 514 andyb      1.1.2.13 
 515 pnkfelix   1.1.2.40     /** Removes <code>this</code> from its current place in the
 516 pnkfelix   1.1.2.40         instruction layout.
 517 pnkfelix   1.1.2.40         <BR> <B>requires:</B> <code>this</code> has a current location
 518 pnkfelix   1.1.2.40              in the instruction layout.
 519 duncan     1.1.2.66              (ie <code>insertAt(CFGEdge)</code> or
 520 pnkfelix   1.1.2.41              <code>layout(Instr, Instr)</code> has been called 
 521 pnkfelix   1.1.2.36              since the last time <code>remove()</code> was called, or
 522 pnkfelix   1.1.2.36              since construction if <code>remove()</code> has never
 523 pnkfelix   1.1.2.36              been called.)
 524 pnkfelix   1.1.2.36         <BR> <B>modifies:</B> <code>this</code>,
 525 pnkfelix   1.1.2.36              <code>this.prev</code>, <code>this.next</code> 
 526 pnkfelix   1.1.2.36         <BR> <B>effects:</B> removes <code>this</code> from its
 527 pnkfelix   1.1.2.36              current instruction stream, updating the
 528 pnkfelix   1.1.2.36              preceeding and succeeding <code>Instr</code>s accordingly
 529 pnkfelix   1.1.2.36              (preceeding and succeeding according to instruction
 530 pnkfelix   1.1.2.36              layout, not according to control flow) and setting the
 531 pnkfelix   1.1.2.36              <code>this.prev</code> and <code>this.next</code> fields
 532 pnkfelix   1.1.2.36              to <code>null</code>. 
 533 pnkfelix   1.1.2.51         @see Instr#insertAt
 534 pnkfelix   1.1.2.51         @see Instr#layout
 535 pnkfelix   1.1.2.36     */    
 536 pnkfelix   1.1.2.36     public void remove() {
 537 cananian   1.3.2.1          assert ! this.hasMultiplePredecessors();
 538 pnkfelix   1.1.2.69 
 539 cananian   1.3.2.1          assert ((harpoon.Backend.Generic.Code)
 540 cananian   1.3.2.1                       inf.getParent()).getRootElement() != this : "Do not remove root element.";
 541 pnkfelix   1.1.2.69 
 542 pnkfelix   1.1.2.74         if (PRINT_REMOVES) System.out.println("removing Instr:"+this);
 543 pnkfelix   1.1.2.74 
 544 cananian   1.11             for(InstrGroup group : getGroups()){
 545 cananian   1.3.2.1              assert group.entry != this : "Can't handle group component removes yet (entry)";
 546 cananian   1.3.2.1              assert group.exit != this : "Can't handle group component removes yet (exit)";
 547 pnkfelix   1.1.2.87         }
 548 pnkfelix   1.1.2.87 
 549 pnkfelix   1.1.2.87 
 550 pnkfelix   1.1.2.36         if (this.next != null) {
 551 pnkfelix   1.1.2.36             // remove ref to this in this.next
 552 pnkfelix   1.1.2.36             this.next.prev = this.prev; 
 553 pnkfelix   1.1.2.36         }
 554 pnkfelix   1.1.2.36         if (this.prev != null) {
 555 pnkfelix   1.1.2.36             // remove ref to this in this.prev
 556 pnkfelix   1.1.2.36             this.prev.next = this.next;
 557 pnkfelix   1.1.2.36         }
 558 pnkfelix   1.1.2.69 
 559 pnkfelix   1.1.2.69 
 560 pnkfelix   1.1.2.36         this.next = null;
 561 pnkfelix   1.1.2.36         this.prev = null;
 562 cananian   1.1.2.57         /* remove mappings in inf.labelToBranchingInstrsSetMap */
 563 cananian   1.11             if (this.targets!=null)
 564 cananian   1.11                 for (Label l : this.targets)
 565 cananian   1.11                     inf.labelToBranches.get(l).remove(this);
 566 pnkfelix   1.1.2.69 
 567 cananian   1.6              // increment parent's modification count (for fail-fast iterator)
 568 cananian   1.6              this.inf.getParent().modCount++;
 569 pnkfelix   1.1.2.40     }
 570 pnkfelix   1.1.2.40 
 571 pnkfelix   1.1.2.40     /** Places <code>this</code> in the instruction layout between
 572 pnkfelix   1.1.2.40         <code>from</code> and <code>to</code>.
 573 pnkfelix   1.1.2.41         <BR> <B>requires:</B> <OL>
 574 pnkfelix   1.1.2.80              <LI> if <code>from</code> is not null, then
 575 pnkfelix   1.1.2.80                   <code>from.getNext()</code> equals <code>to</code>. 
 576 pnkfelix   1.1.2.80              <LI> if <code>to</code> is not null, then
 577 pnkfelix   1.1.2.80                   <code>to.getPrev()</code> equals <code>from</code>.
 578 pnkfelix   1.1.2.40              <LI> <code>this</code> is not currently in an instruction
 579 pnkfelix   1.1.2.51                   stream (ie <code><nobr> this.getPrev() == null
 580 pnkfelix   1.1.2.51                   </nobr></code> and <code><nobr> this.getNext() ==
 581 pnkfelix   1.1.2.51                   null) </nobr></code>. 
 582 pnkfelix   1.1.2.50                   This is true for newly created <code>Instr</code>s
 583 pnkfelix   1.1.2.50                   and for <code>Instr</code> which have just had their 
 584 pnkfelix   1.1.2.40                   <code>remove()</code> method called.
 585 pnkfelix   1.1.2.40         </OL>
 586 pnkfelix   1.1.2.40         <BR> <B>modifies:</B> <code>from</code>, <code>to</code>
 587 pnkfelix   1.1.2.40         <BR> <B>effects:</B> Inserts <code>this</code> into the
 588 pnkfelix   1.1.2.40              instruction stream in between <code>from</code> and
 589 pnkfelix   1.1.2.80              <code>to</code>.  If <code>from</code> is null, then
 590 pnkfelix   1.1.2.80              <code>this</code> is laid out as the beginning of the
 591 pnkfelix   1.1.2.80              Instruction stream.  If <code>to</code> is null, then
 592 pnkfelix   1.1.2.80              <code>this</code> is laid out as the end of the
 593 pnkfelix   1.1.2.80              Instruction stream.
 594 pnkfelix   1.1.2.40     */
 595 pnkfelix   1.1.2.40     public void layout(Instr from, Instr to) { 
 596 cananian   1.3.2.1          assert this.next == null &&
 597 cananian   1.3.2.1                      this.prev == null : "next and prev fields should be null";
 598 pnkfelix   1.1.2.74         
 599 pnkfelix   1.1.2.74         if (PRINT_INSERTS) System.out.println("inserting Instr:"+this);
 600 pnkfelix   1.1.2.74 
 601 pnkfelix   1.1.2.40         if (to != null &&
 602 pnkfelix   1.1.2.40             from != null) {
 603 cananian   1.3.2.1              assert to.prev == from &&
 604 cananian   1.3.2.1                          from.next == to : "to should follow from in the instruction layout "+
 605 cananian   1.3.2.1                          "if they already exist";
 606 pnkfelix   1.1.2.40         }
 607 pnkfelix   1.1.2.40         
 608 pnkfelix   1.1.2.65         if (from!=null) from.next = this;
 609 pnkfelix   1.1.2.40         this.prev = from;
 610 pnkfelix   1.1.2.40         this.next = to;
 611 pnkfelix   1.1.2.65         if (to!=null) to.prev = this;
 612 cananian   1.1.2.57 
 613 cananian   1.1.2.57         /* add this to inf.labelToBranchingInstrSetMap */
 614 cananian   1.11             if (this.targets != null)
 615 cananian   1.11                 for (Label l : this.targets)
 616 cananian   1.11                     inf.labelToBranches.get(l).add(this);
 617 pnkfelix   1.1.2.85 
 618 pnkfelix   1.1.2.85         // choose group of whichever group is in the SURROUNDING area
 619 pnkfelix   1.1.2.85         // (ie higher in the nested scopes)
 620 pnkfelix   1.1.2.85         if (from != null && to != null) {
 621 pnkfelix   1.1.2.85             if (from.groupList != null && 
 622 pnkfelix   1.1.2.85                 from.groupList.subgroupOf( to.groupList )) {
 623 pnkfelix   1.1.2.85                 this.setGroup( to.groupList );
 624 pnkfelix   1.1.2.85                 // System.out.println("FSK: setGroup(to) code called (Instr.java) on "+this);
 625 pnkfelix   1.1.2.85             } else if (to.groupList != null &&
 626 pnkfelix   1.1.2.85                        to.groupList.subgroupOf( from.groupList )) {
 627 pnkfelix   1.1.2.85                 this.setGroup( from.groupList );
 628 pnkfelix   1.1.2.85                 // System.out.println("FSK: setGroup(from) code called (Instr.java) on "+this);
 629 pnkfelix   1.1.2.85             }
 630 pnkfelix   1.1.2.85 
 631 pnkfelix   1.1.2.85             // Else we're inserting an instruction inbetween two
 632 pnkfelix   1.1.2.85             // instructions which don't have a group in common, in
 633 pnkfelix   1.1.2.85             // which case we shouldn't assign a group to the new
 634 pnkfelix   1.1.2.85             // instruction at all.
 635 pnkfelix   1.1.2.85         }
 636 cananian   1.6      
 637 cananian   1.6              // increment parent's modification count (for fail-fast iterator)
 638 cananian   1.6              this.inf.getParent().modCount++;
 639 cananian   1.1.2.57     }
 640 cananian   1.1.2.57 
 641 cananian   1.1.2.57     /* Replaces <code>inOld</code> with <code>inNew</code> in the
 642 cananian   1.1.2.57      * instruction layout. */
 643 cananian   1.1.2.57     public static void replace(Instr inOld, Instr inNew) {
 644 cananian   1.3.2.1          assert inNew.next==null && inNew.prev==null : "newI has a spot";
 645 cananian   1.3.2.1          assert inOld.next!=null || inOld.prev!=null : "oldI has no loc";
 646 pnkfelix   1.1.2.74 
 647 pnkfelix   1.1.2.74         if (PRINT_REPLACES) System.out.println("replacing Instr:"+inOld+" with Instr:"+inNew);
 648 pnkfelix   1.1.2.85 
 649 pnkfelix   1.1.2.85         inNew.setGroup(inOld.groupList);
 650 pnkfelix   1.1.2.85         inOld.groupList = null;
 651 pnkfelix   1.1.2.87         if (inNew.groupList != null) {
 652 pnkfelix   1.1.2.87             if (inNew.groupList.entry == inOld) inNew.groupList.entry = inNew;
 653 pnkfelix   1.1.2.87             if (inNew.groupList.exit == inOld) inNew.groupList.exit = inNew;
 654 pnkfelix   1.1.2.87             inNew.inf.addGroup( inNew.groupList );
 655 pnkfelix   1.1.2.87         }
 656 pnkfelix   1.1.2.85 
 657 cananian   1.1.2.57         inNew.layout(inOld, inOld.getNext());
 658 cananian   1.1.2.57         inOld.remove();
 659 cananian   1.6      
 660 cananian   1.6              // call to layout() above increments modCount of parent for us.
 661 cananian   1.1.2.57     }
 662 cananian   1.1.2.57 
 663 cananian   1.1.2.57     /** Create a new <code>Instr</code> identical to the receiver, but
 664 cananian   1.1.2.57      *  with all <code>Temp</code>s renamed according to the given
 665 pnkfelix   1.1.2.76      *  mappings.  The new <code>Instr</code> will have no edges, and
 666 pnkfelix   1.1.2.76      *  will come from the <code>InstrFactory</code> for
 667 pnkfelix   1.1.2.76      *  <code>this</code>. 
 668 pnkfelix   1.1.2.76      */
 669 pnkfelix   1.1.2.78     public final Instr rename(TempMap tempmap) {
 670 pnkfelix   1.1.2.76         return this.rename(tempmap, tempmap);
 671 pnkfelix   1.1.2.76     }
 672 pnkfelix   1.1.2.76 
 673 pnkfelix   1.1.2.76     /** Create a new <code>Instr</code> identical to the receiver, but
 674 pnkfelix   1.1.2.76      *  with all <code>Temp</code>s renamed according to the given
 675 pnkfelix   1.1.2.76      *  mappings.  The new <code>Instr</code> will have no edges, and
 676 pnkfelix   1.1.2.76      *  will come from the <code>InstrFactory</code> for
 677 pnkfelix   1.1.2.76      *  <code>this</code>. 
 678 pnkfelix   1.1.2.76      */
 679 pnkfelix   1.1.2.78     public final Instr rename(TempMap defMap, TempMap useMap) {
 680 pnkfelix   1.1.2.76         return this.rename(this.inf, defMap, useMap);
 681 pnkfelix   1.1.2.76     }
 682 pnkfelix   1.1.2.76 
 683 pnkfelix   1.1.2.76     /** Create a new <code>Instr</code> identical to the receiver, but
 684 pnkfelix   1.1.2.76      *  with all <code>Temp</code>s renamed according to the given
 685 pnkfelix   1.1.2.76      *  mappings.  The new <code>Instr</code> will have no edges, and
 686 pnkfelix   1.1.2.76      *  will come from the specified <code>InstrFactory</code>. 
 687 pnkfelix   1.1.2.76      *
 688 pnkfelix   1.1.2.76      * FSK: I don't think this "no edges" part of the specification
 689 pnkfelix   1.1.2.76      * holds anymore (it was written before we revised the
 690 pnkfelix   1.1.2.76      * control-flow representation in the Instrs...  
 691 pnkfelix   1.1.2.76      */
 692 cananian   1.1.2.57     public Instr rename(InstrFactory inf, TempMap defMap, TempMap useMap) {
 693 cananian   1.1.2.57         return new Instr(inf, this, getAssem(),
 694 cananian   1.1.2.57                          map(defMap,dst), map(useMap,src),
 695 cananian   1.1.2.58                          this.canFallThrough, getTargets());
 696 pnkfelix   1.1.2.36     }
 697 pnkfelix   1.1.2.36 
 698 andyb      1.1.2.12     /** Accept a visitor. */
 699 pnkfelix   1.1.2.50     public void accept(InstrVisitor v) { v.visit(this); }
 700 andyb      1.1.2.12 
 701 andyb      1.1.2.12     /** Returns the <code>InstrFactory</code> that generated this. */
 702 andyb      1.1.2.12     public InstrFactory getFactory() { return inf; }
 703 andyb      1.1.2.12     // shouldn't this return inf.clone()???????
 704 andyb      1.1.2.12 
 705 andyb      1.1.2.12     /** Returns the hashcode for this. */
 706 andyb      1.1.2.12     public int hashCode() { return hashCode; }
 707 andyb      1.1.2.12 
 708 pnkfelix   1.1.2.19     public String getAssem() { return assem; }
 709 pnkfelix   1.1.2.19 
 710 andyb      1.1.2.12     // ********* INTERFACE IMPLEMENTATIONS and SUPERCLASS OVERRIDES
 711 andyb      1.1.2.12 
 712 andyb      1.1.2.12     // ******************** Object overrides
 713 andyb      1.1.2.12  
 714 pnkfelix   1.1.2.19     /** Returns a string representation of the <code>Instr</code>.  
 715 pnkfelix   1.1.2.19         Note that while in the common case the <code>String</code>
 716 pnkfelix   1.1.2.19         returned will match the executable assembly code for the
 717 pnkfelix   1.1.2.19         <code>Instr</code>, this is not guaranteed.  To produce
 718 pnkfelix   1.1.2.19         executable assembly in all cases, use
 719 pnkfelix   1.1.2.75         <code>IR.Assem.Code.toAssem(Instr i)</code>.
 720 pnkfelix   1.1.2.20     */
 721 andyb      1.1.2.6      public String toString() {
 722 andyb      1.1.2.6          int len = assem.length();
 723 pnkfelix   1.1.2.79         StringBuffer s = new StringBuffer(len);
 724 pnkfelix   1.1.2.44         for (int i = 0; i < len; i++) {
 725 pnkfelix   1.1.2.52             switch(assem.charAt(i)) {
 726 pnkfelix   1.1.2.52             case '`':
 727 cananian   1.1.2.59                 if (i<len-1) switch (assem.charAt(++i)) {
 728 pnkfelix   1.1.2.19                 case 'd': { 
 729 pnkfelix   1.1.2.15                     int n = Character.digit(assem.charAt(++i), 10);
 730 pnkfelix   1.1.2.20                     if (n < dst.length) 
 731 pnkfelix   1.1.2.20                         s.append(dst[n]);
 732 pnkfelix   1.1.2.20                     else 
 733 pnkfelix   1.1.2.20                         s.append("d?");
 734 pnkfelix   1.1.2.15                 }
 735 pnkfelix   1.1.2.15                 break;
 736 pnkfelix   1.1.2.19                 case 's': {
 737 pnkfelix   1.1.2.15                     int n = Character.digit(assem.charAt(++i), 10);
 738 pnkfelix   1.1.2.20                     if (n < src.length) 
 739 pnkfelix   1.1.2.20                         s.append(src[n]);
 740 pnkfelix   1.1.2.20                     else 
 741 pnkfelix   1.1.2.20                         s.append("s?");
 742 pnkfelix   1.1.2.15                 }
 743 pnkfelix   1.1.2.15                 break;
 744 pnkfelix   1.1.2.29                 case 'L': {
 745 pnkfelix   1.1.2.15                     int n = Character.digit(assem.charAt(++i), 10);
 746 pnkfelix   1.1.2.43                     if (n < targets.size()) 
 747 pnkfelix   1.1.2.29                         s.append(targets.get(n));
 748 pnkfelix   1.1.2.20                     else 
 749 pnkfelix   1.1.2.29                         s.append("L?");
 750 pnkfelix   1.1.2.15                 }
 751 pnkfelix   1.1.2.15                 break;
 752 pnkfelix   1.1.2.15                 case '`': 
 753 pnkfelix   1.1.2.15                     s.append('`');
 754 pnkfelix   1.1.2.15                     break;
 755 andyb      1.1.2.6                  }
 756 pnkfelix   1.1.2.52                 break;
 757 pnkfelix   1.1.2.52             case '\n':
 758 pnkfelix   1.1.2.54                 // the below should still be valid, but its causing problems for global labels.
 759 pnkfelix   1.1.2.54                 // so I'm putting back the original, hard-to-read toString format.
 760 pnkfelix   1.1.2.54                 //s.append("\\n ");
 761 pnkfelix   1.1.2.54                 s.append("\n");
 762 pnkfelix   1.1.2.52                 break;
 763 pnkfelix   1.1.2.52             default:
 764 pnkfelix   1.1.2.52                 s.append(assem.charAt(i));
 765 pnkfelix   1.1.2.52             }
 766 pnkfelix   1.1.2.44         }
 767 andyb      1.1.2.6  
 768 andyb      1.1.2.6          return s.toString();
 769 andyb      1.1.2.3      }
 770 andyb      1.1.2.5  
 771 cananian   1.1.2.84     // ******************** UseDefable Interface
 772 andyb      1.1.2.5  
 773 andyb      1.1.2.12     /** Returns the <code>Temp</code>s used by this <code>Instr</code>. */
 774 cananian   1.1.2.73     public final Temp[] use() { 
 775 cananian   1.3.2.2          Collection<Temp> u = useC();
 776 cananian   1.3.2.2          return u.toArray(new Temp[u.size()]);
 777 andyb      1.1.2.12     }
 778 andyb      1.1.2.3  
 779 andyb      1.1.2.12     /** Returns the <code>Temp</code>s defined by this <code>Instr</code>. */
 780 cananian   1.1.2.73     public final Temp[] def() { 
 781 cananian   1.3.2.2          Collection<Temp> d = defC();
 782 cananian   1.3.2.2          return d.toArray(new Temp[d.size()]);
 783 andyb      1.1.2.12     }
 784 cananian   1.3.2.2      public Collection<Temp> useC() { return Collections.unmodifiableList(Arrays.asList(src)); }
 785 cananian   1.3.2.2      public Collection<Temp> defC() { return Collections.unmodifiableList(Arrays.asList(dst)); }
 786 andyb      1.1.2.6  
 787 andyb      1.1.2.12     // ******************* HCodeElement interface
 788 andyb      1.1.2.3  
 789 andyb      1.1.2.4      public String getSourceFile() { return source_file; }
 790 andyb      1.1.2.3  
 791 andyb      1.1.2.3      public int getLineNumber() { return source_line; }
 792 andyb      1.1.2.3  
 793 andyb      1.1.2.3      public int getID() { return id; }
 794 pnkfelix   1.1.2.7  
 795 cananian   1.1.2.61     // ******************** CFGraphable interface
 796 pnkfelix   1.1.2.7  
 797 cananian   1.1.2.57     /** Returns the <I>control flow</I> edges of <code>this</code>.
 798 pnkfelix   1.1.2.51         Note that this returns edges according to <I>control flow</I>, not in
 799 pnkfelix   1.1.2.36         terms of instruction layout.  Look at <code>getNext()</code>
 800 pnkfelix   1.1.2.36         and <code>getPrev()</code> for information on instruction
 801 pnkfelix   1.1.2.36         layout. 
 802 pnkfelix   1.1.2.36     */
 803 cananian   1.3.2.2      public InstrEdge[] edges() { 
 804 cananian   1.3.2.2          Collection<InstrEdge> c = edgeC();
 805 cananian   1.3.2.2          return c.toArray(new InstrEdge[c.size()]);
 806 andyb      1.1.2.12     }
 807 pnkfelix   1.1.2.51     /** Returns the <I>control flow</I> edges of <code>this</code>.
 808 pnkfelix   1.1.2.51         Note that this returns edges according to <I>control flow</I>, not in
 809 pnkfelix   1.1.2.36         terms of instruction layout.  Look at <code>getNext()</code>
 810 pnkfelix   1.1.2.36         and <code>getPrev()</code> for information on instruction
 811 pnkfelix   1.1.2.36         layout. 
 812 pnkfelix   1.1.2.36     */
 813 cananian   1.9          public List<InstrEdge> edgeC() {
 814 cananian   1.9              return new AbstractList<InstrEdge>() {
 815 cananian   1.9                  List<InstrEdge> p=predC(), s=succC();
 816 cananian   1.9                  public int size() { return p.size()+s.size(); }
 817 cananian   1.9                  public InstrEdge get(int i) {
 818 cananian   1.9                      return (i < p.size()) ? p.get(i) : s.get(i - p.size());
 819 sportbilly 1.1.2.18             }
 820 sportbilly 1.1.2.18         };
 821 cananian   1.8          }
 822 cananian   1.8          public boolean isSucc(Instr i) {
 823 cananian   1.8              for (Iterator<InstrEdge> it=succC().iterator(); it.hasNext(); )
 824 cananian   1.8                  if (it.next().to().equals(i)) return true;
 825 cananian   1.8              return false;
 826 cananian   1.8          }
 827 cananian   1.8          public boolean isPred(Instr i) {
 828 cananian   1.8              for (Iterator<InstrEdge> it=predC().iterator(); it.hasNext(); )
 829 cananian   1.8                  if (it.next().from().equals(i)) return true;
 830 cananian   1.8              return false;
 831 sportbilly 1.1.2.18     }
 832 andyb      1.1.2.12 
 833 pnkfelix   1.1.2.51     /** Returns the <I>control flow</I> predecessors of <code>this</code>.
 834 pnkfelix   1.1.2.51         Note that this returns edges according to <I>control flow</I>, not in
 835 pnkfelix   1.1.2.36         terms of instruction layout.  Look at <code>getNext()</code>
 836 pnkfelix   1.1.2.36         and <code>getPrev()</code> for information on instruction
 837 pnkfelix   1.1.2.36         layout.  
 838 pnkfelix   1.1.2.36         
 839 pnkfelix   1.1.2.36         Uses <code>predC()</code> to get the necessary information.
 840 pnkfelix   1.1.2.36     */
 841 cananian   1.3.2.2      public InstrEdge[] pred() {
 842 cananian   1.3.2.2          Collection<InstrEdge> c = predC();
 843 cananian   1.3.2.2          InstrEdge[] edges = new InstrEdge[c.size()];
 844 cananian   1.3.2.2          return c.toArray(edges);
 845 andyb      1.1.2.12     }
 846 pnkfelix   1.1.2.51     /** Returns the <I>control flow</I> predecessors of <code>this</code>.
 847 pnkfelix   1.1.2.51         Note that this returns edges according to <I>control flow</I>, not in
 848 pnkfelix   1.1.2.36         terms of instruction layout.  Look at <code>getNext()</code>
 849 pnkfelix   1.1.2.36         and <code>getPrev()</code> for information on instruction
 850 pnkfelix   1.1.2.36         layout. 
 851 pnkfelix   1.1.2.36     */
 852 cananian   1.6          // XXX make fail-fast?
 853 cananian   1.9          public List<InstrEdge> predC() {
 854 cananian   1.3.2.1          assert !this.hasMultiplePredecessors() : "should not call Instr.predC() if instr"+
 855 cananian   1.3.2.1                      "has multiple predecessors...override method";
 856 cananian   1.9              return new AbstractList<InstrEdge>(){
 857 pnkfelix   1.1.2.36             public int size() {
 858 pnkfelix   1.1.2.36                 if ((prev != null) && prev.canFallThrough) {
 859 pnkfelix   1.1.2.36                     return 1;
 860 pnkfelix   1.1.2.36                 } else {
 861 pnkfelix   1.1.2.36                     return 0;
 862 pnkfelix   1.1.2.36                 }
 863 pnkfelix   1.1.2.36             }
 864 cananian   1.9                  public InstrEdge get(int i) {
 865 pnkfelix   1.1.2.36                 if ((prev != null) && prev.canFallThrough) {
 866 cananian   1.9                          if (i--==0) return new InstrEdge(prev, Instr.this);
 867 pnkfelix   1.1.2.36                 }
 868 cananian   1.9                      // no more edges
 869 cananian   1.9                      throw new IndexOutOfBoundsException();
 870 pnkfelix   1.1.2.36             }
 871 pnkfelix   1.1.2.36         };
 872 sportbilly 1.1.2.18     }
 873 andyb      1.1.2.12 
 874 pnkfelix   1.1.2.51     /** Returns the <I>control flow</I> successors of <code>this</code>.
 875 pnkfelix   1.1.2.51         Note that this returns edges according to <I>control flow</I>, not in
 876 pnkfelix   1.1.2.36         terms of instruction layout.  Look at <code>getNext()</code>
 877 pnkfelix   1.1.2.36         and <code>getPrev()</code> for information on instruction
 878 pnkfelix   1.1.2.36         layout. 
 879 pnkfelix   1.1.2.36     */
 880 cananian   1.3.2.2      public InstrEdge[] succ() { 
 881 cananian   1.3.2.2          Collection<InstrEdge> c = succC();
 882 cananian   1.3.2.2          InstrEdge[] edges = new InstrEdge[c.size()];
 883 cananian   1.3.2.2          return c.toArray(edges);
 884 sportbilly 1.1.2.18     }
 885 pnkfelix   1.1.2.51     /** Returns the <I>control flow</I> successors of <code>this</code>.
 886 pnkfelix   1.1.2.51         Note that this returns edges according to <I>control flow</I>, not in
 887 pnkfelix   1.1.2.36         terms of instruction layout.  Look at <code>getNext()</code>
 888 pnkfelix   1.1.2.36         and <code>getPrev()</code> for information on instruction
 889 pnkfelix   1.1.2.36         layout. 
 890 pnkfelix   1.1.2.36     */
 891 cananian   1.6          // XXX make fail-fast?
 892 cananian   1.9          public List<InstrEdge> succC() {
 893 cananian   1.9              return new AbstractList<InstrEdge>() {
 894 pnkfelix   1.1.2.36             public int size() {
 895 pnkfelix   1.1.2.36                 int total=0;
 896 pnkfelix   1.1.2.36                 if (canFallThrough && (next != null)) {
 897 pnkfelix   1.1.2.36                     total++;
 898 pnkfelix   1.1.2.36                 } 
 899 pnkfelix   1.1.2.36                 if (targets!=null) {
 900 pnkfelix   1.1.2.36                     total += targets.size();
 901 pnkfelix   1.1.2.36                 }
 902 pnkfelix   1.1.2.37                 return total;
 903 pnkfelix   1.1.2.36             }
 904 cananian   1.9                  public InstrEdge get(int i) {
 905 cananian   1.9                      // first edge: fall-through to next?
 906 cananian   1.9                      if ((next!=null)&&canFallThrough) {
 907 cananian   1.9                          if (i--==0) return new InstrEdge(Instr.this,next);
 908 cananian   1.9                      }
 909 cananian   1.9                      // second edge: branch to targets?
 910 cananian   1.9                      if (targets!=null)
 911 cananian   1.9                          return new InstrEdge(Instr.this,
 912 cananian   1.9                                               inf.labelToInstrLABELmap.get
 913 cananian   1.9                                               ( targets.get(i) ));
 914 cananian   1.9                      // no more edges.
 915 cananian   1.9                      throw new IndexOutOfBoundsException();
 916 pnkfelix   1.1.2.36             }
 917 pnkfelix   1.1.2.36         };
 918 pnkfelix   1.1.2.29     }
 919 pnkfelix   1.1.2.29 
 920 pnkfelix   1.1.2.29     /** Checks whether <code>this.targets</code> is modifiable. 
 921 pnkfelix   1.1.2.29         Most instructions with a list of targets allow for dynamic
 922 pnkfelix   1.1.2.29         replacement of elements of the targets list.  This way, branch
 923 pnkfelix   1.1.2.29         targets can be modified to allow for easy insertion of 
 924 pnkfelix   1.1.2.29         arbitrary fixup code on edges between <code>Instr</code>s by
 925 pnkfelix   1.1.2.29         adding new branches and labels.  
 926 pnkfelix   1.1.2.29 
 927 pnkfelix   1.1.2.51         <P> For example: <BR><code>
 928 pnkfelix   1.1.2.51         <TABLE CELLSPACING=0 CELLPADDING=0>
 929 pnkfelix   1.1.2.51         <TR><TD> [<I> code block 1 </I>] 
 930 pnkfelix   1.1.2.51         <TR><TD><code>beq L0</code></TD></TR>
 931 pnkfelix   1.1.2.51         <TR><TD>[<I> code block 2 </I>]</TD></TR>
 932 pnkfelix   1.1.2.51         <TR><TD><code>L0:</code></TD></TR>
 933 pnkfelix   1.1.2.51         <TR><TD>[<I> code block 3, which does not fall through</I>]</TD></TR>
 934 pnkfelix   1.1.2.51         </TABLE>
 935 pnkfelix   1.1.2.51         </code><BR>
 936 pnkfelix   1.1.2.51         can be turned into: <BR>
 937 pnkfelix   1.1.2.51         <TABLE CELLSPACING=0 CELLPADDING=0>
 938 pnkfelix   1.1.2.51         <TR><TD>[<I> code block 1 </I>]</TD></TR>
 939 pnkfelix   1.1.2.51         <TR><TD><code>beq L1</code></TD></TR>
 940 pnkfelix   1.1.2.51         <TR><TD>[<I> code block 2 </I>]</TD></TR>
 941 pnkfelix   1.1.2.51         <TR><TD><code>L0:</code></TD></TR>
 942 pnkfelix   1.1.2.51         <TR><TD>[<I> code block 3, which does not fall through </I>]</TD></TR>
 943 pnkfelix   1.1.2.51         <TR><TD><code>L1:</code></TD></TR>
 944 pnkfelix   1.1.2.51         <TR><TD>[<I> fixup code prefixing block 3 </I>]</TD></TR>
 945 pnkfelix   1.1.2.51         <TR><TD><code>b L0</code></TD></TR>
 946 pnkfelix   1.1.2.51         </TABLE>
 947 pnkfelix   1.1.2.51         </code><BR>
 948 pnkfelix   1.1.2.51         For such instructions, this method returns
 949 pnkfelix   1.1.2.29         <code>true</code>.  
 950 pnkfelix   1.1.2.29 
 951 pnkfelix   1.1.2.29         <P> However, some instructions (such as computed branches)
 952 pnkfelix   1.1.2.51         cannot have their targets list modified in such a manner  
 953 pnkfelix   1.1.2.51         (the only way to safely insert code between blocks is to first
 954 pnkfelix   1.1.2.51         ensure that a given computed branch is the only branch that
 955 pnkfelix   1.1.2.51         jumps to the target label, and then insert the fixup code at
 956 pnkfelix   1.1.2.51         the point of the label). 
 957 pnkfelix   1.1.2.51         
 958 pnkfelix   1.1.2.51         <P> Such instructions should be initialized with an anonymous 
 959 pnkfelix   1.1.2.29         inner class that overrides this method and returns
 960 pnkfelix   1.1.2.51         <code>false</code>.  
 961 pnkfelix   1.1.2.29 
 962 pnkfelix   1.1.2.29         <P> An important invariant that must be preserved (and is high
 963 pnkfelix   1.1.2.29         level enough that Tree form implementors must take note of it)
 964 pnkfelix   1.1.2.29         is that 
 965 pnkfelix   1.1.2.29         
 966 pnkfelix   1.1.2.51         <P> for all <I>n0</I>, <I>n1</I>, <I>n2</I> elem of Instr such
 967 pnkfelix   1.1.2.51         that there exists an edge <nobr> &lt <I>n0</I>, <I>n1</I> &gt
 968 pnkfelix   1.1.2.51         </nobr> and an edge <nobr> &lt <I>n1</I>, <I>n2</I> &gt
 969 pnkfelix   1.1.2.51         </nobr>,  <I>n0</I> doesn't have modifiable targets implies
 970 pnkfelix   1.1.2.51         the edge <nobr> &lt <I>n0</I>, <I>n1</I> &gt </nobr> dominates
 971 pnkfelix   1.1.2.51         the edge <nobr> &lt <I>n1</I>, <I>n2</I> &gt </nobr>. 
 972 pnkfelix   1.1.2.29         
 973 pnkfelix   1.1.2.51         <P> In other words, <I>n1</I> should have no predecessors
 974 pnkfelix   1.1.2.51         other than <I>n0</I>. 
 975 pnkfelix   1.1.2.29      */
 976 pnkfelix   1.1.2.29     public boolean hasModifiableTargets() {
 977 pnkfelix   1.1.2.35         return true;
 978 pnkfelix   1.1.2.35     }
 979 pnkfelix   1.1.2.35     
 980 pnkfelix   1.1.2.35     /** Checks if <code>this</code> has multiple predecessors.
 981 pnkfelix   1.1.2.35         Most <code>Instr</code>s have either zero or one
 982 pnkfelix   1.1.2.35         predecessors.  Any <code>Instr</code>s that can have more than
 983 pnkfelix   1.1.2.35         one predecessor should override this method to return true. 
 984 pnkfelix   1.1.2.35     */
 985 pnkfelix   1.1.2.35     protected boolean hasMultiplePredecessors() {
 986 pnkfelix   1.1.2.29         return false;
 987 cananian   1.1.2.57     }
 988 cananian   1.1.2.57 
 989 cananian   1.1.2.57     // ----------------------------------------------------
 990 cananian   1.1.2.57     // Useful for temp renaming.  Exported only to subclasses.
 991 cananian   1.1.2.57     protected final static Temp map(TempMap tm, Temp t) {
 992 cananian   1.1.2.57         return (t==null)?null:(tm==null)?t:tm.tempMap(t);
 993 cananian   1.1.2.57     }
 994 cananian   1.1.2.57     protected final static Temp[] map(TempMap tm, Temp[] ta) {
 995 cananian   1.1.2.57         Temp[] r = new Temp[ta.length];
 996 cananian   1.1.2.57         for (int i=0; i<r.length; i++)
 997 cananian   1.1.2.57             r[i] = map(tm, ta[i]);
 998 cananian   1.1.2.57         return r;
 999 cananian   1.1.2.57     }
1000 cananian   1.1.2.57     protected final static Temp[][] map(TempMap tm, Temp[][] taa) {
1001 cananian   1.1.2.57         Temp[][] r = new Temp[taa.length][];
1002 cananian   1.1.2.57         for (int i=0; i<r.length; i++)
1003 cananian   1.1.2.57             r[i] = map(tm, taa[i]);
1004 cananian   1.1.2.57         return r;
1005 pnkfelix   1.1.2.83     }
1006 pnkfelix   1.1.2.83 
1007 pnkfelix   1.1.2.83     /** Clones this, mutating the assembly string.
1008 pnkfelix   1.1.2.83         <BR> <B>requires:</B> newAssem != null
1009 pnkfelix   1.1.2.83         <BR> <B>effects:</B> returns cloneMutateAssem(inf, newAssem)
1010 pnkfelix   1.1.2.83     */
1011 pnkfelix   1.1.2.83     public final Instr cloneMutateAssem(String newAssem) {
1012 pnkfelix   1.1.2.83         return cloneMutateAssem(this.inf, newAssem);
1013 pnkfelix   1.1.2.83     }
1014 pnkfelix   1.1.2.83 
1015 pnkfelix   1.1.2.83     /** Clones this, mutating the assembly string.
1016 pnkfelix   1.1.2.83         <BR> <B>requires:</B> newAssem != null
1017 pnkfelix   1.1.2.83         <BR> <B>effects:</B> Returns a new Instr object with the same
1018 pnkfelix   1.1.2.83              compiler-visible high level properties as
1019 pnkfelix   1.1.2.83              <code>this</code> (use/def, isMove, etc), but instead of
1020 pnkfelix   1.1.2.83              having the assembly-string of this, it has
1021 pnkfelix   1.1.2.83              <code>newAssem</code> as its assembly string.  The
1022 pnkfelix   1.1.2.83              generated instr will not have a a place in the
1023 pnkfelix   1.1.2.83              instruction layout; it is the responsiblity of the caller
1024 pnkfelix   1.1.2.83              to subsequently call Instr.replace to swap
1025 pnkfelix   1.1.2.83              <code>this</code> and the returned <code>Instr</code>.
1026 pnkfelix   1.1.2.83     */
1027 pnkfelix   1.1.2.83     public Instr cloneMutateAssem(InstrFactory inf, String newAssem) {
1028 pnkfelix   1.1.2.83         return new Instr(inf, this, newAssem, 
1029 pnkfelix   1.1.2.83                          this.dst, this.src, this.canFallThrough,
1030 pnkfelix   1.1.2.83                          this.targets);
1031 andyb      1.1.2.12     }
1032 pnkfelix   1.1.2.81 
1033 pnkfelix   1.1.2.81     /** Returns true if this is a Move.
1034 pnkfelix   1.1.2.81         <BR> <B>effects:</B> Returns true if the only effect of
1035 pnkfelix   1.1.2.81         executing this instruction is to copy a set of source
1036 pnkfelix   1.1.2.81         <code>Temp</code>s to a set of destination <code>Temp</code>s. 
1037 pnkfelix   1.1.2.81     */
1038 pnkfelix   1.1.2.81     public boolean isMove() { return false; }
1039 pnkfelix   1.1.2.81 
1040 pnkfelix   1.1.2.81     /** Returns true if this is an unconditional Jump.
1041 pnkfelix   1.1.2.81         <BR> <B>effects:</B> Returns true if the only effect of
1042 pnkfelix   1.1.2.81         executing this instruction is to shift control-flow to one
1043 pnkfelix   1.1.2.81         target <code>Label</code> with no side-effects.
1044 pnkfelix   1.1.2.81     */
1045 pnkfelix   1.1.2.81     public boolean isJump() { return false; }
1046 pnkfelix   1.1.2.81     
1047 pnkfelix   1.1.2.82     
1048 pnkfelix   1.1.2.82     /** Returns true if this is a dummy instruction to express
1049 pnkfelix   1.1.2.82         register allocation constraints.
1050 pnkfelix   1.1.2.82         <BR> <B>effects:</B> Returns true if this instruction has no
1051 pnkfelix   1.1.2.82              effect in itself, but instead is an artificial use of
1052 pnkfelix   1.1.2.82              some <code>Temp</code>(s) inserted as a note to the
1053 pnkfelix   1.1.2.82              register allocator not to insert a <em>Spill-Load</em>
1054 pnkfelix   1.1.2.82              before this instruction.
1055 pnkfelix   1.1.2.82     */
1056 pnkfelix   1.1.2.82     public boolean isDummy() { return false; }
1057 pnkfelix   1.1.2.87 
1058 pnkfelix   1.1.2.87     /** Returns true if this is a directive instruction that is meant
1059 pnkfelix   1.1.2.87         to represent data stored in the code segment, not actual
1060 pnkfelix   1.1.2.87         executable code.
1061 pnkfelix   1.1.2.87     */
1062 pnkfelix   1.1.2.87     public boolean isDirective() { return false; } 
1063 pnkfelix   1.1.2.87 
1064 pnkfelix   1.1.2.87     /** Returns true if this is a label instruction that is meant
1065 pnkfelix   1.1.2.87         to mark a location in the code segment, not actual
1066 pnkfelix   1.1.2.87         executable code.
1067 pnkfelix   1.1.2.87     */
1068 pnkfelix   1.1.2.87     public boolean isLabel() { return false; } 
1069 pnkfelix   1.1.2.87 
1070 cananian   1.2      }