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 */ 013package org.jikesrvm.compilers.opt.dfsolver; 014 015import java.util.Enumeration; 016 017import org.jikesrvm.compilers.opt.util.GraphNode; 018 019/** 020 * Represents a single Data Flow equation. 021 */ 022public 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 StringBuilder result = new StringBuilder(operands[0].toString()); 083 result.append(' '); 084 result.append(operator); 085 result.append(' '); 086 for (int i = 1; i < operands.length; i++) { 087 result.append(operands[i]); 088 result.append(" "); 089 } 090 return result.toString(); 091 } 092 093 /** 094 * Constructor for case of one operand on the right-hand side. 095 * 096 * @param lhs the lattice cell set by this equation 097 * @param operator the equation operator 098 * @param op1 the first operand on the rhs 099 */ 100 DF_Equation(DF_LatticeCell lhs, DF_Operator operator, DF_LatticeCell op1) { 101 this.operator = operator; 102 operands = new DF_LatticeCell[2]; 103 operands[0] = lhs; 104 operands[1] = op1; 105 } 106 107 /** 108 * Constructor for case of two operands on the right-hand side. 109 * 110 * @param lhs the lattice cell set by this equation 111 * @param operator the equation operator 112 * @param op1 the first operand on the rhs 113 * @param op2 the second operand on the rhs 114 */ 115 DF_Equation(DF_LatticeCell lhs, DF_Operator operator, DF_LatticeCell op1, DF_LatticeCell op2) { 116 this.operator = operator; 117 operands = new DF_LatticeCell[3]; 118 operands[0] = lhs; 119 operands[1] = op1; 120 operands[2] = op2; 121 } 122 123 /** 124 * Constructor for case of three operands on the right-hand side. 125 * 126 * @param lhs the lattice cell set by this equation 127 * @param operator the equation operator 128 * @param op1 the first operand on the rhs 129 * @param op2 the second operand on the rhs 130 * @param op3 the third operand on the rhs 131 */ 132 DF_Equation(DF_LatticeCell lhs, DF_Operator operator, DF_LatticeCell op1, DF_LatticeCell op2, 133 DF_LatticeCell op3) { 134 this.operator = operator; 135 operands = new DF_LatticeCell[4]; 136 operands[0] = lhs; 137 operands[1] = op1; 138 operands[2] = op2; 139 operands[3] = op3; 140 } 141 142 /** 143 * Constructor for case of more than three operands on the right-hand side. 144 * 145 * @param lhs the lattice cell set by this equation 146 * @param operator the equation operator 147 * @param rhs the operands of the right-hand side in order 148 */ 149 DF_Equation(DF_LatticeCell lhs, DF_Operator operator, DF_LatticeCell[] rhs) { 150 this.operator = operator; 151 operands = new DF_LatticeCell[rhs.length + 1]; 152 operands[0] = lhs; 153 for (int i = 0; i < rhs.length; i++) { 154 operands[i + 1] = rhs[i]; 155 } 156 } 157 158 /** 159 * Get the topological number for this equation 160 * @return the topological number 161 */ 162 int getTopologicalNumber() { 163 return topologicalNumber; 164 } 165 166 /** 167 * Get the topological number for this equation 168 * @param n the topological order 169 */ 170 void setTopologicalNumber(int n) { 171 topologicalNumber = n; 172 } 173 174 /* Implementation */ 175 /** 176 * The operator in the equation 177 */ 178 protected final DF_Operator operator; 179 /** 180 * The operands. Operand[0] is the left hand side. 181 */ 182 protected final DF_LatticeCell[] operands; 183 /** 184 * The number of this equation when the system is sorted in topological 185 * order. 186 */ 187 int topologicalNumber; 188 /** 189 * Field used for GraphNode interface. TODO: is this needed? 190 */ 191 private int index; 192 193 /** 194 * Implementation of GraphNode interface. 195 */ 196 @Override 197 public void setIndex(int i) { 198 index = i; 199 } 200 201 @Override 202 public int getIndex() { 203 return index; 204 } 205 206 /** 207 * Return an enumeration of the equations which use the result of this 208 * equation. 209 * @return an enumeration of the equations which use the result of this 210 * equation. 211 */ 212 @Override 213 public Enumeration<GraphNode> outNodes() { 214 return new Enumeration<GraphNode>() { 215 private GraphNode elt = getLHS(); 216 217 @Override 218 public boolean hasMoreElements() { 219 return elt != null; 220 } 221 222 @Override 223 public GraphNode nextElement() { 224 GraphNode x = elt; 225 elt = null; 226 return x; 227 } 228 }; 229 } 230 231 /** 232 * Return an enumeration of the equations upon whose results this 233 * equation depends. 234 * @return an enumeration of the equations upon whose results this 235 * equation depends 236 */ 237 @Override 238 public Enumeration<GraphNode> inNodes() { 239 return new Enumeration<GraphNode>() { 240 private int i = 1; 241 242 @Override 243 public boolean hasMoreElements() { 244 return (i < operands.length); 245 } 246 247 @Override 248 public GraphNode nextElement() { 249 return operands[i++]; 250 } 251 }; 252 } 253 254}