Mercurial > hg > graal-compiler
comparison graal/com.oracle.graal.nodeinfo.processor/src/com/oracle/graal/nodeinfo/processor/GraphNodeGenerator.java @ 17276:ffb974bef674
moved Node valueNumber and valueEquals logic (optionally) to generated nodes
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 01 Oct 2014 07:39:47 +0200 |
parents | 9eb112c9337d |
children | 072a25e613ba |
comparison
equal
deleted
inserted
replaced
17275:846c059e3ecf | 17276:ffb974bef674 |
---|---|
58 | 58 |
59 final TypeElement Node; | 59 final TypeElement Node; |
60 @SuppressWarnings("unused") private final TypeElement NodeList; | 60 @SuppressWarnings("unused") private final TypeElement NodeList; |
61 private final TypeElement NodeInputList; | 61 private final TypeElement NodeInputList; |
62 private final TypeElement NodeSuccessorList; | 62 private final TypeElement NodeSuccessorList; |
63 private final TypeElement ValueNumberable; | |
63 @SuppressWarnings("unused") private final TypeElement Position; | 64 @SuppressWarnings("unused") private final TypeElement Position; |
64 | 65 |
65 private final List<VariableElement> inputFields = new ArrayList<>(); | 66 private final List<VariableElement> inputFields = new ArrayList<>(); |
66 private final List<VariableElement> inputListFields = new ArrayList<>(); | 67 private final List<VariableElement> inputListFields = new ArrayList<>(); |
67 private final List<VariableElement> successorFields = new ArrayList<>(); | 68 private final List<VariableElement> successorFields = new ArrayList<>(); |
85 this.Node = getTypeElement("com.oracle.graal.graph.Node"); | 86 this.Node = getTypeElement("com.oracle.graal.graph.Node"); |
86 this.NodeList = getTypeElement("com.oracle.graal.graph.NodeList"); | 87 this.NodeList = getTypeElement("com.oracle.graal.graph.NodeList"); |
87 this.NodeInputList = getTypeElement("com.oracle.graal.graph.NodeInputList"); | 88 this.NodeInputList = getTypeElement("com.oracle.graal.graph.NodeInputList"); |
88 this.NodeSuccessorList = getTypeElement("com.oracle.graal.graph.NodeSuccessorList"); | 89 this.NodeSuccessorList = getTypeElement("com.oracle.graal.graph.NodeSuccessorList"); |
89 this.Position = getTypeElement("com.oracle.graal.graph.Position"); | 90 this.Position = getTypeElement("com.oracle.graal.graph.Position"); |
91 this.ValueNumberable = getTypeElement("com.oracle.graal.graph.Node.ValueNumberable"); | |
90 } | 92 } |
91 | 93 |
92 @SafeVarargs | 94 @SafeVarargs |
93 private static Collection<VariableElement> concat(List<VariableElement> fields1, List<VariableElement> fields2, List<VariableElement>... tail) { | 95 private static Collection<VariableElement> concat(List<VariableElement> fields1, List<VariableElement> fields2, List<VariableElement>... tail) { |
94 return new AbstractCollection<VariableElement>() { | 96 return new AbstractCollection<VariableElement>() { |
241 throw new ElementException(field, "NodeInputList field must be annotated with @" + Input.getSimpleName() + " or @" + OptionalInput.getSimpleName()); | 243 throw new ElementException(field, "NodeInputList field must be annotated with @" + Input.getSimpleName() + " or @" + OptionalInput.getSimpleName()); |
242 } | 244 } |
243 if (isAssignableWithErasure(field, NodeSuccessorList)) { | 245 if (isAssignableWithErasure(field, NodeSuccessorList)) { |
244 throw new ElementException(field, "NodeSuccessorList field must be annotated with @" + Successor.getSimpleName()); | 246 throw new ElementException(field, "NodeSuccessorList field must be annotated with @" + Successor.getSimpleName()); |
245 } | 247 } |
248 if (modifiers.contains(PUBLIC) && !modifiers.contains(FINAL)) { | |
249 throw new ElementException(field, "Data field must be final if public otherwise it must be protected or package-private"); | |
250 } else if (modifiers.contains(PRIVATE)) { | |
251 throw new ElementException(field, "Data field must be protected or package-private"); | |
252 } | |
246 dataFields.add(field); | 253 dataFields.add(field); |
247 } | 254 } |
248 } | 255 } |
249 currentClazz = getSuperType(currentClazz); | 256 currentClazz = getSuperType(currentClazz); |
250 } while (!isObject(getSuperType(currentClazz).asType())); | 257 } while (!isObject(getSuperType(currentClazz).asType())); |
332 boolean hasSuccessors = !successorFields.isEmpty() || !successorListFields.isEmpty(); | 339 boolean hasSuccessors = !successorFields.isEmpty() || !successorListFields.isEmpty(); |
333 | 340 |
334 if (hasInputs || hasSuccessors) { | 341 if (hasInputs || hasSuccessors) { |
335 createIsLeafNodeMethod(); | 342 createIsLeafNodeMethod(); |
336 } | 343 } |
344 | |
345 createValueNumberMethod(node); | |
346 createValueEqualsMethod(); | |
337 } | 347 } |
338 compilationUnit.add(genClass); | 348 compilationUnit.add(genClass); |
339 return compilationUnit; | 349 return compilationUnit; |
340 } | 350 } |
341 | 351 |
393 inputTypes.clear(); | 403 inputTypes.clear(); |
394 genClass = null; | 404 genClass = null; |
395 genClassName = null; | 405 genClassName = null; |
396 } | 406 } |
397 | 407 |
398 @SuppressWarnings("unused") | |
399 private CodeVariableElement addParameter(CodeExecutableElement method, TypeMirror type, String name) { | 408 private CodeVariableElement addParameter(CodeExecutableElement method, TypeMirror type, String name) { |
400 return addParameter(method, type, name, true); | 409 return addParameter(method, type, name, true); |
401 } | 410 } |
402 | 411 |
403 private CodeVariableElement addParameter(CodeExecutableElement method, TypeMirror type, String name, boolean checkHiding) { | 412 private CodeVariableElement addParameter(CodeExecutableElement method, TypeMirror type, String name, boolean checkHiding) { |
430 method.createBuilder().startReturn().string("false").end(); | 439 method.createBuilder().startReturn().string("false").end(); |
431 genClass.add(method); | 440 genClass.add(method); |
432 checkOnlyInGenNode(method); | 441 checkOnlyInGenNode(method); |
433 } | 442 } |
434 | 443 |
444 private void createValueNumberMethod(TypeElement node) { | |
445 if (isAssignableWithErasure(node, ValueNumberable)) { | |
446 genClass.add(new CodeVariableElement(modifiers(PRIVATE), getType(int.class), "valueNumber")); | |
447 | |
448 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getType(int.class), "getValueNumber"); | |
449 CodeTreeBuilder b = method.createBuilder(); | |
450 b.startIf().string("valueNumber == 0").end().startBlock(); | |
451 b.startStatement().string("int number = " + node.hashCode()).end(); | |
452 for (VariableElement f : dataFields) { | |
453 String fname = f.getSimpleName().toString(); | |
454 switch (f.asType().getKind()) { | |
455 case BOOLEAN: | |
456 b.startIf().string(fname).end().startBlock(); | |
457 b.startStatement().string("number += 7").end(); | |
458 b.end(); | |
459 break; | |
460 case BYTE: | |
461 case SHORT: | |
462 case CHAR: | |
463 case INT: | |
464 b.startStatement().string("number += 13 * ", fname).end(); | |
465 break; | |
466 case FLOAT: | |
467 b.startStatement().string("number += 17 * Float.floatToRawIntBits(", fname, ")").end(); | |
468 break; | |
469 case LONG: | |
470 b.startStatement().string("number += 19 * ", fname + " ^ (", fname, " >>> 32)").end(); | |
471 break; | |
472 case DOUBLE: | |
473 b.startStatement().string("long longValue = Double.doubleToRawLongBits(", fname, ")").end(); | |
474 b.startStatement().string("number += 23 * longValue ^ (longValue >>> 32)").end(); | |
475 break; | |
476 default: | |
477 b.startIf().string(fname, " != null").end().startBlock(); | |
478 b.startStatement().string("number += 29 * ", fname + ".hashCode()").end(); | |
479 b.end(); | |
480 break; | |
481 } | |
482 } | |
483 b.startStatement().string("valueNumber = number").end(); | |
484 b.end(); | |
485 b.startReturn().string("valueNumber").end(); | |
486 genClass.add(method); | |
487 checkOnlyInGenNode(method); | |
488 } | |
489 } | |
490 | |
491 private void createValueEqualsMethod() { | |
492 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getType(boolean.class), "valueEqualsGen"); | |
493 addParameter(method, Node.asType(), "other"); | |
494 CodeTreeBuilder b = method.createBuilder(); | |
495 if (!dataFields.isEmpty()) { | |
496 String other = "o"; | |
497 b.declaration(genClassName, other, "(" + genClassName + ") other"); | |
498 | |
499 for (VariableElement f : dataFields) { | |
500 String fname = f.getSimpleName().toString(); | |
501 switch (f.asType().getKind()) { | |
502 case BOOLEAN: | |
503 case BYTE: | |
504 case SHORT: | |
505 case CHAR: | |
506 case INT: | |
507 case FLOAT: | |
508 case LONG: | |
509 case DOUBLE: | |
510 b.startIf().string(other, ".", fname, " != ", fname).end().startBlock(); | |
511 b.startStatement().string("return false").end(); | |
512 b.end(); | |
513 break; | |
514 case ARRAY: | |
515 if (((ArrayType) f.asType()).getComponentType().getKind().isPrimitive()) { | |
516 b.startIf().string("!").type(getType(Arrays.class)).string(".equals(", other, ".", fname, ", ", fname, ")").end().startBlock(); | |
517 } else { | |
518 b.startIf().string("!").type(getType(Arrays.class)).string(".deepEquals(", other, ".", fname, ", ", fname, ")").end().startBlock(); | |
519 } | |
520 b.startStatement().string("return false").end(); | |
521 b.end(); | |
522 break; | |
523 default: | |
524 b.startIf().string("!").type(getType(Objects.class)).string(".equals(", other, ".", fname, ", ", fname, ")").end().startBlock(); | |
525 b.startStatement().string("return false").end(); | |
526 b.end(); | |
527 break; | |
528 } | |
529 } | |
530 } | |
531 b.startReturn().string("true").end(); | |
532 genClass.add(method); | |
533 checkOnlyInGenNode(method); | |
534 } | |
535 | |
435 private boolean hidesField(String name) { | 536 private boolean hidesField(String name) { |
436 for (VariableElement field : concat(inputFields, inputListFields, successorFields, successorListFields, dataFields)) { | 537 for (VariableElement field : concat(inputFields, inputListFields, successorFields, successorListFields, dataFields)) { |
437 if (field.getSimpleName().contentEquals(name)) { | 538 if (field.getSimpleName().contentEquals(name)) { |
438 return true; | 539 return true; |
439 } | 540 } |