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> < <I>n0</I>, <I>n1</I> > 968 pnkfelix 1.1.2.51 </nobr> and an edge <nobr> < <I>n1</I>, <I>n2</I> > 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> < <I>n0</I>, <I>n1</I> > </nobr> dominates 971 pnkfelix 1.1.2.51 the edge <nobr> < <I>n1</I>, <I>n2</I> > </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 }