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 org.jikesrvm.compilers.opt.util.GraphNode;
016 import org.jikesrvm.compilers.opt.util.GraphNodeEnumeration;
017
018 /**
019 * DF_Equation.java
020 *
021 * represents a single Data Flow equation
022 */
023 public class DF_Equation implements GraphNode {
024
025 /**
026 * Evaluate this equation, setting a new value for the
027 * left-hand side.
028 *
029 * @return true if the lhs value changed. false otherwise
030 */
031 boolean evaluate() {
032 return operator.evaluate(operands);
033 }
034
035 /**
036 * Return the left-hand side of this equation.
037 *
038 * @return the lattice cell this equation computes
039 */
040 DF_LatticeCell getLHS() {
041 return operands[0];
042 }
043
044 /**
045 * Return the operandsin this equation.
046 * @return the operands in this equation.
047 */
048 public DF_LatticeCell[] getOperands() {
049 return operands;
050 }
051
052 /**
053 * Return the operator for this equation
054 * @return the operator for this equation
055 */
056 DF_Operator getOperator() {
057 return operator;
058 }
059
060 /**
061 * Does this equation contain an appearance of a given cell?
062 * @param cell the cell in question
063 * @return true or false
064 */
065 public boolean hasCell(DF_LatticeCell cell) {
066 for (DF_LatticeCell operand : operands) {
067 if (operand == cell) {
068 return true;
069 }
070 }
071 return false;
072 }
073
074 /**
075 * Return a string representation of this object
076 * @return a string representation of this object
077 */
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 public void setIndex(int i) {
194 index = i;
195 }
196
197 /**
198 * Implementation of GraphNode interface.
199 */
200 public int getIndex() {
201 return index;
202 }
203
204 /**
205 * Return an enumeration of the equations which use the result of this
206 * equation.
207 * @return an enumeration of the equations which use the result of this
208 * equation.
209 */
210 public GraphNodeEnumeration outNodes() {
211 return new GraphNodeEnumeration() {
212 private GraphNode elt = getLHS();
213
214 public boolean hasMoreElements() {
215 return elt != null;
216 }
217
218 public GraphNode next() {
219 GraphNode x = elt;
220 elt = null;
221 return x;
222 }
223
224 public GraphNode nextElement() {
225 return next();
226 }
227 };
228 }
229
230 /**
231 * Return an enumeration of the equations upon whose results this
232 * equation depends.
233 * @return an enumeration of the equations upon whose results this
234 * equation depends
235 */
236 public GraphNodeEnumeration inNodes() {
237 return new GraphNodeEnumeration() {
238 private int i = 1;
239
240 public boolean hasMoreElements() {
241 return (i < operands.length);
242 }
243
244 public GraphNode next() {
245 return operands[i++];
246 }
247
248 public GraphNode nextElement() {
249 return next();
250 }
251 };
252 }
253
254 private int scratch;
255
256 public int getScratch() {
257 return scratch;
258 }
259
260 public int setScratch(int o) {
261 return (scratch = o);
262 }
263 }