1 cananian 1.1 // TreeCallOpt.java, created Thu Jan 11 16:04:23 2001 by cananian
  2 cananian 1.1 // Copyright (C) 2000 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 cananian 1.1 package harpoon.Analysis.DynamicSyncRemoval;
  5 cananian 1.1 
  6 cananian 1.1 import harpoon.Backend.Generic.Frame;
  7 cananian 1.1 import harpoon.Backend.Maps.NameMap;
  8 cananian 1.1 import harpoon.ClassFile.Linker;
  9 cananian 1.1 import harpoon.ClassFile.HClass;
 10 cananian 1.1 import harpoon.ClassFile.HCodeFactory;
 11 cananian 1.1 import harpoon.ClassFile.HField;
 12 cananian 1.1 import harpoon.ClassFile.HMethod;
 13 cananian 1.4 import harpoon.IR.Tree.BINOP;
 14 cananian 1.4 import harpoon.IR.Tree.Bop;
 15 cananian 1.1 import harpoon.IR.Tree.CALL;
 16 cananian 1.1 import harpoon.IR.Tree.CONST;
 17 cananian 1.1 import harpoon.IR.Tree.DerivationGenerator;
 18 cananian 1.1 import harpoon.IR.Tree.Exp;
 19 cananian 1.1 import harpoon.IR.Tree.MEM;
 20 cananian 1.4 import harpoon.IR.Tree.MOVE;
 21 cananian 1.1 import harpoon.IR.Tree.NAME;
 22 cananian 1.1 import harpoon.IR.Tree.NATIVECALL;
 23 cananian 1.1 import harpoon.IR.Tree.Stm;
 24 cananian 1.1 import harpoon.IR.Tree.TreeFactory;
 25 cananian 1.4 import harpoon.IR.Tree.Type;
 26 cananian 1.1 import harpoon.Temp.Label;
 27 cananian 1.1 import harpoon.Util.Util;
 28 cananian 1.1 
 29 cananian 1.1 import java.util.ArrayList;
 30 cananian 1.1 import java.util.List;
 31 cananian 1.1 /**
 32 cananian 1.1  * <code>TreeCallOpt</code> performs some low-level transformations to
 33 cananian 1.1  * tree form to make the calls inserted by <code>SyncRemover</code>
 34 cananian 1.1  * more efficient.
 35 cananian 1.2  * <p>
 36 cananian 1.2  * This optimization may not be safe if you are using precise garbage
 37 cananian 1.2  * collection.
 38 cananian 1.1  *
 39 cananian 1.1  * @author   C. Scott Ananian <cananian@alumni.princeton.edu>
 40 cananian 1.6  * @version $Id: TreeCallOpt.java,v 1.6 2003/07/12 03:13:23 cananian Exp $
 41 cananian 1.1  */
 42 cananian 1.1 class TreeCallOpt extends harpoon.Analysis.Tree.Simplification {
 43 cananian 1.1     private final List<Rule> RULES = new ArrayList<Rule>(); 
 44 cananian 1.1     TreeCallOpt(final Frame f) {
 45 cananian 1.1         Linker l = f.getLinker();
 46 cananian 1.1         final NameMap nm = f.getRuntime().getNameMap();
 47 cananian 1.1 
 48 cananian 1.1         HMethod checkMethod =
 49 cananian 1.2             l.forName("harpoon.Runtime.DynamicSyncImpl")
 50 cananian 1.3             .getMethod("isNoSync",new HClass[]{l.forName("java.lang.Object")});
 51 cananian 1.1         final Label LisSync = nm.label(checkMethod);
 52 cananian 1.1         final Label Lnative_isSync = new Label
 53 cananian 1.6             (nm.c_function_name("EXACT_isNoSync"));
 54 cananian 1.1 
 55 cananian 1.1         // add all rules to rule set
 56 cananian 1.1 
 57 cananian 1.1         // turn calls to certain native methods into direct NATIVECALLs
 58 cananian 1.4         // CALL(retval,retex,NAME(LisSync),ExpList(arg,null),handler,false) ->
 59 cananian 1.4         //    NATIVECALL(retval,NAME(Lnative_isSync),ExpList(arg,null))
 60 cananian 1.4         // or
 61 cananian 1.4         //    MOVE(retval,BINOP(AND,MEM(BINOP(ADD,arg,CONST(OBJ_HASH_OFF))),2))
 62 cananian 1.4         RULES.add(new Rule("isSyncRewrite2") {
 63 cananian 1.1             public boolean match(Stm s) {
 64 cananian 1.1                 if (!contains(_KIND(s), _CALL)) return false;
 65 cananian 1.1                 CALL call = (CALL) s;
 66 cananian 1.1                 if (!contains(_KIND(call.getFunc()), _NAME)) return false;
 67 cananian 1.1                 NAME name = (NAME) call.getFunc();
 68 cananian 1.4                 if (!name.label.equals(LisSync)) return false;
 69 cananian 1.4                 if (call.getArgs()==null ||
 70 cananian 1.4                     call.getArgs().tail!=null) return false;
 71 cananian 1.4                 // yup, this is a match!
 72 cananian 1.4                 return true;
 73 cananian 1.1             }
 74 cananian 1.1             public Stm apply(TreeFactory tf, Stm s, DerivationGenerator dg) {
 75 cananian 1.1                 CALL call = (CALL) s;
 76 cananian 1.4                 if (f.getRuntime().getTreeBuilder() instanceof
 77 cananian 1.4                     harpoon.Backend.Runtime2.TreeBuilder) {
 78 cananian 1.4                     Exp hash =
 79 cananian 1.4                         ((harpoon.Backend.Runtime2.TreeBuilder)
 80 cananian 1.4                          f.getRuntime().getTreeBuilder())
 81 cananian 1.4                         .fetchHash(tf, s, call.getArgs().head);
 82 cananian 1.4                     return new MOVE
 83 cananian 1.4                         (tf, s, call.getRetval(),
 84 cananian 1.4                          new BINOP
 85 cananian 1.4                          (tf, s, Type.INT, Bop.AND,
 86 cananian 1.4                           hash,
 87 cananian 1.4                           new CONST(tf, s, 2)));
 88 cananian 1.4                 } else {
 89 cananian 1.4                     return new NATIVECALL(tf, s, call.getRetval(),
 90 cananian 1.4                                           new NAME(tf, s, Lnative_isSync),
 91 cananian 1.4                                           call.getArgs());
 92 cananian 1.4                 }
 93 cananian 1.1             }
 94 cananian 1.1         });
 95 cananian 1.1     }
 96 cananian 1.1     /** Code factory for applying the post pass to the given tree
 97 cananian 1.1      *  form.  Clones the tree before processing it in-place. */
 98 cananian 1.1     public HCodeFactory codeFactory(final HCodeFactory parent) {
 99 cananian 1.1         return codeFactory(parent, RULES);
100 cananian 1.1     }
101 cananian 1.1 }