< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java

Print this page




 331         final String nodePackage;
 332 
 333         /**
 334          * The matchable inputs of the node.
 335          */
 336         final List<String> inputs;
 337 
 338         /**
 339          * Should swapped variants of this match be generated. The user of the match is expected to
 340          * compensate for any ordering differences in compare which are commutative but require
 341          * reinterpreting the condition in that case.
 342          */
 343         final boolean commutative;
 344 
 345         /**
 346          * Can multiple users of this node subsume it. Constants can be swallowed into a match even
 347          * if there are multiple users.
 348          */
 349         final boolean shareable;
 350 






 351         final Set<Element> originatingElements = new HashSet<>();
 352 
 353         TypeDescriptor(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, List<String> inputs, boolean commutative, boolean shareable) {
 354             this.mirror = mirror;
 355             this.shortName = shortName;
 356             this.nodeClass = nodeClass;
 357             this.nodePackage = nodePackage;
 358             this.inputs = inputs;
 359             this.commutative = commutative;
 360             this.shareable = shareable;

 361             assert !commutative || inputs.size() == 2;
 362         }
 363     }
 364 
 365     /**
 366      * The types which are know for purpose of parsing MatchRule expressions.
 367      */
 368     Map<String, TypeDescriptor> knownTypes = new HashMap<>();
 369 
 370     private TypeDescriptor valueType;
 371 
 372     private void declareType(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, List<String> inputs, boolean commutative, boolean shareable, Element element) {
 373         TypeDescriptor descriptor = new TypeDescriptor(mirror, shortName, nodeClass, nodePackage, inputs, commutative, shareable);

 374         descriptor.originatingElements.add(element);
 375         knownTypes.put(shortName, descriptor);
 376     }
 377 
 378     private String findPackage(Element type) {
 379         PackageElement p = processingEnv.getElementUtils().getPackageOf(type);
 380         if (p != null) {
 381             return p.getQualifiedName().toString();
 382         }
 383         throw new InternalError("Can't find package for " + type);
 384     }
 385 
 386     class MatchDescriptor {
 387         TypeDescriptor nodeType;
 388         String name;
 389         MatchDescriptor[] inputs;
 390 
 391         MatchDescriptor(TypeDescriptor nodeType, String name, boolean forExpression) {
 392             this.nodeType = nodeType;
 393             this.name = name;


 436          * @return a list of Strings which will construct pattern matchers for this rule.
 437          */
 438         List<String> generateVariants() {
 439             String prefix = formatPrefix();
 440             String suffix = formatSuffix();
 441             ArrayList<String> variants = new ArrayList<>();
 442             if (inputs.length > 0) {
 443                 for (String var : recurseVariants(0)) {
 444                     variants.add(prefix + ", " + var + suffix);
 445                 }
 446             } else {
 447                 assert inputs.length == 0;
 448                 variants.add(prefix + suffix);
 449             }
 450 
 451             return variants;
 452         }
 453 
 454         private String formatPrefix() {
 455             if (nodeType == valueType) {
 456                 return String.format("new MatchPattern(%s, false", name != null ? ("\"" + name + "\"") : "null");
 457             } else {
 458                 return String.format("new MatchPattern(%s.class, %s", nodeType.nodeClass, name != null ? ("\"" + name + "\"") : "null");
 459             }
 460         }
 461 
 462         private String formatSuffix() {
 463             if (nodeType != null) {
 464                 if (inputs.length != nodeType.inputs.size()) {
 465                     return ", true)";
 466                 } else {
 467                     if (nodeType.inputs.size() > 0) {
 468                         return ", " + nodeType.nodeClass + "_positions, " + !nodeType.shareable + ")";
 469                     }
 470                     if (nodeType.shareable) {
 471                         return ", false)";
 472                     }
 473                 }
 474             }
 475             return ")";
 476         }
 477 
 478         String generatePositionDeclaration() {
 479             return String.format("Position[] %s_positions = MatchRuleRegistry.findPositions(%s.TYPE, new String[]{\"%s\"});", nodeType.nodeClass, nodeType.nodeClass,
 480                             String.join("\", \"", nodeType.inputs));
 481         }
 482     }
 483 
 484     /**
 485      * Strip the package off a class name leaving the full class name including any outer classes.
 486      */
 487     private String fullClassName(Element element) {
 488         String pkg = findPackage(element);
 489         return ((TypeElement) element).getQualifiedName().toString().substring(pkg.length() + 1);
 490     }
 491 


 704         TypeMirror matchRuleTypeMirror = matchRuleTypeElement.asType();
 705 
 706         TypeElement matchableNodeTypeElement = getTypeElement(MATCHABLE_NODE_CLASS_NAME);
 707         TypeElement matchableNodesTypeElement = getTypeElement(MATCHABLE_NODES_CLASS_NAME);
 708 
 709         currentRound = roundEnv;
 710         try {
 711             for (Element element : roundEnv.getElementsAnnotatedWith(matchableNodeTypeElement)) {
 712                 currentElement = element;
 713                 logMessage("%s\n", element);
 714                 processMatchableNodes(element);
 715             }
 716             for (Element element : roundEnv.getElementsAnnotatedWith(matchableNodesTypeElement)) {
 717                 currentElement = element;
 718                 logMessage("%s\n", element);
 719                 processMatchableNodes(element);
 720             }
 721             // Define a TypeDescriptor for the generic node but don't enter it into the nodeTypes
 722             // table since it shouldn't be mentioned in match rules.
 723             TypeMirror valueTypeMirror = getTypeElement(VALUE_NODE_CLASS_NAME).asType();
 724             valueType = new TypeDescriptor(valueTypeMirror, "Value", "ValueNode", "org.graalvm.compiler.nodes", Collections.emptyList(), false, false);
 725 
 726             Map<TypeElement, MatchRuleDescriptor> map = new HashMap<>();
 727 
 728             for (Element element : roundEnv.getElementsAnnotatedWith(matchRuleTypeElement)) {
 729                 currentElement = element;
 730                 AnnotationMirror matchRule = getAnnotation(element, matchRuleTypeMirror);
 731                 List<AnnotationMirror> matchRuleAnnotations = Collections.singletonList(matchRule);
 732                 processMatchRules(map, element, matchRuleAnnotations);
 733             }
 734             for (Element element : roundEnv.getElementsAnnotatedWith(matchRulesTypeElement)) {
 735                 currentElement = element;
 736                 AnnotationMirror matchRules = getAnnotation(element, matchRulesTypeMirror);
 737                 List<AnnotationMirror> matchRuleAnnotations = getAnnotationValueList(matchRules, "value", AnnotationMirror.class);
 738                 processMatchRules(map, element, matchRuleAnnotations);
 739             }
 740 
 741             currentElement = null;
 742             for (MatchRuleDescriptor info : map.values()) {
 743                 createFiles(info);
 744             }


 814         for (String input : inputs) {
 815             boolean ok = false;
 816             TypeElement current = nodeClassElement;
 817             while (!ok && current != null) {
 818                 for (Element fieldElement : ElementFilter.fieldsIn(current.getEnclosedElements())) {
 819                     if (fieldElement.getSimpleName().toString().equals(input)) {
 820                         ok = true;
 821                         break;
 822                     }
 823                 }
 824                 TypeMirror theSuper = current.getSuperclass();
 825                 current = (TypeElement) typeUtils.asElement(theSuper);
 826             }
 827             if (!ok) {
 828                 printError(element, matchable, "Input named \"%s\" doesn't exist in %s", input, nodeClassElement.getSimpleName());
 829             }
 830         }
 831 
 832         boolean commutative = getAnnotationValue(matchable, "commutative", Boolean.class);
 833         boolean shareable = getAnnotationValue(matchable, "shareable", Boolean.class);
 834         declareType(nodeClassMirror, shortName, nodeClass, nodePackage, inputs, commutative, shareable, element);

 835     }
 836 
 837     private void processMatchRules(Map<TypeElement, MatchRuleDescriptor> map, Element element, List<AnnotationMirror> matchRules) {
 838         if (!processedMatchRules.contains(element)) {
 839             try {
 840                 processedMatchRules.add(element);
 841 
 842                 // The annotation element type should ensure this is true.
 843                 assert element instanceof ExecutableElement;
 844 
 845                 findMatchableNodes(element);
 846 
 847                 TypeElement topDeclaringType = topDeclaringType(element);
 848                 MatchRuleDescriptor info = map.get(topDeclaringType);
 849                 if (info == null) {
 850                     info = new MatchRuleDescriptor(topDeclaringType);
 851                     map.put(topDeclaringType, info);
 852                 }
 853                 for (AnnotationMirror matchRule : matchRules) {
 854                     processMatchRule((ExecutableElement) element, info, matchRule);




 331         final String nodePackage;
 332 
 333         /**
 334          * The matchable inputs of the node.
 335          */
 336         final List<String> inputs;
 337 
 338         /**
 339          * Should swapped variants of this match be generated. The user of the match is expected to
 340          * compensate for any ordering differences in compare which are commutative but require
 341          * reinterpreting the condition in that case.
 342          */
 343         final boolean commutative;
 344 
 345         /**
 346          * Can multiple users of this node subsume it. Constants can be swallowed into a match even
 347          * if there are multiple users.
 348          */
 349         final boolean shareable;
 350 
 351         /**
 352          * Can this node be subsumed into a match even if there are side effecting nodes between
 353          * this node and the match.
 354          */
 355         final boolean ignoresSideEffects;
 356 
 357         final Set<Element> originatingElements = new HashSet<>();
 358 
 359         TypeDescriptor(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, List<String> inputs, boolean commutative, boolean shareable, boolean ignoresSideEffects) {
 360             this.mirror = mirror;
 361             this.shortName = shortName;
 362             this.nodeClass = nodeClass;
 363             this.nodePackage = nodePackage;
 364             this.inputs = inputs;
 365             this.commutative = commutative;
 366             this.shareable = shareable;
 367             this.ignoresSideEffects = ignoresSideEffects;
 368             assert !commutative || inputs.size() == 2;
 369         }
 370     }
 371 
 372     /**
 373      * The types which are know for purpose of parsing MatchRule expressions.
 374      */
 375     Map<String, TypeDescriptor> knownTypes = new HashMap<>();
 376 
 377     private TypeDescriptor valueType;
 378 
 379     private void declareType(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, List<String> inputs, boolean commutative, boolean shareable, boolean ignoresSideEffects,
 380                     Element element) {
 381         TypeDescriptor descriptor = new TypeDescriptor(mirror, shortName, nodeClass, nodePackage, inputs, commutative, shareable, ignoresSideEffects);
 382         descriptor.originatingElements.add(element);
 383         knownTypes.put(shortName, descriptor);
 384     }
 385 
 386     private String findPackage(Element type) {
 387         PackageElement p = processingEnv.getElementUtils().getPackageOf(type);
 388         if (p != null) {
 389             return p.getQualifiedName().toString();
 390         }
 391         throw new InternalError("Can't find package for " + type);
 392     }
 393 
 394     class MatchDescriptor {
 395         TypeDescriptor nodeType;
 396         String name;
 397         MatchDescriptor[] inputs;
 398 
 399         MatchDescriptor(TypeDescriptor nodeType, String name, boolean forExpression) {
 400             this.nodeType = nodeType;
 401             this.name = name;


 444          * @return a list of Strings which will construct pattern matchers for this rule.
 445          */
 446         List<String> generateVariants() {
 447             String prefix = formatPrefix();
 448             String suffix = formatSuffix();
 449             ArrayList<String> variants = new ArrayList<>();
 450             if (inputs.length > 0) {
 451                 for (String var : recurseVariants(0)) {
 452                     variants.add(prefix + ", " + var + suffix);
 453                 }
 454             } else {
 455                 assert inputs.length == 0;
 456                 variants.add(prefix + suffix);
 457             }
 458 
 459             return variants;
 460         }
 461 
 462         private String formatPrefix() {
 463             if (nodeType == valueType) {
 464                 return String.format("new MatchPattern(%s, false, false", name != null ? ("\"" + name + "\"") : "null");
 465             } else {
 466                 return String.format("new MatchPattern(%s.class, %s", nodeType.nodeClass, name != null ? ("\"" + name + "\"") : "null");
 467             }
 468         }
 469 
 470         private String formatSuffix() {
 471             if (nodeType != null) {
 472                 if (inputs.length != nodeType.inputs.size()) {
 473                     return ", true, " + nodeType.ignoresSideEffects + ")";
 474                 } else {
 475                     if (nodeType.inputs.size() > 0) {
 476                         return ", " + nodeType.nodeClass + "_positions, " + !nodeType.shareable + ", " + nodeType.ignoresSideEffects + ")";
 477                     }
 478                     if (nodeType.shareable) {
 479                         return ", false, " + nodeType.ignoresSideEffects + ")";
 480                     }
 481                 }
 482             }
 483             return ")";
 484         }
 485 
 486         String generatePositionDeclaration() {
 487             return String.format("Position[] %s_positions = MatchRuleRegistry.findPositions(%s.TYPE, new String[]{\"%s\"});", nodeType.nodeClass, nodeType.nodeClass,
 488                             String.join("\", \"", nodeType.inputs));
 489         }
 490     }
 491 
 492     /**
 493      * Strip the package off a class name leaving the full class name including any outer classes.
 494      */
 495     private String fullClassName(Element element) {
 496         String pkg = findPackage(element);
 497         return ((TypeElement) element).getQualifiedName().toString().substring(pkg.length() + 1);
 498     }
 499 


 712         TypeMirror matchRuleTypeMirror = matchRuleTypeElement.asType();
 713 
 714         TypeElement matchableNodeTypeElement = getTypeElement(MATCHABLE_NODE_CLASS_NAME);
 715         TypeElement matchableNodesTypeElement = getTypeElement(MATCHABLE_NODES_CLASS_NAME);
 716 
 717         currentRound = roundEnv;
 718         try {
 719             for (Element element : roundEnv.getElementsAnnotatedWith(matchableNodeTypeElement)) {
 720                 currentElement = element;
 721                 logMessage("%s\n", element);
 722                 processMatchableNodes(element);
 723             }
 724             for (Element element : roundEnv.getElementsAnnotatedWith(matchableNodesTypeElement)) {
 725                 currentElement = element;
 726                 logMessage("%s\n", element);
 727                 processMatchableNodes(element);
 728             }
 729             // Define a TypeDescriptor for the generic node but don't enter it into the nodeTypes
 730             // table since it shouldn't be mentioned in match rules.
 731             TypeMirror valueTypeMirror = getTypeElement(VALUE_NODE_CLASS_NAME).asType();
 732             valueType = new TypeDescriptor(valueTypeMirror, "Value", "ValueNode", "org.graalvm.compiler.nodes", Collections.emptyList(), false, false, false);
 733 
 734             Map<TypeElement, MatchRuleDescriptor> map = new HashMap<>();
 735 
 736             for (Element element : roundEnv.getElementsAnnotatedWith(matchRuleTypeElement)) {
 737                 currentElement = element;
 738                 AnnotationMirror matchRule = getAnnotation(element, matchRuleTypeMirror);
 739                 List<AnnotationMirror> matchRuleAnnotations = Collections.singletonList(matchRule);
 740                 processMatchRules(map, element, matchRuleAnnotations);
 741             }
 742             for (Element element : roundEnv.getElementsAnnotatedWith(matchRulesTypeElement)) {
 743                 currentElement = element;
 744                 AnnotationMirror matchRules = getAnnotation(element, matchRulesTypeMirror);
 745                 List<AnnotationMirror> matchRuleAnnotations = getAnnotationValueList(matchRules, "value", AnnotationMirror.class);
 746                 processMatchRules(map, element, matchRuleAnnotations);
 747             }
 748 
 749             currentElement = null;
 750             for (MatchRuleDescriptor info : map.values()) {
 751                 createFiles(info);
 752             }


 822         for (String input : inputs) {
 823             boolean ok = false;
 824             TypeElement current = nodeClassElement;
 825             while (!ok && current != null) {
 826                 for (Element fieldElement : ElementFilter.fieldsIn(current.getEnclosedElements())) {
 827                     if (fieldElement.getSimpleName().toString().equals(input)) {
 828                         ok = true;
 829                         break;
 830                     }
 831                 }
 832                 TypeMirror theSuper = current.getSuperclass();
 833                 current = (TypeElement) typeUtils.asElement(theSuper);
 834             }
 835             if (!ok) {
 836                 printError(element, matchable, "Input named \"%s\" doesn't exist in %s", input, nodeClassElement.getSimpleName());
 837             }
 838         }
 839 
 840         boolean commutative = getAnnotationValue(matchable, "commutative", Boolean.class);
 841         boolean shareable = getAnnotationValue(matchable, "shareable", Boolean.class);
 842         boolean ignoresSideEffects = getAnnotationValue(matchable, "ignoresSideEffects", Boolean.class);
 843         declareType(nodeClassMirror, shortName, nodeClass, nodePackage, inputs, commutative, shareable, ignoresSideEffects, element);
 844     }
 845 
 846     private void processMatchRules(Map<TypeElement, MatchRuleDescriptor> map, Element element, List<AnnotationMirror> matchRules) {
 847         if (!processedMatchRules.contains(element)) {
 848             try {
 849                 processedMatchRules.add(element);
 850 
 851                 // The annotation element type should ensure this is true.
 852                 assert element instanceof ExecutableElement;
 853 
 854                 findMatchableNodes(element);
 855 
 856                 TypeElement topDeclaringType = topDeclaringType(element);
 857                 MatchRuleDescriptor info = map.get(topDeclaringType);
 858                 if (info == null) {
 859                     info = new MatchRuleDescriptor(topDeclaringType);
 860                     map.put(topDeclaringType, info);
 861                 }
 862                 for (AnnotationMirror matchRule : matchRules) {
 863                     processMatchRule((ExecutableElement) element, info, matchRule);


< prev index next >