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 }