1 cananian 1.1.2.1 /* 2 cananian 1.1.2.1 * FlowGraph/AssemFlowGraph.java 3 cananian 1.1.2.1 * construct a flow-graph from a list of instructions. 4 cananian 1.1.2.1 * 5 cananian 1.1.2.1 * C. Scott Ananian, cananian@princeton.edu, COS320 6 cananian 1.1.2.1 */ 7 cananian 1.1.2.2 package harpoon.Backend.CSAHack.FlowGraph; 8 cananian 1.1.2.1 9 cananian 1.1.2.2 import harpoon.Backend.StrongARM.TwoWordTemp; 10 cananian 1.1.2.2 11 cananian 1.1.2.2 import harpoon.IR.Assem.Instr; 12 cananian 1.1.2.2 import harpoon.IR.Assem.InstrLABEL; 13 cananian 1.1.2.2 import harpoon.IR.Assem.InstrMOVE; 14 cananian 1.1.2.5 import harpoon.IR.Properties.UseDefer; 15 cananian 1.1.2.2 import harpoon.Backend.CSAHack.Graph.Node; 16 cananian 1.1.2.2 import harpoon.Backend.CSAHack.Graph.NodeList; 17 cananian 1.1.2.2 import harpoon.Temp.Label; 18 cananian 1.1.2.2 import harpoon.Temp.Temp; 19 cananian 1.1.2.2 import harpoon.Temp.TempList; 20 cananian 1.1.2.2 import harpoon.Util.Util; 21 cananian 1.1.2.1 22 cananian 1.1.2.1 import java.util.Hashtable; 23 cananian 1.1.2.2 import java.util.Iterator; 24 cananian 1.1.2.1 25 cananian 1.1.2.1 /** 26 cananian 1.1.2.1 * A flow graph whose nodes correspond to machine instructions. 27 cananian 1.1.2.1 * @version 1.00, 25 Nov 1996 28 cananian 1.1.2.1 * @author C. Scott Ananian 29 cananian 1.4 * @see harpoon.IR.Assem.Instr 30 cananian 1.1.2.1 */ 31 cananian 1.1.2.1 public class AssemFlowGraph extends FlowGraph { 32 cananian 1.1.2.5 UseDefer ud; 33 cananian 1.1.2.2 boolean twoWord; 34 cananian 1.1.2.1 /** 35 cananian 1.1.2.1 * Construct an AssemFlowGraph from a list of instructions. 36 cananian 1.1.2.1 */ 37 cananian 1.1.2.5 public AssemFlowGraph(Instr root, UseDefer ud, boolean twoWord) { 38 cananian 1.1.2.5 this.ud = ud; 39 cananian 1.1.2.2 this.twoWord = twoWord; 40 cananian 1.3.2.1 assert root.getPrev()==null; 41 cananian 1.1.2.1 Hashtable instr2node; 42 cananian 1.1.2.1 Hashtable label2node; 43 cananian 1.1.2.1 44 cananian 1.1.2.1 instr2node = new Hashtable(); 45 cananian 1.1.2.1 label2node = new Hashtable(); 46 cananian 1.1.2.1 47 cananian 1.1.2.1 // Make a node for each instruction. 48 cananian 1.1.2.1 // add these nodes to various lookup tables. 49 cananian 1.1.2.2 for (Instr il = root; il!=null; il=il.getNext()) { 50 cananian 1.1.2.2 Node n = newNode(il); 51 cananian 1.1.2.2 instr2node.put(il, n); 52 cananian 1.1.2.2 if (il instanceof InstrLABEL) { 53 cananian 1.1.2.2 Object prev = label2node.put(((InstrLABEL)il).getLabel(), n); 54 cananian 1.1.2.1 if (prev!=null) 55 cananian 1.1.2.1 throw new Error("InstrList error: multiple definitions of label "+ 56 cananian 1.1.2.2 ((InstrLABEL)il).getLabel()); 57 cananian 1.1.2.1 } 58 cananian 1.1.2.1 } 59 cananian 1.1.2.1 60 cananian 1.1.2.1 // Add edges for each node. 61 cananian 1.1.2.2 for (Instr il = root; il!=null; il=il.getNext()) { 62 cananian 1.1.2.2 // handle fall through. 63 cananian 1.1.2.2 if (il.canFallThrough) { 64 cananian 1.1.2.2 if (il.getNext() != null) 65 cananian 1.1.2.2 addEdge((Node)instr2node.get(il), 66 cananian 1.1.2.2 (Node)instr2node.get(il.getNext())); 67 cananian 1.1.2.2 } 68 cananian 1.1.2.2 // handle jumps. 69 cananian 1.6 for (Object llO : il.getTargets()) { 70 cananian 1.6 Label ll = (Label) llO; 71 cananian 1.1.2.2 if (label2node.get(ll)==null) 72 cananian 1.1.2.1 throw new Error("Non-existent label used in instruction list: "+ 73 cananian 1.1.2.2 ll.toString()+" used in "+il.toString()); 74 cananian 1.1.2.2 addEdge((Node)instr2node.get(il), 75 cananian 1.1.2.2 (Node)label2node.get(ll)); 76 cananian 1.1.2.1 } 77 cananian 1.1.2.1 } 78 cananian 1.1.2.1 // all done. 79 cananian 1.1.2.1 } 80 cananian 1.1.2.1 /** 81 cananian 1.1.2.1 * @param n a node in the flow graph. 82 cananian 1.1.2.1 * @return the instruction corresponding to node 'n' 83 cananian 1.1.2.1 */ 84 cananian 1.1.2.1 public Instr instr(Node n) { 85 cananian 1.1.2.1 if (!(n instanceof AssemNode)) 86 cananian 1.1.2.1 throw new Error("not a AssemFlowGraph node"); 87 cananian 1.1.2.1 else return ((AssemNode)n).instr; 88 cananian 1.1.2.1 } 89 cananian 1.1.2.1 /** 90 cananian 1.1.2.1 * @param n a node in the flow graph. 91 cananian 1.1.2.1 * @return a list of temps defined by the instruction at node 'n' 92 cananian 1.4 * @see harpoon.Temp.Temp 93 cananian 1.1.2.1 */ 94 cananian 1.1.2.1 public TempList def(Node n) { 95 cananian 1.1.2.2 // CSA'99: clunk. def() returns an array in FLEX. Thunk it to a TempList. 96 cananian 1.1.2.5 Temp[] d = ud.def(instr(n)); 97 cananian 1.1.2.2 TempList tl = null; 98 cananian 1.1.2.2 for (int i=d.length-1; i>=0; i--) 99 cananian 1.1.2.2 if (twoWord && d[i] instanceof TwoWordTemp) { 100 cananian 1.3.2.1 assert instr(n).getAssem().indexOf("`d"+i)!=-1; 101 cananian 1.1.2.4 if (instr(n).getAssem().indexOf("`d"+i+"l")!=-1) 102 cananian 1.1.2.4 tl = new TempList(((TwoWordTemp)d[i]).getLow(), tl); 103 cananian 1.1.2.4 if (instr(n).getAssem().indexOf("`d"+i+"h")!=-1) 104 cananian 1.1.2.4 tl = new TempList(((TwoWordTemp)d[i]).getHigh(), tl); 105 cananian 1.1.2.2 } else tl = new TempList(d[i], tl); 106 cananian 1.1.2.2 return tl; 107 cananian 1.1.2.1 } 108 cananian 1.1.2.1 /** 109 cananian 1.1.2.1 * @param n a node in the flow graph. 110 cananian 1.1.2.1 * @return a list of temps used by the instruction at node 'n' 111 cananian 1.4 * @see harpoon.Temp.Temp 112 cananian 1.1.2.1 */ 113 cananian 1.1.2.1 public TempList use(Node n) { 114 cananian 1.1.2.2 // CSA'99: clunk. use() returns an array in FLEX. Thunk it to a TempList. 115 cananian 1.1.2.5 Temp[] u = ud.use(instr(n)); 116 cananian 1.1.2.2 TempList tl = null; 117 cananian 1.1.2.2 for (int i=u.length-1; i>=0; i--) 118 cananian 1.1.2.2 if (twoWord && u[i] instanceof TwoWordTemp) { 119 cananian 1.3.2.1 assert instr(n).getAssem().indexOf("`s"+i)!=-1; 120 cananian 1.1.2.4 if (instr(n).getAssem().indexOf("`s"+i+"l")!=-1) 121 cananian 1.1.2.4 tl = new TempList(((TwoWordTemp)u[i]).getLow(), tl); 122 cananian 1.1.2.4 if (instr(n).getAssem().indexOf("`s"+i+"h")!=-1) 123 cananian 1.1.2.4 tl = new TempList(((TwoWordTemp)u[i]).getHigh(), tl); 124 cananian 1.1.2.2 } else tl = new TempList(u[i], tl); 125 cananian 1.1.2.2 return tl; 126 cananian 1.1.2.1 } 127 cananian 1.1.2.1 /** 128 cananian 1.1.2.1 * @param n a node in the flow graph. 129 cananian 1.1.2.1 * @return true if node n can be eliminated if use() == def(), false otherwise. 130 cananian 1.1.2.1 */ 131 cananian 1.1.2.1 public boolean isMove(Node n) { 132 cananian 1.1.2.2 return instr(n) instanceof InstrMOVE; 133 cananian 1.1.2.1 } 134 cananian 1.1.2.1 /** 135 cananian 1.1.2.1 * Create a new node in the flow graph that does not correspond to 136 cananian 1.1.2.1 * an instruction. <BR> 137 cananian 1.1.2.1 * <STRONG>NOT RECOMMENDED.</STRONG> Use <TT>newNode(Instr i)</TT> instead. 138 cananian 1.1.2.1 */ 139 cananian 1.1.2.1 public Node newNode() { 140 cananian 1.1.2.1 return new AssemNode(this, null); 141 cananian 1.1.2.1 } 142 cananian 1.1.2.1 /** Create a new node in the flow graph corresponding to the instruction 143 cananian 1.1.2.1 * passed as parameter. 144 cananian 1.1.2.1 */ 145 cananian 1.1.2.1 public Node newNode(Instr i) { 146 cananian 1.1.2.1 return new AssemNode(this, i); 147 cananian 1.1.2.1 } 148 cananian 1.1.2.1 } 149 cananian 1.1.2.1 150 cananian 1.1.2.1 /** 151 cananian 1.1.2.1 * Extension to Graph.Node to represent nodes 152 cananian 1.1.2.1 * corresponding to Assem.Instr's. 153 cananian 1.1.2.1 */ 154 cananian 1.1.2.2 class AssemNode extends harpoon.Backend.CSAHack.Graph.Node 155 cananian 1.1.2.2 // implements harpoon.Temp.TempMap 156 cananian 1.1.2.2 { 157 cananian 1.1.2.1 Instr instr; 158 cananian 1.1.2.2 AssemNode(harpoon.Backend.CSAHack.Graph.Graph g, Instr i) { 159 cananian 1.1.2.1 super(g); 160 cananian 1.1.2.1 instr = i; 161 cananian 1.1.2.1 } 162 cananian 1.1.2.1 public String toString() { 163 cananian 1.1.2.1 if (instr!=null) { 164 cananian 1.1.2.2 String r = "Instr["+super.toString()+"]"; 165 cananian 1.1.2.2 //r+="("+instr.format(this).trim()+") "; 166 cananian 1.1.2.2 r+="("+instr.toString().trim()+") "; 167 cananian 1.1.2.2 /* 168 cananian 1.1.2.2 r+="- use: "; 169 cananian 1.1.2.2 Temp[] u = instr.use(); 170 cananian 1.1.2.2 for (int i=0; i<u.length; i++) 171 cananian 1.1.2.2 r+=u[i].toString()+" "; 172 cananian 1.1.2.2 r+=", def: "; 173 cananian 1.1.2.2 Temp[] d = instr.def(); 174 cananian 1.1.2.2 for (int i=0; i<d.length; i++) 175 cananian 1.1.2.2 r+=d[i].toString()+" "; 176 cananian 1.1.2.2 */ 177 cananian 1.1.2.1 return r; 178 cananian 1.1.2.1 } else return super.toString(); 179 cananian 1.1.2.1 } 180 cananian 1.1.2.2 public String tempMap(harpoon.Temp.Temp t) { 181 cananian 1.1.2.1 return t.toString(); 182 cananian 1.1.2.1 } 183 cananian 1.1.2.3 public int hashCode() { return instr.hashCode(); } 184 cananian 1.1.2.1 } 185 cananian 1.2