1 cananian 1.1.2.1 // ArrayInitRemover.java, created Mon Jan 22 14:33:36 2001 by cananian
 2 cananian 1.1.2.1 // Copyright (C) 2000 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.Analysis.Quads;
 5 cananian 1.1.2.1 
 6 cananian 1.1.2.1 import harpoon.ClassFile.HClass;
 7 cananian 1.1.2.1 import harpoon.ClassFile.HCode;
 8 cananian 1.1.2.1 import harpoon.ClassFile.HCodeAndMaps;
 9 cananian 1.1.2.1 import harpoon.ClassFile.HCodeFactory;
10 cananian 1.1.2.1 import harpoon.IR.Quads.ARRAYINIT;
11 cananian 1.1.2.1 import harpoon.IR.Quads.ASET;
12 cananian 1.1.2.1 import harpoon.IR.Quads.CONST;
13 cananian 1.1.2.1 import harpoon.IR.Quads.Code;
14 cananian 1.1.2.1 import harpoon.IR.Quads.Edge;
15 cananian 1.1.2.1 import harpoon.IR.Quads.HandlerSet;
16 cananian 1.1.2.1 import harpoon.IR.Quads.Quad;
17 cananian 1.1.2.1 import harpoon.IR.Quads.QuadFactory;
18 cananian 1.1.2.1 import harpoon.Temp.Temp;
19 cananian 1.1.2.1 import harpoon.Temp.TempFactory;
20 cananian 1.1.2.1 
21 cananian 1.1.2.1 /**
22 cananian 1.1.2.1  * <code>ArrayInitRemover</code> converts <code>ARRAYINIT</code> quads
23 cananian 1.1.2.1  * into chains of <code>ASET</code> quads.  Works only on hi-quad form.
24 cananian 1.1.2.1  * 
25 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
26 cananian 1.2      * @version $Id: ArrayInitRemover.java,v 1.2 2002/02/25 20:59:22 cananian Exp $
27 cananian 1.1.2.1  */
28 cananian 1.1.2.1 public final class ArrayInitRemover
29 cananian 1.1.2.1     extends harpoon.Analysis.Transformation.MethodMutator {
30 cananian 1.1.2.1     
31 cananian 1.1.2.1     /** Creates a <code>ArrayInitRemover</code>. */
32 cananian 1.1.2.1     public ArrayInitRemover(HCodeFactory parent) { super(parent); }
33 cananian 1.1.2.1 
34 cananian 1.1.2.1     protected HCode mutateHCode(HCodeAndMaps input) {
35 cananian 1.1.2.1         Code hc = (Code) input.hcode();
36 cananian 1.1.2.1         // we put all elements in array to avoid screwing up the
37 cananian 1.1.2.1         // iterator as we mutate the quad graph in-place.
38 cananian 1.1.2.1         Quad[] allquads = (Quad[]) hc.getElements();
39 cananian 1.1.2.1         for (int i=0; i<allquads.length; i++)
40 cananian 1.1.2.1             if (allquads[i] instanceof ARRAYINIT)
41 cananian 1.1.2.1                 replace((ARRAYINIT) allquads[i]);
42 cananian 1.1.2.1         // yay, done!
43 cananian 1.1.2.1         return hc;
44 cananian 1.1.2.1     }
45 cananian 1.1.2.1 
46 cananian 1.1.2.1     private static void replace(ARRAYINIT ai) {
47 cananian 1.1.2.1         HandlerSet h = ai.handlers(); // new quads will have same handlers.
48 cananian 1.1.2.1         Edge e = ai.nextEdge(0); // all insertion will split this edge.
49 cananian 1.1.2.1         QuadFactory qf = ai.getFactory();
50 cananian 1.1.2.1         TempFactory tf = qf.tempFactory();
51 cananian 1.1.2.1         Object[] value = ai.value();
52 cananian 1.1.2.1         for (int i=0; i<value.length; i++) {
53 cananian 1.1.2.1             // temps
54 cananian 1.1.2.1             Temp idxT= new Temp(tf, "idx");
55 cananian 1.1.2.1             Temp valT= new Temp(tf, "val");
56 cananian 1.1.2.1             // quads
57 cananian 1.1.2.1             Quad q0  = new CONST(qf, ai, idxT, new Integer(i+ai.offset()),
58 cananian 1.1.2.1                                  HClass.Int);
59 cananian 1.1.2.1             Quad q1  = new CONST(qf, ai, valT, widen(value[i], ai.type()),
60 cananian 1.1.2.1                                  widen(ai.type()));
61 cananian 1.1.2.1             Quad q2  = new ASET(qf, ai, ai.objectref(), idxT, valT, ai.type());
62 cananian 1.1.2.1             // edges
63 cananian 1.1.2.1             Quad.addEdges(new Quad[] { q0, q1, q2 });
64 cananian 1.1.2.1             Quad.addEdge((Quad)e.from(), e.which_succ(), q0, 0);
65 cananian 1.1.2.1             e = Quad.addEdge(q2, 0, (Quad)e.to(), e.which_pred());
66 cananian 1.1.2.1             // handlers
67 cananian 1.1.2.1             q0.addHandlers(h); q1.addHandlers(h); q2.addHandlers(h);
68 cananian 1.1.2.1         }
69 cananian 1.1.2.1         // remove arrayinit
70 cananian 1.1.2.1         ai.remove();
71 cananian 1.1.2.1         // done!
72 cananian 1.1.2.1     }
73 cananian 1.1.2.1     private static HClass widen(HClass hc) {
74 cananian 1.1.2.1         return (hc==HClass.Boolean || hc==HClass.Byte ||
75 cananian 1.1.2.1                 hc==HClass.Short || hc==HClass.Char) ? HClass.Int : hc;
76 cananian 1.1.2.1     }
77 cananian 1.1.2.1     private static Object widen(Object o, HClass hc) {
78 cananian 1.1.2.1         return (hc==HClass.Byte || hc==HClass.Short) ?
79 cananian 1.1.2.1             new Integer(((Number)o).intValue()) :
80 cananian 1.1.2.1             (hc==HClass.Boolean) ?
81 cananian 1.1.2.1             new Integer(((Boolean)o).booleanValue() ? 1 : 0) :
82 cananian 1.1.2.1             (hc==HClass.Char) ?
83 cananian 1.1.2.1             new Integer((int) ((Character)o).charValue()) :
84 cananian 1.1.2.1             o;
85 cananian 1.1.2.1     }
86 cananian 1.2     }