1 kkz      1.1.2.1 // WriteBarrierConstElim.java, created Thu Aug 23 20:20:34 2001 by kkz
  2 kkz      1.1.2.1 // Copyright (C) 2000 Karen Zee <kkz@tmi.lcs.mit.edu>
  3 kkz      1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 kkz      1.1.2.1 package harpoon.Analysis.PreciseGC;
  5 kkz      1.1.2.1 
  6 kkz      1.1.2.1 import harpoon.Analysis.Tree.Canonicalize;
  7 kkz      1.1.2.1 import harpoon.Analysis.Tree.ConstantPropagation;
  8 kkz      1.1.2.1 import harpoon.Backend.Generic.Frame;
  9 kkz      1.1.2.1 import harpoon.Backend.Maps.NameMap;
 10 kkz      1.5     import harpoon.ClassFile.HClass;
 11 kkz      1.1.2.1 import harpoon.ClassFile.HCode;
 12 kkz      1.1.2.1 import harpoon.ClassFile.HCodeEdge;
 13 kkz      1.1.2.1 import harpoon.ClassFile.HCodeFactory;
 14 kkz      1.1.2.1 import harpoon.ClassFile.HMethod;
 15 kkz      1.5     import harpoon.ClassFile.Linker;
 16 kkz      1.1.2.1 import harpoon.IR.Properties.CFGrapher;
 17 kkz      1.1.2.1 import harpoon.IR.Tree.CALL;
 18 kkz      1.1.2.1 import harpoon.IR.Tree.CanonicalTreeCode;
 19 kkz      1.1.2.1 import harpoon.IR.Tree.CONST;
 20 kkz      1.1.2.1 import harpoon.IR.Tree.DerivationGenerator;
 21 kkz      1.1.2.1 import harpoon.IR.Tree.Exp;
 22 kkz      1.1.2.1 import harpoon.IR.Tree.ExpList;
 23 kkz      1.1.2.1 import harpoon.IR.Tree.EXPR;
 24 kkz      1.1.2.1 import harpoon.IR.Tree.LABEL;
 25 kkz      1.1.2.1 import harpoon.IR.Tree.MOVE;
 26 kkz      1.1.2.1 import harpoon.IR.Tree.NAME;
 27 kkz      1.1.2.1 import harpoon.IR.Tree.Print;
 28 kkz      1.1.2.1 import harpoon.IR.Tree.Stm;
 29 kkz      1.1.2.1 import harpoon.IR.Tree.Tree;
 30 kkz      1.1.2.1 import harpoon.IR.Tree.TreeFactory;
 31 kkz      1.1.2.1 import harpoon.Temp.Label;
 32 kkz      1.1.2.1 import harpoon.Util.Util;
 33 kkz      1.1.2.1 
 34 kkz      1.1.2.1 import java.util.Arrays;
 35 kkz      1.1.2.1 import java.util.List;
 36 kkz      1.1.2.1 
 37 kkz      1.1.2.1 /**
 38 kkz      1.5      * <code>WriteBarrierConstElim</code> operates on <code>Tree</code> form. 
 39 kkz      1.5      * It eliminates write barriers on MOVEs that are assigned from constants. 
 40 kkz      1.5      * Constant propagation should probably be run beforehand for this pass to 
 41 kkz      1.5      * make a difference.
 42 kkz      1.1.2.1  * <p>
 43 kkz      1.5      * If <code>WriteBarrierTreePass</code> is being used, it should be not be run
 44 kkz      1.5      * until after this pass.
 45 kkz      1.1.2.1  * 
 46 kkz      1.1.2.1  * @author  Karen Zee <kkz@tmi.lcs.mit.edu>
 47 cananian 1.6      * @version $Id: WriteBarrierConstElim.java,v 1.6 2003/03/11 19:15:41 cananian Exp $
 48 kkz      1.1.2.1  */
 49 kkz      1.1.2.1 public abstract class WriteBarrierConstElim extends 
 50 kkz      1.1.2.1     harpoon.Analysis.Tree.Simplification {
 51 kkz      1.1.2.1     
 52 kkz      1.1.2.1     // hide constructor
 53 kkz      1.1.2.1     private WriteBarrierConstElim() { }
 54 kkz      1.1.2.1 
 55 kkz      1.1.2.1     /** Code factory for applying <code>WriteBarrierConstElim/code>
 56 kkz      1.1.2.1      *  to a canonical tree.  Clones the tree before doing
 57 kkz      1.1.2.1      *  transformation in-place. */
 58 kkz      1.5         public static HCodeFactory codeFactory(final Frame f, 
 59 kkz      1.5                                                final HCodeFactory parent,
 60 kkz      1.5                                                final Linker linker) {
 61 kkz      1.5             HClass WBC = linker.forName("harpoon.Runtime.PreciseGC.WriteBarrier");
 62 kkz      1.5             HClass JLO = linker.forName("java.lang.Object");
 63 kkz      1.5             HClass JLRF = linker.forName("java.lang.reflect.Field");
 64 kkz      1.5             final HMethod arrayHM = WBC.getMethod("asc", new HClass[]
 65 kkz      1.5                                                   {JLO,HClass.Int,JLO,HClass.Int});
 66 kkz      1.5             final HMethod fieldHM = WBC.getMethod("fsc", new HClass[]
 67 kkz      1.5                                                   {JLO,JLRF,JLO,HClass.Int});
 68 cananian 1.3.2.1         assert parent.getCodeName().equals(CanonicalTreeCode.codename);
 69 kkz      1.1.2.1         return Canonicalize.codeFactory(new HCodeFactory() {
 70 kkz      1.1.2.1             public HCode convert(HMethod m) {
 71 kkz      1.1.2.1                 HCode hc = parent.convert(m);
 72 kkz      1.1.2.1                 if (hc!=null) {
 73 kkz      1.1.2.1                     harpoon.IR.Tree.Code code = (harpoon.IR.Tree.Code) hc;
 74 kkz      1.1.2.1                     // clone code...
 75 kkz      1.1.2.1                     code = (harpoon.IR.Tree.Code) code.clone(m).hcode();
 76 kkz      1.1.2.1                     DerivationGenerator dg = null;
 77 kkz      1.1.2.1                     try {
 78 kkz      1.1.2.1                         dg = (DerivationGenerator) code.getTreeDerivation();
 79 kkz      1.1.2.1                     } catch (ClassCastException ex) { /* i guess not */ }
 80 kkz      1.1.2.1                     // ...do analysis and modify cloned code in-place.
 81 kkz      1.1.2.1                     simplify((Stm)code.getRootElement(), dg, 
 82 kkz      1.1.2.1                              HCE_RULES(code, f, arrayHM, fieldHM));
 83 kkz      1.1.2.1                     hc = code;
 84 kkz      1.1.2.1                 }
 85 kkz      1.1.2.1                 return hc;
 86 kkz      1.1.2.1             }
 87 kkz      1.1.2.1             public String getCodeName() { return parent.getCodeName(); }
 88 kkz      1.1.2.1             public void clear(HMethod m) { parent.clear(m); }
 89 kkz      1.1.2.1         });
 90 kkz      1.1.2.1     }
 91 kkz      1.1.2.1 
 92 cananian 1.6         public static List<Rule> HCE_RULES(final harpoon.IR.Tree.Code code,
 93 kkz      1.1.2.1                                  final Frame f, 
 94 kkz      1.1.2.1                                  final HMethod arrayHM, 
 95 kkz      1.1.2.1                                  final HMethod fieldHM) {
 96 kkz      1.1.2.1         final NameMap nm = f.getRuntime().getNameMap();
 97 kkz      1.1.2.1         final Label LarrayHM = nm.label(arrayHM);
 98 kkz      1.1.2.1         final Label LfieldHM = nm.label(fieldHM);
 99 kkz      1.1.2.1         final CFGrapher cfgr = code.getGrapher();
100 kkz      1.1.2.1         // now make rules
101 kkz      1.1.2.1         return Arrays.asList(new Rule[] {
102 kkz      1.1.2.1             new Rule("removeBarriers") {
103 kkz      1.1.2.1                 public boolean match(Stm stm) {
104 kkz      1.1.2.1                     if (!contains(_KIND(stm), _CALL)) return false;
105 kkz      1.1.2.1                     CALL call = (CALL) stm;
106 kkz      1.1.2.1                     if (!contains(_KIND(call.getFunc()), _NAME)) return false;
107 kkz      1.1.2.1                     NAME n = (NAME) call.getFunc();
108 kkz      1.1.2.1                     if (!n.label.equals(LarrayHM) && !n.label.equals(LfieldHM))
109 kkz      1.1.2.1                         return false;
110 kkz      1.1.2.1                     // now check if we need the write barrier
111 kkz      1.1.2.1                     ExpList explist = call.getArgs();
112 kkz      1.1.2.1                     // get to the third argument
113 kkz      1.1.2.1                     explist = explist.tail;
114 kkz      1.1.2.1                     explist = explist.tail;
115 kkz      1.1.2.1                     Exp val = explist.head;
116 kkz      1.1.2.1                     return (contains(_KIND(val), _CONST|_NAME));
117 kkz      1.1.2.1                 }
118 kkz      1.1.2.1                 public Stm apply(TreeFactory tf, Stm stm, 
119 kkz      1.1.2.1                                  DerivationGenerator dg) {
120 kkz      1.1.2.1                     // we can get rid of the barrier
121 kkz      1.1.2.1                     return new EXPR(tf, stm, new CONST(tf, null));
122 kkz      1.1.2.1                 }
123 kkz      1.1.2.1             }
124 kkz      1.1.2.1         });
125 kkz      1.1.2.1     }
126 cananian 1.2     }