1 cananian 1.1.2.1 // BasicCSE.java, created Sat Sep 26 04:27:12 1998 by marinov 2 cananian 1.1.2.1 // Copyright (C) 1998 Darko Marinov <marinov@lcs.mit.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.Analysis.Quads; 5 cananian 1.1.2.1 6 cananian 1.1.2.2 import harpoon.IR.Quads.CONST; 7 cananian 1.1.2.2 import harpoon.IR.Quads.Edge; 8 cananian 1.1.2.2 import harpoon.IR.Quads.MOVE; 9 cananian 1.1.2.2 import harpoon.IR.Quads.OPER; 10 cananian 1.1.2.2 import harpoon.IR.Quads.Qop; 11 cananian 1.1.2.2 import harpoon.IR.Quads.Quad; 12 cananian 1.1.2.2 import harpoon.ClassFile.HClass; 13 cananian 1.1.2.2 import harpoon.ClassFile.HCode; 14 cananian 1.1.2.2 import harpoon.Temp.Temp; 15 cananian 1.3 import net.cscott.jutil.UniqueVector; 16 cananian 1.1.2.1 import java.util.Vector; 17 cananian 1.1.2.1 import java.util.Hashtable; 18 cananian 1.1.2.1 19 cananian 1.1.2.1 /** 20 cananian 1.1.2.1 * <code>BasicCSE</code> is an attempt to perform 21 cananian 1.1.2.1 * common subexpression elemination, but only within basic blocks. 22 cananian 1.1.2.1 * 23 cananian 1.1.2.1 * @author Darko Marinov <marinov@lcs.mit.edu> 24 cananian 1.3 * @version $Id: BasicCSE.java,v 1.3 2004/02/08 01:53:14 cananian Exp $ 25 cananian 1.1.2.1 */ 26 cananian 1.1.2.1 27 cananian 1.1.2.1 public class BasicCSE { 28 cananian 1.1.2.1 29 cananian 1.1.2.1 private BasicCSE() { } 30 cananian 1.1.2.1 31 cananian 1.1.2.1 /** <code>BasicBlock</code> represents sequence of quadruples. */ 32 cananian 1.1.2.1 private static class BasicBlock { 33 cananian 1.1.2.1 private Quad start,end; 34 cananian 1.1.2.1 public Quad getStart() {return start;} 35 cananian 1.1.2.1 public Quad getEnd() {return end;} 36 cananian 1.1.2.1 public BasicBlock(Quad start, Quad end) { 37 cananian 1.1.2.1 this.start=start; this.end=end; 38 cananian 1.1.2.1 } 39 cananian 1.1.2.1 /** Returns quadruples of the basic block in execution order. */ 40 cananian 1.1.2.1 public Quad[] executionOrder() { 41 cananian 1.1.2.1 Vector c = new Vector(); 42 cananian 1.1.2.1 for (Quad q=start; ;q=q.next(0)) { 43 cananian 1.1.2.1 c.addElement(q); 44 cananian 1.1.2.1 if (q==end) break; 45 cananian 1.1.2.1 } 46 cananian 1.1.2.1 Quad[] r=new Quad[c.size()]; 47 cananian 1.1.2.1 c.copyInto(r); return r; 48 cananian 1.1.2.1 } 49 cananian 1.1.2.1 } 50 cananian 1.1.2.1 51 cananian 1.1.2.1 /** Returns array of basic blocks in code starting with quad start. */ 52 cananian 1.1.2.1 private static BasicBlock[] findBasicBlocks (Quad start) { 53 cananian 1.1.2.1 Vector c = new Vector(); 54 cananian 1.1.2.1 UniqueVector b = new UniqueVector(1); 55 cananian 1.1.2.1 b.addElement(start); 56 cananian 1.1.2.1 for (int i=0; i<b.size(); i++) { 57 cananian 1.1.2.1 Quad s=(Quad)b.elementAt(i); 58 cananian 1.1.2.1 Quad t=s; 59 cananian 1.1.2.1 while ((t.nextEdge().length==1)&&(t.next(0).prevEdge().length==1)) 60 cananian 1.1.2.1 t=t.next(0); 61 cananian 1.1.2.1 c.addElement(new BasicBlock(s,t)); 62 cananian 1.1.2.1 Quad[] n=t.next(); 63 cananian 1.1.2.1 for (int j=0; j<n.length; j++) 64 cananian 1.1.2.1 b.addElement(n[j]); 65 cananian 1.1.2.1 } 66 cananian 1.1.2.1 BasicBlock[] r=new BasicBlock[c.size()]; 67 cananian 1.1.2.1 c.copyInto(r); return r; 68 cananian 1.1.2.1 } 69 cananian 1.1.2.1 70 cananian 1.1.2.1 /** Eliminates common subexpression within basic blocks 71 cananian 1.1.2.1 * in quad-ssi <code>HCode</code>. Uses value numbering algorithm. */ 72 cananian 1.1.2.1 public static void optimize (HCode hc) { 73 cananian 1.1.2.1 BasicBlock[] bbs=findBasicBlocks((Quad)hc.getRootElement()); 74 cananian 1.1.2.1 // for all basic blocks 75 cananian 1.1.2.1 for (int i=0; i<bbs.length; i++) { 76 cananian 1.1.2.1 Hashtable var2val = new Hashtable(); // variable to value map 77 cananian 1.1.2.1 Hashtable exp2val = new Hashtable(); // expression to value 78 cananian 1.1.2.1 Hashtable exp2var = new Hashtable(); // expression to variable 79 cananian 1.1.2.1 Hashtable con2val = new Hashtable(); // constant to value 80 cananian 1.1.2.1 int virtval = 0; 81 cananian 1.1.2.1 Quad[] in = bbs[i].executionOrder(); 82 cananian 1.1.2.1 // for all instructions 83 cananian 1.1.2.1 for (int j=0; j<in.length; j++) { 84 cananian 1.1.2.1 // if instruction is (n-ary) operation dst=op(src1...srcn) 85 cananian 1.1.2.1 if (in[j] instanceof OPER) { 86 cananian 1.1.2.1 OPER ins=(OPER) in[j]; 87 cananian 1.1.2.1 Vector exp = new Vector(1); 88 cananian 1.1.2.1 exp.addElement(Qop.toString(ins.opcode())); 89 cananian 1.1.2.1 // for all src 90 cananian 1.1.2.1 for (int k=0; k<ins.operandsLength(); k++) { 91 cananian 1.1.2.1 Integer v=(Integer)var2val.get(ins.operands(k)); 92 cananian 1.1.2.1 // if var2val(src)==no value than var2val=new value 93 cananian 1.1.2.1 if (v==null) { 94 cananian 1.1.2.1 virtval++; Integer vv=new Integer(virtval); 95 cananian 1.1.2.1 var2val.put(ins.operands(k),vv); 96 cananian 1.1.2.1 exp.addElement(vv); 97 cananian 1.1.2.1 } else exp.addElement(v); 98 cananian 1.1.2.1 } 99 cananian 1.1.2.1 String str=exp.toString(); 100 cananian 1.1.2.1 Integer v=(Integer) exp2val.get(str); 101 cananian 1.1.2.1 // if exp2val(op(var2val(src1)...var2val(srcn)))==no value 102 cananian 1.1.2.1 if (v==null) { 103 cananian 1.1.2.1 Temp t = new Temp(ins.dst()); 104 cananian 1.1.2.1 // insert MOVE t,dst quad 105 cananian 1.1.2.1 Quad[] q=ins.next(); 106 cananian 1.1.2.1 if ((q.length==1)&&(q[0].prev().length==1)) { 107 cananian 1.1.2.1 MOVE m=new MOVE(ins.getFactory(),ins,t,ins.dst()); 108 cananian 1.1.2.1 Quad.addEdge(m,0,q[0],0); 109 cananian 1.1.2.1 Quad.addEdge(ins,0,m,0); 110 cananian 1.1.2.1 exp2var.put(str,t); 111 cananian 1.1.2.1 } 112 cananian 1.1.2.1 virtval++; Integer vv=new Integer(virtval); 113 cananian 1.1.2.1 exp2val.put(str,vv); 114 cananian 1.1.2.1 var2val.put(ins.dst(),vv); 115 cananian 1.1.2.1 } else { 116 cananian 1.1.2.1 Temp t=(Temp) exp2var.get(str); 117 cananian 1.1.2.1 // change OPER quad to a MOVE one 118 cananian 1.1.2.1 if (ins.edges().length==2) { 119 cananian 1.1.2.1 MOVE m=new MOVE(ins.getFactory(),ins,ins.dst(),t); 120 cananian 1.1.2.1 Quad next=ins.next(0); Quad prev=ins.prev(0); 121 cananian 1.1.2.1 if ((prev.next(0)==ins)&&(next.prev(0)==ins)) { 122 cananian 1.1.2.1 Quad.addEdge(m,0,next,0); 123 cananian 1.1.2.1 Quad.addEdge(prev,0,m,0); 124 cananian 1.1.2.1 } 125 cananian 1.1.2.1 } 126 cananian 1.1.2.1 var2val.put(ins.dst(),v); 127 cananian 1.1.2.1 } 128 cananian 1.1.2.1 // if instruction is move, just set var2val for src and dst 129 cananian 1.1.2.1 } else if (in[j] instanceof MOVE) { 130 cananian 1.1.2.1 MOVE ins = (MOVE) in[j]; 131 cananian 1.1.2.1 Integer v=(Integer) var2val.get(ins.src()); 132 cananian 1.1.2.1 if (v==null) { 133 cananian 1.1.2.1 virtval++; Integer vv=new Integer(virtval); 134 cananian 1.1.2.1 var2val.put(ins.src(),vv); 135 cananian 1.1.2.1 var2val.put(ins.dst(),vv); 136 cananian 1.1.2.1 } 137 cananian 1.1.2.1 else var2val.put(ins.dst(),v); 138 cananian 1.1.2.1 // if instruction is const, set var2val for dst, but also con2val for src 139 cananian 1.1.2.1 } else if (in[j] instanceof CONST) { 140 cananian 1.1.2.1 CONST ins = (CONST) in[j]; 141 cananian 1.1.2.1 String str=ins.type().toString() + 142 cananian 1.1.2.1 ((ins.value()==null)?"null":ins.value().toString()); 143 cananian 1.1.2.1 Integer v=(Integer) con2val.get(str); 144 cananian 1.1.2.1 if (v==null) { 145 cananian 1.1.2.1 virtval++; Integer vv=new Integer(virtval); 146 cananian 1.1.2.1 con2val.put(str,vv); 147 cananian 1.1.2.1 var2val.put(ins.dst(),vv); 148 cananian 1.1.2.1 } 149 cananian 1.1.2.1 else var2val.put(ins.dst(),v); 150 cananian 1.1.2.1 } 151 cananian 1.1.2.1 } //for all instructions 152 cananian 1.1.2.1 } //foreach basic block 153 cananian 1.1.2.1 } //optimize 154 cananian 1.1.2.1 155 cananian 1.2 }