1 cananian 1.1.2.1 // EpilogMutator.java, created Fri Feb 23 02:28:16 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.Counters;
 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.ClassFile.HMethod;
11 cananian 1.1.2.1 import harpoon.ClassFile.Linker;
12 cananian 1.1.2.1 import harpoon.IR.Quads.CALL;
13 cananian 1.1.2.1 import harpoon.IR.Quads.Edge;
14 cananian 1.1.2.1 import harpoon.IR.Quads.PHI;
15 cananian 1.1.2.1 import harpoon.IR.Quads.Quad;
16 cananian 1.1.2.1 import harpoon.IR.Quads.QuadFactory;
17 cananian 1.1.2.1 import harpoon.IR.Quads.QuadNoSSA;
18 cananian 1.1.2.1 import harpoon.IR.Quads.QuadRSSx;
19 cananian 1.1.2.1 import harpoon.IR.Quads.QuadSSA;
20 cananian 1.1.2.1 import harpoon.IR.Quads.QuadSSI;
21 cananian 1.1.2.1 import harpoon.IR.Quads.QuadVisitor;
22 cananian 1.1.2.1 import harpoon.IR.Quads.RETURN;
23 cananian 1.1.2.1 import harpoon.IR.Quads.THROW;
24 cananian 1.1.2.1 import harpoon.Temp.Temp;
25 cananian 1.6     import net.cscott.jutil.SnapshotIterator;
26 cananian 1.1.2.1 import harpoon.Util.Util;
27 cananian 1.1.2.1 
28 cananian 1.5     import java.util.Iterator;
29 cananian 1.5     
30 cananian 1.1.2.1 /**
31 cananian 1.1.2.1  * <code>EpilogMutator</code> adds the appropriate call to
32 cananian 1.1.2.1  * <code>harpoon.Runtime.Counters</code><code>.report()</code> at the
33 cananian 1.1.2.1  * end of the main method and just before any call to
34 cananian 1.1.2.1  * <code>System.exit()</code>.  For package-internal use by
35 cananian 1.1.2.1  * <code>CounterFactory</code>.
36 cananian 1.1.2.1  * 
37 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
38 cananian 1.6      * @version $Id: EpilogMutator.java,v 1.6 2004/02/08 01:51:01 cananian Exp $
39 cananian 1.1.2.1  */
40 cananian 1.5     class EpilogMutator
41 cananian 1.5         extends harpoon.Analysis.Transformation.MethodMutator<Quad> {
42 cananian 1.1.2.1     private final HMethod HMmain, HMreport, HMexit;
43 cananian 1.1.2.1     
44 cananian 1.1.2.1     /** Creates a <code>EpilogMutator</code>. */
45 cananian 1.1.2.1     public EpilogMutator(HCodeFactory parent, Linker l, HMethod main) {
46 cananian 1.1.2.1         super(parent);
47 cananian 1.1.2.1         this.HMmain = main;
48 cananian 1.1.2.1         this.HMexit = l.forName("java.lang.Runtime")
49 cananian 1.1.2.1             .getDeclaredMethod("exit","(I)V");
50 cananian 1.1.2.1         this.HMreport = l.forName("harpoon.Runtime.Counters")
51 cananian 1.1.2.1             .getDeclaredMethod("report","()V");
52 cananian 1.3.2.1         assert HMmain.isStatic();
53 cananian 1.3.2.1         assert !HMexit.isStatic();
54 cananian 1.3.2.1         assert HMreport.isStatic();
55 cananian 1.3.2.1         assert parent.getCodeName().equals(QuadNoSSA.codename) ||
56 cananian 1.1.2.1                     parent.getCodeName().equals(QuadRSSx.codename) ||
57 cananian 1.1.2.1                     parent.getCodeName().equals(QuadSSA.codename) ||
58 cananian 1.3.2.1                     parent.getCodeName().equals(QuadSSI.codename);
59 cananian 1.1.2.1     }
60 cananian 1.5         public HCode<Quad> mutateHCode(HCodeAndMaps<Quad> input) {
61 cananian 1.1.2.1         final boolean isMain = input.hcode().getMethod().equals(HMmain);
62 cananian 1.1.2.1         QuadVisitor qv = new QuadVisitor() {
63 cananian 1.1.2.1             public void visit(Quad q) { /* do nothing */ }
64 cananian 1.1.2.1             public void visit(RETURN q) {
65 cananian 1.1.2.1                 if (isMain) addReportBefore(q);
66 cananian 1.1.2.1             }
67 cananian 1.1.2.1             public void visit(THROW q) {
68 cananian 1.1.2.1                 if (isMain) addReportBefore(q);
69 cananian 1.1.2.1             }
70 cananian 1.1.2.1             public void visit(CALL q) {
71 cananian 1.1.2.1                 if (q.method().equals(HMexit)) addReportBefore(q);
72 cananian 1.1.2.1             }
73 cananian 1.1.2.1             private void addReportBefore(Quad q) {
74 cananian 1.3.2.1                 assert q.prevLength()==1;
75 cananian 1.1.2.1                 QuadFactory qf = q.getFactory();
76 cananian 1.1.2.1                 Temp t = new Temp(qf.tempFactory(), "ignore");
77 cananian 1.1.2.1                 Quad q0 = new CALL(qf, q, HMreport, new Temp[0],
78 cananian 1.1.2.1                                    null, t, false, false, new Temp[0]);
79 cananian 1.1.2.1                 Quad q1 = new PHI(qf, q, new Temp[0], 2);
80 cananian 1.1.2.1                 Quad.addEdge(q0, 0, q1, 0);
81 cananian 1.1.2.1                 Quad.addEdge(q0, 1, q1, 1);
82 cananian 1.1.2.1                 Edge e = q.prevEdge(0);
83 cananian 1.1.2.1                 Quad.addEdge((Quad)e.from(), e.which_succ(), q0, 0);
84 cananian 1.1.2.1                 Quad.addEdge(q1, 0, (Quad)e.to(), e.which_pred());
85 cananian 1.1.2.1             }
86 cananian 1.1.2.1         };
87 cananian 1.5             for (Iterator<Quad> it=new SnapshotIterator<Quad>
88 cananian 1.5                      (input.hcode().getElementsI()); it.hasNext(); )
89 cananian 1.5                 it.next().accept(qv);
90 cananian 1.1.2.1         return input.hcode();
91 cananian 1.1.2.1     }
92 cananian 1.2     }