comparison graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java @ 13140:3f1c70baa3bd

use separate data structure for canonicalizing ConstantNodes (GRAAL-508)
author Doug Simon <doug.simon@oracle.com>
date Mon, 25 Nov 2013 12:46:45 +0100
parents 9db9e37ee4b8
children 32f606699ce5
comparison
equal deleted inserted replaced
13139:f9d908fb3492 13140:3f1c70baa3bd
20 * or visit www.oracle.com if you need additional information or have any 20 * or visit www.oracle.com if you need additional information or have any
21 * questions. 21 * questions.
22 */ 22 */
23 package com.oracle.graal.nodes; 23 package com.oracle.graal.nodes;
24 24
25 import static com.oracle.graal.graph.Graph.*;
26
25 import java.util.*; 27 import java.util.*;
26 28
27 import com.oracle.graal.api.meta.*; 29 import com.oracle.graal.api.meta.*;
28 import com.oracle.graal.debug.*; 30 import com.oracle.graal.debug.*;
29 import com.oracle.graal.graph.*; 31 import com.oracle.graal.graph.*;
40 42
41 private static final DebugMetric ConstantNodes = Debug.metric("ConstantNodes"); 43 private static final DebugMetric ConstantNodes = Debug.metric("ConstantNodes");
42 44
43 private final Constant value; 45 private final Constant value;
44 46
45 protected ConstantNode(Constant value) { 47 private static ConstantNode createPrimitive(Constant value) {
46 super(StampFactory.forConstant(value)); 48 assert value.getKind() != Kind.Object;
47 this.value = value; 49 return new ConstantNode(value, StampFactory.forConstant(value));
48 ConstantNodes.increment(); 50 }
49 } 51
50 52 /**
51 /** 53 * Constructs a new node representing the specified constant.
52 * Constructs a new ConstantNode representing the specified constant.
53 * 54 *
54 * @param value the constant 55 * @param value the constant
55 */ 56 */
56 protected ConstantNode(Constant value, MetaAccessProvider metaAccess) { 57 protected ConstantNode(Constant value, Stamp stamp) {
57 super(StampFactory.forConstant(value, metaAccess)); 58 super(stamp);
59 assert stamp != null;
58 this.value = value; 60 this.value = value;
59 ConstantNodes.increment(); 61 ConstantNodes.increment();
60 } 62 }
61 63
62 /** 64 /**
108 } 110 }
109 return usages; 111 return usages;
110 } 112 }
111 113
112 /** 114 /**
113 * Gathers all the {@link ConstantNode}s that are inputs to the {@linkplain Graph#getNodes() 115 * Gathers all the {@link ConstantNode}s that are inputs to the
114 * live nodes} in a given graph. This is an expensive operation that should only be used in 116 * {@linkplain StructuredGraph#getNodes() live nodes} in a given graph. This is an expensive
115 * test/verification/AOT code. 117 * operation that should only be used in test/verification/AOT code.
116 */ 118 */
117 public static NodeIterable<ConstantNode> getConstantNodes(StructuredGraph graph) { 119 public static NodeIterable<ConstantNode> getConstantNodes(StructuredGraph graph) {
118 Map<ConstantNode, ConstantNode> result = new HashMap<>(); 120 Map<ConstantNode, ConstantNode> result = new HashMap<>();
119 for (Node node : graph.getNodes()) { 121 for (Node node : graph.getNodes()) {
120 for (Node input : node.inputs()) { 122 for (Node input : node.inputs()) {
164 } 166 }
165 } 167 }
166 return true; 168 return true;
167 } 169 }
168 170
169 public static ConstantNode forConstant(Constant constant, MetaAccessProvider metaAccess, Graph graph) { 171 public static ConstantNode forConstant(Constant constant, MetaAccessProvider metaAccess, StructuredGraph graph) {
170 if (constant.getKind().getStackKind() == Kind.Int && constant.getKind() != Kind.Int) { 172 if (constant.getKind().getStackKind() == Kind.Int && constant.getKind() != Kind.Int) {
171 return forInt(constant.asInt(), graph); 173 return forInt(constant.asInt(), graph);
172 } else if (constant.getKind() == Kind.Object) { 174 }
173 return unique(graph, new ConstantNode(constant, metaAccess)); 175 if (!CacheExternalNodesInGraph) {
176 Stamp stamp = constant.getKind() == Kind.Object ? StampFactory.forConstant(constant, metaAccess) : StampFactory.forConstant(constant);
177 return graph.asConstantNode(constant, stamp);
178 }
179 if (constant.getKind() == Kind.Object) {
180 return unique(graph, new ConstantNode(constant, StampFactory.forConstant(constant, metaAccess)));
174 } else { 181 } else {
175 return unique(graph, new ConstantNode(constant)); 182 return unique(graph, createPrimitive(constant));
176 } 183 }
177 } 184 }
178 185
179 /** 186 /**
180 * Returns a node for a primitive constant. 187 * Returns a node for a primitive constant.
181 */ 188 */
182 public static ConstantNode forPrimitive(Constant constant, Graph graph) { 189 public static ConstantNode forPrimitive(Constant constant, StructuredGraph graph) {
183 assert constant.getKind() != Kind.Object; 190 assert constant.getKind() != Kind.Object;
184 return forConstant(constant, null, graph); 191 return forConstant(constant, null, graph);
185 } 192 }
186 193
187 /** 194 /**
188 * Returns a node for a double constant. 195 * Returns a node for a double constant.
189 * 196 *
190 * @param d the double value for which to create the instruction 197 * @param d the double value for which to create the instruction
191 * @return a node for a double constant 198 * @return a node for a double constant
192 */ 199 */
193 public static ConstantNode forDouble(double d, Graph graph) { 200 public static ConstantNode forDouble(double d, StructuredGraph graph) {
194 return unique(graph, new ConstantNode(Constant.forDouble(d))); 201 if (!CacheExternalNodesInGraph) {
202 return graph.asConstantNode(Constant.forDouble(d), null);
203 }
204 return unique(graph, createPrimitive(Constant.forDouble(d)));
195 } 205 }
196 206
197 /** 207 /**
198 * Returns a node for a float constant. 208 * Returns a node for a float constant.
199 * 209 *
200 * @param f the float value for which to create the instruction 210 * @param f the float value for which to create the instruction
201 * @return a node for a float constant 211 * @return a node for a float constant
202 */ 212 */
203 public static ConstantNode forFloat(float f, Graph graph) { 213 public static ConstantNode forFloat(float f, StructuredGraph graph) {
204 return unique(graph, new ConstantNode(Constant.forFloat(f))); 214 if (!CacheExternalNodesInGraph) {
215 return graph.asConstantNode(Constant.forFloat(f), null);
216 }
217 return unique(graph, createPrimitive(Constant.forFloat(f)));
205 } 218 }
206 219
207 /** 220 /**
208 * Returns a node for an long constant. 221 * Returns a node for an long constant.
209 * 222 *
210 * @param i the long value for which to create the instruction 223 * @param i the long value for which to create the instruction
211 * @return a node for an long constant 224 * @return a node for an long constant
212 */ 225 */
213 public static ConstantNode forLong(long i, Graph graph) { 226 public static ConstantNode forLong(long i, StructuredGraph graph) {
214 return unique(graph, new ConstantNode(Constant.forLong(i))); 227 if (!CacheExternalNodesInGraph) {
228 return graph.asConstantNode(Constant.forLong(i), null);
229 }
230 return unique(graph, createPrimitive(Constant.forLong(i)));
215 } 231 }
216 232
217 /** 233 /**
218 * Returns a node for an integer constant. 234 * Returns a node for an integer constant.
219 * 235 *
220 * @param i the integer value for which to create the instruction 236 * @param i the integer value for which to create the instruction
221 * @return a node for an integer constant 237 * @return a node for an integer constant
222 */ 238 */
223 public static ConstantNode forInt(int i, Graph graph) { 239 public static ConstantNode forInt(int i, StructuredGraph graph) {
224 return unique(graph, new ConstantNode(Constant.forInt(i))); 240 if (!CacheExternalNodesInGraph) {
241 return graph.asConstantNode(Constant.forInt(i), null);
242 }
243 return unique(graph, createPrimitive(Constant.forInt(i)));
225 } 244 }
226 245
227 /** 246 /**
228 * Returns a node for a boolean constant. 247 * Returns a node for a boolean constant.
229 * 248 *
230 * @param i the boolean value for which to create the instruction 249 * @param i the boolean value for which to create the instruction
231 * @return a node representing the boolean 250 * @return a node representing the boolean
232 */ 251 */
233 public static ConstantNode forBoolean(boolean i, Graph graph) { 252 public static ConstantNode forBoolean(boolean i, StructuredGraph graph) {
234 return unique(graph, new ConstantNode(Constant.forInt(i ? 1 : 0))); 253 if (!CacheExternalNodesInGraph) {
254 return graph.asConstantNode(i ? Constant.INT_1 : Constant.INT_0, null);
255 }
256 return unique(graph, createPrimitive(Constant.forInt(i ? 1 : 0)));
235 } 257 }
236 258
237 /** 259 /**
238 * Returns a node for a byte constant. 260 * Returns a node for a byte constant.
239 * 261 *
240 * @param i the byte value for which to create the instruction 262 * @param i the byte value for which to create the instruction
241 * @return a node representing the byte 263 * @return a node representing the byte
242 */ 264 */
243 public static ConstantNode forByte(byte i, Graph graph) { 265 public static ConstantNode forByte(byte i, StructuredGraph graph) {
244 return unique(graph, new ConstantNode(Constant.forInt(i))); 266 if (!CacheExternalNodesInGraph) {
267 return graph.asConstantNode(Constant.forInt(i), null);
268 }
269 return unique(graph, createPrimitive(Constant.forInt(i)));
245 } 270 }
246 271
247 /** 272 /**
248 * Returns a node for a char constant. 273 * Returns a node for a char constant.
249 * 274 *
250 * @param i the char value for which to create the instruction 275 * @param i the char value for which to create the instruction
251 * @return a node representing the char 276 * @return a node representing the char
252 */ 277 */
253 public static ConstantNode forChar(char i, Graph graph) { 278 public static ConstantNode forChar(char i, StructuredGraph graph) {
254 return unique(graph, new ConstantNode(Constant.forInt(i))); 279 if (!CacheExternalNodesInGraph) {
280 return graph.asConstantNode(Constant.forInt(i), null);
281 }
282 return unique(graph, createPrimitive(Constant.forInt(i)));
255 } 283 }
256 284
257 /** 285 /**
258 * Returns a node for a short constant. 286 * Returns a node for a short constant.
259 * 287 *
260 * @param i the short value for which to create the instruction 288 * @param i the short value for which to create the instruction
261 * @return a node representing the short 289 * @return a node representing the short
262 */ 290 */
263 public static ConstantNode forShort(short i, Graph graph) { 291 public static ConstantNode forShort(short i, StructuredGraph graph) {
264 return unique(graph, new ConstantNode(Constant.forInt(i))); 292 if (!CacheExternalNodesInGraph) {
293 return graph.asConstantNode(Constant.forInt(i), null);
294 }
295 return unique(graph, createPrimitive(Constant.forInt(i)));
265 } 296 }
266 297
267 /** 298 /**
268 * Returns a node for an object constant. 299 * Returns a node for an object constant.
269 * 300 *
270 * @param o the object value for which to create the instruction 301 * @param o the object value for which to create the instruction
271 * @return a node representing the object 302 * @return a node representing the object
272 */ 303 */
273 public static ConstantNode forObject(Object o, MetaAccessProvider metaAccess, Graph graph) { 304 public static ConstantNode forObject(Object o, MetaAccessProvider metaAccess, StructuredGraph graph) {
274 assert !(o instanceof Constant) : "wrapping a Constant into a Constant"; 305 assert !(o instanceof Constant) : "wrapping a Constant into a Constant";
275 return unique(graph, new ConstantNode(Constant.forObject(o), metaAccess)); 306 Constant constant = Constant.forObject(o);
276 } 307 if (!CacheExternalNodesInGraph) {
277 308 return graph.asConstantNode(constant, StampFactory.forConstant(constant, metaAccess));
278 private static ConstantNode unique(Graph graph, ConstantNode node) { 309 }
279 return graph.uniqueWithoutAdd(node); 310 return unique(graph, new ConstantNode(constant, StampFactory.forConstant(constant, metaAccess)));
280 } 311 }
281 312
282 public static ConstantNode forIntegerKind(Kind kind, long value, Graph graph) { 313 private static ConstantNode unique(StructuredGraph graph, ConstantNode node) {
314 assert CacheExternalNodesInGraph;
315 return graph.uniqueExternal(node);
316 }
317
318 public static ConstantNode forIntegerKind(Kind kind, long value, StructuredGraph graph) {
283 switch (kind) { 319 switch (kind) {
284 case Byte: 320 case Byte:
285 case Short: 321 case Short:
286 case Int: 322 case Int:
287 return ConstantNode.forInt((int) value, graph); 323 return ConstantNode.forInt((int) value, graph);
290 default: 326 default:
291 throw GraalInternalError.shouldNotReachHere("unknown kind " + kind); 327 throw GraalInternalError.shouldNotReachHere("unknown kind " + kind);
292 } 328 }
293 } 329 }
294 330
295 public static ConstantNode forFloatingKind(Kind kind, double value, Graph graph) { 331 public static ConstantNode forFloatingKind(Kind kind, double value, StructuredGraph graph) {
296 switch (kind) { 332 switch (kind) {
297 case Float: 333 case Float:
298 return ConstantNode.forFloat((float) value, graph); 334 return ConstantNode.forFloat((float) value, graph);
299 case Double: 335 case Double:
300 return ConstantNode.forDouble(value, graph); 336 return ConstantNode.forDouble(value, graph);
301 default: 337 default:
302 throw GraalInternalError.shouldNotReachHere("unknown kind " + kind); 338 throw GraalInternalError.shouldNotReachHere("unknown kind " + kind);
303 } 339 }
304 } 340 }
305 341
306 public static ConstantNode defaultForKind(Kind kind, Graph graph) { 342 public static ConstantNode defaultForKind(Kind kind, StructuredGraph graph) {
307 switch (kind) { 343 switch (kind) {
308 case Boolean: 344 case Boolean:
309 case Byte: 345 case Byte:
310 case Char: 346 case Char:
311 case Short: 347 case Short: