/* * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package compiler.lib.ir_framework; import compiler.lib.ir_framework.driver.irmatching.IRViolationException; import compiler.lib.ir_framework.shared.TestFormatException; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * This annotation is used to define a constraint/rule/check on the resulting IR of a test method (method with * {@link Test @Test} annotation). A test method can define multiple {@code @IR} rules. *
* There are two kinds of checks that can be specified: *
{@link #failOn()}: Specify a list of (node) regexes that should not be matched on the {@code PrintIdeal} or * {@code PrintOptoAssembly} output.
{@link #counts()}: Specify a list of ({@code regex,count}) pairs: The (node) {@code regex} should be matched * for the specified amount in {@code count} on the {@code PrintIdeal} or {@code PrintOptoAssembly} output.
* Sometimes, the shape of the resulting IR is changed by commonly used VM flags in such a way that an IR rule no longer * applies. Generally, the framework does not apply any IR rules when any of the following flags are used: * {@code -Xint, -XX:-UseCompiler, -XX:TieredStopAtLevel={1,2,3}, -DExcludeRandom=true, -DFlipC1C2=true}. * Furthermore, a JTreg test could be run with additional VM and Javaoptions flags. The IR verification is not * performed in this case if any of these JTreg flags is used that is not part of the whitelist specified by * {@link TestFramework#JTREG_WHITELIST_FLAGS}. *
* For any other flag specified either by user code (e.g. {@link Scenario#Scenario(int, String...)}, * {@link TestFramework#runWithFlags(String...) etc.} or as part of the JTreg whitelist, IR verification is applied. * To restrict the application of IR rules when certain flags are present that could change the IR, each {@code @IR} * annotation can specify additional preconditions on the allowed test VM flags that must hold when an IR rule is applied. * If the specified preconditions fail, then the framework does not apply the IR rule. These preconditions can be * set with {@link #applyIf()}, {@link #applyIfNot()}, {@link #applyIfAnd()}, or {@link #applyIfOr()}. *
* Examples on how to write tests with IR rules can be found in {@link ir_framework.examples.IRExample} * and also as part of the internal testing in {@link ir_framework.tests.TestIRMatching}. * * @see Test * @see IRNode */ @Retention(RetentionPolicy.RUNTIME) @Repeatable(IRs.class) public @interface IR { /** * Define a list of (node) regexes. If any of these regexes are matched on the PrintIdeal or PrintOptoAssembly, the * IR rule fails and an {@link IRViolationException} is thrown. */ String[] failOn() default {}; /** * Define a list of ((node) regexes,count) string pairs: A regex to be matched on the PrintIdeal or PrintOptoAssembly * is immediately followed by a number specifying how often the regex should be matched. The number can be proceeded * by comparators ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is * specified). *
* If any constraint on the number of regexes cannot be met, the IR rule fails and an * {@link IRViolationException} is thrown. */ String[] counts() default {}; /** * Define a list of {@link CompilePhase} enums to apply the IR rule constraint attributes {@link #failOn()} and/or * {@link #counts()} on. By default, IR matching is applied on the predefined default phase of an IR node * placeholder string as defined in {@link IRNode}. For non-IR node constraints (i.e. user-defined regexes with no * definition in {@link IRNode}), a compile phase must explicitly be set. Otherwise, a {@link TestFormatException} * is reported. */ CompilePhase[] phase() default { CompilePhase.DEFAULT }; /** * Define a single VM flag precondition which must hold when applying the IR rule. If the VM flag precondition * fails, then the IR rule is not applied. This is useful if a commonly used flag alters the IR in such a way that an IR rule * would fail. *
* The precondition is a (flag, value) string pair where the flag must be a valid VM flag and the value must conform * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). *
* This is the inverse of {@link #applyIfNot()}. For multiple preconditions, use {@link #applyIfAnd()} or * {@link #applyIfOr()} depending on the use case. */ String[] applyIf() default {}; /** * Accepts a single feature pair which is composed of CPU feature string followed by a true/false * value where a true value necessities existence of CPU feature and vice-versa. * IR verifications checks are enforced only if the specified feature constraint is met. */ String[] applyIfCPUFeature() default {}; /** * Accepts a list of feature pairs where each pair is composed of target feature string followed by a true/false * value where a true value necessities existence of target feature and vice-versa. * IR verifications checks are enforced only if all the specified feature constraints are met. */ String[] applyIfCPUFeatureAnd() default {}; /** * Accepts a list of feature pairs where each pair is composed of target feature string followed by a true/false * value where a true value necessities existence of target feature and vice-versa. * IR verifications checks are enforced if any of the specified feature constraint is met. */ String[] applyIfCPUFeatureOr() default {}; /** * Define a single VM flag precondition which must not hold when applying the IR rule. If, however, * the VM flag precondition holds, then the IR rule is not applied. This could also be defined as negative * precondition. This is useful if a commonly used flag alters the IR in such a way that an IR rule would fail. *
* The precondition is a (flag, value) string pair where the flag must be a valid VM flag and the value must conform * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). *
* This is the inverse of {@link #applyIf()}. For multiple preconditions, use {@link #applyIfAnd()} or * {@link #applyIfOr()} depending on the use case. */ String[] applyIfNot() default {}; /** * Define a list of at least two VM flag precondition which all must hold when applying the IR rule. * If the one of the VM flag preconditions does not hold, then the IR rule is not applied. This is useful if * commonly used flags alter the IR in such a way that an IR rule would fail. This can also be defined as conjunction * of preconditions. *
* A precondition is a (flag, value) string pair where the flag must be a valid VM flag and the value must conform * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). *
* Use {@link #applyIfOr()} for disjunction and for single precondition constraints use {@link #applyIf()} or * {@link #applyIfNot()} depending on the use case. */ String[] applyIfAnd() default {}; /** * Define a list of at least two VM flag precondition from which at least one must hold when applying * the IR rule. If none of the VM flag preconditions holds, then the IR rule is not applied. This is useful if * commonly used flags alter the IR in such a way that an IR rule would fail. This can also be defined as disjunction * of preconditions. *
* A precondition is a (flag, value) string pair where the flag must be a valid VM flag and the value must conform * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). *
* Use {@link #applyIfAnd()} for conjunction and for single precondition constraints use {@link #applyIf()} or * {@link #applyIfNot()} depending on the use case. */ String[] applyIfOr() default {}; }