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 }