1 cananian 1.1.2.6  // InstrLABEL.java, created Wed Feb 17 16:32:40 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.1  import harpoon.ClassFile.HCodeElement;
  7 andyb    1.1.2.1  import harpoon.Temp.Label;
  8 cananian 1.1.2.13 import harpoon.Temp.TempMap;
  9 cananian 1.6      import net.cscott.jutil.CombineIterator;
 10 cananian 1.6      import net.cscott.jutil.Default;
 11 cananian 1.6      import net.cscott.jutil.UnmodifiableIterator;
 12 pnkfelix 1.1.2.9  
 13 cananian 1.5      import java.util.AbstractList;
 14 cananian 1.5      import java.util.Arrays;
 15 cananian 1.5      import java.util.Collection;
 16 pnkfelix 1.1.2.9  import java.util.Iterator;
 17 cananian 1.5      import java.util.List;
 18 pnkfelix 1.1.2.9  import java.util.Set;
 19 andyb    1.1.2.1  
 20 andyb    1.1.2.1  /**
 21 andyb    1.1.2.1   * <code>InstrLABEL</code> is used to represents code labels in
 22 andyb    1.1.2.1   * assembly-level instruction representations.
 23 andyb    1.1.2.1   *
 24 andyb    1.1.2.1   * @author  Andrew Berkheimer <andyb@mit.edu>
 25 cananian 1.6       * @version $Id: InstrLABEL.java,v 1.6 2004/02/08 01:55:08 cananian Exp $
 26 andyb    1.1.2.1   */
 27 andyb    1.1.2.1  public class InstrLABEL extends Instr {
 28 andyb    1.1.2.4      private Label label;
 29 andyb    1.1.2.1  
 30 cananian 1.1.2.5      /** Create a code label <code>Instr</code>. The specified
 31 cananian 1.1.2.5          <code>String</code> <code>a</code> should be the
 32 cananian 1.1.2.5          assembly-language representation of the given
 33 cananian 1.1.2.5          <code>Label</code> <code>l</code>. */
 34 andyb    1.1.2.2      public InstrLABEL(InstrFactory inf, HCodeElement src, String a, Label l) {
 35 pnkfelix 1.1.2.14         this(inf, src, a, l, true);
 36 andyb    1.1.2.1      } 
 37 pnkfelix 1.1.2.14 
 38 pnkfelix 1.1.2.14     private InstrLABEL(InstrFactory inf, HCodeElement src, 
 39 pnkfelix 1.1.2.14                        String a, Label l, boolean falls) {
 40 pnkfelix 1.1.2.14         super(inf, src, a, null, null, falls, null);
 41 pnkfelix 1.1.2.14         label = l;
 42 pnkfelix 1.1.2.14         inf.labelToInstrLABELmap.put(l, this);  
 43 pnkfelix 1.1.2.14     }
 44 pnkfelix 1.1.2.14 
 45 pnkfelix 1.1.2.14     public static InstrLABEL makeNoFall
 46 pnkfelix 1.1.2.14         (InstrFactory inf, HCodeElement src, String a, Label l) {
 47 pnkfelix 1.1.2.14         return new InstrLABEL(inf, src, a, l, false);
 48 pnkfelix 1.1.2.14     }
 49 pnkfelix 1.1.2.3  
 50 cananian 1.1.2.5      /** Return the code label specified in the constructor. */
 51 andyb    1.1.2.4      public Label getLabel() { return label; }
 52 andyb    1.1.2.4      // should clone label!!!!!!!
 53 andyb    1.1.2.4  
 54 cananian 1.1.2.13     public Instr rename(InstrFactory inf, TempMap defMap, TempMap useMap) {
 55 cananian 1.1.2.13         // should clone label or something.
 56 cananian 1.1.2.13         return new InstrLABEL(inf, this, getAssem(), label);
 57 cananian 1.1.2.13     }
 58 pnkfelix 1.1.2.15     public Instr cloneMutateAssem(InstrFactory inf, String newAssem) {
 59 pnkfelix 1.1.2.15         return new InstrLABEL(inf, this, newAssem, label);
 60 pnkfelix 1.1.2.15     }
 61 pnkfelix 1.1.2.15 
 62 andyb    1.1.2.4      /** Accept a visitor. */
 63 pnkfelix 1.1.2.12     public void accept(InstrVisitor v) { v.visit(this); }
 64 pnkfelix 1.1.2.8  
 65 pnkfelix 1.1.2.8      /** Returns true.
 66 pnkfelix 1.1.2.8          Labels are designed to have multiple predecessors.
 67 pnkfelix 1.1.2.8      */
 68 pnkfelix 1.1.2.8      protected boolean hasMultiplePredecessors() {
 69 pnkfelix 1.1.2.8          return true;
 70 pnkfelix 1.1.2.9      }
 71 pnkfelix 1.1.2.9  
 72 cananian 1.5          public List<InstrEdge> predC() {
 73 cananian 1.5              // XXX not entirely happy w/ this.  We're taking an O(s.size())
 74 cananian 1.5              // performance hit on each call to predC().  But this beats taking
 75 cananian 1.5              // the same hit on each call to precC().get().
 76 cananian 1.5              Set<Instr> s = getFactory().labelToBranches.get(label);
 77 cananian 1.5              final List<Instr> branchesHere =
 78 cananian 1.5                  Arrays.asList(s.toArray(new Instr[s.size()]));
 79 cananian 1.5              return new AbstractList<InstrEdge>() {
 80 pnkfelix 1.1.2.9              public int size() {
 81 pnkfelix 1.1.2.9                  int total=0;
 82 pnkfelix 1.1.2.9                  if (prev!=null && prev.canFallThrough) {
 83 pnkfelix 1.1.2.9                      total++;
 84 pnkfelix 1.1.2.9                  }
 85 pnkfelix 1.1.2.9  
 86 cananian 1.5                      total += branchesHere.size();
 87 pnkfelix 1.1.2.9  
 88 pnkfelix 1.1.2.9                  return total;
 89 pnkfelix 1.1.2.9              }
 90 cananian 1.5                  public InstrEdge get(int i) {
 91 cananian 1.5                      // first iterator: prev falls to this?
 92 cananian 1.5                      if ((prev != null) && prev.canFallThrough) {
 93 cananian 1.5                          if (i--==0) return new InstrEdge(prev, InstrLABEL.this);
 94 cananian 1.5                      }
 95 cananian 1.5                      // second iterator: branches to this?
 96 cananian 1.5                      // hm. need to index these; using the static branchesHere
 97 cananian 1.5                      // list may be non-optimal.
 98 cananian 1.5                      return new InstrEdge(branchesHere.get(i), InstrLABEL.this);
 99 pnkfelix 1.1.2.9              }
100 pnkfelix 1.1.2.9          };
101 pnkfelix 1.1.2.8      }
102 pnkfelix 1.1.2.16 
103 pnkfelix 1.1.2.16     public boolean isLabel() { return true; }
104 cananian 1.2      }