1 kkz      1.1 // DynamicWBTreePass.java, created Tue Jun 25 14:35:31 2002 by kkz
 2 kkz      1.1 // Copyright (C) 2000 Karen Zee <kkz@tmi.lcs.mit.edu>
 3 kkz      1.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
 4 kkz      1.1 package harpoon.Analysis.PreciseGC;
 5 kkz      1.1 
 6 kkz      1.1 import harpoon.Analysis.Tree.Canonicalize;
 7 kkz      1.1 import harpoon.Backend.Generic.Frame;
 8 kkz      1.1 import harpoon.Backend.Generic.Runtime;
 9 kkz      1.1 import harpoon.Backend.Runtime1.TreeBuilder;
10 kkz      1.1 import harpoon.ClassFile.HClass;
11 kkz      1.1 import harpoon.ClassFile.HCode;
12 kkz      1.1 import harpoon.ClassFile.HCodeFactory;
13 kkz      1.1 import harpoon.ClassFile.HMethod;
14 kkz      1.1 import harpoon.ClassFile.Linker;
15 kkz      1.1 import harpoon.IR.Tree.CanonicalTreeCode;
16 kkz      1.1 import harpoon.IR.Tree.CALL;
17 kkz      1.1 import harpoon.IR.Tree.DerivationGenerator;
18 kkz      1.1 import harpoon.IR.Tree.NAME;
19 kkz      1.1 import harpoon.IR.Tree.Stm;
20 kkz      1.1 import harpoon.IR.Tree.TreeFactory;
21 kkz      1.1 import harpoon.Temp.Label;
22 kkz      1.1 
23 kkz      1.1 import java.util.Arrays;
24 kkz      1.1 import java.util.List;
25 kkz      1.1 
26 kkz      1.1 /**
27 kkz      1.1  * <code>DynamicWBTreePass</code> performs some low-level transformations to
28 kkz      1.1  * the output of <code>DynamicWBQuadPass</code> which cannot be done in the
29 kkz      1.1  * quad form on which <code>DynamicWBQuadPass</code> operates. 
30 kkz      1.1  * <code>DynamicWBTreePass</code> works on tree form.
31 kkz      1.1  * <p>
32 kkz      1.1  * 
33 kkz      1.1  * 
34 kkz      1.1  * @author  Karen Zee <kkz@tmi.lcs.mit.edu>
35 cananian 1.2  * @version $Id: DynamicWBTreePass.java,v 1.2 2003/03/11 19:15:41 cananian Exp $
36 kkz      1.1  */
37 kkz      1.1 public class DynamicWBTreePass extends harpoon.Analysis.Tree.Simplification {
38 kkz      1.1     
39 kkz      1.1     // hide constructor
40 kkz      1.1     private DynamicWBTreePass() { }
41 kkz      1.1         
42 kkz      1.1     /** Code factory for applying <code>DynamicWBTreePass</code> to a
43 kkz      1.1      *  canonical tree.  Clones the tree before doing transformation in-place.
44 kkz      1.1      */
45 kkz      1.1     static public HCodeFactory codeFactory(final HCodeFactory parent,
46 kkz      1.1                                            final Frame frame,
47 kkz      1.1                                            final Linker linker) {
48 kkz      1.1         final HMethod clearHM = 
49 kkz      1.1             linker.forName("harpoon.Runtime.PreciseGC.WriteBarrier").getMethod
50 kkz      1.1             ("clearBit", new HClass[] { linker.forName("java.lang.Object") });
51 kkz      1.1         assert parent.getCodeName().equals(CanonicalTreeCode.codename);
52 kkz      1.1         return Canonicalize.codeFactory(new HCodeFactory() {
53 kkz      1.1             public HCode convert(HMethod m) {
54 kkz      1.1                 HCode hc = parent.convert(m);
55 kkz      1.1                 if (hc!=null) {
56 kkz      1.1                     harpoon.IR.Tree.Code code = (harpoon.IR.Tree.Code) hc;
57 kkz      1.1                     // clone code...
58 kkz      1.1                     code = (harpoon.IR.Tree.Code) code.clone(m).hcode();
59 kkz      1.1                     DerivationGenerator dg = null;
60 kkz      1.1                     try {
61 kkz      1.1                         dg = (DerivationGenerator) code.getTreeDerivation();
62 kkz      1.1                     } catch (ClassCastException ex) { /* i guess not */ }
63 kkz      1.1                     // ...do analysis and modify cloned code in-place.
64 kkz      1.1                     simplify((Stm)code.getRootElement(), dg, 
65 kkz      1.1                              HCE_RULES(frame, clearHM));
66 kkz      1.1                     hc = code;
67 kkz      1.1                 }
68 kkz      1.1                 return hc;
69 kkz      1.1             }
70 kkz      1.1             public String getCodeName() { return parent.getCodeName(); }
71 kkz      1.1             public void clear(HMethod m) { parent.clear(m); }
72 kkz      1.1         });
73 kkz      1.1     }
74 kkz      1.1 
75 cananian 1.2     private static List<Rule> HCE_RULES(final Frame frame, final HMethod clearHM) {
76 kkz      1.1         final Runtime runtime = frame.getRuntime();
77 kkz      1.1         final Label LclearHM = runtime.getNameMap().label(clearHM);
78 kkz      1.1         // now make rules
79 kkz      1.1         return Arrays.asList(new Rule[] {
80 kkz      1.1             new Rule("replaceClearBit") {
81 kkz      1.1                 // match calls to clearBit method
82 kkz      1.1                 public boolean match(Stm stm) {
83 kkz      1.1                     if (!contains(_KIND(stm), _CALL)) return false;
84 kkz      1.1                     CALL call = (CALL) stm;
85 kkz      1.1                     if (!contains(_KIND(call.getFunc()), _NAME)) return false;
86 kkz      1.1                     return ((NAME) call.getFunc()).label.equals(LclearHM);
87 kkz      1.1                 }
88 kkz      1.1                 public Stm apply(TreeFactory tf, Stm stm,
89 kkz      1.1                                  DerivationGenerator dg) {
90 kkz      1.1                     TreeBuilder tb = (TreeBuilder) runtime.getTreeBuilder();
91 kkz      1.1                     return tb.clearHashBit
92 kkz      1.1                         (tf, stm, dg, ((CALL)stm).getArgs().head);
93 kkz      1.1                 }
94 kkz      1.1             }
95 kkz      1.1         });
96 kkz      1.1     }
97 kkz      1.1 }