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