1 cananian 1.1.2.1 // TreePostPass.java, created Thu Jan 11 16:04:23 2001 by cananian
  2 cananian 1.1.2.3 // 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.Transactions;
  5 cananian 1.1.2.1 
  6 cananian 1.5     import harpoon.Analysis.Maps.Derivation;
  7 cananian 1.1.2.1 import harpoon.Backend.Generic.Frame;
  8 cananian 1.5     import harpoon.Backend.Generic.Runtime.TreeBuilder;
  9 cananian 1.5     import harpoon.Backend.Maps.NameMap;
 10 cananian 1.1.2.1 import harpoon.ClassFile.HClass;
 11 cananian 1.5     import harpoon.ClassFile.HCodeElement;
 12 cananian 1.1.2.1 import harpoon.ClassFile.HCodeFactory;
 13 cananian 1.1.2.1 import harpoon.ClassFile.HField;
 14 cananian 1.5     import harpoon.ClassFile.HMethod;
 15 cananian 1.5     import harpoon.IR.Tree.BINOP;
 16 cananian 1.5     import harpoon.IR.Tree.Bop;
 17 cananian 1.5     import harpoon.IR.Tree.CALL;
 18 cananian 1.1.2.1 import harpoon.IR.Tree.CONST;
 19 cananian 1.1.2.1 import harpoon.IR.Tree.DerivationGenerator;
 20 cananian 1.1.2.1 import harpoon.IR.Tree.Exp;
 21 cananian 1.5     import harpoon.IR.Tree.ExpList;
 22 cananian 1.1.2.1 import harpoon.IR.Tree.MEM;
 23 cananian 1.5     import harpoon.IR.Tree.MOVE;
 24 cananian 1.1.2.1 import harpoon.IR.Tree.NAME;
 25 cananian 1.5     import harpoon.IR.Tree.NATIVECALL;
 26 cananian 1.5     import harpoon.IR.Tree.SEQ;
 27 cananian 1.5     import harpoon.IR.Tree.Stm;
 28 cananian 1.5     import harpoon.IR.Tree.TEMP;
 29 cananian 1.5     import harpoon.IR.Tree.Translation;
 30 cananian 1.1.2.1 import harpoon.IR.Tree.TreeFactory;
 31 cananian 1.5     import harpoon.IR.Tree.Type;
 32 cananian 1.1.2.1 import harpoon.Temp.Label;
 33 cananian 1.5     import harpoon.Temp.Temp;
 34 cananian 1.1.2.1 import harpoon.Util.Util;
 35 cananian 1.1.2.1 
 36 cananian 1.1.2.1 import java.util.ArrayList;
 37 cananian 1.1.2.1 import java.util.List;
 38 cananian 1.5     import java.util.Iterator;
 39 cananian 1.5     import java.util.HashMap;
 40 cananian 1.5     import java.util.Map;
 41 cananian 1.5     import java.util.Set;
 42 cananian 1.1.2.1 /**
 43 cananian 1.1.2.1  * <code>TreePostPass</code> performs some low-level transformations to
 44 cananian 1.1.2.1  * the output of <code>SyncTransformer</code> which cannot be done in
 45 cananian 1.1.2.1  * the quad form which <code>SyncTransformer</code> operates on.
 46 cananian 1.1.2.1  * <code>TreePostPass</code> works on tree form.
 47 cananian 1.1.2.1  * <p>
 48 cananian 1.1.2.1  * This pass is invoked by <code>SyncTransformer.treeCodeFactory()</code>.
 49 cananian 1.1.2.1  * 
 50 cananian 1.1.2.3  * @author   C. Scott Ananian <cananian@alumni.princeton.edu>
 51 cananian 1.7      * @version $Id: TreePostPass.java,v 1.7 2004/02/08 03:20:25 cananian Exp $
 52 cananian 1.1.2.1  */
 53 cananian 1.1.2.1 class TreePostPass extends harpoon.Analysis.Tree.Simplification {
 54 cananian 1.5         private final List<Rule> RULES = new ArrayList<Rule>(); 
 55 cananian 1.5         final Map<Label,HField> label2field = new HashMap<Label,HField>();
 56 cananian 1.5         final TreeBuilder tb;
 57 cananian 1.5         TreePostPass(final Frame f, final long FLAG_VALUE, HField HFflagvalue,
 58 cananian 1.5                      final MethodGenerator gen, final Set<HField> transFields) {
 59 cananian 1.1.2.4         final Label Lflagvalue = f.getRuntime().getNameMap().label(HFflagvalue);
 60 cananian 1.5             final NameMap nm = f.getRuntime().getNameMap();
 61 cananian 1.5             // map generated methods to labels.
 62 cananian 1.5             final Map<Label,HMethod> label2method = new HashMap<Label,HMethod>();
 63 cananian 1.7             for (HMethod hm : gen.generatedMethodSet) {
 64 cananian 1.5                 label2method.put(nm.label(hm), hm);
 65 cananian 1.5             }
 66 cananian 1.5             // map referenced fields to labels.
 67 cananian 1.7             for (HField hf : transFields) {
 68 cananian 1.5                 label2field.put(nm.label(hf, "obj"), hf);
 69 cananian 1.5             }
 70 cananian 1.5             // cache tree builder
 71 cananian 1.5             tb = f.getRuntime().getTreeBuilder();
 72 cananian 1.5     
 73 cananian 1.5             // -----------------------------------------------------------
 74 cananian 1.1.2.1         // add all rules to rule set
 75 cananian 1.1.2.1         //          ...remove mentions of Object.flagValue field...
 76 cananian 1.1.2.2         // MEM(NAME(Label(flagValue))) -> CONST(0xCACACACAL)
 77 cananian 1.1.2.1         RULES.add(new Rule("constFlagValue") {
 78 cananian 1.1.2.1             public boolean match(Exp e) {
 79 cananian 1.1.2.1                 if (!contains(_KIND(e), _MEM)) return false;
 80 cananian 1.1.2.1                 MEM mem = (MEM) e;
 81 cananian 1.1.2.1                 if (!contains(_KIND(mem.getExp()), _NAME)) return false;
 82 cananian 1.1.2.1                 NAME name = (NAME) mem.getExp();
 83 cananian 1.1.2.1                 // check label.
 84 cananian 1.1.2.1                 return name.label.equals(Lflagvalue);
 85 cananian 1.1.2.1             }
 86 cananian 1.1.2.1             public Exp apply(TreeFactory tf, Exp e, DerivationGenerator dg) {
 87 cananian 1.1.2.1                 MEM e1 = (MEM) e;
 88 cananian 1.1.2.1                 NAME e2 = (NAME) e1.getExp();
 89 cananian 1.1.2.1                 if (dg!=null) { dg.remove(e1); dg.remove(e2); }
 90 cananian 1.1.2.1                 CONST c = f.pointersAreLong() ?
 91 cananian 1.1.2.1                     new CONST(tf, e, FLAG_VALUE) :
 92 cananian 1.1.2.1                     new CONST(tf, e, (int) FLAG_VALUE);
 93 cananian 1.1.2.1                 if (dg!=null) { dg.putType(c, HClass.Void); }
 94 cananian 1.1.2.1                 return c;
 95 cananian 1.1.2.1             }
 96 cananian 1.1.2.1         });
 97 cananian 1.1.2.1         // other uses of flagValue are errors.
 98 cananian 1.1.2.1         // NAME(Label(flagValue)) -> CONST(0) (and assert false)
 99 cananian 1.1.2.1         RULES.add(new Rule("assertFlagValue") {
100 cananian 1.1.2.1             public boolean match(Exp e) {
101 cananian 1.1.2.1                 if (contains(_KIND(e.getParent()), _MEM)) return false;
102 cananian 1.1.2.1                 if (!contains(_KIND(e), _NAME)) return false;
103 cananian 1.1.2.1                 NAME name = (NAME) e;
104 cananian 1.1.2.1                 // check label.
105 cananian 1.1.2.1                 boolean b = name.label.equals(Lflagvalue);
106 cananian 1.3.2.1                 assert !b : "flag value slipped past us!";
107 cananian 1.1.2.1                 return b;
108 cananian 1.1.2.1             }
109 cananian 1.1.2.1             // otherwise a very visible (we hope) runtime error.
110 cananian 1.1.2.1             public Exp apply(TreeFactory tf, Exp e, DerivationGenerator dg) {
111 cananian 1.1.2.1                 return new CONST(tf, e); // null pointer
112 cananian 1.1.2.1             }
113 cananian 1.1.2.1         });
114 cananian 1.5     
115 cananian 1.5             // turn calls to certain native methods into direct NATIVECALLs
116 cananian 1.5             // CALL(retval,retex,NAME(xxx),args,handler,false) ->
117 cananian 1.5             //    NATIVECALL(retval,NAME(Lnative_isSync),ExpList(arg,null))
118 cananian 1.5             // or
119 cananian 1.5             //    MOVE(retval,BINOP(AND,MEM(BINOP(ADD,arg,CONST(OBJ_HASH_OFF))),2))
120 cananian 1.5             RULES.add(new Rule("isSyncRewrite2") {
121 cananian 1.5                 public boolean match(Stm s) {
122 cananian 1.5                     if (!contains(_KIND(s), _CALL)) return false;
123 cananian 1.5                     CALL call = (CALL) s;
124 cananian 1.5                     if (!contains(_KIND(call.getFunc()), _NAME)) return false;
125 cananian 1.5                     NAME name = (NAME) call.getFunc();
126 cananian 1.5                     if (!label2method.containsKey(name.label)) return false;
127 cananian 1.5                     String baseName = gen.baseName(label2method.get(name.label));
128 cananian 1.5                     return methodTransformer.containsKey(baseName);
129 cananian 1.5                 }
130 cananian 1.5                 public Stm apply(TreeFactory tf, Stm s, DerivationGenerator dg) {
131 cananian 1.5                     CALL call = (CALL) s;
132 cananian 1.5                     NAME name = (NAME) call.getFunc();
133 cananian 1.5                     HMethod hm = label2method.get(name.label);
134 cananian 1.5                     String baseName = gen.baseName(hm);
135 cananian 1.5                     Transformer t = methodTransformer.get(baseName);
136 cananian 1.5                     String methodName = "EXACT_"+baseName;
137 cananian 1.5                     HClass suf = t.functionSuffix(hm, call.getArgs());
138 cananian 1.5                     if (suf!=null)
139 cananian 1.5                         methodName += "_" + 
140 cananian 1.5                             titlecase(suf.isPrimitive()? suf.getName() : "Object");
141 cananian 1.5                     Label Lmethod = new Label(nm.c_function_name(methodName));
142 cananian 1.5     
143 cananian 1.5                     return new NATIVECALL(tf, s, call.getRetval(),
144 cananian 1.5                                           new NAME(tf, s, Lmethod),
145 cananian 1.5                                           t.transformArgs(tf, s, dg, hm,
146 cananian 1.5                                                           call.getArgs()));
147 cananian 1.5                 }
148 cananian 1.5             });
149 cananian 1.5         }
150 cananian 1.5         private final String titlecase(String s) {
151 cananian 1.5             if (s.length()==0) return s;
152 cananian 1.5             return s.substring(0,1).toUpperCase()+s.substring(1);
153 cananian 1.5         }
154 cananian 1.5     
155 cananian 1.5         abstract class Transformer {
156 cananian 1.5             abstract HClass functionSuffix(HMethod methodVersion,
157 cananian 1.5                                            ExpList javaArgs);
158 cananian 1.5             abstract ExpList transformArgs(TreeFactory tf, HCodeElement source,
159 cananian 1.5                                            DerivationGenerator dg,
160 cananian 1.5                                            HMethod hm, ExpList javaArgs);
161 cananian 1.5             // helper functions.
162 cananian 1.5             Exp extract(ExpList args, int index) {
163 cananian 1.5                 while (index!=0) {
164 cananian 1.5                     args = args.tail;
165 cananian 1.5                     index--;
166 cananian 1.5                 }
167 cananian 1.5                 return args.head;
168 cananian 1.5             }
169 cananian 1.5             ExpList subst(ExpList args, Exp e, int index) {
170 cananian 1.5                 if (index==0) return new ExpList(e, args.tail);
171 cananian 1.5                 else return new ExpList(args.head, subst(args.tail, e, index-1));
172 cananian 1.5             }
173 cananian 1.5             HField findField(Exp e) {
174 cananian 1.5                 NAME name = (NAME) e;
175 cananian 1.5                 return label2field.get(name.label);
176 cananian 1.5             }
177 cananian 1.5         }
178 cananian 1.5         final Transformer nullTransformer = new Transformer() {
179 cananian 1.5                 HClass functionSuffix(HMethod hm, ExpList javaArgs) {
180 cananian 1.5                     return null;
181 cananian 1.5                 }
182 cananian 1.5                 ExpList transformArgs(TreeFactory tf, HCodeElement source,
183 cananian 1.5                                       DerivationGenerator dg,
184 cananian 1.5                                       HMethod hm, ExpList javaArgs) {
185 cananian 1.5                     return javaArgs;
186 cananian 1.5                 }
187 cananian 1.5             };
188 cananian 1.5         final Transformer fieldTransformer = new Transformer() {
189 cananian 1.5                 HClass functionSuffix(HMethod hm, ExpList javaArgs) {
190 cananian 1.5                     return findField(extract(javaArgs, 1)).getType();
191 cananian 1.5                 }
192 cananian 1.5                 ExpList transformArgs(TreeFactory tf, HCodeElement source,
193 cananian 1.5                                       DerivationGenerator dg,
194 cananian 1.5                                       HMethod hm, ExpList javaArgs) {
195 cananian 1.5                     // args are <obj, field, flag field, ...>
196 cananian 1.5                     // we need to calculate offset from fields
197 cananian 1.5                     HField objF = findField(extract(javaArgs, 1));
198 cananian 1.5                     HField flagF = findField(extract(javaArgs, 2)); 
199 cananian 1.5                     Exp offsetE= tb.fieldOffset(tf, source, dg, objF).unEx(tf);
200 cananian 1.5                     Exp flagE = tb.fieldOffset(tf, source, dg, flagF).unEx(tf);
201 cananian 1.5                     return subst(subst(javaArgs, offsetE, 1), flagE, 2);
202 cananian 1.5                 }
203 cananian 1.5             };
204 cananian 1.5         final Transformer arrayTransformer = new Transformer() {
205 cananian 1.5                 HClass functionSuffix(HMethod hm, ExpList javaArgs) {
206 cananian 1.5                     return hm.getParameterTypes()[0].getComponentType();
207 cananian 1.5                 }
208 cananian 1.5                 ExpList transformArgs(TreeFactory tf, HCodeElement source,
209 cananian 1.5                                       DerivationGenerator dg,
210 cananian 1.5                                       HMethod hm, ExpList javaArgs) {
211 cananian 1.5                     HClass objType = hm.getParameterTypes()[0];
212 cananian 1.5                     // args are <obj, index, flag field, ...>
213 cananian 1.5                     // we need to calculate offset from index.
214 cananian 1.5                     Exp indexE = extract(javaArgs, 1);
215 cananian 1.5                     HField flagF = findField(extract(javaArgs, 2)); 
216 cananian 1.5                     Exp offsetE = tb.arrayOffset
217 cananian 1.5                         (tf, source, dg, objType, new Translation.Ex(indexE))
218 cananian 1.5                         .unEx(tf);
219 cananian 1.5                     Exp flagE = tb.fieldOffset(tf, source, dg, flagF).unEx(tf);
220 cananian 1.5                     return subst(subst(javaArgs, offsetE, 1), flagE, 2);
221 cananian 1.5                 }
222 cananian 1.5             };
223 cananian 1.6         final Transformer limitedFieldTransformer = new Transformer() {
224 cananian 1.6                 HClass functionSuffix(HMethod hm, ExpList javaArgs) {
225 cananian 1.6                     return findField(extract(javaArgs, 1)).getType();
226 cananian 1.6                 }
227 cananian 1.6                 ExpList transformArgs(TreeFactory tf, HCodeElement source,
228 cananian 1.6                                       DerivationGenerator dg,
229 cananian 1.6                                       HMethod hm, ExpList javaArgs) {
230 cananian 1.6                     // args are <obj, field, ...>
231 cananian 1.6                     // we need to calculate offset from fields
232 cananian 1.6                     HField objF = findField(extract(javaArgs, 1));
233 cananian 1.6                     Exp offsetE= tb.fieldOffset(tf, source, dg, objF).unEx(tf);
234 cananian 1.6                     return subst(javaArgs, offsetE, 1);
235 cananian 1.6                 }
236 cananian 1.6             };
237 cananian 1.6         final Transformer limitedArrayTransformer = new Transformer() {
238 cananian 1.6                 HClass functionSuffix(HMethod hm, ExpList javaArgs) {
239 cananian 1.6                     return hm.getParameterTypes()[0].getComponentType();
240 cananian 1.6                 }
241 cananian 1.6                 ExpList transformArgs(TreeFactory tf, HCodeElement source,
242 cananian 1.6                                       DerivationGenerator dg,
243 cananian 1.6                                       HMethod hm, ExpList javaArgs) {
244 cananian 1.6                     HClass objType = hm.getParameterTypes()[0];
245 cananian 1.6                     // args are <obj, index, ...>
246 cananian 1.6                     // we need to calculate offset from index.
247 cananian 1.6                     Exp indexE = extract(javaArgs, 1);
248 cananian 1.6                     Exp offsetE = tb.arrayOffset
249 cananian 1.6                         (tf, source, dg, objType, new Translation.Ex(indexE))
250 cananian 1.6                         .unEx(tf);
251 cananian 1.6                     return subst(javaArgs, offsetE, 1);
252 cananian 1.6                 }
253 cananian 1.6             };
254 cananian 1.5     
255 cananian 1.5         final Map<String,Transformer> methodTransformer =
256 cananian 1.5             new HashMap<String,Transformer>();
257 cananian 1.5         {
258 cananian 1.5             // VALUETYPE TA(EXACT_readT)(struct oobj *obj, int offset,
259 cananian 1.5             //                           struct vinfo *version,
260 cananian 1.5             //                           struct commitrec *cr);
261 cananian 1.5             methodTransformer.put("readT", new Transformer() {
262 cananian 1.5                     HClass functionSuffix(HMethod hm, ExpList javaArgs) {
263 cananian 1.5                         return hm.getReturnType();
264 cananian 1.5                     }
265 cananian 1.5                     ExpList transformArgs(TreeFactory tf, HCodeElement source,
266 cananian 1.5                                           DerivationGenerator dg,
267 cananian 1.5                                           HMethod hm, ExpList javaArgs) {
268 cananian 1.5                         // args are <obj, field, version, transaction>
269 cananian 1.5                         // we need to calculate offset from field.
270 cananian 1.5                         HField hf = findField(extract(javaArgs, 1));
271 cananian 1.5                         Exp offsetE = tb.fieldOffset(tf, source, dg, hf)
272 cananian 1.5                             .unEx(tf);
273 cananian 1.5                         return subst(javaArgs, offsetE, 1);
274 cananian 1.5                     }
275 cananian 1.5                 });
276 cananian 1.5             methodTransformer.put("readT_Array", new Transformer() {
277 cananian 1.5                     HClass functionSuffix(HMethod hm, ExpList javaArgs) {
278 cananian 1.5                         return hm.getReturnType();
279 cananian 1.5                     }
280 cananian 1.5                     ExpList transformArgs(TreeFactory tf, HCodeElement source,
281 cananian 1.5                                           DerivationGenerator dg,
282 cananian 1.5                                           HMethod hm, ExpList javaArgs) {
283 cananian 1.5                         HClass objType = hm.getParameterTypes()[0];
284 cananian 1.5                         // args are <obj, index, version, transaction>
285 cananian 1.5                         // we need to calculate offset from index.
286 cananian 1.5                         Exp indexE = extract(javaArgs, 1);
287 cananian 1.5                         Exp offsetE = tb.arrayOffset(tf, source, dg, objType,
288 cananian 1.5                                                      new Translation.Ex(indexE))
289 cananian 1.5                             .unEx(tf);
290 cananian 1.5                         return subst(javaArgs, offsetE, 1);
291 cananian 1.5                     }
292 cananian 1.5                 });
293 cananian 1.5             // VALUETYPE TA(EXACT_readNT)(struct oobj *obj, int offset,
294 cananian 1.5             //                            int flag_offset, int flag_bit);
295 cananian 1.5             methodTransformer.put("readNT", fieldTransformer);
296 cananian 1.5             methodTransformer.put("readNT_Array", arrayTransformer);
297 cananian 1.5             // void TA(EXACT_writeT)(struct oobj *obj, int offset,
298 cananian 1.5             //                       VALUETYPE value, struct vinfo *version);
299 cananian 1.5             methodTransformer.put("writeT", new Transformer() {
300 cananian 1.5                     HClass functionSuffix(HMethod hm, ExpList javaArgs) {
301 cananian 1.5                         return hm.getParameterTypes()[2];
302 cananian 1.5                     }
303 cananian 1.5                     ExpList transformArgs(TreeFactory tf, HCodeElement source,
304 cananian 1.5                                           DerivationGenerator dg,
305 cananian 1.5                                           HMethod hm, ExpList javaArgs) {
306 cananian 1.5                         // args are <obj, field, value, version>
307 cananian 1.5                         // we need to calculate offset from field.
308 cananian 1.5                         HField hf = findField(extract(javaArgs, 1));
309 cananian 1.5                         Exp offsetE = tb.fieldOffset(tf, source, dg, hf)
310 cananian 1.5                             .unEx(tf);
311 cananian 1.5                         return subst(javaArgs, offsetE, 1);
312 cananian 1.5                     }
313 cananian 1.5                 });
314 cananian 1.5             methodTransformer.put("writeT_Array", new Transformer() {
315 cananian 1.5                     HClass functionSuffix(HMethod hm, ExpList javaArgs) {
316 cananian 1.5                         return hm.getParameterTypes()[2];
317 cananian 1.5                     }
318 cananian 1.5                     ExpList transformArgs(TreeFactory tf, HCodeElement source,
319 cananian 1.5                                           DerivationGenerator dg,
320 cananian 1.5                                           HMethod hm, ExpList javaArgs) {
321 cananian 1.5                         HClass objType = hm.getParameterTypes()[0];
322 cananian 1.5                         // args are <obj, index, value, version>
323 cananian 1.5                         // we need to calculate offset from index.
324 cananian 1.5                         Exp indexE = extract(javaArgs, 1);
325 cananian 1.5                         Exp offsetE = tb.arrayOffset(tf, source, dg, objType,
326 cananian 1.5                                                      new Translation.Ex(indexE))
327 cananian 1.5                             .unEx(tf);
328 cananian 1.5                         return subst(javaArgs, offsetE, 1);
329 cananian 1.5                     }
330 cananian 1.5                 });
331 cananian 1.5             // void TA(EXACT_writeNT)(struct oobj *obj, int offset,
332 cananian 1.5             //                        VALUETYPE value,
333 cananian 1.5             //                        int flag_offset, int flag_bit);
334 cananian 1.5             methodTransformer.put("writeNT", new Transformer() {
335 cananian 1.5                     HClass functionSuffix(HMethod hm, ExpList javaArgs) {
336 cananian 1.5                         return hm.getParameterTypes()[2];
337 cananian 1.5                     }
338 cananian 1.5                     ExpList transformArgs(TreeFactory tf, HCodeElement source,
339 cananian 1.5                                           DerivationGenerator dg,
340 cananian 1.5                                           HMethod hm, ExpList javaArgs) {
341 cananian 1.5                         // args are <obj, field, value, flag field, flag bit>
342 cananian 1.5                         // we need to calculate offset from fields
343 cananian 1.5                         HField objF = findField(extract(javaArgs, 1));
344 cananian 1.5                         HField flagF = findField(extract(javaArgs, 3)); 
345 cananian 1.5                         Exp offsetE= tb.fieldOffset(tf, source, dg, objF).unEx(tf);
346 cananian 1.5                         Exp flagE = tb.fieldOffset(tf, source, dg, flagF).unEx(tf);
347 cananian 1.5                         return subst(subst(javaArgs, offsetE, 1), flagE, 3);
348 cananian 1.5                     }
349 cananian 1.5                 });
350 cananian 1.5             methodTransformer.put("writeNT_Array", new Transformer() {
351 cananian 1.5                     HClass functionSuffix(HMethod hm, ExpList javaArgs) {
352 cananian 1.5                         return hm.getParameterTypes()[2];
353 cananian 1.5                     }
354 cananian 1.5                     ExpList transformArgs(TreeFactory tf, HCodeElement source,
355 cananian 1.5                                           DerivationGenerator dg,
356 cananian 1.5                                           HMethod hm, ExpList javaArgs) {
357 cananian 1.5                         HClass objType = hm.getParameterTypes()[0];
358 cananian 1.5                         // args are <obj, index, value, flag field, flag bit>
359 cananian 1.5                         // we need to calculate offset from index.
360 cananian 1.5                         Exp indexE = extract(javaArgs, 1);
361 cananian 1.5                         HField flagF = findField(extract(javaArgs, 3)); 
362 cananian 1.5                         Exp offsetE = tb.arrayOffset
363 cananian 1.5                             (tf, source, dg, objType, new Translation.Ex(indexE))
364 cananian 1.5                             .unEx(tf);
365 cananian 1.5                         Exp flagE = tb.fieldOffset(tf, source, dg, flagF).unEx(tf);
366 cananian 1.5                         return subst(subst(javaArgs, offsetE, 1), flagE, 3);
367 cananian 1.5                     }
368 cananian 1.5                 });
369 cananian 1.5             // void EXACT_ensureReader(struct oobj *obj,
370 cananian 1.5             //                         struct commitrec *cr);
371 cananian 1.5             // struct vinfo *EXACT_ensureWriter(struct oobj *obj,
372 cananian 1.5             //                                  struct commitrec *cr);
373 cananian 1.5             methodTransformer.put("ensureReader", nullTransformer);
374 cananian 1.5             methodTransformer.put("ensureWriter", nullTransformer);
375 cananian 1.5             // struct vinfo *TA(EXACT_setReadFlags)(struct oobj *obj, int offset,
376 cananian 1.5             //                                      int flag_offset, int flag_bit,
377 cananian 1.5             //                                      struct vinfo *version,
378 cananian 1.5             //                                      struct commitrec *cr);
379 cananian 1.5             methodTransformer.put("setReadFlags", fieldTransformer);
380 cananian 1.5             methodTransformer.put("setReadFlags_Array", arrayTransformer);
381 cananian 1.5             // void TA(EXACT_setWriteFlags)(struct oobj *obj, int offset,
382 cananian 1.5             //                              int flag_offset, int flag_bit,
383 cananian 1.5             //                              struct vinfo *version);
384 cananian 1.5             methodTransformer.put("setWriteFlags", fieldTransformer);
385 cananian 1.5             methodTransformer.put("setWriteFlags_Array", arrayTransformer);
386 cananian 1.6     
387 cananian 1.6             // methods related to hardware transaction mechanism.
388 cananian 1.6             methodTransformer.put("XACTION_BEGIN", nullTransformer);
389 cananian 1.6             methodTransformer.put("XACTION_END", nullTransformer);
390 cananian 1.6             // void TA(EXACT_traceRead)(struct oobj *obj, int offset, int istran);
391 cananian 1.6             // void TA(EXACT_traceWrite)(struct oobj *obj, int offset, int istran);
392 cananian 1.6             methodTransformer.put("traceRead", limitedFieldTransformer);
393 cananian 1.6             methodTransformer.put("traceRead_Array", limitedArrayTransformer);
394 cananian 1.6             methodTransformer.put("traceWrite", limitedFieldTransformer);
395 cananian 1.6             methodTransformer.put("traceWrite_Array", limitedArrayTransformer);
396 cananian 1.1.2.1     }
397 cananian 1.5     
398 cananian 1.1.2.1     /** Code factory for applying the post pass to the given tree
399 cananian 1.1.2.1      *  form.  Clones the tree before processing it in-place. */
400 cananian 1.1.2.1     public HCodeFactory codeFactory(final HCodeFactory parent) {
401 cananian 1.1.2.1         return codeFactory(parent, RULES);
402 cananian 1.5         }
403 cananian 1.5     
404 cananian 1.5         // type declaration helper methods
405 cananian 1.5         protected static Exp DECLARE(DerivationGenerator dg, HClass hc, Exp exp) {
406 cananian 1.5             if (dg!=null) dg.putType(exp, hc);
407 cananian 1.5             return exp;
408 cananian 1.5         }
409 cananian 1.5         protected static Exp DECLARE(DerivationGenerator dg, HClass hc, Temp t,
410 cananian 1.5                                      Exp exp) {
411 cananian 1.5             if (dg!=null) dg.putTypeAndTemp(exp, hc, t);
412 cananian 1.5             return exp;
413 cananian 1.5         }
414 cananian 1.5         protected static Exp DECLARE(DerivationGenerator dg, Derivation.DList dl,
415 cananian 1.5                                      Exp exp) {
416 cananian 1.5             if (dg!=null) dg.putDerivation(exp, dl);
417 cananian 1.5             return exp;
418 cananian 1.1.2.1     }
419 cananian 1.2     }