001 /* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013 package org.jikesrvm.compilers.opt.dfsolver; 014 015 import java.util.Enumeration; 016 017 import org.jikesrvm.compilers.opt.util.GraphNode; 018 019 /** 020 * Represents a single Data Flow equation. 021 */ 022 public class DF_Equation implements GraphNode { 023 024 /** 025 * Evaluate this equation, setting a new value for the 026 * left-hand side. 027 * 028 * @return {@code true} if the lhs value changed. {@code false} otherwise 029 */ 030 boolean evaluate() { 031 return operator.evaluate(operands); 032 } 033 034 /** 035 * Return the left-hand side of this equation. 036 * 037 * @return the lattice cell this equation computes 038 */ 039 DF_LatticeCell getLHS() { 040 return operands[0]; 041 } 042 043 /** 044 * Return the operands in this equation. 045 * @return the operands in this equation. 046 */ 047 public DF_LatticeCell[] getOperands() { 048 return operands; 049 } 050 051 /** 052 * Return the operator for this equation 053 * @return the operator for this equation 054 */ 055 DF_Operator getOperator() { 056 return operator; 057 } 058 059 /** 060 * Does this equation contain an appearance of a given cell? 061 * @param cell the cell in question 062 * @return true or false 063 */ 064 public boolean hasCell(DF_LatticeCell cell) { 065 for (DF_LatticeCell operand : operands) { 066 if (operand == cell) { 067 return true; 068 } 069 } 070 return false; 071 } 072 073 /** 074 * Return a string representation of this object 075 * @return a string representation of this object 076 */ 077 @Override 078 public String toString() { 079 if (operands[0] == null) { 080 return ("NULL LHS"); 081 } 082 String result = operands[0].toString(); 083 result = result + " " + operator + " "; 084 for (int i = 1; i < operands.length; i++) { 085 result = result + operands[i] + " "; 086 } 087 return result; 088 } 089 090 /** 091 * Constructor for case of one operand on the right-hand side. 092 * 093 * @param lhs the lattice cell set by this equation 094 * @param operator the equation operator 095 * @param op1 the first operand on the rhs 096 */ 097 DF_Equation(DF_LatticeCell lhs, DF_Operator operator, DF_LatticeCell op1) { 098 this.operator = operator; 099 operands = new DF_LatticeCell[2]; 100 operands[0] = lhs; 101 operands[1] = op1; 102 } 103 104 /** 105 * Constructor for case of two operands on the right-hand side. 106 * 107 * @param lhs the lattice cell set by this equation 108 * @param operator the equation operator 109 * @param op1 the first operand on the rhs 110 * @param op2 the second operand on the rhs 111 */ 112 DF_Equation(DF_LatticeCell lhs, DF_Operator operator, DF_LatticeCell op1, DF_LatticeCell op2) { 113 this.operator = operator; 114 operands = new DF_LatticeCell[3]; 115 operands[0] = lhs; 116 operands[1] = op1; 117 operands[2] = op2; 118 } 119 120 /** 121 * Constructor for case of three operands on the right-hand side. 122 * 123 * @param lhs the lattice cell set by this equation 124 * @param operator the equation operator 125 * @param op1 the first operand on the rhs 126 * @param op2 the second operand on the rhs 127 * @param op3 the third operand on the rhs 128 */ 129 DF_Equation(DF_LatticeCell lhs, DF_Operator operator, DF_LatticeCell op1, DF_LatticeCell op2, 130 DF_LatticeCell op3) { 131 this.operator = operator; 132 operands = new DF_LatticeCell[4]; 133 operands[0] = lhs; 134 operands[1] = op1; 135 operands[2] = op2; 136 operands[3] = op3; 137 } 138 139 /** 140 * Constructor for case of more than three operands on the right-hand side. 141 * 142 * @param lhs the lattice cell set by this equation 143 * @param operator the equation operator 144 * @param rhs the operands of the right-hand side in order 145 */ 146 DF_Equation(DF_LatticeCell lhs, DF_Operator operator, DF_LatticeCell[] rhs) { 147 this.operator = operator; 148 operands = new DF_LatticeCell[rhs.length + 1]; 149 operands[0] = lhs; 150 for (int i = 0; i < rhs.length; i++) { 151 operands[i + 1] = rhs[i]; 152 } 153 } 154 155 /** 156 * Get the topological number for this equation 157 * @return the topological number 158 */ 159 int getTopologicalNumber() { 160 return topologicalNumber; 161 } 162 163 /** 164 * Get the topological number for this equation 165 * @param n the topological order 166 */ 167 void setTopologicalNumber(int n) { 168 topologicalNumber = n; 169 } 170 171 /* Implementation */ 172 /** 173 * The operator in the equation 174 */ 175 protected final DF_Operator operator; 176 /** 177 * The operands. Operand[0] is the left hand side. 178 */ 179 protected final DF_LatticeCell[] operands; 180 /** 181 * The number of this equation when the system is sorted in topological 182 * order. 183 */ 184 int topologicalNumber; 185 /** 186 * Field used for GraphNode interface. TODO: is this needed? 187 */ 188 private int index; 189 190 /** 191 * Implementation of GraphNode interface. 192 */ 193 @Override 194 public void setIndex(int i) { 195 index = i; 196 } 197 198 @Override 199 public int getIndex() { 200 return index; 201 } 202 203 /** 204 * Return an enumeration of the equations which use the result of this 205 * equation. 206 * @return an enumeration of the equations which use the result of this 207 * equation. 208 */ 209 @Override 210 public Enumeration<GraphNode> outNodes() { 211 return new Enumeration<GraphNode>() { 212 private GraphNode elt = getLHS(); 213 214 @Override 215 public boolean hasMoreElements() { 216 return elt != null; 217 } 218 219 @Override 220 public GraphNode nextElement() { 221 GraphNode x = elt; 222 elt = null; 223 return x; 224 } 225 }; 226 } 227 228 /** 229 * Return an enumeration of the equations upon whose results this 230 * equation depends. 231 * @return an enumeration of the equations upon whose results this 232 * equation depends 233 */ 234 @Override 235 public Enumeration<GraphNode> inNodes() { 236 return new Enumeration<GraphNode>() { 237 private int i = 1; 238 239 @Override 240 public boolean hasMoreElements() { 241 return (i < operands.length); 242 } 243 244 @Override 245 public GraphNode nextElement() { 246 return operands[i++]; 247 } 248 }; 249 } 250 251 private int scratch; 252 253 @Override 254 public int getScratch() { 255 return scratch; 256 } 257 258 @Override 259 public int setScratch(int o) { 260 return (scratch = o); 261 } 262 }