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 }