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 }