PageRenderTime 25ms CodeModel.GetById 6ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 1ms

/src/kilim/analysis/Value.java

http://github.com/kilim/kilim
Java | 199 lines | 126 code | 26 blank | 47 comment | 36 complexity | fa17ea5e9ee1dc6b861688f753a85d71 MD5 | raw file
  1/* Copyright (c) 2006, Sriram Srinivasan
  2 *
  3 * You may distribute this software under the terms of the license 
  4 * specified in the file "License"
  5 */
  6
  7package kilim.analysis;
  8import static kilim.Constants.D_UNDEFINED;
  9import static kilim.Constants.D_NULL;
 10
 11import java.util.Arrays;
 12import kilim.mirrors.Detector;
 13
 14/**
 15 * A SSA value that represents all objects produced at a particular 
 16 * location in the code. Value objects are used by dataflow analysis
 17 * (@see BasicBlock)
 18 * 
 19 */
 20public class Value {
 21    public static Object NO_VAL = new Object();
 22    public static Value V_UNDEFINED = new Value(0, D_UNDEFINED, NO_VAL); 
 23    
 24    private String typeDesc;
 25    
 26    private Object constVal;
 27    
 28    private int  numSites;
 29    private int[] sites;
 30    
 31    public int getNumSites() {return numSites;}
 32    
 33    public int[] getCreationSites() {return sites;}
 34    
 35    public String getTypeDesc() {return typeDesc;}
 36    
 37    public Object getConstVal() {return constVal;}
 38    
 39    private Value(int aPos, String aDesc, Object aConst) {
 40        sites = new int[2];
 41        numSites = 1;
 42        sites[0] = aPos;
 43        typeDesc = aDesc;
 44        constVal = aConst;
 45        //System.out.println("V[" + aPos + ":" + aDesc + ((aConst == NO_VAL) ? "" : (": " + aConst)) + "]");
 46    }
 47    
 48    private Value(int newNumSites, int[] newSites, String newType, Object newConst) {
 49        Arrays.sort(newSites, 0, newNumSites);
 50        numSites = newNumSites;
 51        sites = newSites;
 52        typeDesc = newType;
 53        constVal = newConst;
 54        /*//debug
 55        StringBuilder sb = new StringBuilder(80);
 56        sb.append("V[");
 57        for (int i = 0; i < newNumSites; i++) {
 58            if (i > 0) sb.append(",");
 59            sb.append(newSites[i]);
 60        }
 61        sb.append(":").append(newType).append(":");
 62        if (newConst != NO_VAL) {
 63            sb.append(": ").append(newConst.toString());
 64        }
 65        sb.append("]");
 66        System.out.println(sb);
 67        */
 68    }
 69
 70    /**
 71     * Produces a new value (if necessary), if the instructions are different or 
 72     * the types are different. The types are merged to form a least common
 73     * upper bound, and the instruction sets are unioned.
 74     * @param vb
 75     * @return this if the result of the merge is no different, or the new value
 76     */
 77    public Value merge(Detector det,Value other) {
 78        int[] newSites = new int[this.numSites + other.numSites];
 79        for (int i = 0; i < newSites.length; i++) newSites[i] = -1;
 80        int newNumSites = mergeSites(newSites, other);
 81        String newType;
 82        try {
 83            newType = TypeDesc.mergeType(det, this.typeDesc, other.typeDesc);
 84        } catch (IncompatibleTypesException e) {
 85            newType = D_UNDEFINED;
 86        }
 87        Object newConst = (constVal.equals(other.constVal)) ? constVal : NO_VAL;
 88        if (newNumSites != numSites || newType != typeDesc || newConst != constVal) {
 89            return new Value(newNumSites, newSites, newType, newConst);
 90        } else {
 91            return this; // no change
 92        }
 93    }
 94    
 95    private int mergeSites(int[]newSites, Value other) {
 96        int uniqueNumSites = 0;
 97        for (int i = 0; i < numSites; i++) {
 98            uniqueNumSites += addTo(newSites, sites[i]);
 99        }
100        for (int i = 0; i < other.numSites; i++) {
101            uniqueNumSites += addTo(newSites, other.sites[i]);
102        }
103        return uniqueNumSites;
104    }
105    
106    
107    private int addTo(int[] newSites, int site) {
108        for (int i = 0; i < newSites.length; i++) {
109            int s = newSites[i];
110            if (s == -1) {
111                newSites[i] = site;
112                return 1; // added an element 
113            }
114            if (s == site) return 0; // added no elements
115        }
116        return 0;
117    }
118
119    @Override
120    public boolean equals(Object obj) {
121        if (this == obj) return true;
122        Value other = (Value)obj;
123        if (this.typeDesc.equals(other.typeDesc) &&
124                this.constVal.equals(other.constVal) &&
125                        this.numSites == other.numSites) {
126            // Check sites
127            for (int i = 0; i < this.numSites; i++) {
128                if (sites[i] != other.sites[i]) {
129                    return false;
130                }
131            }
132                return true;
133            }
134        return false;
135    }
136
137    @Override
138    public int hashCode() {
139        int h = typeDesc.hashCode();
140        for (int i = 0; i < numSites; i++) {
141            h ^= sites[i];
142        }
143        return h;
144    }
145
146    /** 
147     * create a new Value with the given position and type and no constant value
148     * @param pos the position in the method for the corresponding instruction, or a unique value for method params
149     * @param desc the type descriptor
150     * @return the new Value
151     */
152    public static Value make(int pos, String desc) {
153        return new Value(pos, desc, NO_VAL);
154    }
155    
156    /**
157     * create a new Value
158     * @param pos the position in the method for the corresponding instruction, or a unique value for method params
159     * @param desc the type descriptor
160     * @param aConstVal the constant value
161     * @return the new Value
162     */
163    public static Value make(int pos, String desc, Object aConstVal) {
164        return new Value(pos, desc, aConstVal);
165    }
166
167    public boolean isCategory2() {
168        return category() == 2;
169    }
170    
171    public boolean isCategory1() {
172        return category() == 1;
173    }
174    
175    @Override
176    public String toString() {
177        if (numSites == 0 && typeDesc == D_UNDEFINED) return "undef";
178        StringBuffer sb = new StringBuffer(40);
179        sb.append(typeDesc).append('[');
180        for (int i = 0; i < numSites; i++) {
181            if (i > 0) sb.append(' ');
182            sb.append(sites[i]);
183        }
184        sb.append(']');
185        if (constVal != NO_VAL) {
186            sb.append(" == ").append(constVal.toString());
187        }
188        return sb.toString();
189    }
190
191    public boolean isConstant() {
192        return constVal != NO_VAL || typeDesc == D_NULL;
193    }
194
195    public int category() {
196        return TypeDesc.isDoubleWord(typeDesc) ? 2 : 1;
197    }
198    
199}