1 cananian 1.2 // TreeDataFilter.java, created Fri Oct 15 14:13:17 1999 by cananian
  2 cananian 1.2 // Copyright (C) 1999 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.2 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 cananian 1.2 package harpoon.Analysis.Transactions;
  5 cananian 1.2 
  6 cananian 1.2 import harpoon.Analysis.Transactions.BitFieldNumbering.BitFieldTuple;
  7 cananian 1.2 import harpoon.Backend.Generic.Frame;
  8 cananian 1.2 import harpoon.Backend.Generic.Runtime.TreeBuilder;
  9 cananian 1.2 import harpoon.Backend.Maps.NameMap;
 10 cananian 1.2 import harpoon.ClassFile.HClass;
 11 cananian 1.2 import harpoon.ClassFile.HData;
 12 cananian 1.2 import harpoon.ClassFile.HDataElement;
 13 cananian 1.2 import harpoon.ClassFile.HField;
 14 cananian 1.2 import harpoon.ClassFile.HMethod;
 15 cananian 1.2 import harpoon.IR.Tree.Stm;
 16 cananian 1.2 import harpoon.IR.Tree.TreeFactory;
 17 cananian 1.2 import harpoon.IR.Tree.ALIGN;
 18 cananian 1.2 import harpoon.IR.Tree.CONST;
 19 cananian 1.2 import harpoon.IR.Tree.DATUM;
 20 cananian 1.2 import harpoon.IR.Tree.Exp;
 21 cananian 1.2 import harpoon.IR.Tree.LABEL;
 22 cananian 1.2 import harpoon.IR.Tree.SEGMENT;
 23 cananian 1.2 import harpoon.IR.Tree.SEQ;
 24 cananian 1.2 import harpoon.IR.Tree.TreeKind;
 25 cananian 1.2 import harpoon.Temp.Label;
 26 cananian 1.3 import net.cscott.jutil.FilterIterator;
 27 cananian 1.2 
 28 cananian 1.2 import java.util.ArrayList;
 29 cananian 1.2 import java.util.HashMap;
 30 cananian 1.2 import java.util.Iterator;
 31 cananian 1.2 import java.util.List;
 32 cananian 1.2 import java.util.Map;
 33 cananian 1.2 import java.util.Set;
 34 cananian 1.2 import java.util.Stack;
 35 cananian 1.2 /**
 36 cananian 1.2  * <code>TreeDataFilter</code> hacks through the field information tables
 37 cananian 1.2  * emitted by <code>Runtime1.DataReflection2</code> to add in additional
 38 cananian 1.2  * information about the bitfield-numbering of fields.
 39 cananian 1.2  * 
 40 cananian 1.2  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 41 cananian 1.4  * @version $Id: TreeDataFilter.java,v 1.4 2004/02/08 03:20:25 cananian Exp $
 42 cananian 1.2  */
 43 cananian 1.2 public class TreeDataFilter extends FilterIterator.Filter<HData,HData> {
 44 cananian 1.2     final Frame f;
 45 cananian 1.2     final NameMap nm;
 46 cananian 1.2     final TreeBuilder tb;
 47 cananian 1.2     final BitFieldNumbering bfn;
 48 cananian 1.2     final Set<HField> transFields;
 49 cananian 1.2     final Map<Label,HField> label2field = new HashMap<Label,HField>();
 50 cananian 1.2     final boolean pointersAreLong;
 51 cananian 1.2     /** Creates a <code>DataInitializers</code>. */
 52 cananian 1.2     public TreeDataFilter(Frame f,
 53 cananian 1.2                           BitFieldNumbering bfn, Set<HField> transFields) {
 54 cananian 1.2         this.f = f; this.bfn = bfn;  this.transFields = transFields;
 55 cananian 1.2         this.nm = f.getRuntime().getNameMap();
 56 cananian 1.2         this.tb = f.getRuntime().getTreeBuilder();
 57 cananian 1.2         this.pointersAreLong = f.pointersAreLong();
 58 cananian 1.2         // map fields to field info labels.
 59 cananian 1.4         for (HField hf : transFields) {
 60 cananian 1.2             Label l = nm.label(hf, "info");
 61 cananian 1.2             label2field.put(l, hf);
 62 cananian 1.2         }
 63 cananian 1.2     }
 64 cananian 1.2     public HData map(HData d) {
 65 cananian 1.2         if (d instanceof harpoon.Backend.Runtime1.DataReflection2) {
 66 cananian 1.2             // iterate through the Data, looking for the field info
 67 cananian 1.2             // table.
 68 cananian 1.2             int countdown=-1; HField which=null;
 69 cananian 1.4             for (Stm s : linearize((Stm)d.getRootElement())
 70 cananian 1.4                 ) {
 71 cananian 1.2                 if (s instanceof LABEL &&
 72 cananian 1.2                     label2field.containsKey(((LABEL)s).label)) {
 73 cananian 1.2                     // hey, we're getting close!  it's the fifth datum
 74 cananian 1.2                     // that we want to change, now.
 75 cananian 1.2                     which = label2field.get(((LABEL)s).label);
 76 cananian 1.2                     countdown=5;
 77 cananian 1.2                 } else if (which!=null && s instanceof DATUM) {
 78 cananian 1.2                     countdown--;
 79 cananian 1.2                     if (countdown==0) { // this is the one to change.
 80 cananian 1.2                         TreeFactory tf = s.getFactory();
 81 cananian 1.2                         BitFieldTuple bft = bfn.bfLoc(which);
 82 cananian 1.2                         Exp fldoffE = // get bitfield offset
 83 cananian 1.2                             tb.fieldOffset(tf, null, null, bft.field).unEx(tf);
 84 cananian 1.2                         int data = 1 /* indicate data is valid */ +
 85 cananian 1.2                             2 * bft.bit /* bit # in bitfield */ +
 86 cananian 1.2                             64 * ((CONST)fldoffE).value.intValue();
 87 cananian 1.2                         CONST c;
 88 cananian 1.2                         if (pointersAreLong)
 89 cananian 1.2                             c = new CONST(tf, null, (long) data);
 90 cananian 1.2                         else
 91 cananian 1.2                             c = new CONST(tf, null, (int) data);
 92 cananian 1.2                         s.replace(new DATUM(tf, null, c));
 93 cananian 1.2                         // done!
 94 cananian 1.2                         which=null;
 95 cananian 1.2                     }
 96 cananian 1.2                 }
 97 cananian 1.2             }
 98 cananian 1.2         }
 99 cananian 1.2         return d;
100 cananian 1.2     }
101 cananian 1.2     // from Stm.java
102 cananian 1.2     public static List<Stm> linearize(Stm stm) {
103 cananian 1.2         List<Stm>  l = new ArrayList<Stm>();
104 cananian 1.2         Stack<Stm> s = new Stack<Stm>();
105 cananian 1.2         s.push(stm);
106 cananian 1.2 
107 cananian 1.2         while (!s.isEmpty()) {
108 cananian 1.2             Stm next = s.pop();
109 cananian 1.2             if (next.kind() == TreeKind.SEQ) {
110 cananian 1.2                 SEQ seq = (SEQ)next;
111 cananian 1.2                 s.push(seq.getRight());
112 cananian 1.2                 s.push(seq.getLeft());
113 cananian 1.2             }
114 cananian 1.2             else {
115 cananian 1.2                 l.add(next);
116 cananian 1.2             }
117 cananian 1.2         }
118 cananian 1.2         return l;
119 cananian 1.2     }
120 cananian 1.2 }