1 cananian 1.1.2.1 // SWITCH.java, created Wed Aug 26 20:45:24 1998 by cananian
  2 cananian 1.1.2.1 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 cananian 1.1.2.1 package harpoon.IR.Quads;
  5 cananian 1.1.2.1 
  6 cananian 1.1.2.8 import harpoon.ClassFile.HCodeElement;
  7 cananian 1.1.2.1 import harpoon.Temp.Temp;
  8 cananian 1.1.2.1 import harpoon.Temp.TempMap;
  9 cananian 1.1.2.2 import harpoon.Util.Util;
 10 cananian 1.1.2.1 
 11 cananian 1.1.2.1 /**
 12 cananian 1.1.2.1  * <code>SWITCH</code> represents a switch construct.
 13 cananian 1.1.2.1  * 
 14 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 15 cananian 1.5      * @version $Id: SWITCH.java,v 1.5 2002/04/11 04:00:35 cananian Exp $
 16 cananian 1.1.2.1  */
 17 cananian 1.1.2.1 public class SWITCH extends SIGMA {
 18 cananian 1.1.2.1     /** The discriminant, compared against each value in <code>keys</code>.*/
 19 cananian 1.1.2.2     protected Temp index;
 20 cananian 1.1.2.1     /** Integer keys for switch cases. <p>
 21 cananian 1.1.2.1      *  <code>next(n)</code> is the jump target corresponding to
 22 cananian 1.1.2.1      *  <code>keys[n]</code> for <code>0 <= n < keys.length</code>. <p>
 23 cananian 1.1.2.1      *  <code>next(keys.length)</code> is the default target. */
 24 cananian 1.1.2.2     protected int keys[];
 25 cananian 1.1.2.2 
 26 cananian 1.1.2.1     /** Creates a <code>SWITCH</code> operation. <p>
 27 cananian 1.1.2.1      *  <code>next[n]</code> is the jump target corresponding to
 28 cananian 1.1.2.1      *  <code>keys[n]</code> for <code>0 <= n < keys.length</code>. <p>
 29 cananian 1.1.2.1      *  <code>next[keys.length]</code> is the default target.
 30 cananian 1.1.2.2      * @param index
 31 cananian 1.1.2.2      *        the discriminant.
 32 cananian 1.1.2.2      * @param keys
 33 cananian 1.1.2.2      *        integer keys for switch cases.
 34 cananian 1.1.2.2      * @param dst
 35 cananian 1.1.2.2      *        sigma function left-hand sides.
 36 cananian 1.1.2.2      * @param src
 37 cananian 1.1.2.2      *        sigma function arguments.
 38 cananian 1.1.2.1      */
 39 cananian 1.1.2.4     public SWITCH(QuadFactory qf, HCodeElement source,
 40 cananian 1.1.2.1                   Temp index, int keys[],
 41 cananian 1.1.2.1                   Temp dst[][], Temp src[]) {
 42 cananian 1.1.2.4         super(qf, source, dst, src, keys.length+1 /*multiple targets*/);
 43 cananian 1.1.2.1         this.index = index;
 44 cananian 1.1.2.1         this.keys = keys;
 45 cananian 1.1.2.2         // VERIFY legality of SWITCH.
 46 cananian 1.3.2.1         assert index!=null && keys!=null;
 47 cananian 1.3.2.1         assert keys.length+1==arity();
 48 cananian 1.1.2.1     }
 49 cananian 1.1.2.2     /** Creates a switch with arity defined by the keys array. */
 50 cananian 1.1.2.4     public SWITCH(QuadFactory qf, HCodeElement source,
 51 cananian 1.1.2.4                   Temp index, int keys[], Temp src[]) {
 52 cananian 1.1.2.4         this(qf,source, index, keys, new Temp[src.length][keys.length+1], src);
 53 cananian 1.1.2.1     }
 54 cananian 1.1.2.2     /** Returns the <code>Temp</code> holding the discriminant. */
 55 cananian 1.1.2.2     public Temp index() { return index; }
 56 cananian 1.1.2.2     /** Returns the array of integer keys for the switch cases. */
 57 cananian 1.1.2.2     public int[] keys() { return (int[]) keys.clone(); }
 58 cananian 1.1.2.2     /** Returns a given element in the <code>keys</code> array. */
 59 cananian 1.1.2.2     public int keys(int i) { return keys[i]; }
 60 cananian 1.1.2.2     /** Returns the length of the <code>keys</code> array. */
 61 cananian 1.1.2.2     public int keysLength() { return keys.length; }
 62 cananian 1.1.2.1 
 63 cananian 1.1.2.2     /** Returns the <code>Temp</code> used by this quad.
 64 cananian 1.1.2.1      * @return the <code>index</code> field. */
 65 cananian 1.1.2.1     public Temp[] use() { 
 66 cananian 1.1.2.1         Temp[] u = super.use();
 67 cananian 1.1.2.1         Temp[] r = new Temp[u.length+1];
 68 cananian 1.1.2.1         System.arraycopy(u, 0, r, 0, u.length);
 69 cananian 1.1.2.1         // add 'index' to end of use array.
 70 cananian 1.1.2.1         r[u.length] = index;
 71 cananian 1.1.2.1         return r;
 72 cananian 1.1.2.1     }
 73 cananian 1.1.2.1 
 74 cananian 1.1.2.3     public int kind() { return QuadKind.SWITCH; }
 75 cananian 1.1.2.3 
 76 cananian 1.1.2.6     public Quad rename(QuadFactory qqf, TempMap defMap, TempMap useMap) {
 77 cananian 1.1.2.6         return new SWITCH(qqf, this, map(useMap,index), (int[])keys.clone(),
 78 cananian 1.1.2.6                           map(defMap,dst), map(useMap,src));
 79 cananian 1.1.2.3     }
 80 cananian 1.1.2.6     /** Rename all used variables in this Quad according to a mapping.
 81 cananian 1.1.2.6      * @deprecated does not preserve immutability. */
 82 cananian 1.1.2.3     void renameUses(TempMap tm) {
 83 cananian 1.1.2.1         super.renameUses(tm);
 84 cananian 1.1.2.1         index = tm.tempMap(index);
 85 cananian 1.1.2.1     }
 86 cananian 1.1.2.6     /** Rename all defined variables in this Quad according to a mapping.
 87 cananian 1.1.2.6      * @deprecated does not preserve immutability. */
 88 cananian 1.1.2.3     void renameDefs(TempMap tm) {
 89 cananian 1.1.2.1         super.renameDefs(tm);
 90 cananian 1.1.2.1     }
 91 cananian 1.1.2.1 
 92 cananian 1.1.2.9     public void accept(QuadVisitor v) { v.visit(this); }
 93 cananian 1.5         public <T> T accept(QuadValueVisitor<T> v) { return v.visit(this); }
 94 cananian 1.1.2.1 
 95 cananian 1.1.2.1     /** Returns human-readable representation of this quad. */
 96 cananian 1.1.2.1     public String toString() {
 97 cananian 1.1.2.1         StringBuffer sb = new StringBuffer("SWITCH "+index+": ");
 98 cananian 1.1.2.1         for (int i=0; i<keys.length; i++)
 99 cananian 1.1.2.5             sb.append("case "+keys[i]+"; ");
100 cananian 1.1.2.5         sb.append("default");
101 cananian 1.1.2.1         sb.append(" / "); sb.append(super.toString());
102 cananian 1.1.2.1         return sb.toString();
103 cananian 1.1.2.1     }
104 cananian 1.2     }